Akim Demaille wrote: > "Derek R. Price" <[EMAIL PROTECTED]> writes: > > > Ok, I have amtraces code that slurps in almost all the information that > > scan_one_autoconf_file used to. Unfortuantely I hit a minor snag: > > We are probably working on the same things. Please, show some code so > that we don't duplicate. Patch against the current CVS Automake attached. Please excuse all the "print STDERR"s and my initials littered in comments around the things I was still working on. > I really don't understand what you are talking about... What is > DEFAULT_INCLUDES, how does it work? >From comp-vars.am: DEFS = @DEFS@@DEFAULT_INCLUDES@ Automake subs some compiler include paths into @DEFAULT_INCLUDES@ during the creation of Makefile.ins from Makefile.ams so that any headers described in AM_CONFIG_HEADER can be found during compilation. Unfortuantely, it will not do this if it thinks AC_SUBST(DEFS) was called by configure.ac. Before amtraces this meant that the user had called AC_SUBST(DEFS) themselves and asumedly wanted to override Automake's definition of DEFS. Now I think the structure of the comp-vars.am will need to be changed to define some var other than DEFS to @DEFAULT_INCLUDES@ and then that var should be included as part of the COMPILE makefile variable. Derek -- Derek Price CVS Solutions Architect ( http://CVSHome.org ) mailto:[EMAIL PROTECTED] OpenAvenue ( http://OpenAvenue.com ) -- This sentance has threee errors.
Index: automake.in =================================================================== RCS file: /cvs/automake/automake.in,v retrieving revision 1.846 diff -u -r1.846 automake.in --- automake.in 2001/02/01 22:51:40 1.846 +++ automake.in 2001/02/02 18:13:49 @@ -311,6 +311,155 @@ # 'md_PATH_PROG', ); +# Keep track of which macros to trace and what data format to use +# +# Bourne shell metachars must be escaped :( +%traced_macro_format = +( + # note that this only works to get the first argument since the second + # and third arguments to AC_CONFIG_FILES are generally shell scripts + # and expecting them not ot contain a comma is probably just too much + 'AC_CONFIG_FILES' => '\\$f:\\$l:\\$n:\\$\\{,\\}%', +); +# callbacks for each invocation of each macro +# +# called as: +# +# &{$hash{ref}}($here, $macro, @args) +# +# where $here is the file:line where the macro was found, $macro is the +# macro being processed, and @args are the args the macro was called with +# +# REFERENCE NOTE: Macro args start at $_[2] :^) +# +# Please try and stick to alphabetical order (minus /^_*A[CM]/) with the +# exceptions of the macros which populate the libobjs arrays, which should be +# reordered and filed at the end of this hash +# +# Hmmm... The macro groupings in scan_one_autoconf_files might make +# more sense, but I skipped it for now since the alphabetizing wasn't my +# request +%traced_macro_function = +( + # Some things required by Automake. + AC_ARG_PROGRAM => sub { $seen_arg_prog = $_[0] }, + AM_C_PROTOTYPES => sub { $am_c_prototypes = $_[0] }, + AC_CANONICAL_HOST => \&scan_autoconf_traces_AC_CANONICAL_HOST, + AC_CANONICAL_SYSTEM => sub { $seen_canonical = $AC_CANONICAL_SYSTEM }, + AC_CHECK_TOOL => \&scan_autoconf_traces_AC_CANONICAL_HOST, + AM_CONDITIONAL => sub { $configure_cond{$_[2]} = $_[0] }, + AC_CONFIG_AUX_DIR => sub { @config_aux_path = $_[2] }, + AC_CONFIG_FILES => sub { &scan_autoconf_config_files ($_[2]) }, + # Handle configuration headers + AC_CONFIG_HEADER => \&scan_autoconf_traces_AC_CONFIG_HEADER, + AC_CONFIG_HEADERS => \&scan_autoconf_traces_AC_CONFIG_HEADER, + AM_CONFIG_HEADER => \&scan_autoconf_traces_AM_CONFIG_HEADER, + AC_DECL_YYTEXT => + sub { unless ($seen_decl_yytext eq $_[0]) + { + $seen_decl_yytext = $_[0]; + &am_conf_line_warning ( + split (/:/, $_[0]), + "\`AC_DECL_YYTEXT' is covered by \`AM_PROG_LEX'"); + } + }, + AM_ENABLE_MULTILIB => sub { $seen_multilib = $_[0] }, + AC_EXEEXT => sub { $seen_exeext = 1 }, + # Check for NLS support. + AM_GNU_GETTEXT => + sub { # FIXME: eliminate redundant $ac_gettext_line + $seen_gettext = $_[0]; + $ac_gettext_line = (split /:/, $_[0])[1]; + }, + # This macro handles several different things. + AM_INIT_AUTOMAKE => + sub { $seen_make_set = $_[0]; + $seen_arg_prog = $_[0]; + $seen_prog_install = $_[0]; + $package_version = $_[3]; + $package_version_line = (split /:/, $_[0])[2]; + $seen_init_automake = $_[0]; + }, + AC_LIBOBJ => sub { $libsources{"$_[2].c"} = $_[0] }, + _AC_LIBOBJ_DECL => + sub { $libsources{"$_[1].c"} = $_[0] + unless defined $libsources{"$_[2].c"}; + }, + AM_MAINTAINER_MODE => + sub { $seen_maint_mode = $_[0]; + $configure_cond{'MAINTAINER_MODE'} = $_[0]; + }, + AC_OBJEXT => sub { $seen_objext = 1 }, + # Like AC_CONFIG_FILES + AC_OUTPUT => sub { &scan_autoconf_config_files ($_[2]) }, + AM_PATH_LISPDIR => sub { $seen_lispdir = $_[0] }, + AM_PATH_PYTHON => sub { $seen_pythondir = $_[0] }, + AC_PATH_XTRA => sub { $seen_path_xtra = $_[0] }, + # Check for `-c -o' code. + AM_PROG_CC_C_O => sub { $seen_cc_c_o = $_[0] }, + AC_PROG_LEX => + sub { &am_conf_line_warning ( + split (/:/, $_[0]), + "automake requires \`AM_PROG_LEX', not \`AC_PROG_LEX'") + unless ($seen_decl_yytext eq $_[0]); + }, + AM_PROG_LEX => sub { $seen_decl_yytext = $_[0] }, + AC_PROG_LIBTOOL => + sub { $seen_libtool = $_[0]; + $libtool_line = (split /:/, $_[0])[1]; + }, + AM_PROG_LIBTOOL => + sub { &am_conf_line_warning ( + split (/:/, $_[0]), + "\`AM_PROG_LIBTOOL' is obsolete, use \`AC_PROG_LIBTOOL' instead" + ); + # FIXME: should we really be preserving AC_PROG_LIBTOOL behavior + # below? + $seen_libtool = $_[0]; + $libtool_line = (split /:/, $_[0])[1]; + }, + AC_PROG_INSTALL => sub { $seen_prog_install = $_[0] }, + AC_PROG_MAKE_SET => sub { $seen_make_set = $_[0] }, + AC_REPLACE_FUNCS => + sub { foreach (split /\s/, $_[2]) + { $libsources{$_ . '.c'} = $_[0] } + }, + AC_SUBST => + sub { $configure_vars{$_[2]} = $_[0] + unless defined $configure_vars{$_[2]}; + }, + # Populate libobjs array. + # This section is an exception to the alphabetical ordering + AC_FUNC_ALLOCA => sub { $libsources{'alloca.c'} = $_[0] }, + AM_FUNC_ERROR_AT_LINE => + sub { $libsources{'error.c'} = $_[0]; + $libsources{'error.h'} = $_[0]; + }, + AC_FUNC_GETLOADAVG => sub { $libsources{'getloadavg.c'} = $_[0] }, + AC_FUNC_MEMCMP => sub { $libsources{'memcmp.c'} = $_[0] }, + AC_FUNC_MKTIME => sub { $libsources{'mktime.c'} = $_[0] }, + AM_FUNC_OBSTACK => + sub { $libsources{'obstack.c'} = $_[0]; + $libsources{'obstack.h'} = $_[0]; + }, + AM_FUNC_STRTOD => sub { $libsources{'strtod.c'} = $_[0] }, + AC_REPLACE_GNU_GETOPT => + sub { $libsources{'getopt.c'} = $_[0]; + $libsources{'getopt1.c'} = $_[0]; + }, + AM_REPLACE_GNU_GETOPT => + sub { $libsources{'getopt.c'} = $_[0]; + $libsources{'getopt1.c'} = $_[0]; + }, + AC_STRUCT_ST_BLOCKS => sub { $libsources{'fileblocks.c'} = $_[0] }, + AM_WITH_REGEX => + sub { $libsources{'rx.c'} = $_[0]; + $libsources{'rx.h'} = $_[0]; + $libsources{'regex.c'} = $_[0]; + $libsources{'regex.h'} = $_[0]; + }, +); + # Regexp to match the above macros. $obsolete_rx = '(\b' . join ('\b|\b', keys %obsolete_macros) . '\b)'; @@ -840,6 +989,7 @@ $extension = '.$(OBJEXT)' if $seen_objext; $extension = '.lo' if ($out =~ /\.la$/); + print STDERR "entering included generic compile loop\n"; if (! $included_generic_compile) { # Boilerplate. @@ -858,6 +1008,7 @@ } } } + print STDERR "set DEFAULT_INCLUDES = $default_include\n"; local ($xform) = &transform ('DEFAULT_INCLUDES' => $default_include); $output_vars .= &file_contents ('comp-vars', $xform); @@ -3014,7 +3165,6 @@ $i += 3; my $val = "${derived}_${flag}"; - my $obj_compile = $language_map{"$lang-compile"}; $obj_compile =~ s/\(AM_$flag/\($val/; my $obj_ltcompile = '$(LIBTOOL) --mode=compile ' . $obj_compile; @@ -3492,8 +3642,10 @@ local ($one_name); local ($config_header) = ''; + print STDERR "entering CONFIG_HEADER loop\n"; foreach $one_name (@config_names) { + print STDERR "one_name = $one_name\n"; # Generate CONFIG_HEADER define. local ($one_hdr); if ($relative_dir eq &dirname ($one_name)) @@ -3510,6 +3662,7 @@ } if ($config_header) { + print STDERR "defining CONFIG_HEADER = $config_header\n"; &define_variable ("CONFIG_HEADER", $config_header); } @@ -4301,7 +4454,7 @@ sub scan_autoconf_config_files { # Look at potential Makefile.am's. - foreach (split) + foreach (split /\s/, $_[0]) { # Must skip empty string for Perl 4. next if $_ eq "\\" || $_ eq ''; @@ -4336,6 +4489,54 @@ } + +# &scan_autoconf_traces_MACRO ($here, $macro, @args) +# ----------------------------------- +# Parse the args for a particular macro +# +# REFERENCE NOTE: Macro args start at $_[2] :^) +sub scan_autoconf_traces_AC_CANONICAL_HOST +{ + # Handle AC_CANONICAL_*. Always allow upgrading to + # AC_CANONICAL_SYSTEM, but never downgrading. + $seen_canonical = $AC_CANONICAL_HOST if ! $seen_canonical; +} +sub scan_autoconf_traces_AC_CONFIG_HEADER +{ + # make pattern safe + $_[2] =~ s/\W/\\$&/; + &am_conf_line_error + (split (/:/, $_[0]), + "\`automake requires \`AM_CONFIG_HEADER', not \`AC_CONFIG_HEADER'") + # but make sure we're not called from AM_CONFIG_HEADER + unless grep /^$_[2]$/, @config_fullnames; +} +sub scan_autoconf_traces_AM_CONFIG_HEADER +{ + # FIXME: We might want to keep track of file _and_ line here + # + # also, thinking ahead, multiple calls to AM_CONFIG_HEADER will be allowed + # in the future, so tracking a single line number will be mostly useless + $config_header_line = (split /:/, $_[0])[1]; + local ($one_hdr); + foreach $one_hdr (split ('\s', $_[2])) + { + print STDERR "$one_hdr\n"; + push (@config_fullnames, $one_hdr); + if ($one_hdr =~ /^([^:]+):(.+)$/) + { + push (@config_names, $1); + push (@config_headers, $2); + } + else + { + push (@config_names, $one_hdr); + push (@config_headers, $one_hdr . '.in'); + } + } + print STDERR join (", ", @config_names) . "\n"; +} + # &scan_autoconf_traces ($FILENAME) # --------------------------------- # FIXME: For the time being, we don't care about the FILENAME. @@ -4346,10 +4547,18 @@ local ($traces) = "$ENV{amtraces} "; - $traces .= ' -t AC_CONFIG_FILES'; - $traces .= ' -t _AC_LIBOBJ_DECL'; - $traces .= ' -t AC_SUBST'; + local ($traced); + foreach $traced (keys %traced_macro_function) + { + # FIXME: I imagine we'll run into the system argument + # length limits eventually... + $traces .= " -t $traced" + . (exists $traced_macro_format{$traced} + ? ":" . $traced_macro_format{$traced} + : ""); + } + printf STDERR "$traces\n"; open (TRACES, "$traces |") || die "automake: couldn't open \`$traces': $!\n"; print "automake: reading $traces\n" if $verbose; @@ -4357,34 +4566,33 @@ while (<TRACES>) { chomp; - local ($file, $line, $macro, @args) = split /:/; + /^([^:]*):([^:]*):([^:]*):/; + local ($file, $line, $macro, $rest) = ($1, $2, $3, $'); local ($here) = "$file:$line"; + local (@args); - # Alphabetical ordering please. - if ($macro eq 'AC_CONFIG_FILES') + if (exists $traced_macro_format{$macro}) { - # Look at potential Makefile.am's. - &scan_autoconf_config_files ($args[0]); + # need to grab the alternate argument seperator + $traced_macro_format{$macro} =~ /\\\$\\\{(.+)\\\}%$/ + || $traced_macro_format{$macro} =~ /\\\$\\?(.)%$/; + local ($sep) = $1; + $sep =~ s/\W/\\$&/; + @args = split /$sep/, $rest; } - elsif ($macro eq '_AC_LIBOBJ_DECL') + else { - local ($source) = "$args[0].c"; - # We should actually also `close' the sources: getopt.c - # wants getopt.h etc. But actually it should be done in the - # macro itself, i.e., we have to first fix Autoconf to extend - # _AC_LIBOBJ_DECL and use it the in various macros. - if (!defined $libsources{$source}) - { - $libsources{$source} = $here; - } - } - elsif ($macro eq 'AC_SUBST') - { - if (!defined $configure_vars{$args[0]}) - { - $configure_vars{$args[0]} = $here; - } + @args = split /:/, $rest; } + + print STDERR "traces: discovered $macro" + . (@args ? " ($args[0])" : "") + . "\n"; + print STDERR "traces: discovered $macro" + . (@args ? " (" . join(", ", @args) . ")" : "") + . "\n"; + + &{$traced_macro_function{$macro}}($here, $macro, @args); } close (TRACES) @@ -4422,7 +4630,6 @@ { &scan_one_autoconf_file ($1); } - # Populate libobjs array. if (/AC_FUNC_ALLOCA/) { @@ -4470,6 +4677,8 @@ $libsources{'obstack.c'} = 1; $libsources{'obstack.h'} = 1; } +# DRP's mark +# FIXME - haven't figured out how tracing will parse simple shell sets yet elsif (/LIBOBJS="(.*)\s+\$LIBOBJS"/ || /LIBOBJS="\$LIBOBJS\s+(.*)"/) { @@ -4483,6 +4692,7 @@ } } } +# DRP's mark elsif (/AC_LIBOBJ\(([^)]+)\)/) { $libsources{"$1.c"} = 1; @@ -4504,6 +4714,7 @@ $libsources{$_ . '.c'} = 1; } } +# DRP's mark if (/$obsolete_rx/o) { @@ -4514,6 +4725,7 @@ } &am_conf_line_error ($filename, $., "\`$1' is obsolete$hint"); } +# DRP's mark # Process the AC_OUTPUT and AC_CONFIG_FILES macros. if (! $in_ac_output && s/AC_(OUTPUT|CONFIG_FILES)\s*\(\[?//) @@ -4572,6 +4784,8 @@ $ac_gettext_line = $.; } +# DRP's mark +# FIXME - haven't figured out how tracing will parse simple shell sets yet # Look for ALL_LINGUAS. if (/ALL_LINGUAS="(.*)"$/ || /ALL_LINGUAS=(.*)$/) { @@ -4579,6 +4793,7 @@ $all_linguas = $1; $all_linguas_line = $.; } +# DRP's mark # Handle configuration headers. A config header of `[$1]' # means we are actually scanning AM_CONFIG_HEADER from @@ -4663,6 +4878,7 @@ $configure_vars{$1} = $filename . ':' . $.; } +# DRP's mark # Explicitly avoid ANSI2KNR -- we AC_SUBST that in protos.m4, # but later define it elsewhere. This is pretty hacky. We # also explicitly avoid INSTALL_SCRIPT and some other @@ -4747,9 +4963,6 @@ die "automake: \`configure.ac' or \`configure.in' is required\n" if !$configure_ac; - &scan_one_autoconf_file ($configure_ac); - &scan_one_autoconf_file ('aclocal.m4') - if -f 'aclocal.m4'; if (defined $ENV{'amtraces'}) { @@ -4757,6 +4970,12 @@ warn 'automake: use at your own risks'; &scan_autoconf_traces ($configure_ac); + } + else + { + &scan_one_autoconf_file ($configure_ac); + &scan_one_autoconf_file ('aclocal.m4') + if -f 'aclocal.m4'; } # Set input and output files if not specified by user.