12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214 |
- #!@PERL@ -w
- # -*- perl -*-
- # @configure_input@
- eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
- if 0;
- # aclocal - create aclocal.m4 by scanning configure.ac
- # Copyright (C) 1996-2017 Free Software Foundation, Inc.
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2, or (at your option)
- # any later version.
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- # Written by Tom Tromey <tromey@redhat.com>, and
- # Alexandre Duret-Lutz <adl@gnu.org>.
- BEGIN
- {
- @Aclocal::perl_libdirs = ('@datadir@/@PACKAGE@-@APIVERSION@')
- unless @Aclocal::perl_libdirs;
- unshift @INC, @Aclocal::perl_libdirs;
- }
- use strict;
- use Automake::Config;
- use Automake::General;
- use Automake::Configure_ac;
- use Automake::Channels;
- use Automake::ChannelDefs;
- use Automake::XFile;
- use Automake::FileUtils;
- use File::Basename;
- use File::Path ();
- # Some globals.
- # Support AC_CONFIG_MACRO_DIRS also with older autoconf.
- # FIXME: To be removed in Automake 2.0, once we can assume autoconf
- # 2.70 or later.
- # FIXME: keep in sync with 'internal/ac-config-macro-dirs.m4'.
- my $ac_config_macro_dirs_fallback =
- 'm4_ifndef([AC_CONFIG_MACRO_DIRS], [' .
- 'm4_defun([_AM_CONFIG_MACRO_DIRS], [])' .
- 'm4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])' .
- '])';
- # We do not operate in threaded mode.
- $perl_threads = 0;
- # Include paths for searching macros. We search macros in this order:
- # user-supplied directories first, then the directory containing the
- # automake macros, and finally the system-wide directories for
- # third-party macros.
- # @user_includes can be augmented with -I or AC_CONFIG_MACRO_DIRS.
- # @automake_includes can be reset with the '--automake-acdir' option.
- # @system_includes can be augmented with the 'dirlist' file or the
- # ACLOCAL_PATH environment variable, and reset with the '--system-acdir'
- # option.
- my @user_includes = ();
- my @automake_includes = ("@datadir@/aclocal-$APIVERSION");
- my @system_includes = ('@datadir@/aclocal');
- # Whether we should copy M4 file in $user_includes[0].
- my $install = 0;
- # --diff
- my @diff_command;
- # --dry-run
- my $dry_run = 0;
- # configure.ac or configure.in.
- my $configure_ac;
- # Output file name.
- my $output_file = 'aclocal.m4';
- # Option --force.
- my $force_output = 0;
- # Modification time of the youngest dependency.
- my $greatest_mtime = 0;
- # Which macros have been seen.
- my %macro_seen = ();
- # Remember the order into which we scanned the files.
- # It's important to output the contents of aclocal.m4 in the opposite order.
- # (Definitions in first files we have scanned should override those from
- # later files. So they must appear last in the output.)
- my @file_order = ();
- # Map macro names to file names.
- my %map = ();
- # Ditto, but records the last definition of each macro as returned by --trace.
- my %map_traced_defs = ();
- # Map basenames to macro names.
- my %invmap = ();
- # Map file names to file contents.
- my %file_contents = ();
- # Map file names to file types.
- my %file_type = ();
- use constant FT_USER => 1;
- use constant FT_AUTOMAKE => 2;
- use constant FT_SYSTEM => 3;
- # Map file names to included files (transitively closed).
- my %file_includes = ();
- # Files which have already been added.
- my %file_added = ();
- # Files that have already been scanned.
- my %scanned_configure_dep = ();
- # Serial numbers, for files that have one.
- # The key is the basename of the file,
- # the value is the serial number represented as a list.
- my %serial = ();
- # Matches a macro definition.
- # AC_DEFUN([macroname], ...)
- # or
- # AC_DEFUN(macroname, ...)
- # When macroname is '['-quoted , we accept any character in the name,
- # except ']'. Otherwise macroname stops on the first ']', ',', ')',
- # or '\n' encountered.
- my $ac_defun_rx =
- "(?:AU_ALIAS|A[CU]_DEFUN|AC_DEFUN_ONCE)\\((?:\\[([^]]+)\\]|([^],)\n]+))";
- # Matches an AC_REQUIRE line.
- my $ac_require_rx = "AC_REQUIRE\\((?:\\[([^]]+)\\]|([^],)\n]+))\\)";
- # Matches an m4_include line.
- my $m4_include_rx = "(m4_|m4_s|s)include\\((?:\\[([^]]+)\\]|([^],)\n]+))\\)";
- # Match a serial number.
- my $serial_line_rx = '^#\s*serial\s+(\S*)';
- my $serial_number_rx = '^\d+(?:\.\d+)*$';
- # Autoconf version. This variable is set by 'trace_used_macros'.
- my $ac_version;
- # User directory containing extra m4 files for macros definition,
- # as extracted from calls to the macro AC_CONFIG_MACRO_DIRS.
- # This variable is updated by 'trace_used_macros'.
- my @ac_config_macro_dirs;
- # If set, names a temporary file that must be erased on abnormal exit.
- my $erase_me;
- # Constants for the $ERR_LEVEL parameter of the 'scan_m4_dirs' function.
- use constant SCAN_M4_DIRS_SILENT => 0;
- use constant SCAN_M4_DIRS_WARN => 1;
- use constant SCAN_M4_DIRS_ERROR => 2;
- ################################################################
- # Prototypes for all subroutines.
- #! Prototypes here will automatically be generated by the build system.
- ################################################################
- # Erase temporary file ERASE_ME. Handle signals.
- sub unlink_tmp (;$)
- {
- my ($sig) = @_;
- if ($sig)
- {
- verb "caught SIG$sig, bailing out";
- }
- if (defined $erase_me && -e $erase_me && !unlink ($erase_me))
- {
- fatal "could not remove '$erase_me': $!";
- }
- undef $erase_me;
- # reraise default handler.
- if ($sig)
- {
- $SIG{$sig} = 'DEFAULT';
- kill $sig => $$;
- }
- }
- $SIG{'INT'} = $SIG{'TERM'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'unlink_tmp';
- END { unlink_tmp }
- sub xmkdir_p ($)
- {
- my $dir = shift;
- local $@ = undef;
- return
- if -d $dir or eval { File::Path::mkpath $dir };
- chomp $@;
- $@ =~ s/\s+at\s.*\bline\s\d+.*$//;
- fatal "could not create directory '$dir': $@";
- }
- # Check macros in acinclude.m4. If one is not used, warn.
- sub check_acinclude ()
- {
- foreach my $key (keys %map)
- {
- # FIXME: should print line number of acinclude.m4.
- msg ('syntax', "macro '$key' defined in acinclude.m4 but never used")
- if $map{$key} eq 'acinclude.m4' && ! exists $macro_seen{$key};
- }
- }
- sub reset_maps ()
- {
- $greatest_mtime = 0;
- %macro_seen = ();
- @file_order = ();
- %map = ();
- %map_traced_defs = ();
- %file_contents = ();
- %file_type = ();
- %file_includes = ();
- %file_added = ();
- %scanned_configure_dep = ();
- %invmap = ();
- %serial = ();
- undef &search;
- }
- # install_file ($SRC, $DESTDIR)
- sub install_file ($$)
- {
- my ($src, $destdir) = @_;
- my $dest = $destdir . "/" . basename ($src);
- my $diff_dest;
- verb "installing $src to $dest";
- if ($force_output
- || !exists $file_contents{$dest}
- || $file_contents{$src} ne $file_contents{$dest})
- {
- if (-e $dest)
- {
- msg 'note', "overwriting '$dest' with '$src'";
- $diff_dest = $dest;
- }
- else
- {
- msg 'note', "installing '$dest' from '$src'";
- }
- if (@diff_command)
- {
- if (! defined $diff_dest)
- {
- # $dest does not exist. We create an empty one just to
- # run diff, and we erase it afterward. Using the real
- # the destination file (rather than a temporary file) is
- # good when diff is run with options that display the
- # file name.
- #
- # If creating $dest fails, fall back to /dev/null. At
- # least one diff implementation (Tru64's) cannot deal
- # with /dev/null. However working around this is not
- # worth the trouble since nobody run aclocal on a
- # read-only tree anyway.
- $erase_me = $dest;
- my $f = new IO::File "> $dest";
- if (! defined $f)
- {
- undef $erase_me;
- $diff_dest = '/dev/null';
- }
- else
- {
- $diff_dest = $dest;
- $f->close;
- }
- }
- my @cmd = (@diff_command, $diff_dest, $src);
- $! = 0;
- verb "running: @cmd";
- my $res = system (@cmd);
- Automake::FileUtils::handle_exec_errors "@cmd", 1
- if $res;
- unlink_tmp;
- }
- elsif (!$dry_run)
- {
- xmkdir_p ($destdir);
- xsystem ('cp', $src, $dest);
- }
- }
- }
- # Compare two lists of numbers.
- sub list_compare (\@\@)
- {
- my @l = @{$_[0]};
- my @r = @{$_[1]};
- while (1)
- {
- if (0 == @l)
- {
- return (0 == @r) ? 0 : -1;
- }
- elsif (0 == @r)
- {
- return 1;
- }
- elsif ($l[0] < $r[0])
- {
- return -1;
- }
- elsif ($l[0] > $r[0])
- {
- return 1;
- }
- shift @l;
- shift @r;
- }
- }
- ################################################################
- # scan_m4_dirs($TYPE, $ERR_LEVEL, @DIRS)
- # -----------------------------------------------
- # Scan all M4 files installed in @DIRS for new macro definitions.
- # Register each file as of type $TYPE (one of the FT_* constants).
- # If a directory in @DIRS cannot be read:
- # - fail hard if $ERR_LEVEL == SCAN_M4_DIRS_ERROR
- # - just print a warning if $ERR_LEVEL == SCAN_M4_DIRS_WA
- # - continue silently if $ERR_LEVEL == SCAN_M4_DIRS_SILENT
- sub scan_m4_dirs ($$@)
- {
- my ($type, $err_level, @dirlist) = @_;
- foreach my $m4dir (@dirlist)
- {
- if (! opendir (DIR, $m4dir))
- {
- # TODO: maybe avoid complaining only if errno == ENONENT?
- my $message = "couldn't open directory '$m4dir': $!";
- if ($err_level == SCAN_M4_DIRS_ERROR)
- {
- fatal $message;
- }
- elsif ($err_level == SCAN_M4_DIRS_WARN)
- {
- msg ('unsupported', $message);
- next;
- }
- elsif ($err_level == SCAN_M4_DIRS_SILENT)
- {
- next; # Silently ignore.
- }
- else
- {
- prog_error "invalid \$err_level value '$err_level'";
- }
- }
- # We reverse the directory contents so that foo2.m4 gets
- # used in preference to foo1.m4.
- foreach my $file (reverse sort grep (! /^\./, readdir (DIR)))
- {
- # Only examine .m4 files.
- next unless $file =~ /\.m4$/;
- # Skip some files when running out of srcdir.
- next if $file eq 'aclocal.m4';
- my $fullfile = File::Spec->canonpath ("$m4dir/$file");
- scan_file ($type, $fullfile, 'aclocal');
- }
- closedir (DIR);
- }
- }
- # Scan all the installed m4 files and construct a map.
- sub scan_m4_files ()
- {
- # First, scan configure.ac. It may contain macro definitions,
- # or may include other files that define macros.
- scan_file (FT_USER, $configure_ac, 'aclocal');
- # Then, scan acinclude.m4 if it exists.
- if (-f 'acinclude.m4')
- {
- scan_file (FT_USER, 'acinclude.m4', 'aclocal');
- }
- # Finally, scan all files in our search paths.
- if (@user_includes)
- {
- # Don't explore the same directory multiple times. This is here not
- # only for speedup purposes. We need this when the user has e.g.
- # specified 'ACLOCAL_AMFLAGS = -I m4' and has also set
- # AC_CONFIG_MACRO_DIR[S]([m4]) in configure.ac. This makes the 'm4'
- # directory to occur twice here and fail on the second call to
- # scan_m4_dirs([m4]) when the 'm4' directory doesn't exist.
- # TODO: Shouldn't there be rather a check in scan_m4_dirs for
- # @user_includes[0]?
- @user_includes = uniq @user_includes;
- # Don't complain if the first user directory doesn't exist, in case
- # we need to create it later (can happen if '--install' was given).
- scan_m4_dirs (FT_USER,
- $install ? SCAN_M4_DIRS_SILENT : SCAN_M4_DIRS_WARN,
- $user_includes[0]);
- scan_m4_dirs (FT_USER,
- SCAN_M4_DIRS_ERROR,
- @user_includes[1..$#user_includes]);
- }
- scan_m4_dirs (FT_AUTOMAKE, SCAN_M4_DIRS_ERROR, @automake_includes);
- scan_m4_dirs (FT_SYSTEM, SCAN_M4_DIRS_ERROR, @system_includes);
- # Construct a new function that does the searching. We use a
- # function (instead of just evaluating $search in the loop) so that
- # "die" is correctly and easily propagated if run.
- my $search = "sub search {\nmy \$found = 0;\n";
- foreach my $key (reverse sort keys %map)
- {
- $search .= ('if (/\b\Q' . $key . '\E(?!\w)/) { add_macro ("' . $key
- . '"); $found = 1; }' . "\n");
- }
- $search .= "return \$found;\n};\n";
- eval $search;
- prog_error "$@\n search is $search" if $@;
- }
- ################################################################
- # Add a macro to the output.
- sub add_macro ($)
- {
- my ($macro) = @_;
- # Ignore unknown required macros. Either they are not really
- # needed (e.g., a conditional AC_REQUIRE), in which case aclocal
- # should be quiet, or they are needed and Autoconf itself will
- # complain when we trace for macro usage later.
- return unless defined $map{$macro};
- verb "saw macro $macro";
- $macro_seen{$macro} = 1;
- add_file ($map{$macro});
- }
- # scan_configure_dep ($file)
- # --------------------------
- # Scan a configure dependency (configure.ac, or separate m4 files)
- # for uses of known macros and AC_REQUIREs of possibly unknown macros.
- # Recursively scan m4_included files.
- sub scan_configure_dep ($)
- {
- my ($file) = @_;
- # Do not scan a file twice.
- return ()
- if exists $scanned_configure_dep{$file};
- $scanned_configure_dep{$file} = 1;
- my $mtime = mtime $file;
- $greatest_mtime = $mtime if $greatest_mtime < $mtime;
- my $contents = exists $file_contents{$file} ?
- $file_contents{$file} : contents $file;
- my $line = 0;
- my @rlist = ();
- my @ilist = ();
- foreach (split ("\n", $contents))
- {
- ++$line;
- # Remove comments from current line.
- s/\bdnl\b.*$//;
- s/\#.*$//;
- # Avoid running all the following regexes on white lines.
- next if /^\s*$/;
- while (/$m4_include_rx/go)
- {
- my $ifile = $2 || $3;
- # Skip missing 'sinclude'd files.
- next if $1 ne 'm4_' && ! -f $ifile;
- push @ilist, $ifile;
- }
- while (/$ac_require_rx/go)
- {
- push (@rlist, $1 || $2);
- }
- # The search function is constructed dynamically by
- # scan_m4_files. The last parenthetical match makes sure we
- # don't match things that look like macro assignments or
- # AC_SUBSTs.
- if (! &search && /(^|\s+)(AM_[A-Z0-9_]+)($|[^\]\)=A-Z0-9_])/)
- {
- # Macro not found, but AM_ prefix found.
- # Make this just a warning, because we do not know whether
- # the macro is actually used (it could be called conditionally).
- msg ('unsupported', "$file:$line",
- "macro '$2' not found in library");
- }
- }
- add_macro ($_) foreach (@rlist);
- scan_configure_dep ($_) foreach @ilist;
- }
- # add_file ($FILE)
- # ----------------
- # Add $FILE to output.
- sub add_file ($)
- {
- my ($file) = @_;
- # Only add a file once.
- return if ($file_added{$file});
- $file_added{$file} = 1;
- scan_configure_dep $file;
- }
- # Point to the documentation for underquoted AC_DEFUN only once.
- my $underquoted_manual_once = 0;
- # scan_file ($TYPE, $FILE, $WHERE)
- # --------------------------------
- # Scan a single M4 file ($FILE), and all files it includes.
- # Return the list of included files.
- # $TYPE is one of FT_USER, FT_AUTOMAKE, or FT_SYSTEM, depending
- # on where the file comes from.
- # $WHERE is the location to use in the diagnostic if the file
- # does not exist.
- sub scan_file ($$$)
- {
- my ($type, $file, $where) = @_;
- my $basename = basename $file;
- # Do not scan the same file twice.
- return @{$file_includes{$file}} if exists $file_includes{$file};
- # Prevent potential infinite recursion (if two files include each other).
- return () if exists $file_contents{$file};
- unshift @file_order, $file;
- $file_type{$file} = $type;
- fatal "$where: file '$file' does not exist" if ! -e $file;
- my $fh = new Automake::XFile $file;
- my $contents = '';
- my @inc_files = ();
- my %inc_lines = ();
- my $defun_seen = 0;
- my $serial_seen = 0;
- my $serial_older = 0;
- while ($_ = $fh->getline)
- {
- # Ignore '##' lines.
- next if /^##/;
- $contents .= $_;
- my $line = $_;
- if ($line =~ /$serial_line_rx/go)
- {
- my $number = $1;
- if ($number !~ /$serial_number_rx/go)
- {
- msg ('syntax', "$file:$.",
- "ill-formed serial number '$number', "
- . "expecting a version string with only digits and dots");
- }
- elsif ($defun_seen)
- {
- # aclocal removes all definitions from M4 file with the
- # same basename if a greater serial number is found.
- # Encountering a serial after some macros will undefine
- # these macros...
- msg ('syntax', "$file:$.",
- 'the serial number must appear before any macro definition');
- }
- # We really care about serials only for non-automake macros
- # and when --install is used. But the above diagnostics are
- # made regardless of this, because not using --install is
- # not a reason not the fix macro files.
- elsif ($install && $type != FT_AUTOMAKE)
- {
- $serial_seen = 1;
- my @new = split (/\./, $number);
- verb "$file:$.: serial $number";
- if (!exists $serial{$basename}
- || list_compare (@new, @{$serial{$basename}}) > 0)
- {
- # Delete any definition we knew from the old macro.
- foreach my $def (@{$invmap{$basename}})
- {
- verb "$file:$.: ignoring previous definition of $def";
- delete $map{$def};
- }
- $invmap{$basename} = [];
- $serial{$basename} = \@new;
- }
- else
- {
- $serial_older = 1;
- }
- }
- }
- # Remove comments from current line.
- # Do not do it earlier, because the serial line is a comment.
- $line =~ s/\bdnl\b.*$//;
- $line =~ s/\#.*$//;
- while ($line =~ /$ac_defun_rx/go)
- {
- $defun_seen = 1;
- if (! defined $1)
- {
- msg ('syntax', "$file:$.", "underquoted definition of $2"
- . "\n run info Automake 'Extending aclocal'\n"
- . " or see http://www.gnu.org/software/automake/manual/"
- . "automake.html#Extending-aclocal")
- unless $underquoted_manual_once;
- $underquoted_manual_once = 1;
- }
- # If this macro does not have a serial and we have already
- # seen a macro with the same basename earlier, we should
- # ignore the macro (don't exit immediately so we can still
- # diagnose later #serial numbers and underquoted macros).
- $serial_older ||= ($type != FT_AUTOMAKE
- && !$serial_seen && exists $serial{$basename});
- my $macro = $1 || $2;
- if (!$serial_older && !defined $map{$macro})
- {
- verb "found macro $macro in $file: $.";
- $map{$macro} = $file;
- push @{$invmap{$basename}}, $macro;
- }
- else
- {
- # Note: we used to give an error here if we saw a
- # duplicated macro. However, this turns out to be
- # extremely unpopular. It causes actual problems which
- # are hard to work around, especially when you must
- # mix-and-match tool versions.
- verb "ignoring macro $macro in $file: $.";
- }
- }
- while ($line =~ /$m4_include_rx/go)
- {
- my $ifile = $2 || $3;
- # Skip missing 'sinclude'd files.
- next if $1 ne 'm4_' && ! -f $ifile;
- push (@inc_files, $ifile);
- $inc_lines{$ifile} = $.;
- }
- }
- # Ignore any file that has an old serial (or no serial if we know
- # another one with a serial).
- return ()
- if ($serial_older ||
- ($type != FT_AUTOMAKE && !$serial_seen && exists $serial{$basename}));
- $file_contents{$file} = $contents;
- # For some reason I don't understand, it does not work
- # to do "map { scan_file ($_, ...) } @inc_files" below.
- # With Perl 5.8.2 it undefines @inc_files.
- my @copy = @inc_files;
- my @all_inc_files = (@inc_files,
- map { scan_file ($type, $_,
- "$file:$inc_lines{$_}") } @copy);
- $file_includes{$file} = \@all_inc_files;
- return @all_inc_files;
- }
- # strip_redundant_includes (%FILES)
- # ---------------------------------
- # Each key in %FILES is a file that must be present in the output.
- # However some of these files might already include other files in %FILES,
- # so there is no point in including them another time.
- # This removes items of %FILES which are already included by another file.
- sub strip_redundant_includes (%)
- {
- my %files = @_;
- # Always include acinclude.m4, even if it does not appear to be used.
- $files{'acinclude.m4'} = 1 if -f 'acinclude.m4';
- # File included by $configure_ac are redundant.
- $files{$configure_ac} = 1;
- # Files at the end of @file_order should override those at the beginning,
- # so it is important to preserve these trailing files. We can remove
- # a file A if it is going to be output before a file B that includes
- # file A, not the converse.
- foreach my $file (reverse @file_order)
- {
- next unless exists $files{$file};
- foreach my $ifile (@{$file_includes{$file}})
- {
- next unless exists $files{$ifile};
- delete $files{$ifile};
- verb "$ifile is already included by $file";
- }
- }
- # configure.ac is implicitly included.
- delete $files{$configure_ac};
- return %files;
- }
- sub trace_used_macros ()
- {
- my %files = map { $map{$_} => 1 } keys %macro_seen;
- %files = strip_redundant_includes %files;
- # When AC_CONFIG_MACRO_DIRS is used, avoid possible spurious warnings
- # from autom4te about macros being "m4_require'd but not m4_defun'd";
- # for more background, see:
- # http://lists.gnu.org/archive/html/autoconf-patches/2012-11/msg00004.html
- # as well as autoconf commit 'v2.69-44-g1ed0548', "warn: allow aclocal
- # to silence m4_require warnings".
- my $early_m4_code .= "m4_define([m4_require_silent_probe], [-])";
- my $traces = ($ENV{AUTOM4TE} || '@am_AUTOM4TE@');
- $traces .= " --language Autoconf-without-aclocal-m4 ";
- $traces = "echo '$early_m4_code' | $traces - ";
- # Support AC_CONFIG_MACRO_DIRS also with older autoconf.
- # Note that we can't use '$ac_config_macro_dirs_fallback' here, because
- # a bug in option parsing code of autom4te 2.68 and earlier will cause
- # it to read standard input last, even if the "-" argument is specified
- # early.
- # FIXME: To be removed in Automake 2.0, once we can assume autoconf
- # 2.70 or later.
- $traces .= "$automake_includes[0]/internal/ac-config-macro-dirs.m4 ";
- # All candidate files.
- $traces .= join (' ',
- (map { "'$_'" }
- (grep { exists $files{$_} } @file_order))) . " ";
- # All candidate macros.
- $traces .= join (' ',
- (map { "--trace='$_:\$f::\$n::\${::}%'" }
- ('AC_DEFUN',
- 'AC_DEFUN_ONCE',
- 'AU_DEFUN',
- '_AM_AUTOCONF_VERSION',
- 'AC_CONFIG_MACRO_DIR_TRACE',
- # FIXME: Tracing the next two macros is a hack for
- # compatibility with older autoconf. Remove this in
- # Automake 2.0, when we can assume Autoconf 2.70 or
- # later.
- 'AC_CONFIG_MACRO_DIR',
- '_AM_CONFIG_MACRO_DIRS')),
- # Do not trace $1 for all other macros as we do
- # not need it and it might contains harmful
- # characters (like newlines).
- (map { "--trace='$_:\$f::\$n'" } (keys %macro_seen)));
- verb "running $traces $configure_ac";
- my $tracefh = new Automake::XFile ("$traces $configure_ac |");
- @ac_config_macro_dirs = ();
- my %traced = ();
- while ($_ = $tracefh->getline)
- {
- chomp;
- my ($file, $macro, $arg1) = split (/::/);
- $traced{$macro} = 1 if exists $macro_seen{$macro};
- if ($macro eq 'AC_DEFUN' || $macro eq 'AC_DEFUN_ONCE'
- || $macro eq 'AU_DEFUN')
- {
- $map_traced_defs{$arg1} = $file;
- }
- elsif ($macro eq '_AM_AUTOCONF_VERSION')
- {
- $ac_version = $arg1;
- }
- elsif ($macro eq 'AC_CONFIG_MACRO_DIR_TRACE')
- {
- push @ac_config_macro_dirs, $arg1;
- }
- # FIXME: We still need to trace AC_CONFIG_MACRO_DIR
- # for compatibility with older autoconf. Remove this
- # once we can assume Autoconf 2.70 or later.
- elsif ($macro eq 'AC_CONFIG_MACRO_DIR')
- {
- @ac_config_macro_dirs = ($arg1);
- }
- # FIXME:This is an hack for compatibility with older autoconf.
- # Remove this once we can assume Autoconf 2.70 or later.
- elsif ($macro eq '_AM_CONFIG_MACRO_DIRS')
- {
- # Empty leading/trailing fields might be produced by split,
- # hence the grep is really needed.
- push @ac_config_macro_dirs, grep (/./, (split /\s+/, $arg1));
- }
- }
- # FIXME: in Autoconf >= 2.70, AC_CONFIG_MACRO_DIR calls
- # AC_CONFIG_MACRO_DIR_TRACE behind the scenes, which could
- # leave unwanted duplicates in @ac_config_macro_dirs.
- # Remove this in Automake 2.0, when we'll stop tracing
- # AC_CONFIG_MACRO_DIR explicitly.
- @ac_config_macro_dirs = uniq @ac_config_macro_dirs;
- $tracefh->close;
- return %traced;
- }
- sub scan_configure ()
- {
- # Make sure we include acinclude.m4 if it exists.
- if (-f 'acinclude.m4')
- {
- add_file ('acinclude.m4');
- }
- scan_configure_dep ($configure_ac);
- }
- ################################################################
- # Write output.
- # Return 0 iff some files were installed locally.
- sub write_aclocal ($@)
- {
- my ($output_file, @macros) = @_;
- my $output = '';
- my %files = ();
- # Get the list of files containing definitions for the macros used.
- # (Filter out unused macro definitions with $map_traced_defs. This
- # can happen when an Autoconf macro is conditionally defined:
- # aclocal sees the potential definition, but this definition is
- # actually never processed and the Autoconf implementation is used
- # instead.)
- for my $m (@macros)
- {
- $files{$map{$m}} = 1
- if (exists $map_traced_defs{$m}
- && $map{$m} eq $map_traced_defs{$m});
- }
- # Do not explicitly include a file that is already indirectly included.
- %files = strip_redundant_includes %files;
- my $installed = 0;
- for my $file (grep { exists $files{$_} } @file_order)
- {
- # Check the time stamp of this file, and of all files it includes.
- for my $ifile ($file, @{$file_includes{$file}})
- {
- my $mtime = mtime $ifile;
- $greatest_mtime = $mtime if $greatest_mtime < $mtime;
- }
- # If the file to add looks like outside the project, copy it
- # to the output. The regex catches filenames starting with
- # things like '/', '\', or 'c:\'.
- if ($file_type{$file} != FT_USER
- || $file =~ m,^(?:\w:)?[\\/],)
- {
- if (!$install || $file_type{$file} != FT_SYSTEM)
- {
- # Copy the file into aclocal.m4.
- $output .= $file_contents{$file} . "\n";
- }
- else
- {
- # Install the file (and any file it includes).
- my $dest;
- for my $ifile (@{$file_includes{$file}}, $file)
- {
- install_file ($ifile, $user_includes[0]);
- }
- $installed = 1;
- }
- }
- else
- {
- # Otherwise, simply include the file.
- $output .= "m4_include([$file])\n";
- }
- }
- if ($installed)
- {
- verb "running aclocal anew, because some files were installed locally";
- return 0;
- }
- # Nothing to output?!
- # FIXME: Shouldn't we diagnose this?
- return 1 if ! length ($output);
- if ($ac_version)
- {
- # Do not use "$output_file" here for the same reason we do not
- # use it in the header below. autom4te will output the name of
- # the file in the diagnostic anyway.
- $output = "m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
- m4_if(m4_defn([AC_AUTOCONF_VERSION]), [$ac_version],,
- [m4_warning([this file was generated for autoconf $ac_version.
- You have another version of autoconf. It may work, but is not guaranteed to.
- If you have problems, you may need to regenerate the build system entirely.
- To do so, use the procedure documented by the package, typically 'autoreconf'.])])
- $output";
- }
- # We used to print "# $output_file generated automatically etc." But
- # this creates spurious differences when using autoreconf. Autoreconf
- # creates aclocal.m4t and then rename it to aclocal.m4, but the
- # rebuild rules generated by Automake create aclocal.m4 directly --
- # this would gives two ways to get the same file, with a different
- # name in the header.
- $output = "# generated automatically by aclocal $VERSION -*- Autoconf -*-
- # Copyright (C) 1996-$RELEASE_YEAR Free Software Foundation, Inc.
- # This file is free software; the Free Software Foundation
- # gives unlimited permission to copy and/or distribute it,
- # with or without modifications, as long as this notice is preserved.
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY, to the extent permitted by law; without
- # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- # PARTICULAR PURPOSE.
- $ac_config_macro_dirs_fallback
- $output";
- # We try not to update $output_file unless necessary, because
- # doing so invalidate Autom4te's cache and therefore slows down
- # tools called after aclocal.
- #
- # We need to overwrite $output_file in the following situations.
- # * The --force option is in use.
- # * One of the dependencies is younger.
- # (Not updating $output_file in this situation would cause
- # make to call aclocal in loop.)
- # * The contents of the current file are different from what
- # we have computed.
- if (!$force_output
- && $greatest_mtime < mtime ($output_file)
- && $output eq contents ($output_file))
- {
- verb "$output_file unchanged";
- return 1;
- }
- verb "writing $output_file";
- if (!$dry_run)
- {
- if (-e $output_file && !unlink $output_file)
- {
- fatal "could not remove '$output_file': $!";
- }
- my $out = new Automake::XFile "> $output_file";
- print $out $output;
- }
- return 1;
- }
- ################################################################
- # Print usage and exit.
- sub usage ($)
- {
- my ($status) = @_;
- print <<'EOF';
- Usage: aclocal [OPTION]...
- Generate 'aclocal.m4' by scanning 'configure.ac' or 'configure.in'
- Options:
- --automake-acdir=DIR directory holding automake-provided m4 files
- --system-acdir=DIR directory holding third-party system-wide files
- --diff[=COMMAND] run COMMAND [diff -u] on M4 files that would be
- changed (implies --install and --dry-run)
- --dry-run pretend to, but do not actually update any file
- --force always update output file
- --help print this help, then exit
- -I DIR add directory to search list for .m4 files
- --install copy third-party files to the first -I directory
- --output=FILE put output in FILE (default aclocal.m4)
- --print-ac-dir print name of directory holding system-wide
- third-party m4 files, then exit
- --verbose don't be silent
- --version print version number, then exit
- -W, --warnings=CATEGORY report the warnings falling in CATEGORY
- Warning categories include:
- syntax dubious syntactic constructs (default)
- unsupported unknown macros (default)
- all all the warnings (default)
- no-CATEGORY turn off warnings in CATEGORY
- none turn off all the warnings
- error treat warnings as errors
- Report bugs to <@PACKAGE_BUGREPORT@>.
- GNU Automake home page: <@PACKAGE_URL@>.
- General help using GNU software: <http://www.gnu.org/gethelp/>.
- EOF
- exit $status;
- }
- # Print version and exit.
- sub version ()
- {
- print <<EOF;
- aclocal (GNU $PACKAGE) $VERSION
- Copyright (C) $RELEASE_YEAR Free Software Foundation, Inc.
- License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>
- This is free software: you are free to change and redistribute it.
- There is NO WARRANTY, to the extent permitted by law.
- Written by Tom Tromey <tromey\@redhat.com>
- and Alexandre Duret-Lutz <adl\@gnu.org>.
- EOF
- exit 0;
- }
- # Parse command line.
- sub parse_arguments ()
- {
- my $print_and_exit = 0;
- my $diff_command;
- my %cli_options =
- (
- 'help' => sub { usage(0); },
- 'version' => \&version,
- 'system-acdir=s' => sub { shift; @system_includes = @_; },
- 'automake-acdir=s' => sub { shift; @automake_includes = @_; },
- 'diff:s' => \$diff_command,
- 'dry-run' => \$dry_run,
- 'force' => \$force_output,
- 'I=s' => \@user_includes,
- 'install' => \$install,
- 'output=s' => \$output_file,
- 'print-ac-dir' => \$print_and_exit,
- 'verbose' => sub { setup_channel 'verb', silent => 0; },
- 'W|warnings=s' => \&parse_warnings,
- );
- use Automake::Getopt ();
- Automake::Getopt::parse_options %cli_options;
- if (@ARGV > 0)
- {
- fatal ("non-option arguments are not accepted: '$ARGV[0]'.\n"
- . "Try '$0 --help' for more information.");
- }
- if ($print_and_exit)
- {
- print "@system_includes\n";
- exit 0;
- }
- if (defined $diff_command)
- {
- $diff_command = 'diff -u' if $diff_command eq '';
- @diff_command = split (' ', $diff_command);
- $install = 1;
- $dry_run = 1;
- }
- # Finally, adds any directory listed in the 'dirlist' file.
- if (open (DIRLIST, "$system_includes[0]/dirlist"))
- {
- while (<DIRLIST>)
- {
- # Ignore '#' lines.
- next if /^#/;
- # strip off newlines and end-of-line comments
- s/\s*\#.*$//;
- chomp;
- foreach my $dir (glob)
- {
- push (@system_includes, $dir) if -d $dir;
- }
- }
- close (DIRLIST);
- }
- }
- # Add any directory listed in the 'ACLOCAL_PATH' environment variable
- # to the list of system include directories.
- sub parse_ACLOCAL_PATH ()
- {
- return if not defined $ENV{"ACLOCAL_PATH"};
- # Directories in ACLOCAL_PATH should take precedence over system
- # directories, so we use unshift. However, directories that
- # come first in ACLOCAL_PATH take precedence over directories
- # coming later, which is why the result of split is reversed.
- foreach my $dir (reverse split /:/, $ENV{"ACLOCAL_PATH"})
- {
- unshift (@system_includes, $dir) if $dir ne '' && -d $dir;
- }
- }
- ################################################################
- parse_WARNINGS; # Parse the WARNINGS environment variable.
- parse_arguments;
- parse_ACLOCAL_PATH;
- $configure_ac = require_configure_ac;
- # We may have to rerun aclocal if some file have been installed, but
- # it should not happen more than once. The reason we must run again
- # is that once the file has been moved from /usr/share/aclocal/ to the
- # local m4/ directory it appears at a new place in the search path,
- # hence it should be output at a different position in aclocal.m4. If
- # we did not rerun aclocal, the next run of aclocal would produce a
- # different aclocal.m4.
- my $loop = 0;
- my $rerun_due_to_macrodir = 0;
- while (1)
- {
- ++$loop;
- prog_error "too many loops" if $loop > 2 + $rerun_due_to_macrodir;
- reset_maps;
- scan_m4_files;
- scan_configure;
- last if $exit_code;
- my %macro_traced = trace_used_macros;
- if (!$rerun_due_to_macrodir && @ac_config_macro_dirs)
- {
- # The directory specified in calls to the AC_CONFIG_MACRO_DIRS
- # m4 macro (if any) must go after the user includes specified
- # explicitly with the '-I' option.
- push @user_includes, @ac_config_macro_dirs;
- # We might have to scan some new directory of .m4 files.
- $rerun_due_to_macrodir++;
- next;
- }
- if ($install && !@user_includes)
- {
- fatal "installation of third-party macros impossible without " .
- "-I options nor AC_CONFIG_MACRO_DIR{,S} m4 macro(s)";
- }
- last if write_aclocal ($output_file, keys %macro_traced);
- last if $dry_run;
- }
- check_acinclude;
- exit $exit_code;
- ### Setup "GNU" style for perl-mode and cperl-mode.
- ## Local Variables:
- ## perl-indent-level: 2
- ## perl-continued-statement-offset: 2
- ## perl-continued-brace-offset: 0
- ## perl-brace-offset: 0
- ## perl-brace-imaginary-offset: 0
- ## perl-label-offset: -2
- ## cperl-indent-level: 2
- ## cperl-brace-offset: 0
- ## cperl-continued-brace-offset: 0
- ## cperl-label-offset: -2
- ## cperl-extra-newline-before-brace: t
- ## cperl-merge-trailing-else: nil
- ## cperl-continued-statement-offset: 2
- ## End:
|