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_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 enviroment)

msg_failure

Prints "configure: " @_ to stderr and exits with exit code 0 (tells toolchain to stop here and report unsupported enviroment). 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

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 macro 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.

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.

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_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.

_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)