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 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).
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.
push_link_flags¶
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.
link_if_else( $src [, action-if-true [, action-if-false ] ]
)¶
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.
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.
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.
This function checks each given header for usability.
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.
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 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.
_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 Simo~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)