Config-AutoConf
view release on metacpan or search on metacpan
lib/Config/AutoConf.pm view on Meta::CPAN
my $options = {};
scalar @_ > 4 and ref $_[-1] eq "HASH" and $options = pop @_;
$self->msg_checking($message);
defined $ENV{$cache_name}
and not defined $self->{cache}->{$cache_name}
and $self->{cache}->{$cache_name} = $ENV{$cache_name};
my @cached_result;
defined($self->{cache}->{$cache_name}) and push @cached_result, "(cached)";
defined($self->{cache}->{$cache_name}) or $self->{cache}->{$cache_name} = $check_sub->();
$self->msg_result(@cached_result, $self->{cache}->{$cache_name});
$options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $self->{cache}->{$cache_name}
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$self->{cache}->{$cache_name}
and $options->{action_on_false}->();
$self->{cache}->{$cache_name};
}
=head2 cache_val
This function returns the value of a previously check_cached call.
=cut
sub cache_val
{
my ($self, $cache_name) = @_;
ref $self or $self = $self->_get_instance();
defined $self->{cache}->{$cache_name} or return;
$self->{cache}->{$cache_name};
}
=head2 check_decl( $symbol, \%options? )
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 C<ac_cv_decl_E<lt>set langE<gt>>_symbol
variable.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
=cut
sub check_decl
{
my ($self, $symbol) = @_;
$self = $self->_get_instance();
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
defined($symbol) or return croak("No symbol to check for");
ref($symbol) eq "" or return croak("No symbol to check for");
(my $sym_plain = $symbol) =~ s/ *\(.*//;
my $sym_call = $symbol;
$sym_call =~ s/\(/((/;
$sym_call =~ s/\)/) 0)/;
$sym_call =~ s/,/) 0, (/g;
my $cache_name = $self->_cache_name("decl", $self->{lang}, $symbol);
my $check_sub = sub {
my $body = <<ACEOF;
#ifndef $sym_plain
(void) $sym_call;
#endif
ACEOF
my $conftest = $self->lang_build_program($options->{prologue}, $body);
my $have_decl = $self->compile_if_else(
$conftest,
{
($options->{action_on_true} ? (action_on_true => $options->{action_on_true}) : ()),
($options->{action_on_false} ? (action_on_false => $options->{action_on_false}) : ())
}
);
$have_decl;
};
$self->check_cached(
$cache_name,
"whether $symbol is declared",
$check_sub,
{
($options->{action_on_cache_true} ? (action_on_true => $options->{action_on_cache_true}) : ()),
($options->{action_on_cache_false} ? (action_on_false => $options->{action_on_cache_false}) : ())
}
);
}
=head2 check_decls( symbols, \%options? )
For each of the symbols (with optional function argument types for C++
overloads), run L<check_decl>.
Contrary to B<GNU Autoconf>, this method does not declare C<HAVE_DECL_symbol>
macros for the resulting C<confdefs.h>, because it differs as C<check_decl>
between compiling languages.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
Given callbacks for I<action_on_symbol_true> or I<action_on_symbol_false> are
called for each symbol checked using L</check_decl> receiving the symbol as
first argument.
=cut
sub check_decls
{
my ($self, $symbols) = @_;
$self = $self->_get_instance();
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my %pass_options;
defined $options->{prologue} and $pass_options{prologue} = $options->{prologue};
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
my $have_syms = 1;
foreach my $symbol (@$symbols)
{
$have_syms &= $self->check_decl(
$symbol,
{
%pass_options,
(
$options->{action_on_symbol_true} && "CODE" eq ref $options->{action_on_symbol_true}
? (action_on_true => sub { $options->{action_on_symbol_true}->($symbol) })
: ()
),
(
$options->{action_on_symbol_false} && "CODE" eq ref $options->{action_on_symbol_false}
? (action_on_false => sub { $options->{action_on_symbol_false}->($symbol) })
: ()
),
}
);
}
$have_syms
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$have_syms
and $options->{action_on_false}->();
$have_syms;
}
sub _have_func_define_name
{
my $func = $_[0];
my $have_name = "HAVE_" . uc($func);
$have_name =~ tr/_A-Za-z0-9/_/c;
$have_name;
}
=head2 check_func( $function, \%options? )
This method actually tests whether I<$funcion> can be linked into a program
trying to call I<$function>. This method caches its result in the
ac_cv_func_FUNCTION variable.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
If any of I<action_on_cache_true>, I<action_on_cache_false> is defined,
both callbacks are passed to L</check_cached> as I<action_on_true> or
I<action_on_false> to C<check_cached>, respectively.
Returns: True if the function was found, false otherwise
=cut
sub check_func
{
my ($self, $function) = @_;
$self = $self->_get_instance();
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
# Build the name of the cache variable.
my $cache_name = $self->_cache_name('func', $function);
# Wrap the actual check in a closure so that we can use check_cached.
my $check_sub = sub {
my $have_func = $self->link_if_else(
$self->lang_call(q{}, $function),
{
($options->{action_on_true} ? (action_on_true => $options->{action_on_true}) : ()),
($options->{action_on_false} ? (action_on_false => $options->{action_on_false}) : ())
}
);
$have_func;
};
# Run the check and cache the results.
return $self->check_cached(
$cache_name,
"for $function",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_have_func_define_name($function),
$self->cache_val($cache_name),
"Defined when $function is available"
);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_have_func_define_name($function), undef, "Defined when $function is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 check_funcs( \@functions-list, $action-if-true?, $action-if-false? )
The same as check_func, but takes a list of functions in I<\@functions-list>
to look for and checks for each in turn. Define HAVE_FUNCTION for each
function that was found.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
If any of I<action_on_cache_true>, I<action_on_cache_false> is defined,
both callbacks are passed to L</check_cached> as I<action_on_true> or
I<action_on_false> to C<check_cached>, respectively. Given callbacks
for I<action_on_function_true> or I<action_on_function_false> are called for
each symbol checked using L</check_func> receiving the symbol as first
argument.
=cut
sub check_funcs
{
my ($self, $functions_ref) = @_;
$self = $self->_get_instance();
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my %pass_options;
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
# Go through the list of functions and call check_func for each one. We
# generate new closures for the found and not-found functions that pass in
# the relevant function name.
my $have_funcs = 1;
for my $function (@{$functions_ref})
{
# Build the code reference to run when a function was found. This defines
# a HAVE_FUNCTION symbol, plus runs the current $action-if-true if there is
# one.
$pass_options{action_on_true} = sub {
# Run the user-provided hook, if there is one.
defined $options->{action_on_function_true}
and ref $options->{action_on_function_true} eq "CODE"
and $options->{action_on_function_true}->($function);
};
defined $options->{action_on_function_false}
and ref $options->{action_on_function_false} eq "CODE"
and $pass_options{action_on_false} = sub { $options->{action_on_function_false}->($function); };
$have_funcs &= check_func($self, $function, \%pass_options);
}
$have_funcs
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$have_funcs
and $options->{action_on_false}->();
return $have_funcs;
}
=head2 check_builtin( $builtin, \%options? )
This method actually tests whether I<$builtin> is a supported built-in
known by the compiler. Either, by giving us the type of the built-in or
by taking the value from C<__has_builtin>. This method caches its result
in the ac_cv_builtin_FUNCTION variable.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
If any of I<action_on_cache_true>, I<action_on_cache_false> is defined,
both callbacks are passed to L</check_cached> as I<action_on_true> or
I<action_on_false> to C<check_cached>, respectively.
Returns: True if the function was found, false otherwise
=cut
sub _have_builtin_define_name
{
my $builtin = $_[0];
my $have_name = "HAVE_BUILTIN_" . uc($builtin);
$have_name =~ tr/_A-Za-z0-9/_/c;
$have_name;
}
sub check_builtin
{
my ($self, $builtin) = @_;
$self = $self->_get_instance();
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
# Build the name of the cache variable.
my $cache_name = $self->_cache_name('builtin', $builtin);
# Wrap the actual check in a closure so that we can use check_cached.
my $check_sub = sub {
my $have_builtin = $self->link_if_else(
$self->lang_builtin(q{}, $builtin),
{
($options->{action_on_true} ? (action_on_true => $options->{action_on_true}) : ()),
($options->{action_on_false} ? (action_on_false => $options->{action_on_false}) : ())
}
);
$have_builtin;
};
# Run the check and cache the results.
return $self->check_cached(
$cache_name,
"for builtin $builtin",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_have_builtin_define_name($builtin),
$self->cache_val($cache_name),
"Defined when builtin $builtin is available"
);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_have_builtin_define_name($builtin), undef, "Defined when builtin $builtin is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
sub _have_type_define_name
{
my $type = $_[0];
my $have_name = "HAVE_" . uc($type);
$have_name =~ tr/*/P/;
$have_name =~ tr/_A-Za-z0-9/_/c;
$have_name;
}
=head2 check_type( $symbol, \%options? )
Check whether type is defined. It may be a compiler builtin type or defined
by the includes. In C, type must be a type-name, so that the expression
C<sizeof (type)> is valid (but C<sizeof ((type))> is not).
If I<type> type is defined, preprocessor macro HAVE_I<type> (in all
capitals, with "*" replaced by "P" and spaces and dots replaced by
underscores) is defined.
This method caches its result in the C<ac_cv_type_>type variable.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
=cut
sub check_type
{
my ($self, $type) = @_;
$self = $self->_get_instance();
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
defined($type) or return croak("No type to check for");
ref($type) eq "" or return croak("No type to check for");
my $cache_name = $self->_cache_type_name("type", $type);
my $check_sub = sub {
my $body = <<ACEOF;
if( sizeof ($type) )
return 0;
ACEOF
my $conftest = $self->lang_build_program($options->{prologue}, $body);
my $have_type = $self->compile_if_else(
$conftest,
{
($options->{action_on_true} ? (action_on_true => $options->{action_on_true}) : ()),
($options->{action_on_false} ? (action_on_false => $options->{action_on_false}) : ())
}
);
$have_type;
};
$self->check_cached(
$cache_name,
"for $type",
$check_sub,
{
action_on_true => sub {
$self->define_var(_have_type_define_name($type), $self->cache_val($cache_name),
"defined when $type is available");
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_have_type_define_name($type), undef, "defined when $type is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 check_types( \@type-list, \%options? )
For each type in I<@type-list>, call L<check_type> is called to check
for type and return the accumulated result (accumulation op is binary and).
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
Given callbacks for I<action_on_type_true> or I<action_on_type_false> are
called for each symbol checked using L</check_type> receiving the symbol as
first argument.
=cut
sub check_types
{
my ($self, $types) = @_;
$self = $self->_get_instance();
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my %pass_options;
defined $options->{prologue} and $pass_options{prologue} = $options->{prologue};
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
my $have_types = 1;
foreach my $type (@$types)
{
$have_types &= $self->check_type(
$type,
{
%pass_options,
(
$options->{action_on_type_true} && "CODE" eq ref $options->{action_on_type_true}
? (action_on_true => sub { $options->{action_on_type_true}->($type) })
: ()
),
(
$options->{action_on_type_false} && "CODE" eq ref $options->{action_on_type_false}
? (action_on_false => sub { $options->{action_on_type_false}->($type) })
: ()
),
}
);
}
$have_types
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$have_types
and $options->{action_on_false}->();
$have_types;
}
sub _compute_int_compile
{
my ($self, $expr, $prologue, @decls) = @_;
$self = $self->_get_instance();
my ($body, $conftest, $compile_result);
my ($low, $mid, $high) = (0, 0, 0);
if ($self->compile_if_else($self->lang_build_bool_test($prologue, "((long int)($expr)) >= 0", @decls)))
lib/Config/AutoConf.pm view on Meta::CPAN
{
$low = 0;
last;
}
$mid = $low * 2;
}
}
elsif ($self->compile_if_else($self->lang_build_bool_test($prologue, "((long int)($expr)) < 0", @decls)))
{
$high = $mid = -1;
while (1)
{
if ($self->compile_if_else($self->lang_build_bool_test($prologue, "((long int)($expr)) >= $mid", @decls)))
{
$low = $mid;
last;
}
$high = $mid - 1;
# avoid overflow
if ($mid < $high)
{
$high = 0;
last;
}
$mid = $high * 2;
}
}
# perform binary search between $low and $high
while ($low <= $high)
{
$mid = int(($high - $low) / 2 + $low);
if ($self->compile_if_else($self->lang_build_bool_test($prologue, "((long int)($expr)) < $mid", @decls)))
{
$high = $mid - 1;
}
elsif ($self->compile_if_else($self->lang_build_bool_test($prologue, "((long int)($expr)) > $mid", @decls)))
{
$low = $mid + 1;
}
else
{
return $mid;
}
}
return;
}
=head2 compute_int( $expression, @decls?, \%options )
Returns the value of the integer I<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.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
=cut
sub _expr_value_define_name
{
my $expr = $_[0];
my $have_name = "EXPR_" . uc($expr);
$have_name =~ tr/*/P/;
$have_name =~ tr/_A-Za-z0-9/_/c;
$have_name;
}
sub compute_int
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $expr, @decls) = @_;
$self = $self->_get_instance();
my $cache_name = $self->_cache_type_name("compute_int", $self->{lang}, $expr);
my $check_sub = sub {
my $val = $self->_compute_int_compile($expr, $options->{prologue}, @decls);
defined $val
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !defined $val
and $options->{action_on_false}->();
$val;
};
$self->check_cached(
$cache_name,
"for compute result of ($expr)",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_expr_value_define_name($expr),
$self->cache_val($cache_name),
"defined when ($expr) could computed"
);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_expr_value_define_name($expr), undef, "defined when ($expr) could computed");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 check_sizeof_type( $type, \%options? )
Checks for the size of the specified type by compiling and define
C<SIZEOF_type> using the determined size.
In opposition to GNU AutoConf, this method can determine size of structure
members, e.g.
$ac->check_sizeof_type( "SV.sv_refcnt", { prologue => $include_perl } );
# or
$ac->check_sizeof_type( "struct utmpx.ut_id", { prologue => "#include <utmpx.h>" } );
This method caches its result in the C<ac_cv_sizeof_E<lt>set langE<gt>>_type variable.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
=cut
sub _sizeof_type_define_name
{
my $type = $_[0];
my $have_name = "SIZEOF_" . uc($type);
$have_name =~ tr/*/P/;
$have_name =~ tr/_A-Za-z0-9/_/c;
$have_name;
}
sub check_sizeof_type
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $type) = @_;
$self = $self->_get_instance();
defined($type) or return croak("No type to check for");
ref($type) eq "" or return croak("No type to check for");
my $cache_name = $self->_cache_type_name("sizeof", $self->{lang}, $type);
my $check_sub = sub {
my @decls;
if ($type =~ m/^([^.]+)\.([^.]+)$/)
{
my $struct = $1;
$type = "_ac_test_aggr.$2";
my $decl = "static $struct _ac_test_aggr;";
push(@decls, $decl);
}
my $typesize = $self->_compute_int_compile("sizeof($type)", $options->{prologue}, @decls);
$typesize
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$typesize
and $options->{action_on_false}->();
$typesize;
};
$self->check_cached(
$cache_name,
"for size of $type",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_sizeof_type_define_name($type),
$self->cache_val($cache_name),
"defined when sizeof($type) is available"
);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_sizeof_type_define_name($type), undef, "defined when sizeof($type) is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 check_sizeof_types( type, \%options? )
For each type L<check_sizeof_type> is called to check for size of type.
If I<action-if-found> is given, it is additionally executed when all of the
sizes of the types could determined. If I<action-if-not-found> is given, it
is executed when one size of the types could not determined.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
Given callbacks for I<action_on_size_true> or I<action_on_size_false> are
called for each symbol checked using L</check_sizeof_type> receiving the
symbol as first argument.
=cut
sub check_sizeof_types
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $types) = @_;
$self = $self->_get_instance();
my %pass_options;
defined $options->{prologue} and $pass_options{prologue} = $options->{prologue};
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
my $have_sizes = 1;
foreach my $type (@$types)
{
$have_sizes &= !!(
$self->check_sizeof_type(
$type,
{
%pass_options,
(
$options->{action_on_size_true} && "CODE" eq ref $options->{action_on_size_true}
? (action_on_true => sub { $options->{action_on_size_true}->($type) })
: ()
),
(
$options->{action_on_size_false} && "CODE" eq ref $options->{action_on_size_false}
? (action_on_false => sub { $options->{action_on_size_false}->($type) })
: ()
),
}
)
);
}
$have_sizes
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$have_sizes
and $options->{action_on_false}->();
$have_sizes;
}
sub _alignof_type_define_name
{
my $type = $_[0];
my $have_name = "ALIGNOF_" . uc($type);
$have_name =~ tr/*/P/;
$have_name =~ tr/_A-Za-z0-9/_/c;
$have_name;
}
=head2 check_alignof_type( type, \%options? )
Define ALIGNOF_type to be the alignment in bytes of type. I<type> must
be valid as a structure member declaration or I<type> must be a structure
member itself.
This method caches its result in the C<ac_cv_alignof_E<lt>set langE<gt>>_type
variable, with I<*> mapped to C<p> and other characters not suitable for a
variable name mapped to underscores.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
=cut
sub check_alignof_type
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $type) = @_;
$self = $self->_get_instance();
defined($type) or return croak("No type to check for");
ref($type) eq "" or return croak("No type to check for");
my $cache_name = $self->_cache_type_name("alignof", $self->{lang}, $type);
my $check_sub = sub {
my @decls = (
"#ifndef offsetof",
"# ifdef __ICC",
"# define offsetof(type,memb) ((size_t)(((char *)(&((type*)0)->memb)) - ((char *)0)))",
"# else", "# define offsetof(type,memb) ((size_t)&((type*)0)->memb)",
"# endif", "#endif"
);
my ($struct, $memb);
if ($type =~ m/^([^.]+)\.([^.]+)$/)
{
$struct = $1;
$memb = $2;
}
else
{
push(@decls, "typedef struct { char x; $type y; } ac__type_alignof_;");
$struct = "ac__type_alignof_";
$memb = "y";
}
my $typealign = $self->_compute_int_compile("offsetof($struct, $memb)", $options->{prologue}, @decls);
$typealign
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$typealign
and $options->{action_on_false}->();
$typealign;
};
$self->check_cached(
$cache_name,
"for align of $type",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_alignof_type_define_name($type),
$self->cache_val($cache_name),
"defined when alignof($type) is available"
);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_alignof_type_define_name($type), undef, "defined when alignof($type) is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 check_alignof_types (type, [action-if-found], [action-if-not-found], [prologue = default includes])
For each type L<check_alignof_type> is called to check for align of type.
If I<action-if-found> is given, it is additionally executed when all of the
aligns of the types could determined. If I<action-if-not-found> is given, it
is executed when one align of the types could not determined.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
Given callbacks for I<action_on_align_true> or I<action_on_align_false> are
called for each symbol checked using L</check_alignof_type> receiving the
symbol as first argument.
=cut
sub check_alignof_types
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $types) = @_;
$self = $self->_get_instance();
my %pass_options;
defined $options->{prologue} and $pass_options{prologue} = $options->{prologue};
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
my $have_aligns = 1;
foreach my $type (@$types)
{
$have_aligns &= !!(
$self->check_alignof_type(
$type,
{
%pass_options,
(
$options->{action_on_align_true} && "CODE" eq ref $options->{action_on_align_true}
? (action_on_true => sub { $options->{action_on_align_true}->($type) })
: ()
),
(
$options->{action_on_align_false} && "CODE" eq ref $options->{action_on_align_false}
? (action_on_false => sub { $options->{action_on_align_false}->($type) })
: ()
),
}
)
);
}
$have_aligns
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$have_aligns
and $options->{action_on_false}->();
$have_aligns;
}
sub _have_member_define_name
{
my $member = $_[0];
my $have_name = "HAVE_" . uc($member);
$have_name =~ tr/_A-Za-z0-9/_/c;
$have_name;
}
=head2 check_member( member, \%options? )
Check whether I<member> is in form of I<aggregate>.I<member> and
I<member> is a member of the I<aggregate> aggregate.
which are used prior to the aggregate under test.
Config::AutoConf->check_member(
"struct STRUCT_SV.sv_refcnt",
{
action_on_false => sub { Config::AutoConf->msg_failure( "sv_refcnt member required for struct STRUCT_SV" ); },
prologue => "#include <EXTERN.h>\n#include <perl.h>"
}
);
This function will return a true value (1) if the member is found.
If I<aggregate> aggregate has I<member> member, preprocessor
macro HAVE_I<aggregate>_I<MEMBER> (in all capitals, with spaces
and dots replaced by underscores) is defined.
This macro caches its result in the C<ac_cv_>aggr_member variable.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
=cut
sub check_member
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $member) = @_;
$self = $self->_get_instance();
defined($member) or return croak("No type to check for");
ref($member) eq "" or return croak("No type to check for");
$member =~ m/^([^.]+)\.([^.]+)$/ or return croak("check_member(\"struct foo.member\", \%options)");
my $type = $1;
$member = $2;
my $cache_name = $self->_cache_type_name("$type.$member");
my $check_sub = sub {
my $body = <<ACEOF;
static $type check_aggr;
if( check_aggr.$member )
return 0;
ACEOF
my $conftest = $self->lang_build_program($options->{prologue}, $body);
my $have_member = $self->compile_if_else($conftest);
unless ($have_member)
{
$body = <<ACEOF;
static $type check_aggr;
if( sizeof check_aggr.$member )
return 0;
ACEOF
$conftest = $self->lang_build_program($options->{prologue}, $body);
$have_member = $self->compile_if_else($conftest);
}
$have_member
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and $options->{action_on_false}->()
unless $have_member;
$have_member;
};
$self->check_cached(
$cache_name,
"for $type.$member",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_have_member_define_name("$type.$member"),
$self->cache_val($cache_name),
"defined when $type.$member is available"
);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_have_member_define_name("$type.$member"), undef, "defined when $type.$member is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 check_members( members, \%options? )
For each member L<check_member> is called to check for member of aggregate.
This function will return a true value (1) if at least one member is found.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be favored
over C<default includes> (represented by L</_default_includes>). If any of
I<action_on_cache_true>, I<action_on_cache_false> is defined, both callbacks
are passed to L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
Given callbacks for I<action_on_member_true> or I<action_on_member_false> are
called for each symbol checked using L</check_member> receiving the symbol as
first argument.
=cut
sub check_members
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $members) = @_;
$self = $self->_get_instance();
my %pass_options;
defined $options->{prologue} and $pass_options{prologue} = $options->{prologue};
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
my $have_members = 0;
foreach my $member (@$members)
{
$have_members |= (
$self->check_member(
$member,
{
%pass_options,
(
$options->{action_on_member_true} && "CODE" eq ref $options->{action_on_member_true}
? (action_on_true => sub { $options->{action_on_member_true}->($member) })
: ()
),
(
$options->{action_on_member_false} && "CODE" eq ref $options->{action_on_member_false}
? (action_on_false => sub { $options->{action_on_member_false}->($member) })
: ()
),
}
)
);
}
$have_members
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$have_members
and $options->{action_on_false}->();
$have_members;
}
sub _have_header_define_name
{
my $header = $_[0];
my $have_name = "HAVE_" . uc($header);
$have_name =~ tr/_A-Za-z0-9/_/c;
return $have_name;
}
sub _check_header
{
my $options = {};
scalar @_ > 4 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $header, $prologue, $body) = @_;
$prologue .= <<"_ACEOF";
#include <$header>
_ACEOF
my $conftest = $self->lang_build_program($prologue, $body);
$self->compile_if_else($conftest, $options);
}
=head2 check_header( $header, \%options? )
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.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
When a I<prologue> exists in the optional hash at end, it will be prepended
to the tested header. If any of I<action_on_cache_true>,
I<action_on_cache_false> is defined, both callbacks are passed to
L</check_cached> as I<action_on_true> or I<action_on_false> to
C<check_cached>, respectively.
=cut
sub check_header
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $header) = @_;
$self = $self->_get_instance();
defined($header) or return croak("No type to check for");
ref($header) eq "" or return croak("No type to check for");
return 0 unless $header;
my $cache_name = $self->_cache_name($header);
my $check_sub = sub {
my $prologue = defined $options->{prologue} ? $options->{prologue} : "";
my $have_header = $self->_check_header(
$header,
$prologue,
"",
{
($options->{action_on_true} ? (action_on_true => $options->{action_on_true}) : ()),
($options->{action_on_false} ? (action_on_false => $options->{action_on_false}) : ())
}
);
$have_header;
};
$self->check_cached(
$cache_name,
"for $header",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_have_header_define_name($header),
$self->cache_val($cache_name),
"defined when $header is available"
);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_have_header_define_name($header), undef, "defined when $header is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 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.
Passes an optional \%options hash to each L</check_header> call.
=cut
sub check_headers
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my $self = shift->_get_instance();
$self->check_header($_, $options) and return $_ for (@_);
return;
}
=head2 check_all_headers
This function checks each given header for usability and returns true
when each header can be used -- otherwise false.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
Each of existing key/value pairs using I<prologue>, I<action_on_cache_true>
or I<action_on_cache_false> as key are passed-through to each call of
L</check_header>.
Given callbacks for I<action_on_header_true> or I<action_on_header_false> are
called for each symbol checked using L</check_header> receiving the symbol as
first argument.
=cut
sub check_all_headers
{
my $options = {};
scalar @_ > 2 and ref $_[-1] eq "HASH" and $options = pop @_;
my $self = shift->_get_instance();
@_ or return;
my %pass_options;
defined $options->{prologue} and $pass_options{prologue} = $options->{prologue};
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
my $all_headers = 1;
foreach my $header (@_)
{
$all_headers &= $self->check_header(
$header,
{
%pass_options,
(
$options->{action_on_header_true} && "CODE" eq ref $options->{action_on_header_true}
? (action_on_true => sub { $options->{action_on_header_true}->($header) })
: ()
),
(
$options->{action_on_header_false} && "CODE" eq ref $options->{action_on_header_false}
? (action_on_false => sub { $options->{action_on_header_false}->($header) })
: ()
),
}
);
}
$all_headers
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$all_headers
and $options->{action_on_false}->();
$all_headers;
}
=head2 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.
lib/Config/AutoConf.pm view on Meta::CPAN
=cut
sub check_default_headers
{
my $options = {};
scalar @_ > 1 and ref $_[-1] eq "HASH" and $options = pop @_;
my $self = shift->_get_instance();
$self->check_stdc_headers($options)
and $self->check_all_headers(qw(sys/types.h sys/stat.h memory.h strings.h inttypes.h stdint.h unistd.h), $options);
}
=head2 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 C<struct dirent>, not C<struct direct>, and would access the length
of a directory entry name by passing a pointer to a C<struct dirent> to
the C<NAMLEN> macro.
For the found header, the macro HAVE_DIRENT_IN_${header} is defined.
This method might be obsolescent, as all current systems with directory
libraries have C<< E<lt>dirent.hE<gt> >>. Programs supporting only newer OS
might not need to use this method.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
Each of existing key/value pairs using I<prologue>, I<action_on_header_true>
(as I<action_on_true> having the name of the tested header as first argument)
or I<action_on_header_false> (as I<action_on_false> having the name of the
tested header as first argument) as key are passed-through to each call of
L</_check_header>.
Given callbacks for I<action_on_cache_true> or I<action_on_cache_false> are
passed to the call of L</check_cached>.
=cut
sub _have_dirent_header_define_name
{
my $header = $_[0];
my $have_name = "HAVE_DIRENT_IN_" . uc($header);
$have_name =~ tr/_A-Za-z0-9/_/c;
return $have_name;
}
sub check_dirent_header
{
my $options = {};
scalar @_ > 1 and ref $_[-1] eq "HASH" and $options = pop @_;
my $self = shift->_get_instance();
my %pass_options;
defined $options->{prologue} and $pass_options{prologue} = $options->{prologue};
my $have_dirent;
foreach my $header (qw(dirent.h sys/ndir.h sys/dir.h ndir.h))
{
if ($self->check_header($header))
{
my $cache_name = $self->_cache_name("dirent", $header);
my $check_sub = sub {
my $have_dirent;
$have_dirent = $self->_check_header(
$header,
"#include <sys/types.h>\n",
"if ((DIR *) 0) { return 0; }",
{
%pass_options,
(
$options->{action_on_header_true} && "CODE" eq ref $options->{action_on_header_true}
? (action_on_true => sub { $options->{action_on_header_true}->($header) })
: ()
),
(
$options->{action_on_header_false} && "CODE" eq ref $options->{action_on_header_false}
? (action_on_false => sub { $options->{action_on_header_false}->($header) })
: ()
),
}
);
};
$have_dirent = $self->check_cached(
$cache_name,
"for header defining DIR *",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_have_dirent_header_define_name($header),
$self->cache_val($cache_name),
"defined when $header is available"
);
lib/Config/AutoConf.pm view on Meta::CPAN
my $have_libperl = $self->link_if_else($conftest);
$have_libperl or $self->{extra_libs} = [@save_libs];
$have_libperl or $self->{extra_link_flags} = [@save_extra_link_flags];
$have_libperl;
}
=head2 check_link_perlapi
This method can be used from other checks to prove whether we have a perl
development environment or not (perl.h, libperl.la, reasonable basic
checks - types, etc.)
=cut
sub check_link_perlapi
{
my $self = shift->_get_instance;
my $cache_name = $self->_cache_name(qw(link perlapi));
$self->check_cached($cache_name, "whether perlapi is linkable", sub { $self->_check_link_perlapi });
}
sub _have_lib_define_name
{
my $lib = $_[0];
my $have_name = "HAVE_LIB" . uc($lib);
$have_name =~ tr/_A-Za-z0-9/_/c;
return $have_name;
}
=head2 check_lib( lib, func, @other-libs?, \%options? )
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.
In case of function found, the HAVE_LIBlibrary (all in capitals)
preprocessor macro is defined with 1 and $lib together with @other_libs
are added to the list of libraries to link with.
If linking with library results in unresolved symbols that would be
resolved by linking with additional libraries, give those libraries
as the I<other-libs> argument: e.g., C<[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.
This method caches its result in the C<ac_cv_lib_>lib_func variable.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
If any of I<action_on_cache_true>, I<action_on_cache_false> is defined,
both callbacks are passed to L</check_cached> as I<action_on_true> or
I<action_on_false> to C<check_cached>, respectively.
It's recommended to use L<search_libs> instead of check_lib these days.
=cut
sub check_lib
{
my $options = {};
scalar @_ > 1 and ref $_[-1] eq "HASH" and $options = pop @_;
my $self = shift->_get_instance();
my ($lib, $func, @other_libs) = @_;
return 0 unless $lib and $func;
scalar(@other_libs) == 1
and ref($other_libs[0]) eq "ARRAY"
and @other_libs = @{$other_libs[0]};
my $cache_name = $self->_cache_name("lib", $lib, $func);
my $check_sub = sub {
my $conftest = $self->lang_call("", $func);
my @save_libs = @{$self->{extra_libs}};
push(@{$self->{extra_libs}}, $lib, @other_libs);
my $have_lib = $self->link_if_else(
$conftest,
{
($options->{action_on_true} ? (action_on_true => $options->{action_on_true}) : ()),
($options->{action_on_false} ? (action_on_false => $options->{action_on_false}) : ())
}
);
$self->{extra_libs} = [@save_libs];
$have_lib;
};
$self->check_cached(
$cache_name,
"for $func in -l$lib",
$check_sub,
{
action_on_true => sub {
$self->define_var(
_have_lib_define_name($lib),
$self->cache_val($cache_name),
"defined when library $lib is available"
);
push(@{$self->{extra_libs}}, $lib, @other_libs);
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
action_on_false => sub {
$self->define_var(_have_lib_define_name($lib), undef, "defined when library $lib is available");
$options->{action_on_cache_false}
and ref $options->{action_on_cache_false} eq "CODE"
and $options->{action_on_cache_false}->();
},
}
);
}
=head2 search_libs( function, search-libs, @other-libs?, @extra_link_flags?, \%options? )
Config::AutoConf->search_libs("gethostent", "nsl", [qw(socket net)], {
action_on_true => sub { ... }
});
Config::AutoConf->search_libs("log4cplus_initialize", ["log4cplus"],
[[qw(stdc++)], [qw(stdc++ unwind)]],
[qw(-pthread -thread)]
);
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.
I<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.
If linking with library results in unresolved symbols that would be
resolved by linking with additional libraries, give those libraries as
the I<other-libraries> argument: e.g., C<[qw(Xt X11)]> or C<[qw(intl),
qw(intl iconv)]>. 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 C<0> if no
library containing function was found, otherwise as the -llibrary option
that needs to be prepended to LIBS.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
If any of I<action_on_cache_true>, I<action_on_cache_false> is defined,
both callbacks are passed to L</check_cached> as I<action_on_true> or
I<action_on_false> to C<check_cached>, respectively. Given callbacks
for I<action_on_lib_true> or I<action_on_lib_false> are called for
each library checked using L</link_if_else> receiving the library as
first argument and all C<@other_libs> subsequently.
=cut
sub search_libs
{
my $options = {};
scalar @_ > 1 and ref $_[-1] eq "HASH" and $options = pop @_;
my $self = shift->_get_instance();
my ($func, $libs, @other_libs, @other_link_flags) = @_;
(defined($libs) and "ARRAY" eq ref($libs) and scalar(@{$libs}) > 0)
or return 0; # XXX would prefer croak
return 0 unless $func;
scalar(@other_libs) == 1
and ref($other_libs[0]) eq "ARRAY"
and @other_libs = @{$other_libs[0]};
scalar(@other_link_flags) == 1
and ref($other_link_flags[0]) eq "ARRAY"
and @other_link_flags = @{$other_link_flags[0]};
my $cache_name = $self->_cache_name("search", $func);
my $check_sub = sub {
my $conftest = $self->lang_call("", $func);
my @save_libs = @{$self->{extra_libs}};
my @save_extra = @{$self->{extra_link_flags}};
my $have_lib = 0;
my $if_else_sub = sub {
my ($libstest, @other) = @_;
defined($libstest) and unshift(@{$self->{extra_libs}}, $libstest, @other);
$self->link_if_else(
$conftest,
{
(
$options->{action_on_lib_true} && "CODE" eq ref $options->{action_on_lib_true}
? (action_on_true => sub { $options->{action_on_lib_true}->($libstest, @other, @_) })
: ()
),
(
$options->{action_on_lib_false} && "CODE" eq ref $options->{action_on_lib_false}
? (action_on_false => sub { $options->{action_on_lib_false}->($libstest, @other, @_) })
: ()
),
}
) and ($have_lib = defined($libstest) ? $libstest : "none required");
};
LIBTEST:
foreach my $libstest (undef, @$libs)
{
foreach my $linkextra (undef, @other_link_flags)
{
# XXX would local work on array refs? can we omit @save_libs?
$self->{extra_libs} = [@save_libs];
lib/Config/AutoConf.pm view on Meta::CPAN
}
}
else
{
$if_else_sub->($libstest, @other_libs) and last LIBTEST;
}
}
}
$self->{extra_libs} = [@save_libs];
$have_lib
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and !$have_lib
and $options->{action_on_false}->();
$have_lib;
};
return $self->check_cached(
$cache_name,
"for library containing $func",
$check_sub,
{
action_on_true => sub {
$self->cache_val($cache_name) eq "none required"
or unshift(@{$self->{extra_libs}}, $self->cache_val($cache_name));
$options->{action_on_cache_true}
and ref $options->{action_on_cache_true} eq "CODE"
and $options->{action_on_cache_true}->();
},
($options->{action_on_cache_false} ? (action_on_false => $options->{action_on_cache_false}) : ())
}
);
}
sub _check_lm_funcs { qw(log2 pow log10 log exp sqrt) }
=head2 check_lm( \%options? )
This method is used to check if some common C<math.h> functions are
available, and if C<-lm> is needed. Returns the empty string if no
library is needed, or the "-lm" string if libm is needed.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
Each of existing key/value pairs using I<action_on_func_true> (as
I<action_on_true> having the name of the tested functions as first argument),
I<action_on_func_false> (as I<action_on_false> having the name of the tested
functions as first argument), I<action_on_func_lib_true> (as
I<action_on_lib_true> having the name of the tested functions as first
argument), I<action_on_func_lib_false> (as I<action_on_lib_false> having
the name of the tested functions as first argument) as key are passed-
through to each call of L</search_libs>.
Given callbacks for I<action_on_lib_true>, I<action_on_lib_false>,
I<action_on_cache_true> or I<action_on_cache_false> are passed to the
call of L</search_libs>.
B<Note> that I<action_on_lib_true> and I<action_on_func_lib_true> or
I<action_on_lib_false> and I<action_on_func_lib_false> cannot be used
at the same time, respectively.
=cut
sub check_lm
{
my $options = {};
scalar @_ > 1 and ref $_[-1] eq "HASH" and $options = pop @_;
my $self = shift->_get_instance();
defined $options->{action_on_lib_true}
and defined $options->{action_on_func_lib_true}
and croak("action_on_lib_true and action_on_func_lib_true cannot be used together");
defined $options->{action_on_lib_false}
and defined $options->{action_on_func_lib_false}
and croak("action_on_lib_false and action_on_func_lib_false cannot be used together");
my %pass_options;
defined $options->{action_on_cache_true} and $pass_options{action_on_cache_true} = $options->{action_on_cache_true};
defined $options->{action_on_cache_false} and $pass_options{action_on_cache_false} = $options->{action_on_cache_false};
defined $options->{action_on_lib_true} and $pass_options{action_on_lib_true} = $options->{action_on_lib_true};
defined $options->{action_on_lib_false} and $pass_options{action_on_lib_false} = $options->{action_on_lib_false};
my $fail = 0;
my $required = "";
my @math_funcs = $self->_check_lm_funcs;
for my $func (@math_funcs)
{
my $ans = $self->search_libs(
$func,
['m'],
{
%pass_options,
(
$options->{action_on_func_true} && "CODE" eq ref $options->{action_on_func_true}
? (action_on_true => sub { $options->{action_on_func_true}->($func, @_) })
: ()
),
(
$options->{action_on_func_false} && "CODE" eq ref $options->{action_on_func_false}
? (action_on_false => sub { $options->{action_on_func_false}->($func, @_) })
: ()
),
(
$options->{action_on_func_lib_true} && "CODE" eq ref $options->{action_on_func_lib_true}
? (action_on_lib_true => sub { $options->{action_on_func_lib_true}->($func, @_) })
: ()
),
(
$options->{action_on_func_lib_false} && "CODE" eq ref $options->{action_on_func_lib_false}
? (action_on_lib_false => sub { $options->{action_on_func_lib_false}->($func, @_) })
: ()
),
},
);
$ans or $fail = 1;
$ans ne "none required" and $required = $ans;
}
!$fail
and $options->{action_on_true}
and ref $options->{action_on_true} eq "CODE"
and $options->{action_on_true}->();
$fail
and $options->{action_on_false}
and ref $options->{action_on_false} eq "CODE"
and $options->{action_on_false}->();
$required;
}
=head2 pkg_config_package_flags($package, \%options?)
use Config::AutoConf
my $c = Config::AutoConf->new;
$c->pkg_config_package_flags('log4cplus');
WriteMakefile(
...
INC => $c->_get_extra_compiler_flags,
LIBS => $c->_get_extra_linker_flags,
);
Search for C<pkg-config> flags for package as specified. The flags which are
extracted are C<--cflags> and C<--libs>. The extracted flags are appended
to the global C<extra_preprocess_flags>, C<extra_link_flags> or C<extra_libs>,
respectively. Distinguishing between C<extra_link_flags> and C<extra_libs>
is essential to avoid conflicts with L<search_libs function|/search_libs>
and family. In case, no I<package configuration> matching given criteria
could be found, return a C<false> value (C<0>).
The C<pkg-config> flags are taken from I<environment variables>
C<< ${package}_CFLAGS >> or C<< ${package}_LIBS >> when defined, respectively.
It will be a nice touch to document the particular environment variables
for your build procedure - as for above example it should be
$ env log4cplus_CFLAGS="-I/opt/coolapp/include" \
log4cplus_LIBS="-L/opt/coolapp/lib -Wl,-R/opt/coolapp/lib -llog4cplus" \
perl Makefile.PL
Call C<pkg_config_package_flags> with the package you're looking for and
optional callback whether found or not.
To support stage compiling properly (C<rpath> vs. library file location),
the internal representation is a moving target. Do not use the result
directly - the getters L<_get_extra_compiler_flags|/_get_extra_compiler_flags>
and L<_get_extra_linker_flags|/_get_extra_linker_flags> are strongly
encouraged. In case this is not possible, please open a ticket to get
informed on invasive changes.
If the very last parameter contains a hash reference, C<CODE> references
to I<action_on_true> or I<action_on_false> are executed, respectively.
If any of I<action_on_cache_true>, I<action_on_cache_false> is defined,
both callbacks are passed to L</check_cached> as I<action_on_true> or
I<action_on_false> to L</check_cached>, respectively.
=cut
my $_pkg_config_prog;
sub _pkg_config_flag
{
defined $_pkg_config_prog or croak("pkg_config_prog required");
my @pkg_config_args = @_;
my ($stdout, $stderr, $exit) =
capture { system($_pkg_config_prog, @pkg_config_args); };
chomp $stdout;
0 == $exit and return $stdout;
return $exit;
}
sub pkg_config_package_flags
{
my $options = {};
scalar @_ > 1 and ref $_[-1] eq "HASH" and $options = pop @_;
my ($self, $package) = @_;
$self = $self->_get_instance();
(my $pkgpfx = $package) =~ s/^(\w+).*?$/$1/;
my $cache_name = $self->_cache_name("pkg", $pkgpfx);
defined $_pkg_config_prog or $_pkg_config_prog = $self->{cache}->{$self->_cache_name("prog", "PKG_CONFIG")};
defined $_pkg_config_prog or $_pkg_config_prog = $self->check_prog_pkg_config;
my $check_sub = sub {
my (@pkg_cflags, @pkg_libs);
(my $ENV_CFLAGS = $package) =~ s/^(\w+).*?$/$1_CFLAGS/;
(my $ENV_LIBS = $package) =~ s/^(\w+).*?$/$1_LIBS/;
my $pkg_exists = 0 + (
defined $ENV{$ENV_CFLAGS}
or defined $ENV{$ENV_LIBS}
or _pkg_config_flag($package, "--exists") eq ""
);
looks_like_number($pkg_exists) and $pkg_exists == 0 and return 0;
my $CFLAGS =
defined $ENV{$ENV_CFLAGS}
? $ENV{$ENV_CFLAGS}
: _pkg_config_flag($package, "--cflags");
$CFLAGS and not looks_like_number($CFLAGS) and @pkg_cflags = (
map { $_ =~ s/^\s+//; $_ =~ s/\s+$//; Text::ParseWords::shellwords $_; }
split(m/\n/, $CFLAGS)
) and push @{$self->{extra_preprocess_flags}}, @pkg_cflags;
# do not separate between libs and extra (for now) - they come with -l prepended
my $LIBS =
defined $ENV{$ENV_LIBS}
? $ENV{$ENV_LIBS}
: _pkg_config_flag($package, "--libs");
$LIBS and not looks_like_number($LIBS) and @pkg_libs = (
map { $_ =~ s/^\s+//; $_ =~ s/\s+$//; Text::ParseWords::shellwords $_; }
split(m/\n/, $LIBS)
);
( run in 0.431 second using v1.01-cache-2.11-cpan-39bf76dae61 )