The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Config::AutoConf - A module to implement some of AutoConf macros in pure perl.

ABSTRACT

With this module I pretend to simulate some of the tasks AutoConf macros do. To detect a command, to detect a library, etc.

SYNOPSIS

    use Config::AutoConf;

    Config::AutoConf->check_prog("agrep");
    my $grep = Config::AutoConf->check_progs("agrep", "egrep", "grep");

    Config::AutoConf->check_header("ncurses.h");
    my $curses = Config::AutoConf->check_headers("ncurses.h","curses.h");

    Config::AutoConf->check_prog_awk;
    Config::AutoConf->check_prog_egrep;

    Config::AutoConf->check_cc();

    Config::AutoConf->check_lib("ncurses", "tgoto");

    Config::AutoConf->check_file("/etc/passwd"); # -f && -r

FUNCTIONS

new

This function instantiates a new instance of Config::AutoConf, eg. to configure child components.

check_file

This function checks if a file exists in the system and is readable by the user. Returns a boolean. You can use '-f $file && -r $file' so you don't need to use a function call.

check_files

This function checks if a set of files exist in the system and are readable by the user. Returns a boolean.

check_prog

This function checks for a program with the supplied name. In success returns the full path for the executable;

check_progs

This function takes a list of program names. Returns the full path for the first found on the system. Returns undef if none was found.

check_prog_yacc

From the autoconf documentation,

  If `bison' is found, set [...] `bison -y'.
  Otherwise, if `byacc' is found, set [...] `byacc'. 
  Otherwise set [...] `yacc'.

Returns the full path, if found.

check_prog_awk

From the autoconf documentation,

  Check for `gawk', `mawk', `nawk', and `awk', in that order, and
  set output [...] to the first one that is found.  It tries
  `gawk' first because that is reported to be the best
  implementation.

Note that it returns the full path, if found.

check_prog_egrep

From the autoconf documentation,

  Check for `grep -E' and `egrep', in that order, and [...] output
  [...] the first one that is found.

Note that it returns the full path, if found.

check_prog_pkg_config

Checks for pkg-config program. No additional tests are made for it ...

check_cc

This function checks if you have a running C compiler.

msg_checking

Prints "Checking @_ ..."

msg_result

Prints result \n

msg_notice

Prints "configure: " @_ to stdout

msg_warn

Prints "configure: " @_ to stderr

msg_error

Prints "configure: " @_ to stderr and exits with exit code 0 (tells toolchain to stop here and report unsupported environment)

msg_failure

Prints "configure: " @_ to stderr and exits with exit code 0 (tells toolchain to stop here and report unsupported environment). Additional details are provides in config.log (probably more information in a later stage).

define_var( $name, $value [, $comment ] )

Defines a check variable for later use in further checks or code to compile.

write_config_h( [$target] )

Writes the defined constants into given target:

  Config::AutoConf->write_config_h( "config.h" );

push_lang(lang [, implementor ])

Puts the current used language on the stack and uses specified language for subsequent operations until ending pop_lang call.

pop_lang([ lang ])

Pops the currently used language from the stack and restores previously used language. If lang specified, it's asserted that the current used language equals to specified language (helps finding control flow bugs).

lang_call( [prologue], function )

Builds program which simply calls given function. When given, prologue is prepended otherwise, the default includes are used.

lang_build_program( prologue, body )

Builds program for current chosen language. If no prologue is given (undef), the default headers are used. If body is missing, default body is used.

Typical call of

  Config::AutoConf->lang_build_program( "const char hw[] = \"Hello, World\\n\";",
                                        "fputs (hw, stdout);" )

will create

  const char hw[] = "Hello, World\n";

  /* Override any gcc2 internal prototype to avoid an error.  */
  #ifdef __cplusplus
  extern "C" {
  #endif

  int
  main (int argc, char **argv)
  {
    (void)argc;
    (void)argv;
    fputs (hw, stdout);;
    return 0;
  }

  #ifdef __cplusplus
  }
  #endif

lang_build_bool_test (prologue, test, [@decls])

Builds a static test which will fail to compile when test evaluates to false. If @decls is given, it's prepended before the test code at the variable definition place.

push_includes

Adds given list of directories to preprocessor/compiler invocation. This is not proved to allow adding directories which might be created during the build.

push_preprocess_flags

Adds given flags to the parameter list for preprocessor invocation.

push_compiler_flags

Adds given flags to the parameter list for compiler invocation.

push_libraries

Adds given list of libraries to the parameter list for linker invocation.

push_library_paths

Adds given list of library paths to the parameter list for linker invocation.

Adds given flags to the parameter list for linker invocation.

compile_if_else( $src [, action-if-true [, action-if-false ] ] )

This function trys to compile specified code and runs action-if-true on success or action-if-false otherwise.

Returns a boolean value containing check success state.

This function trys to compile and link specified code and runs action-if-true on success or action-if-false otherwise.

Returns a boolean value containing check success state.

check_cached( cache-var, message, sub-to-check )

This function checks whether a specified cache variable is set or not, and if not it's going to set it using specified sub-to-check.

cache_val

This functions returns the value of a previously check_cached call.

check_decl( symbol, [action-if-found], [action-if-not-found], [prologue = default includes] )

If symbol (a function, variable or constant) is not declared in includes and a declaration is needed, run the code ref given in action-if-not-found, otherwise action-if-found. includes is a series of include directives, defaulting to default includes, which are used prior to the declaration under test.

This method actually tests whether symbol is defined as a macro or can be used as an r-value, not whether it is really declared, because it is much safer to avoid introducing extra declarations when they are not needed. In order to facilitate use of C++ and overloaded function declarations, it is possible to specify function argument types in parentheses for types which can be zero-initialized:

          Config::AutoConf->check_decl("basename(char *)")

This method caches its result in the ac_cv_decl_<set lang>_symbol variable.

check_decls( symbols, [action-if-found], [action-if-not-found], [prologue = default includes] )

For each of the symbols (with optional function argument types for C++ overloads), run check_decl. If action-if-not-found is given, it is additional code to execute when one of the symbol declarations is needed, otherwise action-if-found is executed.

Contrary to GNU autoconf, this method does not declare HAVE_DECL_symbol macros for the resulting confdefs.h, because it differs as check_decl between compiling languages.

check_type (type, [action-if-found], [action-if-not-found], [prologue = default includes])

Check whether type is defined. It may be a compiler builtin type or defined by the includes. prologue should be a series of include directives, defaulting to default includes, which are used prior to the type under test.

In C, type must be a type-name, so that the expression sizeof (type) is valid (but sizeof ((type)) is not)

If type type is defined, preprocessor macro HAVE_type (in all capitals, with "*" replaced by "P" and spaces and dots replaced by underscores) is defined.

This method caches its result in the ac_cv_type_type variable.

check_types (types, [action-if-found], [action-if-not-found], [prologue = default includes])

For each type check_type is called to check for type.

If action-if-found is given, it is additionally executed when all of the types are found. If action-if-not-found is given, it is executed when one of the types is not found.

compute_int (expression, [action-if-fails], [prologue = default includes], [@decls])

Returns the value of the integer expression. The value should fit in an initializer in a C variable of type signed long. It should be possible to evaluate the expression at compile-time. If no includes are specified, the default includes are used.

Execute action-if-fails if the value cannot be determined correctly.

check_sizeof_type (type, [action-if-found], [action-if-not-found], [prologue = default includes])

Checks for the size of the specified type by compiling. If no size can determined, action-if-not-found is invoked when given. Otherwise action-if-found is invoked and SIZEOF_type is defined using the determined size.

In opposition to GNU AutoConf, this method can determine size of structure members, eg.

  $ac->check_sizeof_type( "SV.sv_refcnt", undef, undef, $include_perl );
  # or
  $ac->check_sizeof_type( "struct utmpx.ut_id", undef, undef, "#include <utmpx.h>" );

This method caches its result in the ac_cv_sizeof_<set lang>_type variable.

check_sizeof_types (type, [action-if-found], [action-if-not-found], [prologue = default includes])

For each type check_sizeof_type is called to check for size of type.

If action-if-found is given, it is additionally executed when all of the sizes of the types could determined. If action-if-not-found is given, it is executed when one size of the types could not determined.

check_alignof_type (type, [action-if-found], [action-if-not-found], [prologue = default includes])

Define ALIGNOF_type to be the alignment in bytes of type. type y; must be valid as a structure member declaration or type must be a structure member itself.

This method caches its result in the ac_cv_alignof_<set lang>_type variable, with * mapped to p and other characters not suitable for a variable name mapped to underscores.

check_alignof_types (type, [action-if-found], [action-if-not-found], [prologue = default includes])

For each type check_alignof_type is called to check for align of type.

If action-if-found is given, it is additionally executed when all of the aligns of the types could determined. If action-if-not-found is given, it is executed when one align of the types could not determined.

check_member (member, [action-if-found], [action-if-not-found], [prologue = default includes])

Check whether member is in form of aggregate.member and member is a member of the aggregate aggregate. prologue should be a series of include directives, defaulting to default includes, which are used prior to the aggregate under test.

  Config::AutoConf->check_member(
    "struct STRUCT_SV.sv_refcnt",
    undef,
    sub { Config::AutoConf->msg_failure( "sv_refcnt member required for struct STRUCT_SV" ); }
    "#include <EXTERN.h>\n#include <perl.h>"
  );

If aggregate aggregate has member member, preprocessor macro HAVE_aggregate_MEMBER (in all capitals, with spaces and dots replaced by underscores) is defined.

This macro caches its result in the ac_cv_aggr_member variable.

check_members (members, [action-if-found], [action-if-not-found], [prologue = default includes])

For each member check_member is called to check for member of aggregate.

If action-if-found is given, it is additionally executed when all of the aggregate members are found. If action-if-not-found is given, it is executed when one of the aggregate members is not found.

check_headers

This function uses check_header to check if a set of include files exist in the system and can be included and compiled by the available compiler. Returns the name of the first header file found.

check_header

This function is used to check if a specific header file is present in the system: if we detect it and if we can compile anything with that header included. Note that normally you want to check for a header first, and then check for the corresponding library (not all at once).

The standard usage for this module is:

  Config::AutoConf->check_header("ncurses.h");
  

This function will return a true value (1) on success, and a false value if the header is not present or not available for common usage.

check_all_headers

This function checks each given header for usability.

check_stdc_headers

Checks for standard C89 headers, namely stdlib.h, stdarg.h, string.h and float.h. If those are found, additional all remaining C89 headers are checked: assert.h, ctype.h, errno.h, limits.h, locale.h, math.h, setjmp.h, signal.h, stddef.h, stdio.h and time.h.

Returns a false value if it fails.

check_default_headers

This function checks for some default headers, the std c89 haeders and sys/types.h, sys/stat.h, memory.h, strings.h, inttypes.h, stdint.h and unistd.h

check_dirent_header

Check for the following header files. For the first one that is found and defines 'DIR', define the listed C preprocessor macro:

  dirent.h      HAVE_DIRENT_H
  sys/ndir.h    HAVE_SYS_NDIR_H
  sys/dir.h     HAVE_SYS_DIR_H
  ndir.h        HAVE_NDIR_H

The directory-library declarations in your source code should look something like the following:

  #include <sys/types.h>
  #ifdef HAVE_DIRENT_H
  # include <dirent.h>
  # define NAMLEN(dirent) strlen ((dirent)->d_name)
  #else
  # define dirent direct
  # define NAMLEN(dirent) ((dirent)->d_namlen)
  # ifdef HAVE_SYS_NDIR_H
  #  include <sys/ndir.h>
  # endif
  # ifdef HAVE_SYS_DIR_H
  #  include <sys/dir.h>
  # endif
  # ifdef HAVE_NDIR_H
  #  include <ndir.h>
  # endif
  #endif

Using the above declarations, the program would declare variables to be of type struct dirent, not struct direct, and would access the length of a directory entry name by passing a pointer to a struct dirent to the NAMLEN macro.

This macro might be obsolescent, as all current systems with directory libraries have <<dirent.h>>. Programs supporting only newer OS might not need touse this macro.

check_lm( [ action-if-found ], [ action-if-not-found ] )

This method is used to check if some common math.h functions are available, and if -lm is needed. Returns the empty string if no library is needed, or the "-lm" string if libm is needed.

Actions are only called at the end of the list of tests. If one fails, action-if-not-found is run. Otherwise, action-if-found is run.

check_lib( lib, func, [ action-if-found ], [ action-if-not-found ], [ @other-libs ] )

This function is used to check if a specific library includes some function. Call it with the library name (without the lib portion), and the name of the function you want to test:

  Config::AutoConf->check_lib("z", "gzopen");

It returns 1 if the function exist, 0 otherwise.

action-if-found and action-if-not-found can be CODE references whereby the default action in case of function found is to define the HAVE_LIBlibrary (all in capitals) preprocessor macro with 1 and add $lib to the list of libraries to link.

If linking with library results in unresolved symbols that would be resolved by linking with additional libraries, give those libraries as the other-libs argument: e.g., [qw(Xt X11)]. Otherwise, this routine may fail to detect that library is present, because linking the test program can fail with unresolved symbols. The other-libraries argument should be limited to cases where it is desirable to test for one library in the presence of another that is not already in LIBS.

It's recommended to use search_libs instead of check_lib these days.

search_libs( function, search-libs, [action-if-found], [action-if-not-found], [other-libs] )

Search for a library defining function if it's not already available. This equates to calling

    Config::AutoConf->link_if_else(
        Config::AutoConf->lang_call( "", "$function" ) );

first with no libraries, then for each library listed in search-libs. search-libs must be specified as an array reference to avoid confusion in argument order.

Prepend -llibrary to LIBS for the first library found to contain function, and run action-if-found. If the function is not found, run action-if-not-found.

If linking with library results in unresolved symbols that would be resolved by linking with additional libraries, give those libraries as the other-libraries argument: e.g., [qw(Xt X11)]. Otherwise, this method fails to detect that function is present, because linking the test program always fails with unresolved symbols.

The result of this test is cached in the ac_cv_search_function variable as "none required" if function is already available, as 0 if no library containing function was found, otherwise as the -llibrary option that needs to be prepended to LIBS.

pkg_config_package_flags($package, [action-if-found], [action-if-not-found])

Search for pkg-config flags for package as specified. The flags which are extracted are --cflags and --libs. The extracted flags are appended to the global extra_compile_flags and extra_link_flags, respectively.

Call it with the package you're looking for and optional callback whether found or not.

_default_includes

returns a string containing default includes for program prologue taken from autoconf/headers.m4:

  #include <stdio.h>
  #ifdef HAVE_SYS_TYPES_H
  # include <sys/types.h>
  #endif
  #ifdef HAVE_SYS_STAT_H
  # include <sys/stat.h>
  #endif
  #ifdef STDC_HEADERS
  # include <stdlib.h>
  # include <stddef.h>
  #else
  # ifdef HAVE_STDLIB_H
  #  include <stdlib.h>
  # endif
  #endif
  #ifdef HAVE_STRING_H
  # if !defined STDC_HEADERS && defined HAVE_MEMORY_H
  #  include <memory.h>
  # endif
  # include <string.h>
  #endif
  #ifdef HAVE_STRINGS_H
  # include <strings.h>
  #endif
  #ifdef HAVE_INTTYPES_H
  # include <inttypes.h>
  #endif
  #ifdef HAVE_STDINT_H
  # include <stdint.h>
  #endif
  #ifdef HAVE_UNISTD_H
  # include <unistd.h>
  #endif

AUTHOR

Alberto Simões, <ambs@cpan.org>

Jens Rehsack, <rehsack@cpan.org>

NEXT STEPS

Although a lot of work needs to be done, this is the next steps I intent to take.

  - detect flex/lex
  - detect yacc/bison/byacc
  - detect ranlib (not sure about its importance)

These are the ones I think not too much important, and will be addressed later, or by request.

  - detect an 'install' command
  - detect a 'ln -s' command -- there should be a module doing
    this kind of task.

BUGS

A lot. Portability is a pain. <Patches welcome!>.

Please report any bugs or feature requests to bug-extutils-autoconf@rt.cpan.org, or through the web interface at http://rt.cpan.org. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGEMENTS

Michael Schwern for kind MacOS X help.

Ken Williams for ExtUtils::CBuilder

COPYRIGHT & LICENSE

Copyright 2004-2011 by the Authors

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

ExtUtils::CBuilder(3)