# automake - create Makefile.in from Makefile.am
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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)
+# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Originally written by David Mackenzie <djm@gnu.ai.mit.edu>.
# Perl reimplementation by Tom Tromey <tromey@redhat.com>, and
use Automake::Struct;
struct (# Short name of the language (c, f77...).
- 'name' => "\$",
- # Nice name of the language (C, Fortran 77...).
- 'Name' => "\$",
+ 'name' => "\$",
+ # Nice name of the language (C, Fortran 77...).
+ 'Name' => "\$",
# List of configure variables which must be defined.
'config_vars' => '@',
- 'ansi' => "\$",
+ 'ansi' => "\$",
# `pure' is `1' or `'. A `pure' language is one where, if
# all the files in a directory are of that language, then we
# do not require the C compiler or any code to call it.
'autodep' => "\$",
# Name of the compiling variable (COMPILE).
- 'compiler' => "\$",
- # Content of the compiling variable.
- 'compile' => "\$",
- # Flag to require compilation without linking (-c).
- 'compile_flag' => "\$",
- 'extensions' => '@',
+ 'compiler' => "\$",
+ # Content of the compiling variable.
+ 'compile' => "\$",
+ # Flag to require compilation without linking (-c).
+ 'compile_flag' => "\$",
+ 'extensions' => '@',
# A subroutine to compute a list of possible extensions of
# the product given the input extensions.
# (defaults to a subroutine which returns ('.$(OBJEXT)', '.lo'))
'output_extensions' => "\$",
# A list of flag variables used in 'compile'.
# (defaults to [])
- 'flags' => "@",
+ 'flags' => "@",
# Any tag to pass to libtool while compiling.
'libtool_tag' => "\$",
# The default is 'depend2'.
'rule_file' => "\$",
- # Name of the linking variable (LINK).
- 'linker' => "\$",
- # Content of the linking variable.
- 'link' => "\$",
+ # Name of the linking variable (LINK).
+ 'linker' => "\$",
+ # Content of the linking variable.
+ 'link' => "\$",
- # Name of the linker variable (LD).
- 'lder' => "\$",
- # Content of the linker variable ($(CC)).
- 'ld' => "\$",
+ # Name of the linker variable (LD).
+ 'lder' => "\$",
+ # Content of the linker variable ($(CC)).
+ 'ld' => "\$",
- # Flag to specify the output file (-o).
- 'output_flag' => "\$",
- '_finish' => "\$",
+ # Flag to specify the output file (-o).
+ 'output_flag' => "\$",
+ '_finish' => "\$",
# This is a subroutine which is called whenever we finally
# determine the context in which a source file will be
use strict;
use Automake::Config;
+BEGIN
+{
+ if ($perl_threads)
+ {
+ require threads;
+ import threads;
+ require Thread::Queue;
+ import Thread::Queue;
+ }
+}
use Automake::General;
use Automake::XFile;
use Automake::Channels;
use Automake::RuleDef;
use Automake::Wrap 'makefile_wrap';
use File::Basename;
+use File::Spec;
use Carp;
## ----------- ##
my $IGNORE_PATTERN = '^\s*##([^#\n].*)?\n';
my $WHITE_PATTERN = '^\s*' . "\$";
my $COMMENT_PATTERN = '^#';
-my $TARGET_PATTERN='[$a-zA-Z_.@%][-.a-zA-Z0-9_(){}/$+@%]*';
+my $TARGET_PATTERN='[$a-zA-Z0-9_.@%][-.a-zA-Z0-9_(){}/$+@%]*';
# A rule has three parts: a list of targets, a list of dependencies,
# and optionally actions.
my $RULE_PATTERN =
# Standard directories from the GNU Coding Standards, and additional
# pkg* directories from Automake. Stored in a hash for fast member check.
my %standard_prefix =
- map { $_ => 1 } (qw(bin data exec include info lib libexec lisp
- localstate man man1 man2 man3 man4 man5 man6
- man7 man8 man9 oldinclude pkgdatadir
- pkgincludedir pkglibdir sbin sharedstate
- sysconf));
+ map { $_ => 1 } (qw(bin data dataroot dvi exec html include info
+ lib libexec lisp localstate man man1 man2 man3
+ man4 man5 man6 man7 man8 man9 oldinclude pdf
+ pkgdatadir pkgincludedir pkglibdir pkglibexecdir
+ ps sbin sharedstate sysconf));
# Copyright on generated Makefile.ins.
my $gen_copyright = "\
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
# This Makefile.in 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.
# PARTICULAR PURPOSE.
";
-# These constants are returned by lang_*_rewrite functions.
+# These constants are returned by the lang_*_rewrite functions.
# LANG_SUBDIR means that the resulting object file should be in a
# subdir if the source file is. In this case the file name cannot
# have `..' components.
use constant COMPILE_ORDINARY => 2;
# We can't always associate a location to a variable or a rule,
-# when its defined by Automake. We use INTERNAL in this case.
+# when it's defined by Automake. We use INTERNAL in this case.
use constant INTERNAL => new Automake::Location;
+
+# Serialization keys for message queues.
+use constant QUEUE_MESSAGE => "msg";
+use constant QUEUE_CONF_FILE => "conf file";
+use constant QUEUE_LOCATION => "location";
+use constant QUEUE_STRING => "string";
\f
## ---------------------------------- ##
# Where each AC_CONFIG_FILES/AC_OUTPUT/AC_CONFIG_LINK/AC_CONFIG_HEADER appears.
# The keys are the files created by these macros.
my %ac_config_files_location = ();
+# The condition under which AC_CONFIG_FOOS appears.
+my %ac_config_files_condition = ();
# Directory to search for configure-required files. This
# will be computed by &locate_aux_dir and can be set using
# in Makefiles.
my $am_config_aux_dir = '';
+# Directory to search for AC_LIBSOURCE files, as set by AC_CONFIG_LIBOBJ_DIR
+# in configure.ac.
+my $config_libobj_dir = '';
+
# Whether AM_GNU_GETTEXT has been seen in configure.ac.
my $seen_gettext = 0;
# Whether AM_GNU_GETTEXT([external]) is used.
my $seen_gettext_external = 0;
# Where AM_GNU_GETTEXT appears.
my $ac_gettext_location;
+# Whether AM_GNU_GETTEXT_INTL_SUBDIR has been seen.
+my $seen_gettext_intl = 0;
# Lists of tags supported by Libtool.
my %libtool_tags = ();
# 1 if Libtool uses LT_SUPPORTED_TAG. If it does, then it also
-# use AC_REQUIRE_AUX_FILE.
+# uses AC_REQUIRE_AUX_FILE.
my $libtool_new_api = 0;
# Most important AC_CANONICAL_* macro seen so far.
# Where version is defined.
my $package_version_location;
-# TRUE if we've seen AC_ENABLE_MULTILIB.
+# TRUE if we've seen AM_ENABLE_MULTILIB.
my $seen_multilib = 0;
# TRUE if we've seen AM_PROG_CC_C_O
# generation.
my %configure_vars = ();
+# Ignored configure substitutions (i.e., variables not to be output in
+# Makefile.in)
+my %ignored_configure_vars = ();
+
# Files included by $configure_ac.
my @configure_deps = ();
# This maps languages names onto objects.
my %languages = ();
+# Maps each linker variable onto a language object.
+my %link_languages = ();
+
+# maps extensions to needed source flags.
+my %sourceflags = ();
# List of targets we must always output.
# FIXME: Complete, and remove falsely required targets.
# FIXME: Not required, temporary hacks.
# Well, actually they are sort of required: the -recursive
# targets will run them anyway...
+ 'html-am' => 1,
'dvi-am' => 1,
'pdf-am' => 1,
'ps-am' => 1,
'info-am' => 1,
'install-data-am' => 1,
'install-exec-am' => 1,
+ 'install-html-am' => 1,
+ 'install-dvi-am' => 1,
+ 'install-pdf-am' => 1,
+ 'install-ps-am' => 1,
+ 'install-info-am' => 1,
'installcheck-am' => 1,
'uninstall-am' => 1,
'install-man' => 1,
);
-# Set to 1 if this run will create the Makefile.in that distribute
+# Set to 1 if this run will create the Makefile.in that distributes
# the files in config_aux_dir.
my $automake_will_process_aux_dir = 0;
my $in_file_name;
my $relative_dir;
+# Relative path to the top directory.
+my $topsrcdir;
+
# Greatest timestamp of the output's dependencies (excluding
# configure's dependencies).
my $output_deps_greatest_timestamp;
-# These two variables are used when generating each Makefile.in.
+# These variables are used when generating each Makefile.in.
# They hold the Makefile.in until it is ready to be printed.
-my $output_rules;
my $output_vars;
-my $output_trailer;
my $output_all;
my $output_header;
+my $output_rules;
+my $output_trailer;
# This is the conditional stack, updated on if/else/endif, and
# used to build Condition objects.
# This holds the set of included files.
my @include_stack;
-# This holds a list of directories which we must create at `dist'
-# time. This is used in some strange scenarios involving weird
-# AC_OUTPUT commands.
-my %dist_dirs;
-
# List of dependencies for the obvious targets.
my @all;
my @check;
# This keeps track of the directories for which we've already
-# created dirstamp code.
+# created dirstamp code. Keys are directories, values are stamp files.
+# Several keys can share the same stamp files if they are equivalent
+# (as are `.//foo' and `foo').
my %directory_map;
# All .P files.
# This is a list of all targets to run during "make dist".
my @dist_targets;
+# Keep track of all programs declared in this Makefile, without
+# $(EXEEXT). @substitutions@ are not listed.
+my %known_programs;
+
# Keys in this hash are the basenames of files which must depend on
# ansi2knr. Values are either the empty string, or the directory in
# which the ANSI source file appears; the directory must have a
# trailing `/'.
my %de_ansi_files;
-# This is the name of the redirect `all' target to use.
-my $all_target;
-
# This keeps track of which extensions we've seen (that we care
# about).
my %extension_seen;
# Record each file processed by make_paragraphs.
my %transformed_files;
+\f
+
+################################################################
+
+## ---------------------------------------------- ##
+## Variables not reset by &initialize_per_input. ##
+## ---------------------------------------------- ##
# Cache each file processed by make_paragraphs.
# (This is different from %transformed_files because
{
reset_local_duplicates ();
- $am_file_name = '';
- $am_relative_dir = '';
+ $am_file_name = undef;
+ $am_relative_dir = undef;
- $in_file_name = '';
- $relative_dir = '';
+ $in_file_name = undef;
+ $relative_dir = undef;
+ $topsrcdir = undef;
$output_deps_greatest_timestamp = 0;
- $output_rules = '';
$output_vars = '';
- $output_trailer = '';
$output_all = '';
$output_header = '';
+ $output_rules = '';
+ $output_trailer = '';
Automake::Options::reset;
Automake::Variable::reset;
@include_stack = ();
- %dist_dirs = ();
-
@all = ();
@check = ();
@check_tests = ();
%clean_files = ();
+ %compile_clean_files = ();
+
+ # We always include `.'. This isn't strictly correct.
+ %libtool_clean_directories = ('.' => 1);
@sources = ();
@dist_sources = ();
@dist_targets = ();
- %de_ansi_files = ();
+ %known_programs = ();
- $all_target = '';
+ %de_ansi_files = ();
%extension_seen = ();
$get_object_extension_was_run = 0;
- %compile_clean_files = ();
-
- # We always include `.'. This isn't strictly correct.
- %libtool_clean_directories = ('.' => 1);
-
%transformed_files = ();
}
register_language ('name' => 'objc',
'Name' => 'Objective C',
'config_vars' => ['OBJC'],
- 'linker' => 'OBJCLINK',,
- 'link' => '$(OBJCLD) $(AM_OBJCFLAGS) $(OBJCFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
+ 'linker' => 'OBJCLINK',
+ 'link' => '$(OBJCLD) $(AM_OBJCFLAGS) $(OBJCFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
'autodep' => 'OBJC',
'flags' => ['OBJCFLAGS', 'CPPFLAGS'],
'compile' => '$(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS)',
'pure' => 1,
'extensions' => ['.m']);
+# Unified Parallel C.
+register_language ('name' => 'upc',
+ 'Name' => 'Unified Parallel C',
+ 'config_vars' => ['UPC'],
+ 'linker' => 'UPCLINK',
+ 'link' => '$(UPCLD) $(AM_UPCFLAGS) $(UPCFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
+ 'autodep' => 'UPC',
+ 'flags' => ['UPCFLAGS', 'CPPFLAGS'],
+ 'compile' => '$(UPC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_UPCFLAGS) $(UPCFLAGS)',
+ 'compiler' => 'UPCCOMPILE',
+ 'compile_flag' => '-c',
+ 'output_flag' => '-o',
+ 'lder' => 'UPCLD',
+ 'ld' => '$(UPC)',
+ 'pure' => 1,
+ 'extensions' => ['.upc']);
+
# Headers.
register_language ('name' => 'header',
'Name' => 'Header',
'flags' => ['CCASFLAGS'],
# Users can set AM_CCASFLAGS to include DEFS, INCLUDES,
# or anything else required. They can also set CCAS.
+ # Or simply use Preprocessed Assembler.
'compile' => '$(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)',
'compiler' => 'CCASCOMPILE',
'compile_flag' => '-c',
+ 'output_flag' => '-o',
'extensions' => ['.s'],
# With assembly we still use the C linker.
'autodep' => 'CCAS',
'flags' => ['CCASFLAGS', 'CPPFLAGS'],
- # Users can set AM_ASFLAGS to include DEFS, INCLUDES,
- # or anything else required. They can also set CCAS.
- 'compile' => '$(CCAS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)',
+ 'compile' => '$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)',
'compiler' => 'CPPASCOMPILE',
'compile_flag' => '-c',
- 'extensions' => ['.S'],
+ 'output_flag' => '-o',
+ 'extensions' => ['.S', '.sx'],
# With assembly we still use the C linker.
'_finish' => \&lang_c_finish);
# Fortran 77
register_language ('name' => 'f77',
'Name' => 'Fortran 77',
+ 'config_vars' => ['F77'],
'linker' => 'F77LINK',
'link' => '$(F77LD) $(AM_FFLAGS) $(FFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
'flags' => ['FFLAGS'],
# Fortran
register_language ('name' => 'fc',
'Name' => 'Fortran',
+ 'config_vars' => ['FC'],
'linker' => 'FCLINK',
'link' => '$(FCLD) $(AM_FCFLAGS) $(FCFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
'flags' => ['FCFLAGS'],
'lder' => 'FCLD',
'ld' => '$(FC)',
'pure' => 1,
- 'extensions' => ['.f90', '.f95']);
+ 'extensions' => ['.f90', '.f95', '.f03', '.f08']);
# Preprocessed Fortran
register_language ('name' => 'ppfc',
'output_flag' => '-o',
'libtool_tag' => 'FC',
'pure' => 1,
- 'extensions' => ['.F90','.F95']);
+ 'extensions' => ['.F90','.F95', '.F03', '.F08']);
# Preprocessed Fortran 77
#
next if $_ eq '.' || $_ eq '';
if ($_ eq '..')
{
- pop @res;
+ pop @res
+ or prog_error ("trying to reverse path `$file' pointing outside tree");
}
else
{
my $var = var ('AUTOMAKE_OPTIONS');
if ($var)
{
- # FIXME: We should disallow conditional definitions of AUTOMAKE_OPTIONS.
- if (process_option_list ($var->rdef (TRUE)->location,
- $var->value_as_list_recursive (cond_filter =>
- TRUE)))
+ if ($var->has_conditional_contents)
+ {
+ msg_var ('unsupported', $var,
+ "`AUTOMAKE_OPTIONS' cannot have conditional contents");
+ }
+ foreach my $locvals ($var->value_as_list_recursive (cond_filter => TRUE,
+ location => 1))
{
- return 1;
+ my ($loc, $value) = @$locvals;
+ return 1 if (process_option_list ($loc, $value))
}
}
# check_user_variables (@LIST)
# ----------------------------
-# Make sure each variable VAR in @LIST do not exist, suggest using AM_VAR
+# Make sure each variable VAR in @LIST does not exist, suggest using AM_VAR
# otherwise.
sub check_user_variables (@)
{
# seems safest.
$output_rules .= "\n";
foreach my $iter (@deplist)
- {
+ {
$output_rules .= (subst ('AMDEP_TRUE')
. subst ('am__include')
. ' '
'AMDEP' => $AMDEP,
'FASTDEP' => $FASTDEP,
'-c' => $lang->compile_flag || '',
- 'MORE-THAN-ONE'
- => (count_files_for_language ($lang->name) > 1),
# These are not used, but they need to be defined
# so &transform do not complain.
SUBDIROBJ => 0,
# objects in sub-directories too. Dependencies should
# go into the appropriate sub-directories, e.g.,
# `sub/$(DEPDIR)/'. The value of this directory
- # need the be computed on-the-fly.
+ # needs to be computed on-the-fly.
#
# DEPBASE holds the name of this directory, plus the
# basename part of the object file (extensions Po, TPo,
DEPBASE => $depbase,
BASE => '$*',
SOURCE => '$<',
+ SOURCEFLAG => $sourceflags{$ext} || '',
OBJ => '$@',
OBJOBJ => '$@',
LTOBJ => '$@',
my %seen_files = ();
foreach my $file (@{$lang_specific_files{$lang->name}})
{
- my ($derived, $source, $obj, $myext, %file_transform) = @$file;
+ my ($derived, $source, $obj, $myext, $srcext, %file_transform) = @$file;
# We might see a given object twice, for instance if it is
# used under different conditions.
DEPBASE => $depbase_,
BASE => $obj_,
SOURCE => $source_,
+ SOURCEFLAG => $sourceflags{$srcext} || '',
OBJ => "$obj_$myext",
OBJOBJ => "$obj_.obj",
LTOBJ => "$obj_.lo",
DEPBASE => $depbase,
BASE => $obj,
SOURCE => $source,
+ SOURCEFLAG => $sourceflags{$srcext} || '',
# Use $myext and not `.o' here, in case
# we are actually building a new source
# file -- e.g. via yacc.
}
}
+
+# append_exeext { PREDICATE } $MACRO
+# ----------------------------------
+# Append $(EXEEXT) to each filename in $F appearing in the Makefile
+# variable $MACRO if &PREDICATE($F) is true. @substitutions@ are
+# ignored.
+#
+# This is typically used on all filenames of *_PROGRAMS, and filenames
+# of TESTS that are programs.
+sub append_exeext (&$)
+{
+ my ($pred, $macro) = @_;
+
+ transform_variable_recursively
+ ($macro, $macro, 'am__EXEEXT', 0, INTERNAL,
+ sub {
+ my ($subvar, $val, $cond, $full_cond) = @_;
+ # Append $(EXEEXT) unless the user did it already, or it's a
+ # @substitution@.
+ $val .= '$(EXEEXT)'
+ if $val !~ /(?:\$\(EXEEXT\)$|^[@]\w+[@]$)/ && &$pred ($val);
+ return $val;
+ });
+}
+
+
# Check to make sure a source defined in LIBOBJS is not explicitly
# mentioned. This is a separate function (as opposed to being inlined
# in handle_source_transform) because it isn't always appropriate to
{
$_ = shift @files;
- # Configure substitutions in _SOURCES variables are errors.
- if (/^\@.*\@$/)
- {
+ # Configure substitutions in _SOURCES variables are errors.
+ if (/^\@.*\@$/)
+ {
my $parent_msg = '';
$parent_msg = "\nand is referred to from `$topparent'"
if $topparent ne $var->name;
. $parent_msg . ";\nconfigure " .
"substitutions are not allowed in _SOURCES variables");
next;
- }
+ }
- # If the source file is in a subdirectory then the `.o' is put
- # into the current directory, unless the subdir-objects option
- # is in effect.
+ # If the source file is in a subdirectory then the `.o' is put
+ # into the current directory, unless the subdir-objects option
+ # is in effect.
- # Split file name into base and extension.
- next if ! /^(?:(.*)\/)?([^\/]*)($KNOWN_EXTENSIONS_PATTERN)$/;
- my $full = $_;
- my $directory = $1 || '';
- my $base = $2;
- my $extension = $3;
+ # Split file name into base and extension.
+ next if ! /^(?:(.*)\/)?([^\/]*)($KNOWN_EXTENSIONS_PATTERN)$/;
+ my $full = $_;
+ my $directory = $1 || '';
+ my $base = $2;
+ my $extension = $3;
- # We must generate a rule for the object if it requires its own flags.
- my $renamed = 0;
- my ($linker, $object);
+ # We must generate a rule for the object if it requires its own flags.
+ my $renamed = 0;
+ my ($linker, $object);
# This records whether we've seen a derived source file (e.g.
# yacc output).
# language function.
my $aggregate = 'AM';
- $extension = &derive_suffix ($extension, $nonansi_obj);
- my $lang;
- if ($extension_map{$extension} &&
- ($lang = $languages{$extension_map{$extension}}))
+ $extension = &derive_suffix ($extension, $nonansi_obj);
+ my $lang;
+ if ($extension_map{$extension} &&
+ ($lang = $languages{$extension_map{$extension}}))
{
- # Found the language, so see what it says.
- &saw_extension ($extension);
+ # Found the language, so see what it says.
+ &saw_extension ($extension);
# Do we have per-executable flags for this executable?
my $have_per_exec_flags = 0;
}
}
- # Note: computed subr call. The language rewrite function
- # should return one of the LANG_* constants. It could
- # also return a list whose first value is such a constant
- # and whose second value is a new source extension which
- # should be applied. This means this particular language
- # generates another source file which we must then process
- # further.
- my $subr = \&{'lang_' . $lang->name . '_rewrite'};
- my ($r, $source_extension)
+ # Note: computed subr call. The language rewrite function
+ # should return one of the LANG_* constants. It could
+ # also return a list whose first value is such a constant
+ # and whose second value is a new source extension which
+ # should be applied. This means this particular language
+ # generates another source file which we must then process
+ # further.
+ my $subr = \&{'lang_' . $lang->name . '_rewrite'};
+ my ($r, $source_extension)
= &$subr ($directory, $base, $extension,
$nonansi_obj, $have_per_exec_flags, $var);
- # Skip this entry if we were asked not to process it.
- next if $r == LANG_IGNORE;
+ # Skip this entry if we were asked not to process it.
+ next if $r == LANG_IGNORE;
- # Now extract linker and other info.
- $linker = $lang->linker;
+ # Now extract linker and other info.
+ $linker = $lang->linker;
- my $this_obj_ext;
+ my $this_obj_ext;
if (defined $source_extension)
{
$this_obj_ext = $source_extension;
}
$object = $base . $this_obj_ext;
- if ($have_per_exec_flags)
- {
- # We have a per-executable flag in effect for this
- # object. In this case we rewrite the object's
- # name to ensure it is unique.
-
- # We choose the name `DERIVED_OBJECT' to ensure
- # (1) uniqueness, and (2) continuity between
- # invocations. However, this will result in a
- # name that is too long for losing systems, in
- # some situations. So we provide _SHORTNAME to
- # override.
-
- my $dname = $derived;
+ if ($have_per_exec_flags)
+ {
+ # We have a per-executable flag in effect for this
+ # object. In this case we rewrite the object's
+ # name to ensure it is unique.
+
+ # We choose the name `DERIVED_OBJECT' to ensure
+ # (1) uniqueness, and (2) continuity between
+ # invocations. However, this will result in a
+ # name that is too long for losing systems, in
+ # some situations. So we provide _SHORTNAME to
+ # override.
+
+ my $dname = $derived;
my $var = var ($derived . '_SHORTNAME');
- if ($var)
- {
- # FIXME: should use the same Condition as
- # the _SOURCES variable. But this is really
- # silly overkill -- nobody should have
- # conditional shortnames.
- $dname = $var->variable_value;
- }
- $object = $dname . '-' . $object;
+ if ($var)
+ {
+ # FIXME: should use the same Condition as
+ # the _SOURCES variable. But this is really
+ # silly overkill -- nobody should have
+ # conditional shortnames.
+ $dname = $var->variable_value;
+ }
+ $object = $dname . '-' . $object;
prog_error ($lang->name . " flags defined without compiler")
if ! defined $lang->compile;
- $renamed = 1;
- }
+ $renamed = 1;
+ }
- # If rewrite said it was ok, put the object into a
- # subdir.
- if ($r == LANG_SUBDIR && $directory ne '')
- {
- $object = $directory . '/' . $object;
- }
+ # If rewrite said it was ok, put the object into a
+ # subdir.
+ if ($r == LANG_SUBDIR && $directory ne '')
+ {
+ $object = $directory . '/' . $object;
+ }
# If the object file has been renamed (because per-target
# flags are used) we cannot compile the file with an
# thought that inferences rules would work for
# subdirectory objects too. Later, on 1999-11-22,
# automake was changed to output explicit rules even for
- # subdir-objects. Nobody remembers why, but this occured
+ # subdir-objects. Nobody remembers why, but this occurred
# soon after the merge of the user-dep-gen-branch so it
# might be related. In late 2003 people complained about
# the size of the generated Makefile.ins (libgcj, with
# Using inference rules for subdir-objects has been tested
# with GNU make, Solaris make, Ultrix make, BSD make,
# HP-UX make, and OSF1 make successfully.
- if ($renamed
+ if ($renamed
|| ($directory ne '' && ! option 'subdir-objects')
# We must also use specific rules for a nodist_ source
# if its language requests it.
|| ($lang->nodist_specific && ! $transform{'DIST_SOURCE'}))
- {
- my $obj_sans_ext = substr ($object, 0,
+ {
+ my $obj_sans_ext = substr ($object, 0,
- length ($this_obj_ext));
my $full_ansi = $full;
if ($lang->ansi && option 'ansi2knr')
# Only use $this_obj_ext in the derived
# source case because in the other case we
# *don't* want $(OBJEXT) to appear here.
- ($derived_source ? $this_obj_ext : '.o'));
+ ($derived_source ? $this_obj_ext : '.o'),
+ $extension);
# If we renamed the object then we want to use the
# per-executable flag name. But if this is simply a
# (e.g. for `foo_CFLAGS', it is `foo'), the name of the
# source file, the base name of the output file, and
# the extension for the object file.
- push (@{$lang_specific_files{$lang->name}},
+ push (@{$lang_specific_files{$lang->name}},
[@specifics, %transform]);
- }
- }
- elsif ($extension eq $nonansi_obj)
- {
- # This is probably the result of a direct suffix rule.
- # In this case we just accept the rewrite.
- $object = "$base$extension";
- $linker = '';
- }
- else
- {
- # No error message here. Used to have one, but it was
- # very unpopular.
+ }
+ }
+ elsif ($extension eq $nonansi_obj)
+ {
+ # This is probably the result of a direct suffix rule.
+ # In this case we just accept the rewrite.
+ $object = "$base$extension";
+ $object = "$directory/$object" if $directory ne '';
+ $linker = '';
+ }
+ else
+ {
+ # No error message here. Used to have one, but it was
+ # very unpopular.
# FIXME: we could potentially do more processing here,
# perhaps treating the new extension as though it were a
# new source extension (as above). This would require
# more restructuring than is appropriate right now.
- next;
- }
+ next;
+ }
err_am "object `$object' created by `$full' and `$object_map{$object}'"
if (defined $object_map{$object}
next;
}
- $linkers_used{$linker} = 1;
+ $linkers_used{$linker} = 1;
- push (@result, $object);
+ push (@result, $object);
- if (! defined $object_map{$object})
- {
- my @dep_list = ();
- $object_map{$object} = $full;
+ if (! defined $object_map{$object})
+ {
+ my @dep_list = ();
+ $object_map{$object} = $full;
- # If resulting object is in subdir, we need to make
- # sure the subdir exists at build time.
- if ($object =~ /\//)
- {
- # FIXME: check that $DIRECTORY is somewhere in the
- # project
+ # If resulting object is in subdir, we need to make
+ # sure the subdir exists at build time.
+ if ($object =~ /\//)
+ {
+ # FIXME: check that $DIRECTORY is somewhere in the
+ # project
# For Java, the way we're handling it right now, a
# `..' component doesn't make sense.
- if ($lang->name eq 'java' && $object =~ /(\/|^)\.\.\//)
+ if ($lang && $lang->name eq 'java' && $object =~ /(\/|^)\.\.\//)
{
err_am "`$full' should not contain a `..' component";
}
$libtool_clean_directories{$directory} = 1;
}
- push (@dep_list, require_build_directory ($directory));
+ push (@dep_list, require_build_directory ($directory));
- # If we're generating dependencies, we also want
- # to make sure that the appropriate subdir of the
- # .deps directory is created.
+ # If we're generating dependencies, we also want
+ # to make sure that the appropriate subdir of the
+ # .deps directory is created.
push (@dep_list,
require_build_directory ($directory . '/$(DEPDIR)'))
unless option 'no-dependencies';
- }
+ }
- &pretty_print_rule ($object . ':', "\t", @dep_list)
- if scalar @dep_list > 0;
- }
+ &pretty_print_rule ($object . ':', "\t", @dep_list)
+ if scalar @dep_list > 0;
+ }
- # Transform .o or $o file into .P file (for automatic
- # dependency code).
- if ($lang && $lang->autodep ne 'no')
- {
- my $depfile = $object;
- $depfile =~ s/\.([^.]*)$/.P$1/;
- $depfile =~ s/\$\(OBJEXT\)$/o/;
- $dep_files{dirname ($depfile) . '/$(DEPDIR)/'
- . basename ($depfile)} = 1;
- }
+ # Transform .o or $o file into .P file (for automatic
+ # dependency code).
+ if ($lang && $lang->autodep ne 'no')
+ {
+ my $depfile = $object;
+ $depfile =~ s/\.([^.]*)$/.P$1/;
+ $depfile =~ s/\$\(OBJEXT\)$/o/;
+ $dep_files{dirname ($depfile) . '/$(DEPDIR)/'
+ . basename ($depfile)} = 1;
+ }
}
return @result;
# Arguments are:
# canonical (transformed) name of target to build
# actual target of object to build
-# object extension (i.e. either `.o' or `$o'.
+# object extension (i.e., either `.o' or `$o')
# location of the source variable
# extra arguments to pass to file_contents when producing rules
-# Return result is name of linker variable that must be used.
+# Return the name of the linker variable that must be used.
# Empty return means just use `LINK'.
sub handle_source_transform ($$$$%)
{
# object extension.
my ($one_file, $unxformed, $obj, $where, %transform) = @_;
- my ($linker) = '';
+ my $linker = '';
# No point in continuing if _OBJECTS is defined.
return if reject_var ($one_file . '_OBJECTS',
unless $prefix =~ /EXTRA_/;
push @sources, "\$($varname)";
- push @dist_sources, shadow_unconditionally ($varname, $where)
- unless (option ('no-dist') || $prefix =~ /^nodist_/);
+ push @dist_sources, shadow_unconditionally ($varname, $where)
+ unless (option ('no-dist') || $prefix =~ /^nodist_/);
$needlinker |=
define_objects_from_sources ($varname,
if (scalar @keys == 0)
{
# The default source for libfoo.la is libfoo.c, but for
- # backward compatibility we first look at libfoo_la.c
+ # backward compatibility we first look at libfoo_la.c,
+ # if no default source suffix is given.
my $old_default_source = "$one_file.c";
- (my $default_source = $unxformed) =~ s,(\.[^./\\]*)?$,.c,;
+ my $ext_var = var ('AM_DEFAULT_SOURCE_EXT');
+ my $default_source_ext = $ext_var ? variable_value ($ext_var) : '.c';
+ msg_var ('unsupported', $ext_var, $ext_var->name . " can assume at most one value")
+ if $default_source_ext =~ /[\t ]/;
+ (my $default_source = $unxformed) =~ s,(\.[^./\\]*)?$,$default_source_ext,;
if ($old_default_source ne $default_source
+ && !$ext_var
&& (rule $old_default_source
|| rule '$(srcdir)/' . $old_default_source
|| rule '${srcdir}/' . $old_default_source
if ($val !~ /^-[lL]/ &&
# Skip -dlopen and -dlpreopen; these are explicitly allowed
# for Libtool libraries or programs. (Actually we are a bit
- # laxest here since this code also applies to non-libtool
+ # laxe here since this code also applies to non-libtool
# libraries or programs, for which -dlopen and -dlopreopen
- # are pure non-sence. Diagnosting this doesn't seems very
+ # are pure nonsense. Diagnosing this doesn't seem very
# important: the developer will quickly get complaints from
# the linker.)
$val !~ /^-dl(?:pre)?open$/ &&
return $seen_libobjs;
}
+# handle_LIBOBJS_or_ALLOCA ($VAR)
+# -------------------------------
+# Definitions common to LIBOBJS and ALLOCA.
+# VAR should be one of LIBOBJS, LTLIBOBJS, ALLOCA, or LTALLOCA.
+sub handle_LIBOBJS_or_ALLOCA ($)
+{
+ my ($var) = @_;
+
+ my $dir = '';
+
+ # If LIBOBJS files must be built in another directory we have
+ # to define LIBOBJDIR and ensure the files get cleaned.
+ # Otherwise LIBOBJDIR can be left undefined, and the cleaning
+ # is achieved by `rm -f *.$(OBJEXT)' in compile.am.
+ if ($config_libobj_dir
+ && $relative_dir ne $config_libobj_dir)
+ {
+ if (option 'subdir-objects')
+ {
+ # In the top-level Makefile we do not use $(top_builddir), because
+ # we are already there, and since the targets are built without
+ # a $(top_builddir), it helps BSD Make to match them with
+ # dependencies.
+ $dir = "$config_libobj_dir/" if $config_libobj_dir ne '.';
+ $dir = "$topsrcdir/$dir" if $relative_dir ne '.';
+ define_variable ('LIBOBJDIR', "$dir", INTERNAL);
+ $clean_files{"\$($var)"} = MOSTLY_CLEAN;
+ # If LTLIBOBJS is used, we must also clear LIBOBJS (which might
+ # be created by libtool as a side-effect of creating LTLIBOBJS).
+ $clean_files{"\$($var)"} = MOSTLY_CLEAN if $var =~ s/^LT//;
+ }
+ else
+ {
+ error ("`\$($var)' cannot be used outside `$config_libobj_dir' if"
+ . " `subdir-objects' is not set");
+ }
+ }
+
+ return $dir;
+}
+
sub handle_LIBOBJS ($$$)
{
my ($var, $cond, $lt) = @_;
+ my $myobjext = $lt ? 'lo' : 'o';
$lt ||= '';
- my $myobjext = ($1 ? 'l' : '') . 'o';
$var->requires_variables ("\@${lt}LIBOBJS\@ used", $lt . 'LIBOBJS')
if ! keys %libsources;
+ my $dir = handle_LIBOBJS_or_ALLOCA "${lt}LIBOBJS";
+
foreach my $iter (keys %libsources)
{
if ($iter =~ /\.[cly]$/)
if ($iter =~ /\.h$/)
{
- require_file_with_macro ($cond, $var, FOREIGN, $iter);
+ require_libsource_with_macro ($cond, $var, FOREIGN, $iter);
}
elsif ($iter ne 'alloca.c')
{
my $rewrite = $iter;
$rewrite =~ s/\.c$/.P$myobjext/;
- $dep_files{'$(DEPDIR)/' . $rewrite} = 1;
+ $dep_files{$dir . '$(DEPDIR)/' . $rewrite} = 1;
$rewrite = "^" . quotemeta ($iter) . "\$";
# Only require the file if it is not a built source.
my $bs = var ('BUILT_SOURCES');
if (! $bs || ! grep (/$rewrite/, $bs->value_as_list_recursive))
{
- require_file_with_macro ($cond, $var, FOREIGN, $iter);
+ require_libsource_with_macro ($cond, $var, FOREIGN, $iter);
}
}
}
sub handle_ALLOCA ($$$)
{
my ($var, $cond, $lt) = @_;
- my $myobjext = ($lt ? 'l' : '') . 'o';
+ my $myobjext = $lt ? 'lo' : 'o';
$lt ||= '';
+ my $dir = handle_LIBOBJS_or_ALLOCA "${lt}ALLOCA";
+
$var->requires_variables ("\@${lt}ALLOCA\@ used", $lt . 'ALLOCA');
- $dep_files{'$(DEPDIR)/alloca.P' . $myobjext} = 1;
- require_file_with_macro ($cond, $var, FOREIGN, 'alloca.c');
- &saw_extension ('c');
+ $dep_files{$dir . '$(DEPDIR)/alloca.P' . $myobjext} = 1;
+ require_libsource_with_macro ($cond, $var, FOREIGN, 'alloca.c');
+ &saw_extension ('.c');
}
# Canonicalize the input parameter
my $default_includes = '';
if (! option 'nostdinc')
{
- $default_includes = ' -I. -I$(srcdir)';
+ my @incs = ('-I.', subst ('am__isrc'));
my $var = var 'CONFIG_HEADER';
if ($var)
{
foreach my $hdr (split (' ', $var->variable_value))
{
- $default_includes .= ' -I' . dirname ($hdr);
+ push @incs, '-I' . dirname ($hdr);
}
}
+ # We want `-I. -I$(srcdir)', but the latter -I is redundant
+ # and unaesthetic in non-VPATH builds. We use `-I.@am__isrc@`
+ # instead. It will be replaced by '-I.' or '-I. -I$(srcdir)'.
+ # Items in CONFIG_HEADER are never in $(srcdir) so it is safe
+ # to just put @am__isrc@ right after `-I.', without a space.
+ ($default_includes = ' ' . uniq (@incs)) =~ s/ @/@/;
}
my (@mostly_rms, @dist_rms);
# We'll add $(EXEEXT) back later anyway.
$one_file =~ s/\$\(EXEEXT\)$//;
+ $known_programs{$one_file} = $where;
+
# Canonicalize names and check for misspellings.
my $xname = &check_canonical_spelling ($one_file, '_LDADD', '_LDFLAGS',
'_SOURCES', '_OBJECTS',
set_seen ($xname . '_LDFLAGS');
# Determine program to use for link.
- my $xlink;
- if (var ($xname . '_LINK'))
- {
- $xlink = $xname . '_LINK';
- }
- else
- {
- $xlink = $linker ? $linker : 'LINK';
- }
+ my $xlink = &define_per_target_linker_variable ($linker, $xname);
# If the resulting program lies into a subdirectory,
# make sure this directory will exist.
my $dirstamp = require_build_directory_maybe ($one_file);
+ $libtool_clean_directories{dirname ($one_file)} = 1;
+
$output_rules .= &file_contents ('program',
$where,
PROGRAM => $one_file,
}
my %instdirs = ();
+ my %instsubdirs = ();
my %instconds = ();
my %liblocations = (); # Location (in Makefile.am) of each library.
foreach my $key (@prefix)
{
# Get the installation directory of each library.
- (my $dir = $key) =~ s/^nobase_//;
+ my $dir = $key;
+ my $strip_subdir = 1;
+ if ($dir =~ /^nobase_/)
+ {
+ $dir =~ s/^nobase_//;
+ $strip_subdir = 0;
+ }
my $var = rvar ($key . '_LTLIBRARIES');
# We reject libraries which are installed in several places
my ($var, $val, $cond, $full_cond) = @_;
my $hcond = $full_cond->human;
my $where = $var->rdef ($cond)->location;
+ my $ldir = '';
+ $ldir = '/' . dirname ($val)
+ if (!$strip_subdir);
# A library cannot be installed in different directory
# in overlapping conditions.
if (exists $instconds{$val})
if ($msg)
{
error ($where, $msg, partial => 1);
-
- my $dirtxt = "installed in `$dir'";
+ my $dirtxt = "installed " . ($strip_subdir ? "in" : "below") . " `$dir'";
$dirtxt = "built for `$dir'"
if $dir eq 'EXTRA' || $dir eq 'noinst' || $dir eq 'check';
my $dircond =
$instconds{$val} = new Automake::DisjConditions;
}
$instdirs{$val}{$full_cond} = $dir;
+ $instsubdirs{$val}{$full_cond} = $ldir;
$liblocations{$val}{$full_cond} = $where;
$instconds{$val} = $instconds{$val}->merge ($full_cond);
},
{
return ();
},
- skip_ac_subst => 1);
+ skip_ac_subst => 1);
}
foreach my $pair (@liblist)
my $bn = basename ($onelib);
if ($bn !~ /$libname_rx$/)
{
- my $type = 'library';
- if ($libname_rx eq '\.la')
+ my $type = 'library';
+ if ($libname_rx eq '\.la')
{
$bn =~ s/^(lib|)(.*?)(?:\.[^.]*)?$/$1$2.la/;
- $type = 'module';
+ $type = 'module';
}
- else
+ else
{
$bn =~ s/^(?:lib)?(.*?)(?:\.[^.]*)?$/lib$1.la/;
}
NONLIBTOOL => 0, LIBTOOL => 1);
# Determine program to use for link.
- my $xlink;
- if (var ($xlib . '_LINK'))
- {
- $xlink = $xlib . '_LINK';
- }
- else
- {
- $xlink = $linker ? $linker : 'LINK';
- }
+ my $xlink = &define_per_target_linker_variable ($linker, $xlib);
my $rpathvar = "am_${xlib}_rpath";
my $rpath = "\$($rpathvar)";
foreach my $rcond ($instconds{$onelib}->conds)
- {
+ {
my $val;
if ($instdirs{$onelib}{$rcond} eq 'EXTRA'
|| $instdirs{$onelib}{$rcond} eq 'noinst'
else
{
$val = ('-rpath $(' . $instdirs{$onelib}{$rcond} . 'dir)');
+ $val .= $instsubdirs{$onelib}{$rcond}
+ if defined $instsubdirs{$onelib}{$rcond};
}
if ($rcond->true)
{
next if $outfile;
$outfile = $1;
- if ($outfile =~ /\.(.+)$/ && $1 ne 'info')
+ if ($outfile =~ /\.([^.]+)$/ && $1 ne 'info')
{
error ("$filename:$.",
"output `$outfile' has unrecognized extension");
# nodist_info_TEXINFOS or something similar. (Doing this
# requires some sanity checks. For instance Automake should
# not allow:
- # dist_info_TEXINFO = foo.texi
- # nodist_foo_TEXINFO = included.texi
+ # dist_info_TEXINFOS = foo.texi
+ # nodist_foo_TEXINFOS = included.texi
# because a distributed file should never depend on a
# non-distributed file.)
#
# * If .texi files are not distributed, then .info files should
# not be distributed either. There are also cases where one
- # want to distribute .texi files, but do not want to
+ # wants to distribute .texi files, but does not want to
# distribute the .info files. For instance the Texinfo package
# distributes the tool used to build these files; it would
# be a waste of space to distribute them. It's not clear
# Find all the sections in use. We do this by first looking for
# "standard" sections, and then looking for any additional
# sections used in man_MANS.
- my (%sections, %vlist);
+ my (%sections, %notrans_sections, %trans_sections,
+ %notrans_vars, %trans_vars, %notrans_sect_vars, %trans_sect_vars);
# We handle nodist_ for uniformity. man pages aren't distributed
# by default so it isn't actually very important.
- foreach my $pfx ('', 'dist_', 'nodist_')
+ foreach my $npfx ('', 'notrans_')
{
- # Add more sections as needed.
- foreach my $section ('0'..'9', 'n', 'l')
+ foreach my $pfx ('', 'dist_', 'nodist_')
{
- my $varname = $pfx . 'man' . $section . '_MANS';
- if (var ($varname))
+ # Add more sections as needed.
+ foreach my $section ('0'..'9', 'n', 'l')
{
- $sections{$section} = 1;
- $varname = '$(' . $varname . ')';
- $vlist{$varname} = 1;
+ my $varname = $npfx . $pfx . 'man' . $section . '_MANS';
+ if (var ($varname))
+ {
+ $sections{$section} = 1;
+ $varname = '$(' . $varname . ')';
+ if ($npfx eq 'notrans_')
+ {
+ $notrans_sections{$section} = 1;
+ $notrans_sect_vars{$varname} = 1;
+ }
+ else
+ {
+ $trans_sections{$section} = 1;
+ $trans_sect_vars{$varname} = 1;
+ }
- &push_dist_common ($varname)
- if $pfx eq 'dist_';
+ &push_dist_common ($varname)
+ if $pfx eq 'dist_';
+ }
}
- }
- my $varname = $pfx . 'man_MANS';
- my $var = var ($varname);
- if ($var)
- {
- foreach ($var->value_as_list_recursive)
+ my $varname = $npfx . $pfx . 'man_MANS';
+ my $var = var ($varname);
+ if ($var)
{
- # A page like `foo.1c' goes into man1dir.
- if (/\.([0-9a-z])([a-z]*)$/)
+ foreach ($var->value_as_list_recursive)
+ {
+ # A page like `foo.1c' goes into man1dir.
+ if (/\.([0-9a-z])([a-z]*)$/)
+ {
+ $sections{$1} = 1;
+ if ($npfx eq 'notrans_')
+ {
+ $notrans_sections{$1} = 1;
+ }
+ else
+ {
+ $trans_sections{$1} = 1;
+ }
+ }
+ }
+
+ $varname = '$(' . $varname . ')';
+ if ($npfx eq 'notrans_')
+ {
+ $notrans_vars{$varname} = 1;
+ }
+ else
{
- $sections{$1} = 1;
+ $trans_vars{$varname} = 1;
}
+ &push_dist_common ($varname)
+ if $pfx eq 'dist_';
}
-
- $varname = '$(' . $varname . ')';
- $vlist{$varname} = 1;
- &push_dist_common ($varname)
- if $pfx eq 'dist_';
}
}
return unless %sections;
+ my @unsorted_deps;
+
+ # Build section independent variables.
+ my $have_notrans = %notrans_vars;
+ my @notrans_list = sort keys %notrans_vars;
+ my $have_trans = %trans_vars;
+ my @trans_list = sort keys %trans_vars;
+
# Now for each section, generate an install and uninstall rule.
# Sort sections so output is deterministic.
foreach my $section (sort keys %sections)
{
+ # Build section dependent variables.
+ my $notrans_mans = $have_notrans || exists $notrans_sections{$section};
+ my $trans_mans = $have_trans || exists $trans_sections{$section};
+ my (%notrans_this_sect, %trans_this_sect);
+ my $expr = 'man' . $section . '_MANS';
+ foreach my $varname (keys %notrans_sect_vars)
+ {
+ if ($varname =~ /$expr/)
+ {
+ $notrans_this_sect{$varname} = 1;
+ }
+ }
+ foreach my $varname (keys %trans_sect_vars)
+ {
+ if ($varname =~ /$expr/)
+ {
+ $trans_this_sect{$varname} = 1;
+ }
+ }
+ my @notrans_sect_list = sort keys %notrans_this_sect;
+ my @trans_sect_list = sort keys %trans_this_sect;
+ @unsorted_deps = (keys %notrans_vars, keys %trans_vars,
+ keys %notrans_this_sect, keys %trans_this_sect);
+ my @deps = sort @unsorted_deps;
$output_rules .= &file_contents ('mans',
new Automake::Location,
- SECTION => $section);
- }
-
- my @mans = sort keys %vlist;
+ SECTION => $section,
+ DEPS => "@deps",
+ NOTRANS_MANS => $notrans_mans,
+ NOTRANS_SECT_LIST => "@notrans_sect_list",
+ HAVE_NOTRANS => $have_notrans,
+ NOTRANS_LIST => "@notrans_list",
+ TRANS_MANS => $trans_mans,
+ TRANS_SECT_LIST => "@trans_sect_list",
+ HAVE_TRANS => $have_trans,
+ TRANS_LIST => "@trans_list");
+ }
+
+ @unsorted_deps = (keys %notrans_vars, keys %trans_vars,
+ keys %notrans_sect_vars, keys %trans_sect_vars);
+ my @mans = sort @unsorted_deps;
$output_vars .= file_contents ('mans-vars',
new Automake::Location,
MANS => "@mans");
sub handle_data
{
&am_install_var ('-noextra', '-candist', 'data', 'DATA',
- 'data', 'sysconf', 'sharedstate', 'localstate',
+ 'data', 'dataroot', 'dvi', 'html', 'pdf', 'ps',
+ 'sysconf', 'sharedstate', 'localstate',
'pkgdata', 'lisp', 'noinst', 'check');
}
. "\tlist=\'\$(SUBDIRS)\'; for subdir in \$\$list; do \\\n"
# Never fail here if a subdir fails; it
# isn't important.
- . "\t test \"\$\$subdir\" = . || (cd \$\$subdir"
+ . "\t test \"\$\$subdir\" = . || (\$(am__cd) \$\$subdir"
. " && \$(MAKE) \$(AM_MAKEFLAGS) tags); \\\n"
. "\tdone\n");
push (@tag_deps, 'tags-recursive');
&depend ('.PHONY', 'tags-recursive');
+ &depend ('.MAKE', 'tags-recursive');
$output_rules .= ("ctags-recursive:\n"
. "\tlist=\'\$(SUBDIRS)\'; for subdir in \$\$list; do \\\n"
# Never fail here if a subdir fails; it
# isn't important.
- . "\t test \"\$\$subdir\" = . || (cd \$\$subdir"
+ . "\t test \"\$\$subdir\" = . || (\$(am__cd) \$\$subdir"
. " && \$(MAKE) \$(AM_MAKEFLAGS) ctags); \\\n"
. "\tdone\n");
push (@ctag_deps, 'ctags-recursive');
&depend ('.PHONY', 'ctags-recursive');
+ &depend ('.MAKE', 'ctags-recursive');
}
if (&saw_sources_p (1)
sub for_dist_common
{
return 0
- if $a eq $b;
+ if $a eq $b;
return -1
- if $a eq 'README';
+ if $a eq 'README';
return 1
- if $b eq 'README';
+ if $b eq 'README';
return $a cmp $b;
}
-
# handle_dist
# -----------
# Handle 'dist' target.
sub handle_dist ()
{
- # Substutions for distdit.am
+ # Substitutions for distdir.am
my %transform;
# Define DIST_SUBDIRS. This must always be done, regardless of the
{
my $archive_defined = option 'no-dist-gzip' ? 0 : 1;
$archive_defined ||=
- grep { option "dist-$_" } ('shar', 'zip', 'tarZ', 'bzip2');
+ grep { option "dist-$_" } qw(shar zip tarZ bzip2 lzma xz);
error (option 'no-dist-gzip',
"no-dist-gzip specified but no dist-* specified, "
. "at least one archive format must be enabled")
# originally, but there were so many requests that I finally
# relented.
my $extra_dist = var ('EXTRA_DIST');
- if ($extra_dist)
- {
- # FIXME: This should be fixed to work with conditions. That
- # will require only making the entries in %dist_dirs under the
- # appropriate condition. This is meaningful if the nature of
- # the distribution should depend upon the configure options
- # used.
- foreach ($extra_dist->value_as_list_recursive (skip_ac_subst => 1))
- {
- next unless s,/+[^/]+$,,;
- $dist_dirs{$_} = 1
- unless $_ eq '.';
- }
- }
-
- # We have to check DIST_COMMON for extra directories in case the
- # user put a source used in AC_OUTPUT into a subdir.
- my $topsrcdir = backname ($relative_dir);
- foreach (rvar ('DIST_COMMON')->value_as_list_recursive (skip_ac_subst => 1))
- {
- s/\$\(top_srcdir\)/$topsrcdir/;
- s/\$\(srcdir\)/./;
- # Strip any leading `./'.
- s,^(:?\./+)*,,;
- next unless s,/+[^/]+$,,;
- $dist_dirs{$_} = 1
- unless $_ eq '.';
- }
$transform{'DISTCHECK-HOOK'} = !! rule 'distcheck-hook';
$transform{'GETTEXT'} = $seen_gettext && !$seen_gettext_external;
- # Prepend $(distdir) to each directory given.
- my %rewritten = map { '$(distdir)/' . "$_" => 1 } keys %dist_dirs;
- $transform{'DISTDIRS'} = join (' ', sort keys %rewritten);
-
# If the target `dist-hook' exists, make sure it is run. This
# allows users to do random weird things to the distribution
# before it is packaged up.
# check_directory ($NAME, $WHERE)
# -------------------------------
-# Ensure $NAME is a directory, and that it uses sane name.
+# Ensure $NAME is a directory, and that it uses a sane name.
# Use $WHERE as a location in the diagnostic, if any.
sub check_directory ($$)
{
}
+# Helper function for substitute_ac_subst_variables.
+sub substitute_ac_subst_variables_worker($)
+{
+ my ($token) = @_;
+ return "\@$token\@" if var $token;
+ return "\${$token\}";
+}
+
+# substitute_ac_subst_variables ($TEXT)
+# -------------------------------------
+# Replace any occurrence of ${FOO} in $TEXT by @FOO@ if FOO is an AC_SUBST
+# variable.
+sub substitute_ac_subst_variables ($)
+{
+ my ($text) = @_;
+ $text =~ s/\${([^ \t=:+{}]+)}/&substitute_ac_subst_variables_worker ($1)/ge;
+ return $text;
+}
+
# @DEPENDENCIES
# &prepend_srcdir (@INPUTS)
# -------------------------
# Compute a list of dependencies appropriate for the rebuild
# rule of
# AC_CONFIG_FILES($OUTPUT:$INPUT[0]:$INPUTS[1]:...)
-# Also distribute $INPUTs which are not build by another AC_CONFIG_FILES.
+# Also distribute $INPUTs which are not built by another AC_CONFIG_FOOS.
sub rewrite_inputs_into_dependencies ($@)
{
my ($file, @inputs) = @_;
for my $i (@inputs)
{
- if (exists $ac_config_files_location{$i})
+ # We cannot create dependencies on shell variables.
+ next if (substitute_ac_subst_variables $i) =~ /\$/;
+
+ if (exists $ac_config_files_location{$i} && $i ne $file)
{
my $di = dirname $i;
if ($di eq $relative_dir)
{
msg ('error', $ac_config_files_location{$file},
"required file `$i' not found")
- unless exists $output_files{$i} || -f $i;
+ unless $i =~ /\$/ || exists $output_files{$i} || -f $i;
($i) = prepend_srcdir ($i);
push_dist_common ($i);
}
'MAKEFILE-IN-DEPS' => "@include_stack",
'MAKEFILE-AM' => $rel_makefile_am,
STRICTNESS => global_option 'cygnus'
- ? 'cygnus' : $strictness_name,
+ ? 'cygnus' : $strictness_name,
'USE-DEPS' => global_option 'no-dependencies'
- ? ' --ignore-deps' : '',
+ ? ' --ignore-deps' : '',
'MAKEFILE-AM-SOURCES' => "$makefile$colon_infile",
'REGEN-ACLOCAL-M4' => $regen_aclocal_m4);
# This will also distribute all inputs.
@ins = rewrite_inputs_into_dependencies ($config_h_path, @ins);
- # Header defined and in this directory.
+ # Cannot define rebuild rules for filenames with shell variables.
+ next if (substitute_ac_subst_variables $config_h_path) =~ /\$/;
+
+ # Header defined in this directory.
my @files;
if (-f $config_h_path . '.top')
{
}
else
{
- # Use $(install_sh), not $(mkdir_p) because the latter requires
+ # Use $(install_sh), not $(MKDIR_P) because the latter requires
# at least one argument, and $(mkinstalldirs) used to work
# even without arguments (e.g. $(mkinstalldirs) $(conditional_dir)).
define_variable ('mkinstalldirs', '$(install_sh) -d', INTERNAL);
# Now look for other files in this directory which must be remade
# by config.status, and generate rules for them.
my @actual_other_files = ();
+ # These get cleaned only in a VPATH build.
+ my @actual_other_vpath_files = ();
foreach my $lfile (@other_input_files)
{
my $file;
my $local = basename ($file);
- # Make sure the dist directory for each input file is created.
- # We only have to do this at the topmost level though. This
- # is a bit ugly but it easier than spreading out the logic,
- # especially in cases like AC_OUTPUT(foo/out:bar/in), where
- # there is no Makefile in bar/.
- if ($relative_dir eq '.')
- {
- foreach (@inputs)
- {
- $dist_dirs{dirname ($_)} = 1;
- }
- }
-
# We skip files that aren't in this directory. However, if
# the file's directory does not have a Makefile, and we are
# currently doing `.', then we create a rule to rebuild the
my @rewritten_inputs = rewrite_inputs_into_dependencies ($file, @inputs);
- $output_rules .= ($local . ': '
+ # Cannot output rules for shell variables.
+ next if (substitute_ac_subst_variables $local) =~ /\$/;
+
+ my $condstr = '';
+ my $cond = $ac_config_files_condition{$lfile};
+ if (defined $cond)
+ {
+ $condstr = $cond->subst_string;
+ Automake::Rule::define ($local, $configure_ac, RULE_AUTOMAKE, $cond,
+ $ac_config_files_location{$file});
+ }
+ $output_rules .= ($condstr . $local . ': '
. '$(top_builddir)/config.status '
. "@rewritten_inputs\n"
- . "\t"
+ . $condstr . "\t"
. 'cd $(top_builddir) && '
. '$(SHELL) ./config.status '
. ($relative_dir eq '.' ? '' : '$(subdir)/')
my $where = $ac_config_files_location{$link};
# Skip destinations that contain shell variables.
- if ($link !~ /\$/)
+ if ((substitute_ac_subst_variables $link) !~ /\$/)
{
# We skip links that aren't in this directory. However, if
# the link's directory does not have a Makefile, and we are
$local = undef;
}
}
- push @actual_other_files, $local if $local;
+ if ($file ne $link)
+ {
+ push @actual_other_files, $local if $local;
+ }
+ else
+ {
+ push @actual_other_vpath_files, $local if $local;
+ }
}
# Do not process sources that contain shell variables.
- if ($file !~ /\$/)
+ if ((substitute_ac_subst_variables $file) !~ /\$/)
{
my $fd = dirname ($file);
- # Make sure the dist directory for each input file is created.
- # We only have to do this at the topmost level though.
- if ($relative_dir eq '.')
- {
- $dist_dirs{$fd} = 1;
- }
-
# We distribute files that are in this directory.
# At the top-level (`.') we also distribute files whose
# directory does not have a Makefile.
# These files get removed by "make distclean".
define_pretty_variable ('CONFIG_CLEAN_FILES', TRUE, INTERNAL,
@actual_other_files);
+ define_pretty_variable ('CONFIG_CLEAN_VPATH_FILES', TRUE, INTERNAL,
+ @actual_other_vpath_files);
}
# Handle C headers.
"AM_GNU_GETTEXT used but `po' not in SUBDIRS")
if ! grep ($_ eq 'po', @subdirs);
- # intl/ is not required when AM_GNU_GETTEXT is called with
- # the `external' option.
+ # intl/ is not required when AM_GNU_GETTEXT is called with the
+ # `external' option and AM_GNU_GETTEXT_INTL_SUBDIR is not called.
msg_var ('syntax', $subdirs,
"AM_GNU_GETTEXT used but `intl' not in SUBDIRS")
- if (! $seen_gettext_external
+ if (! ($seen_gettext_external && ! $seen_gettext_intl)
&& ! grep ($_ eq 'intl', @subdirs));
- # intl/ should not be used with AM_GNU_GETTEXT([external])
+ # intl/ should not be used with AM_GNU_GETTEXT([external]), except
+ # if AM_GNU_GETTEXT_INTL_SUBDIR is called.
msg_var ('syntax', $subdirs,
"`intl' should not be in SUBDIRS when "
. "AM_GNU_GETTEXT([external]) is used")
- if ($seen_gettext_external && grep ($_ eq 'intl', @subdirs));
+ if ($seen_gettext_external && ! $seen_gettext_intl
+ && grep ($_ eq 'intl', @subdirs));
}
require_file ($ac_gettext_location, GNU, 'ABOUT-NLS');
# Handle footer elements.
sub handle_footer
{
- # NOTE don't use define_pretty_variable here, because
- # $contents{...} is already defined.
- $output_vars .= 'SOURCES = ' . variable_value ('SOURCES') . "\n\n"
- if variable_value ('SOURCES');
-
reject_rule ('.SUFFIXES',
"use variable `SUFFIXES', not target `.SUFFIXES'");
foreach my $spec (@config_headers)
{
- my ($out, @ins) = split_config_file_spec ($spec);
+ my ($out, @ins) = split_config_file_spec ($spec);
push (@all, basename ($out))
if dirname ($out) eq $relative_dir;
}
if var ('BUILT_SOURCES');
foreach my $spec (@config_headers)
{
- my ($out, @ins) = split_config_file_spec ($spec);
+ my ($out, @ins) = split_config_file_spec ($spec);
push @local_headers, basename ($out)
if dirname ($out) eq $relative_dir;
}
. '$(MAKE) $(AM_MAKEFLAGS) '
. (var ('SUBDIRS') ? 'all-recursive' : 'all-am')
. "\n\n");
+ depend ('.MAKE', 'all');
}
else
{
# `all', to ensure all the primary targets are built. Then it
# must build the local check rules.
$output_rules .= "check-am: all-am\n";
+ if (@check)
+ {
+ pretty_print_rule ("\t\$(MAKE) \$(AM_MAKEFLAGS)", "\t ",
+ @check);
+ depend ('.MAKE', 'check-am');
+ }
+ }
+ if (@check_tests)
+ {
pretty_print_rule ("\t\$(MAKE) \$(AM_MAKEFLAGS)", "\t ",
- @check)
- if @check;
+ @check_tests);
+ depend ('.MAKE', 'check-am');
}
- pretty_print_rule ("\t\$(MAKE) \$(AM_MAKEFLAGS)", "\t ",
- @check_tests)
- if @check_tests;
depend '.PHONY', 'check', 'check-am';
# Handle recursion. We have to honor BUILT_SOURCES like for `all:'.
: '')
. (var ('SUBDIRS') ? 'check-recursive' : 'check-am')
. "\n");
+ depend ('.MAKE', 'check')
+ if var ('BUILT_SOURCES');
}
# handle_clean ($MAKEFILE)
{
# Reject bad hooks.
foreach my $utarg ('uninstall-data-local', 'uninstall-data-hook',
- 'uninstall-exec-local', 'uninstall-exec-hook')
+ 'uninstall-exec-local', 'uninstall-exec-hook',
+ 'uninstall-dvi-local',
+ 'uninstall-html-local',
+ 'uninstall-info-local',
+ 'uninstall-pdf-local',
+ 'uninstall-ps-local')
{
my $x = $utarg;
- $x =~ s/(data|exec)-//;
+ $x =~ s/-.*-/-/;
reject_rule ($utarg, "use `$x', not `$utarg'");
}
"use `install-data-local' or `install-exec-local', "
. "not `install-local'");
- reject_rule ('install-info-local',
- "`install-info-local' target defined but "
- . "`no-installinfo' option not in use")
- unless option 'no-installinfo';
+ reject_rule ('install-hook',
+ "use `install-data-hook' or `install-exec-hook', "
+ . "not `install-hook'");
# Install the -local hooks.
foreach (keys %dependencies)
{
if (user_phony_rule "$_-hook")
{
- $actions{"$_-am"} .=
- ("\t\@\$(NORMAL_INSTALL)\n"
- . "\t" . '$(MAKE) $(AM_MAKEFLAGS) ' . "$_-hook\n");
depend ('.MAKE', "$_-am");
+ register_action("$_-am",
+ ("\t\@\$(NORMAL_INSTALL)\n"
+ . "\t\$(MAKE) \$(AM_MAKEFLAGS) $_-hook"));
}
}
if (var ('TESTS'))
{
push (@check_tests, 'check-TESTS');
- $output_rules .= &file_contents ('check', new Automake::Location);
+ $output_rules .= &file_contents ('check', new Automake::Location,
+ COLOR => !! option 'color-tests');
+
+ # Tests that are known programs should have $(EXEEXT) appended.
+ # For matching purposes, we need to adjust XFAIL_TESTS as well.
+ append_exeext { exists $known_programs{$_[0]} } 'TESTS';
+ append_exeext { exists $known_programs{$_[0]} } 'XFAIL_TESTS'
+ if (var ('XFAIL_TESTS'));
}
}
# Handle $local:$input syntax.
my ($local, @rest) = split (/:/);
@rest = ("$local.in",) unless @rest;
+ msg ('portability', $where,
+ "Omit leading `./' from config file names such as `$local',"
+ . "\nas not all make implementations treat `file' and `./file' equally.")
+ if ($local =~ /^\.\//);
my $input = locate_am @rest;
if ($input)
- {
+ {
# We have a file that automake should generate.
$make_list{$input} = join (':', ($local, @rest));
- }
+ }
else
- {
+ {
# We have a file that automake should cause to be
# rebuilt, but shouldn't generate itself.
push (@other_input_files, $_);
- }
+ }
$ac_config_files_location{$local} = $where;
+ $ac_config_files_condition{$local} =
+ new Automake::Condition (@cond_stack)
+ if (@cond_stack);
}
}
AC_CONFIG_AUX_DIR => 1,
AC_CONFIG_FILES => 1,
AC_CONFIG_HEADERS => 1,
+ AC_CONFIG_LIBOBJ_DIR => 1,
AC_CONFIG_LINKS => 1,
+ AC_FC_SRCEXT => 1,
AC_INIT => 0,
AC_LIBSOURCE => 1,
- AC_REQUIRE_AUX_FILE => 1,
- AC_SUBST => 1,
+ AC_REQUIRE_AUX_FILE => 1,
+ AC_SUBST_TRACE => 1,
AM_AUTOMAKE_VERSION => 1,
AM_CONDITIONAL => 2,
AM_ENABLE_MULTILIB => 0,
AM_GNU_GETTEXT => 0,
+ AM_GNU_GETTEXT_INTL_SUBDIR => 0,
AM_INIT_AUTOMAKE => 0,
AM_MAINTAINER_MODE => 0,
AM_PROG_CC_C_O => 0,
+ _AM_SUBST_NOTMAKE => 1,
+ _AM_COND_IF => 1,
+ _AM_COND_ELSE => 1,
+ _AM_COND_ENDIF => 1,
LT_SUPPORTED_TAG => 1,
_LT_AC_TAGCONFIG => 0,
m4_include => 1,
# Use a separator unlikely to be used, not `:', the default, which
# has a precise meaning for AC_CONFIG_FILES and so on.
$traces .= join (' ',
- map { "--trace=$_" . ':\$f:\$l::\$n::\${::}%' }
+ map { "--trace=$_" . ':\$f:\$l::\$d::\$n::\${::}%' }
(keys %traced));
my $tracefh = new Automake::XFile ("$traces $filename |");
verb "reading $traces";
+ @cond_stack = ();
+ my $where;
+
while ($_ = $tracefh->getline)
{
chomp;
- my ($here, @args) = split (/::/);
- my $where = new Automake::Location $here;
+ my ($here, $depth, @args) = split (/::/);
+ $where = new Automake::Location $here;
my $macro = $args[0];
prog_error ("unrequested trace `$macro'")
push @config_headers, $spec;
}
}
+ elsif ($macro eq 'AC_CONFIG_LIBOBJ_DIR')
+ {
+ $config_libobj_dir = $args[1];
+ $relative_dir = '.';
+ check_directory ($config_libobj_dir, $where);
+ }
elsif ($macro eq 'AC_CONFIG_LINKS')
{
foreach my $spec (split (' ', $args[1]))
push @config_links, $spec;
}
}
+ elsif ($macro eq 'AC_FC_SRCEXT')
+ {
+ my $suffix = $args[1];
+ # These flags are used as %SOURCEFLAG% in depend2.am,
+ # where the trailing space is important.
+ $sourceflags{'.' . $suffix} = '$(FCFLAGS_' . $suffix . ') '
+ if ($suffix eq 'f90' || $suffix eq 'f95' || $suffix eq 'f03' || $suffix eq 'f08');
+ }
elsif ($macro eq 'AC_INIT')
- {
+ {
if (defined $args[2])
{
$package_version = $args[2];
{
$libsources{$args[1]} = $here;
}
- elsif ($macro eq 'AC_SUBST')
+ elsif ($macro eq 'AC_REQUIRE_AUX_FILE')
+ {
+ # Only remember the first time a file is required.
+ $required_aux_file{$args[1]} = $where
+ unless exists $required_aux_file{$args[1]};
+ }
+ elsif ($macro eq 'AC_SUBST_TRACE')
{
- # Just check for alphanumeric in AC_SUBST. If you do
+ # Just check for alphanumeric in AC_SUBST_TRACE. If you do
# AC_SUBST(5), then too bad.
$configure_vars{$args[1]} = $where
if $args[1] =~ /^\w+$/;
}
elsif ($macro eq 'AM_AUTOMAKE_VERSION')
- {
+ {
error ($where,
"version mismatch. This is Automake $VERSION,\n" .
"but the definition used by this AM_INIT_AUTOMAKE\n" .
if $VERSION ne $args[1];
$seen_automake_version = 1;
- }
+ }
elsif ($macro eq 'AM_CONDITIONAL')
{
$configure_cond{$args[1]} = $where;
- }
+ }
elsif ($macro eq 'AM_ENABLE_MULTILIB')
{
$seen_multilib = $where;
$ac_gettext_location = $where;
$seen_gettext_external = grep ($_ eq 'external', @args);
}
+ elsif ($macro eq 'AM_GNU_GETTEXT_INTL_SUBDIR')
+ {
+ $seen_gettext_intl = $where;
+ }
elsif ($macro eq 'AM_INIT_AUTOMAKE')
{
$seen_init_automake = $where;
{
$seen_cc_c_o = $where;
}
- elsif ($macro eq 'AC_REQUIRE_AUX_FILE')
+ elsif ($macro eq '_AM_COND_IF')
+ {
+ cond_stack_if ('', $args[1], $where);
+ error ($where, "missing m4 quoting, macro depth $depth")
+ if ($depth != 1);
+ }
+ elsif ($macro eq '_AM_COND_ELSE')
+ {
+ cond_stack_else ('!', $args[1], $where);
+ error ($where, "missing m4 quoting, macro depth $depth")
+ if ($depth != 1);
+ }
+ elsif ($macro eq '_AM_COND_ENDIF')
+ {
+ cond_stack_endif (undef, undef, $where);
+ error ($where, "missing m4 quoting, macro depth $depth")
+ if ($depth != 1);
+ }
+ elsif ($macro eq '_AM_SUBST_NOTMAKE')
{
- # Only remember the first time a file is required.
- $required_aux_file{$args[1]} = $where
- unless exists $required_aux_file{$args[1]};
+ $ignored_configure_vars{$args[1]} = $where;
}
elsif ($macro eq 'm4_include'
|| $macro eq 'm4_sinclude'
|| $macro eq 'sinclude')
{
+ # Skip missing `sinclude'd files.
+ next if $macro ne 'm4_include' && ! -f $args[1];
+
# Some modified versions of Autoconf don't use
- # forzen files. Consequently it's possible that we see all
+ # frozen files. Consequently it's possible that we see all
# m4_include's performed during Autoconf's startup.
# Obviously we don't want to distribute Autoconf's files
# so we skip absolute filenames here.
}
elsif ($macro eq 'LT_SUPPORTED_TAG')
{
- $libtool_tags{$args[1]} = 1;
+ $libtool_tags{$args[1]} = 1;
$libtool_new_api = 1;
}
elsif ($macro eq '_LT_AC_TAGCONFIG')
{
# _LT_AC_TAGCONFIG is an old macro present in Libtool 1.5.
# We use it to detect whether tags are supported. Our
- # prefered interface is LT_SUPPORTED_TAG, but it was
+ # preferred interface is LT_SUPPORTED_TAG, but it was
# introduced in Libtool 1.6.
if (0 == keys %libtool_tags)
{
}
}
+ error ($where, "condition stack not properly closed")
+ if (@cond_stack);
+
$tracefh->close;
}
# check must be done for every run, even those where we are only
# looking at a subdir Makefile. We must set relative_dir for
# maybe_push_required_file to work.
+ # Sort the files for stable verbose output.
$relative_dir = '.';
- foreach my $file (keys %required_aux_file)
+ foreach my $file (sort keys %required_aux_file)
{
require_conf_file ($required_aux_file{$file}->get, FOREIGN, $file)
}
# libtool is always able to put the object at the proper place,
# so we do not have to require AM_PROG_CC_C_O when building .lo files.
- err_var ($var, "compiling `$base.c' in subdir requires "
+ msg_var ('portability', $var,
+ "compiling `$base.c' in subdir requires "
. "`AM_PROG_CC_C_O' in `$configure_ac'",
uniq_scope => US_GLOBAL,
uniq_part => 'AM_PROG_CC_C_O subdir')
&& ! option 'subdir-objects'
&& $nonansi_obj ne '.lo')
{
- err_var ($var, "compiling `$base.c' with per-target flags requires "
+ msg_var ('portability',
+ $var, "compiling `$base.c' with per-target flags requires "
. "`AM_PROG_CC_C_O' in `$configure_ac'",
uniq_scope => US_GLOBAL,
uniq_part => 'AM_PROG_CC_C_O per-target')
# Rewrite a single Fortran 77 file.
sub lang_f77_rewrite
{
- return LANG_PROCESS;
+ return &lang_sub_obj;
}
# Rewrite a single Fortran file.
sub lang_fc_rewrite
{
- return LANG_PROCESS;
+ return &lang_sub_obj;
}
# Rewrite a single preprocessed Fortran file.
sub lang_ppfc_rewrite
{
- return LANG_PROCESS;
+ return &lang_sub_obj;
}
# Rewrite a single preprocessed Fortran 77 file.
sub lang_ppf77_rewrite
{
- return LANG_PROCESS;
+ return &lang_sub_obj;
}
# Rewrite a single ratfor file.
sub lang_ratfor_rewrite
{
- return LANG_PROCESS;
+ return &lang_sub_obj;
}
# Rewrite a single Objective C file.
return &lang_sub_obj;
}
+# Rewrite a single Unified Parallel C file.
+sub lang_upc_rewrite
+{
+ return &lang_sub_obj;
+}
+
# Rewrite a single Java file.
sub lang_java_rewrite
{
if (option 'ansi2knr' && keys %de_ansi_files)
{
- # Make all _.c files depend on their corresponding .c files.
- my @objects;
- foreach my $base (sort keys %de_ansi_files)
- {
+ # Make all _.c files depend on their corresponding .c files.
+ my @objects;
+ foreach my $base (sort keys %de_ansi_files)
+ {
# Each _.c file must depend on ansi2knr; otherwise it
# might be used in a parallel build before it is built.
# We need to support files in the srcdir and in the build
# we can't use $< -- some makes only define $< during a
# suffix rule.
my $ansfile = $de_ansi_files{$base} . $base . '.c';
- $output_rules .= ($base . "_.c: $ansfile \$(ANSI2KNR)\n\t"
+ $output_rules .= ($base . "_.c: $ansfile \$(ANSI2KNR)\n\t"
. '$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) '
. '`if test -f $(srcdir)/' . $ansfile
. '; then echo $(srcdir)/' . $ansfile
# If ansi2knr fails then we shouldn't
# create the _.c file
. " || rm -f \$\@\n");
- push (@objects, $base . '_.$(OBJEXT)');
- push (@objects, $base . '_.lo')
+ push (@objects, $base . '_.$(OBJEXT)');
+ push (@objects, $base . '_.lo')
if var ('LIBTOOL');
# Explicitly clean the _.c files if they are in a
# by a `rm -f *_.c' rule.)
$clean_files{$base . '_.c'} = MOSTLY_CLEAN
if dirname ($base) ne '.';
- }
+ }
- # Make all _.o (and _.lo) files depend on ansi2knr.
- # Use a sneaky little hack to make it print nicely.
- &pretty_print_rule ('', '', @objects, ':', '$(ANSI2KNR)');
+ # Make all _.o (and _.lo) files depend on ansi2knr.
+ # Use a sneaky little hack to make it print nicely.
+ &pretty_print_rule ('', '', @objects, ':', '$(ANSI2KNR)');
}
}
INTERNAL))
{
my $condstr = $cond->subst_string;
- $output_rules .= ("$condstr${header}: $output\n"
- # Recover from removal of $header
- . "$condstr\t\@if test ! -f \$@; then \\\n"
- . "$condstr\t rm -f $output; \\\n"
- . "$condstr\t \$(MAKE) $output; \\\n"
- . "$condstr\telse :; fi\n");
+ $output_rules .=
+ "$condstr${header}: $output\n"
+ # Recover from removal of $header
+ . "$condstr\t\@if test ! -f \$@; then \\\n"
+ . "$condstr\t rm -f $output; \\\n"
+ . "$condstr\t \$(MAKE) \$(AM_MAKEFLAGS) $output; \\\n"
+ . "$condstr\telse :; fi\n";
}
# Distribute the generated file, unless its .y source was
# listed in a nodist_ variable. (&handle_source_transform
return if defined $language_scratch{'lex-yacc-done'};
$language_scratch{'lex-yacc-done'} = 1;
- # If there is more than one distinct yacc (resp lex) source file
- # in a given directory, then the `ylwrap' program is required to
- # allow parallel builds to work correctly. FIXME: for now, no
- # line number.
+ # FIXME: for now, no line number.
require_conf_file ($configure_ac, FOREIGN, 'ylwrap');
&define_variable ('YLWRAP', "$am_config_aux_dir/ylwrap", INTERNAL);
}
reject_var 'YACCFLAGS', "`YACCFLAGS' obsolete; use `YFLAGS' instead";
- &yacc_lex_finish_helper
- if count_files_for_language ('yacc') > 1;
+ yacc_lex_finish_helper;
}
return if defined $language_scratch{'lex-done'};
$language_scratch{'lex-done'} = 1;
- &yacc_lex_finish_helper
- if count_files_for_language ('lex') > 1;
+ yacc_lex_finish_helper;
}
{
my (%linkers) = @_;
- foreach my $l (qw(GCJLINK CXXLINK F77LINK FCLINK OBJCLINK))
+ foreach my $l (qw(GCJLINK CXXLINK F77LINK FCLINK OBJCLINK UPCLINK))
{
return $l if defined $linkers{$l};
}
foreach my $ext (@{$lang->extensions})
{
$r += $extension_seen{$ext}
- if defined $extension_seen{$ext};
+ if defined $extension_seen{$ext};
}
}
# Fill indexes.
$extension_map{$_} = $lang->name foreach @{$lang->extensions};
$languages{$lang->name} = $lang;
+ my $link = $lang->linker;
+ if ($link)
+ {
+ if (exists $link_languages{$link})
+ {
+ prog_error ("`$link' has different definitions in "
+ . $lang->name . " and " . $link_languages{$link}->name)
+ if $lang->link ne $link_languages{$link}->link;
+ }
+ else
+ {
+ $link_languages{$link} = $lang;
+ }
+ }
# Update the pattern of known extensions.
accept_extensions (@{$lang->extensions});
}
+my %_am_macro_for_cond =
+ (
+ AMDEP => "one of the compiler tests\n"
+ . " AC_PROG_CC, AC_PROG_CXX, AC_PROG_CXX, AC_PROG_OBJC,\n"
+ . " AM_PROG_AS, AM_PROG_GCJ, AM_PROG_UPC",
+ am__fastdepCC => 'AC_PROG_CC',
+ am__fastdepCCAS => 'AM_PROG_AS',
+ am__fastdepCXX => 'AC_PROG_CXX',
+ am__fastdepGCJ => 'AM_PROG_GCJ',
+ am__fastdepOBJC => 'AC_PROG_OBJC',
+ am__fastdepUPC => 'AM_PROG_UPC'
+ );
+
# $COND
# cond_stack_if ($NEGATE, $COND, $WHERE)
# --------------------------------------
{
my ($negate, $cond, $where) = @_;
- error $where, "$cond does not appear in AM_CONDITIONAL"
- if ! $configure_cond{$cond} && $cond !~ /^TRUE|FALSE$/;
+ if (! $configure_cond{$cond} && $cond !~ /^TRUE|FALSE$/)
+ {
+ my $text = "$cond does not appear in AM_CONDITIONAL";
+ my $scope = US_LOCAL;
+ if (exists $_am_macro_for_cond{$cond})
+ {
+ my $mac = $_am_macro_for_cond{$cond};
+ $text .= "\n The usual way to define `$cond' is to add ";
+ $text .= ($mac =~ / /) ? $mac : "`$mac'";
+ $text .= "\n to `$configure_ac' and run `aclocal' and `autoconf' again.";
+ # These warnings appear in Automake files (depend2.am),
+ # so there is no need to display them more than once:
+ $scope = US_GLOBAL;
+ }
+ error $where, $text, uniq_scope => $scope;
+ }
push (@cond_stack, make_conditional_string ($negate, $cond));
# &define_pretty_variable ($VAR, $COND, $WHERE, @VALUE)
# -----------------------------------------------------
# Like define_variable, but the value is a list, and the variable may
-# be defined conditionally. The second argument is the Condition
+# be defined conditionally. The second argument is the condition
# under which the value should be defined; this should be the empty
# string to define the variable unconditionally. The third argument
# is a list holding the values to use for the variable. The value is
if (! vardef ($var, $cond))
{
- Automake::Variable::define ($var, VAR_AUTOMAKE, '', $cond, "@value",
+ Automake::Variable::define ($var, VAR_AUTOMAKE, '', $cond, "@value",
'', $where, VAR_PRETTY);
rvar ($var)->rdef ($cond)->set_seen;
}
my $pretty = VAR_ASIS;
my $owner = VAR_CONFIGURE;
- # Do not output the ANSI2KNR configure variable -- we AC_SUBST
- # it in protos.m4, but later redefine it elsewhere. This is
- # pretty hacky. We also don't output AMDEPBACKSLASH: it might
- # be subst'd by `\', which certainly would not be appreciated by
- # Make.
- if ($var eq 'ANSI2KNR' || $var eq 'AMDEPBACKSLASH')
- {
- $pretty = VAR_SILENT;
- $owner = VAR_AUTOMAKE;
- }
+ # Some variables we do not want to output. For instance it
+ # would be a bad idea to output `U = @U@` when `@U@` can be
+ # substituted as `\`.
+ $pretty = VAR_SILENT if exists $ignored_configure_vars{$var};
+
+ # ANSI2KNR is a variable that Automake wants to redefine, so
+ # it must be owned by Automake. (It is also used as a proof
+ # that AM_C_PROTOTYPES has been run, that's why we do not simply
+ # omit the AC_SUBST.)
+ $owner = VAR_AUTOMAKE if $var eq 'ANSI2KNR';
Automake::Variable::define ($var, $owner, '', TRUE, subst $var,
'', $configure_vars{$var}, $pretty);
{
my ($lang) = @_;
- my ($var, $value) = ($lang->lder, $lang->ld);
my $libtool_tag = '';
$libtool_tag = '--tag=' . $lang->libtool_tag . ' '
if $lang->libtool_tag && exists $libtool_tags{$lang->libtool_tag};
INTERNAL);
}
+sub define_per_target_linker_variable ($$)
+{
+ my ($linker, $target) = @_;
+
+ # If the user wrote a custom link command, we don't define ours.
+ return "${target}_LINK"
+ if set_seen "${target}_LINK";
+
+ my $xlink = $linker ? $linker : 'LINK';
+
+ my $lang = $link_languages{$xlink};
+ prog_error "Unknown language for linker variable `$xlink'"
+ unless $lang;
+
+ my $link_command = $lang->link;
+ if (var 'LIBTOOL')
+ {
+ my $libtool_tag = '';
+ $libtool_tag = '--tag=' . $lang->libtool_tag . ' '
+ if $lang->libtool_tag && exists $libtool_tags{$lang->libtool_tag};
+
+ $link_command =
+ "\$(LIBTOOL) $libtool_tag\$(AM_LIBTOOLFLAGS) \$(LIBTOOLFLAGS) "
+ . "--mode=link " . $link_command;
+ }
+
+ # Rewrite each occurrence of `AM_$flag' in the link
+ # command into `${derived}_$flag' if it exists.
+ my $orig_command = $link_command;
+ my @flags = (@{$lang->flags}, 'LDFLAGS');
+ push @flags, 'LIBTOOLFLAGS' if var 'LIBTOOL';
+ for my $flag (@flags)
+ {
+ my $val = "${target}_$flag";
+ $link_command =~ s/\(AM_$flag\)/\($val\)/
+ if set_seen ($val);
+ }
+
+ # If the computed command is the same as the generic command, use
+ # the command linker variable.
+ return $lang->linker
+ if $link_command eq $orig_command;
+
+ &define_variable ("${target}_LINK", $link_command, INTERNAL);
+ return "${target}_LINK";
+}
+
################################################################
# &check_trailing_slash ($WHERE, $LINE)
my $comment = '';
my $blank = 0;
my $saw_bk = 0;
+ my $var_look = VAR_ASIS;
use constant IN_VAR_DEF => 0;
use constant IN_RULE_DEF => 1;
while ($_ = $am_file->getline)
{
- $where->set ("$amfile:$.");
+ $where->set ("$amfile:$.");
if (/$IGNORE_PATTERN/o)
{
# Merely delete comments beginning with two hashes.
# FIXME: shouldn't use $_ in this loop; it is too big.
while ($_)
{
- $where->set ("$amfile:$.");
+ $where->set ("$amfile:$.");
# Make sure the line is \n-terminated.
chomp;
if (/$IGNORE_PATTERN/o)
{
# Merely delete comments beginning with two hashes.
+
+ # Keep any backslash from the previous line.
+ $new_saw_bk = $saw_bk;
}
elsif (/$WHITE_PATTERN/o)
{
}
elsif (/$COMMENT_PATTERN/o)
{
+ error $where, "comment following trailing backslash"
+ if $saw_bk && $comment eq '';
+
# Stick comments before the incoming macro or rule.
$comment .= $spacing . $_;
$spacing = '';
- error $where, "comment following trailing backslash"
- if $saw_bk && $comment eq '';
$prev_state = IN_COMMENT;
}
elsif ($saw_bk)
# For now we have to output all definitions of user rules
# and can't diagnose duplicates (see the comment in
- # rule_define). So we go on and ignore the return value.
+ # Automake::Rule::define). So we go on and ignore the return value.
Automake::Rule::define ($1, $amfile, RULE_USER, $cond, $where);
check_variable_expansions ($_, $where);
$output_trailer .= $comment . $spacing;
my $cond = new Automake::Condition @cond_stack;
$output_trailer .= $cond->subst_string;
- $output_trailer .= $_;
+ $output_trailer .= $_;
$comment = $spacing = '';
}
elsif (/$ASSIGNMENT_PATTERN/o)
$last_var_value = $3;
$last_where = $where->clone;
if ($3 ne '' && substr ($3, -1) eq "\\")
- {
+ {
# We preserve the `\' because otherwise the long lines
# that are generated will be truncated by broken
# `sed's.
$last_var_value = $3 . "\n";
- }
+ }
+ # Normally we try to output variable definitions in the
+ # same format they were input. However, POSIX compliant
+ # systems are not required to support lines longer than
+ # 2048 bytes (most notably, some sed implementation are
+ # limited to 4000 bytes, and sed is used by config.status
+ # to rewrite Makefile.in into Makefile). Moreover nobody
+ # would really write such long lines by hand since it is
+ # hardly maintainable. So if a line is longer that 1000
+ # bytes (an arbitrary limit), assume it has been
+ # automatically generated by some tools, and flatten the
+ # variable definition. Otherwise, keep the variable as it
+ # as been input.
+ $var_look = VAR_PRETTY if length ($last_var_value) >= 1000;
if (!/\\$/)
{
Automake::Variable::define ($last_var_name, VAR_MAKEFILE,
$last_var_type, $cond,
$last_var_value, $comment,
- $last_where, VAR_ASIS)
+ $last_where, $var_look)
if $cond != FALSE;
$comment = $spacing = '';
+ $var_look = VAR_ASIS;
}
}
- elsif (/$INCLUDE_PATTERN/o)
- {
- my $path = $1;
+ elsif (/$INCLUDE_PATTERN/o)
+ {
+ my $path = $1;
- if ($path =~ s/^\$\(top_srcdir\)\///)
+ if ($path =~ s/^\$\(top_srcdir\)\///)
{
- push (@include_stack, "\$\(top_srcdir\)/$path");
+ push (@include_stack, "\$\(top_srcdir\)/$path");
# Distribute any included file.
# Always use the $(top_srcdir) prefix in DIST_COMMON,
# (subdircond2.test and subdircond3.test will fail.)
push_dist_common ("\$\(top_srcdir\)/$path");
}
- else
+ else
{
- $path =~ s/\$\(srcdir\)\///;
- push (@include_stack, "\$\(srcdir\)/$path");
+ $path =~ s/\$\(srcdir\)\///;
+ push (@include_stack, "\$\(srcdir\)/$path");
# Always use the $(srcdir) prefix in DIST_COMMON,
# otherwise OSF make will implicitly copy the included
# file in the build tree during `make distdir' to satisfy
$path = $relative_dir . "/" . $path if $relative_dir ne '.';
}
$where->push_context ("`$path' included from here");
- &read_am_file ($path, $where);
+ &read_am_file ($path, $where);
$where->pop_context;
- }
+ }
else
- {
+ {
# This isn't an error; it is probably a continued rule.
# In fact, this is what we assume.
$prev_state = IN_RULE_DEF;
}
$saw_bk = $new_saw_bk;
- $_ = $am_file->getline;
+ $_ = $am_file->getline;
}
$output_trailer .= $comment;
return $_;
}
-# transform($TOKEN, \%PAIRS)
-# ==========================
+
+# transform_token ($TOKEN, \%PAIRS, $KEY)
+# =======================================
+# Return the value associated to $KEY in %PAIRS, as used on $TOKEN
+# (which should be ?KEY? or any of the special %% requests)..
+sub transform_token ($$$)
+{
+ my ($token, $transform, $key) = @_;
+ my $res = $transform->{$key};
+ prog_error "Unknown key `$key' in `$token'" unless defined $res;
+ return $res;
+}
+
+
+# transform ($TOKEN, \%PAIRS)
+# ===========================
# If ($TOKEN, $VAL) is in %PAIRS:
-# - replaces %$TOKEN% with $VAL,
-# - enables/disables ?$TOKEN? and ?!$TOKEN?,
-# - replaces %?$TOKEN% with TRUE or FALSE.
-sub transform($$)
+# - replaces %KEY% with $VAL,
+# - enables/disables ?KEY? and ?!KEY?,
+# - replaces %?KEY% with TRUE or FALSE.
+# - replaces %KEY?IFTRUE%, %KEY:IFFALSE%, and %KEY?IFTRUE:IFFALSE% with
+# IFTRUE / IFFALSE, as appropriate.
+sub transform ($$)
{
my ($token, $transform) = @_;
- if (substr ($token, 0, 1) eq '%')
+ # %KEY%.
+ # Must be before the following pattern to exclude the case
+ # when there is neither IFTRUE nor IFFALSE.
+ if ($token =~ /^%([\w\-]+)%$/)
{
- my $cond = (substr ($token, 1, 1) eq '?') ? 1 : 0;
- $token = substr ($token, 1 + $cond, -1);
- my $val = $transform->{$token};
- prog_error "Unknown %token% `$token'" unless defined $val;
- if ($cond)
- {
- return $val ? 'TRUE' : 'FALSE';
- }
- else
- {
- return $val;
- }
+ return transform_token ($token, $transform, $1);
+ }
+ # %KEY?IFTRUE%, %KEY:IFFALSE%, and %KEY?IFTRUE:IFFALSE%.
+ elsif ($token =~ /^%([\w\-]+)(?:\?([^?:%]+))?(?::([^?:%]+))?%$/)
+ {
+ return transform_token ($token, $transform, $1) ? ($2 || '') : ($3 || '');
+ }
+ # %?KEY%.
+ elsif ($token =~ /^%\?([\w\-]+)%$/)
+ {
+ return transform_token ($token, $transform, $1) ? 'TRUE' : 'FALSE';
+ }
+ # ?KEY? and ?!KEY?.
+ elsif ($token =~ /^ \? (!?) ([\w\-]+) \? $/x)
+ {
+ my $neg = ($1 eq '!') ? 1 : 0;
+ my $val = transform_token ($token, $transform, $2);
+ return (!!$val == $neg) ? '##%' : '';
+ }
+ else
+ {
+ prog_error "Unknown request format: $token";
}
- # Now $token is '?xxx?' or '?!xxx?'.
- my $neg = (substr ($token, 1, 1) eq '!') ? 1 : 0;
- $token = substr ($token, 1 + $neg, -1);
- my $val = $transform->{$token};
- prog_error "Unknown ?token? `$token' (neg = $neg)" unless defined $val;
- return (!!$val == $neg) ? '##%' : '';
}
+
# @PARAGRAPHS
# &make_paragraphs ($MAKEFILE, [%TRANSFORM])
# ------------------------------------------
'MAINTAINER-MODE'
=> $seen_maint_mode ? subst ('MAINTAINER_MODE_TRUE') : '',
+ 'XZ' => !! option 'dist-xz',
+ 'LZMA' => !! option 'dist-lzma',
'BZIP2' => !! option 'dist-bzip2',
'COMPRESS' => !! option 'dist-tarZ',
'GZIP' => ! option 'no-dist-gzip',
'INSTALL-INFO' => ! option 'no-installinfo',
'INSTALL-MAN' => ! option 'no-installman',
+ 'HAVE-MANS' => !! var ('MANS'),
'CK-NEWS' => !! option 'check-news',
'SUBDIRS' => !! var ('SUBDIRS'),
- 'TOPDIR' => backname ($relative_dir),
'TOPDIR_P' => $relative_dir eq '.',
'BUILD' => ($seen_canonical >= AC_CANONICAL_BUILD),
}
# Substitute Automake template tokens.
- s/(?:%\??[\w\-]+%|\?!?[\w\-]+\?)/transform($&, \%transform)/ge;
+ s/(?: % \?? [\w\-]+ %
+ | % [\w\-]+ (?:\?[^?:%]+)? (?::[^?:%]+)? %
+ | \? !? [\w\-]+ \?
+ )/transform($&, \%transform)/gex;
# transform() may have added some ##%-comments to strip.
# (we use `##%' instead of `##' so we can distinguish ##%##%##% from
# ####### and do not remove the latter.)
foreach (make_paragraphs ($file, %transform))
{
- # FIXME: no line number available.
- $where->set ($file);
+ # FIXME: no line number available.
+ $where->set ($file);
- # Sanity checks.
+ # Sanity checks.
error $where, "blank line following trailing backslash:\n$_"
if /\\$/;
error $where, "comment following trailing backslash:\n$_"
if /\\#/;
- if (/^$/)
- {
+ if (/^$/)
+ {
$is_rule = 0;
- # Stick empty line before the incoming macro or rule.
- $spacing = "\n";
- }
- elsif (/$COMMENT_PATTERN/mso)
- {
+ # Stick empty line before the incoming macro or rule.
+ $spacing = "\n";
+ }
+ elsif (/$COMMENT_PATTERN/mso)
+ {
$is_rule = 0;
- # Stick comments before the incoming macro or rule.
- $comment = "$_\n";
+ # Stick comments before the incoming macro or rule.
+ $comment = "$_\n";
}
# Handle inclusion of other files.
- elsif (/$INCLUDE_PATTERN/o)
- {
+ elsif (/$INCLUDE_PATTERN/o)
+ {
if ($cond != FALSE)
{
my $file = ($is_am ? "$libdir/am/" : '') . $1;
$result_vars .= $vars;
$result_rules .= $rules;
}
- }
+ }
- # Handling the conditionals.
- elsif (/$IF_PATTERN/o)
+ # Handling the conditionals.
+ elsif (/$IF_PATTERN/o)
{
$cond = cond_stack_if ($1, $2, $file);
}
$cond = cond_stack_endif ($1, $2, $file);
}
- # Handling rules.
- elsif (/$RULE_PATTERN/mso)
- {
+ # Handling rules.
+ elsif (/$RULE_PATTERN/mso)
+ {
$is_rule = 1;
$discard_rule = 0;
# Separate relationship from optional actions: the first
my $flat_deps = &flatten ($dependencies);
my @deps = split (' ', $flat_deps);
- foreach (split (' ' , $targets))
+ foreach (split (' ', $targets))
{
# FIXME: 1. We are not robust to people defining several targets
# at once, only some of them being in %dependencies. The
if (defined $dependencies{$_} && $cond != FALSE)
{
&depend ($_, @deps);
- if ($actions{$_})
- {
- $actions{$_} .= "\n$actions" if $actions;
- }
- else
- {
- $actions{$_} = $actions;
- }
+ register_action ($_, $actions);
}
else
{
last;
}
}
- }
+ }
- elsif (/$ASSIGNMENT_PATTERN/mso)
- {
+ elsif (/$ASSIGNMENT_PATTERN/mso)
+ {
my ($var, $type, $val) = ($1, $2, $3);
- error $where, "variable `$var' with trailing backslash"
+ error $where, "variable `$var' with trailing backslash"
if /\\$/;
$is_rule = 0;
VAR_ASIS)
if $cond != FALSE;
- $comment = $spacing = '';
- }
- else
- {
+ $comment = $spacing = '';
+ }
+ else
+ {
# This isn't an error; it is probably some tokens which
# configure is supposed to replace, such as `@SET-MAKE@',
# or some part of a rule cut by an if/endif.
- if (! $cond->false && ! ($is_rule && $discard_rule))
+ if (! $cond->false && ! ($is_rule && $discard_rule))
{
s/^/$cond->subst_string/gme;
$result_rules .= "$spacing$comment$_\n";
}
- $comment = $spacing = '';
- }
+ $comment = $spacing = '';
+ }
}
error ($where, @cond_stack ?
}
-# &append_exeext ($MACRO)
-# -----------------------
-# Macro is an Automake magic macro which primary is PROGRAMS, e.g.
-# bin_PROGRAMS. Make sure these programs have $(EXEEXT) appended.
-sub append_exeext ($)
-{
- my ($macro) = @_;
-
- prog_error "append_exeext ($macro)"
- unless $macro =~ /_PROGRAMS$/;
-
- transform_variable_recursively
- ($macro, $macro, 'am__EXEEXT', 0, INTERNAL,
- sub {
- my ($subvar, $val, $cond, $full_cond) = @_;
- # Append $(EXEEXT) unless the user did it already, or it's a
- # @substitution@.
- $val .= '$(EXEEXT)' unless $val =~ /(?:\$\(EXEEXT\)$|^[@]\w+[@]$)/;
- return $val;
- });
-}
-
-
# @PREFIX
# &am_primary_prefixes ($PRIMARY, $CAN_DIST, @PREFIXES)
# -----------------------------------------------------
#
# As a side effect, it looks for misspellings. It is an error to have
# a variable ending in a "reserved" suffix whose prefix is unknown, e.g.
-# "bin_PROGRAMS". However, unusual prefixes are allowed if a variable
+# "bni_PROGRAMS". However, unusual prefixes are allowed if a variable
# of the same name (with "dir" appended) exists. For instance, if the
# variable "zardir" is defined, then "zar_PROGRAMS" becomes valid.
# This is to provide a little extra flexibility in those cases which
{
my ($base, $dist, $X) = ($1 || '', $2 || '', $3 || '');
if ($dist ne '' && ! $can_dist)
- {
+ {
err_var ($var,
"invalid variable `$varname': `dist' is forbidden");
}
}
# A blatant hack: we rewrite each _PROGRAMS primary to include
# EXEEXT.
- append_exeext ($one_name)
+ append_exeext { 1 } $one_name
if $primary eq 'PROGRAMS';
# "EXTRA" shouldn't be used when generating clean targets,
# all, or install targets. We used to warn if EXTRA_FOO was
# Use the location of the currently processed variable as context.
$where->push_context ("while processing `$one_name'");
- # The variable containing all file to distribute.
+ # The variable containing all files to distribute.
my $distvar = "\$($one_name)";
$distvar = shadow_unconditionally ($one_name, $where)
if ($dist_p && $one_var->has_conditional_contents);
EXEC => $exec_p,
INSTALL => $install_p,
DIST => $dist_p,
- DISTVAR => $distvar,
+ DISTVAR => $distvar,
'CK-OPTS' => $check_options_p);
}
}
my $trailer = '';
+ my $trailer2 = '';
my $suppress = 0;
# Only install missing files according to our desired
my $message = "required file `$fullfile' not found";
if ($add_missing)
{
- if (-f ("$libdir/$file"))
+ if (-f "$libdir/$file")
{
$suppress = 1;
# can, copy if we must. Note: delete the file
# first, in case it is a dangling symlink.
$message = "installing `$fullfile'";
+
+ # The license file should not be volatile.
+ if ($file eq "COPYING")
+ {
+ $message .= " using GNU General Public License v3 file";
+ $trailer2 = "\n Consider adding the COPYING file"
+ . " to the version control system"
+ . "\n for your code, to avoid questions"
+ . " about which license your project uses.";
+ }
+
# Windows Perl will hang if we try to delete a
# file that doesn't exist.
unlink ($fullfile) if -f $fullfile;
$suppress = 0;
$trailer = "\n error while copying";
}
- reset_dir_cache ($dir);
+ set_dir_cache_file ($dir, $file);
}
if (! maybe_push_required_file (dirname ($fullfile),
# an auxiliary file and we are not processing
# the top level Makefile. Furthermore Automake
# hasn't been asked to create the Makefile.in
- # that distribute the aux dir files.
+ # that distributes the aux dir files.
error ($where, 'Please make a full run of automake'
. " so $fullfile gets distributed.");
}
}
}
+ else
+ {
+ $trailer = "\n `automake --add-missing' can install `$file'"
+ if -f "$libdir/$file";
+ }
# If --force-missing was specified, and we have
# actually found the file, then do nothing.
next
if $found_it && $force_missing;
- # If we couldn' install the file, but it is a target in
+ # If we couldn't install the file, but it is a target in
# the Makefile, don't print anything. This allows files
# like README, AUTHORS, or THANKS to be generated.
next
if !$suppress && rule $file;
- msg ($suppress ? 'note' : 'error', $where, "$message$trailer");
+ msg ($suppress ? 'note' : 'error', $where, "$message$trailer$trailer2");
}
}
}
require_file ($macro->rdef ($cond)->location, $mystrict, @files);
}
+# &require_libsource_with_macro ($COND, $MACRO, $MYSTRICT, @FILES)
+# ----------------------------------------------------------------
+# Require an AC_LIBSOURCEd file. If AC_CONFIG_LIBOBJ_DIR was called, it
+# must be in that directory. Otherwise expect it in the current directory.
+sub require_libsource_with_macro ($$$@)
+{
+ my ($cond, $macro, $mystrict, @files) = @_;
+ $macro = rvar ($macro) unless ref $macro;
+ if ($config_libobj_dir)
+ {
+ require_file_internal ($macro->rdef ($cond)->location, $mystrict,
+ $config_libobj_dir, @files);
+ }
+ else
+ {
+ require_file ($macro->rdef ($cond)->location, $mystrict, @files);
+ }
+}
+
+# Queue to push require_conf_file requirements to.
+my $required_conf_file_queue;
+
+# &queue_required_conf_file ($QUEUE, $KEY, $DIR, $WHERE, $MYSTRICT, @FILES)
+# -------------------------------------------------------------------------
+sub queue_required_conf_file ($$$$@)
+{
+ my ($queue, $key, $dir, $where, $mystrict, @files) = @_;
+ my @serial_loc;
+ if (ref $where)
+ {
+ @serial_loc = (QUEUE_LOCATION, $where->serialize ());
+ }
+ else
+ {
+ @serial_loc = (QUEUE_STRING, $where);
+ }
+ $queue->enqueue ($key, $dir, @serial_loc, $mystrict, 0 + @files, @files);
+}
+
+# &require_queued_conf_file ($QUEUE)
+# ----------------------------------
+sub require_queued_conf_file ($)
+{
+ my ($queue) = @_;
+ my $where;
+ my $dir = $queue->dequeue ();
+ my $loc_key = $queue->dequeue ();
+ if ($loc_key eq QUEUE_LOCATION)
+ {
+ $where = Automake::Location::deserialize ($queue);
+ }
+ elsif ($loc_key eq QUEUE_STRING)
+ {
+ $where = $queue->dequeue ();
+ }
+ else
+ {
+ prog_error "unexpected key $loc_key";
+ }
+ my $mystrict = $queue->dequeue ();
+ my $nfiles = $queue->dequeue ();
+ my @files;
+ push @files, $queue->dequeue ()
+ foreach (1 .. $nfiles);
+
+ # Dequeuing happens outside of per-makefile context, so we have to
+ # set the variables used by require_file_internal and the functions
+ # it calls. Gross!
+ $relative_dir = $dir;
+ require_file_internal ($where, $mystrict, $config_aux_dir, @files);
+}
# &require_conf_file ($WHERE, $MYSTRICT, @FILES)
# ----------------------------------------------
-# Looks in configuration path, as specified by AC_CONFIG_AUX_DIR.
+# Looks in configuration path, as specified by AC_CONFIG_AUX_DIR;
+# worker threads may queue up the action to be serialized by the master.
+#
+# FIXME: this seriously relies on the semantics of require_file_internal
+# and maybe_push_required_file, in that we exploit the fact that only the
+# contents of the last handled output file may be impacted (which in turn
+# is dealt with by the master thread).
sub require_conf_file ($$@)
{
my ($where, $mystrict, @files) = @_;
- require_file_internal ($where, $mystrict, $config_aux_dir, @files);
+ if (defined $required_conf_file_queue)
+ {
+ queue_required_conf_file ($required_conf_file_queue, QUEUE_CONF_FILE,
+ $relative_dir, $where, $mystrict, @files);
+ }
+ else
+ {
+ require_file_internal ($where, $mystrict, $config_aux_dir, @files);
+ }
}
# Emit rules to create $DIRECTORY if needed, and return
# the file that any target requiring this directory should be made
# dependent upon.
+# We don't want to emit the rule twice, and want to reuse it
+# for directories with equivalent names (e.g., `foo/bar' and `./foo//bar').
sub require_build_directory ($)
{
my $directory = shift;
- my $dirstamp = "$directory/\$(am__dirstamp)";
- # Don't emit the rule twice.
- if (! defined $directory_map{$directory})
+ return $directory_map{$directory} if exists $directory_map{$directory};
+
+ my $cdir = File::Spec->canonpath ($directory);
+
+ if (exists $directory_map{$cdir})
{
- $directory_map{$directory} = 1;
+ my $stamp = $directory_map{$cdir};
+ $directory_map{$directory} = $stamp;
+ return $stamp;
+ }
- # Set a variable for the dirstamp basename.
- define_pretty_variable ('am__dirstamp', TRUE, INTERNAL,
- '$(am__leading_dot)dirstamp');
+ my $dirstamp = "$cdir/\$(am__dirstamp)";
- # Directory must be removed by `make distclean'.
- $clean_files{$dirstamp} = DIST_CLEAN;
+ $directory_map{$directory} = $dirstamp;
+ $directory_map{$cdir} = $dirstamp;
- $output_rules .= ("$dirstamp:\n"
- . "\t\@\$(mkdir_p) $directory\n"
- . "\t\@: > $dirstamp\n");
- }
+ # Set a variable for the dirstamp basename.
+ define_pretty_variable ('am__dirstamp', TRUE, INTERNAL,
+ '$(am__leading_dot)dirstamp');
+
+ # Directory must be removed by `make distclean'.
+ $clean_files{$dirstamp} = DIST_CLEAN;
+
+ $output_rules .= ("$dirstamp:\n"
+ . "\t\@\$(MKDIR_P) $directory\n"
+ . "\t\@: > $dirstamp\n");
return $dirstamp;
}
$relative_dir = dirname ($makefile);
$am_relative_dir = dirname ($makefile_am);
+ $topsrcdir = backname ($relative_dir);
read_main_am_file ($makefile_am);
if (handle_options)
handle_subdirs;
handle_tags;
handle_minor_options;
+ # Must come after handle_programs so that %known_programs is up-to-date.
handle_tests;
# This must come after most other rules.
{
$output_rules .= "install-binPROGRAMS: install-libLTLIBRARIES\n\n";
}
+ if (var ('nobase_lib_LTLIBRARIES') && var ('bin_PROGRAMS'))
+ {
+ $output_rules .= "install-binPROGRAMS: install-nobase_libLTLIBRARIES\n\n";
+ }
handle_install;
handle_clean ($makefile);
{
print <<EOF;
automake (GNU $PACKAGE) $VERSION
+Copyright (C) 2009 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.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>.
-
-Copyright 2004 Free Software Foundation, Inc.
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
# --version always returns 0 per GNU standards.
exit 0;
my $cli_where = new Automake::Location;
my %cli_options =
(
- 'libdir=s' => \$libdir,
- 'gnu' => sub { set_strictness ('gnu'); },
- 'gnits' => sub { set_strictness ('gnits'); },
- 'cygnus' => sub { set_global_option ('cygnus', $cli_where); },
+ 'libdir=s' => \$libdir,
+ 'gnu' => sub { set_strictness ('gnu'); },
+ 'gnits' => sub { set_strictness ('gnits'); },
+ 'cygnus' => sub { set_global_option ('cygnus', $cli_where); },
'foreign' => sub { set_strictness ('foreign'); },
- 'include-deps' => sub { unset_global_option ('no-dependencies'); },
- 'i|ignore-deps' => sub { set_global_option ('no-dependencies',
+ 'include-deps' => sub { unset_global_option ('no-dependencies'); },
+ 'i|ignore-deps' => sub { set_global_option ('no-dependencies',
$cli_where); },
- 'no-force' => sub { $force_generation = 0; },
+ 'no-force' => sub { $force_generation = 0; },
'f|force-missing' => \$force_missing,
'o|output-dir=s' => \$output_directory,
- 'a|add-missing' => \$add_missing,
- 'c|copy' => \$copy_missing,
- 'v|verbose' => sub { setup_channel 'verb', silent => 0; },
+ 'a|add-missing' => \$add_missing,
+ 'c|copy' => \$copy_missing,
+ 'v|verbose' => sub { setup_channel 'verb', silent => 0; },
'W|warnings=s' => \&parse_warnings,
# These long options (--Werror and --Wno-error) for backward
# compatibility. Use -Werror and -Wno-error today.
if $errspec && ! @input_files;
}
+
+# handle_makefile ($MAKEFILE_IN)
+# ------------------------------
+# Deal with $MAKEFILE_IN.
+sub handle_makefile ($)
+{
+ my ($file) = @_;
+ ($am_file = $file) =~ s/\.in$//;
+ if (! -f ($am_file . '.am'))
+ {
+ error "`$am_file.am' does not exist";
+ }
+ else
+ {
+ # Any warning setting now local to this Makefile.am.
+ dup_channel_setup;
+
+ generate_makefile ($am_file . '.am', $file);
+
+ # Back out any warning setting.
+ drop_channel_setup;
+ }
+}
+
+# handle_makefiles_serial ()
+# --------------------------
+# Deal with all makefiles, without threads.
+sub handle_makefiles_serial ()
+{
+ foreach my $file (@input_files)
+ {
+ handle_makefile ($file);
+ }
+}
+
+# get_number_of_threads ()
+# ------------------------
+# Logic for deciding how many worker threads to use.
+sub get_number_of_threads
+{
+ my $nthreads = $ENV{'AUTOMAKE_JOBS'} || 0;
+
+ $nthreads = 0
+ unless $nthreads =~ /^[0-9]+$/;
+
+ # It doesn't make sense to use more threads than makefiles,
+ my $max_threads = @input_files;
+
+ # but a single worker thread is helpful for exposing bugs.
+ if ($automake_will_process_aux_dir && $max_threads > 1)
+ {
+ $max_threads--;
+ }
+ if ($nthreads > $max_threads)
+ {
+ $nthreads = $max_threads;
+ }
+ return $nthreads;
+}
+
+# handle_makefiles_threaded ($NTHREADS)
+# -------------------------------------
+# Deal with all makefiles, using threads. The general strategy is to
+# spawn NTHREADS worker threads, dispatch makefiles to them, and let the
+# worker threads push back everything that needs serialization:
+# * warning and (normal) error messages, for stable stderr output
+# order and content (avoiding duplicates, for example),
+# * races when installing aux files (and respective messages),
+# * races when collecting aux files for distribution.
+#
+# The latter requires that the makefile that deals with the aux dir
+# files be handled last, done by the master thread.
+sub handle_makefiles_threaded ($)
+{
+ my ($nthreads) = @_;
+
+ my @queued_input_files = @input_files;
+ my $last_input_file = undef;
+ if ($automake_will_process_aux_dir)
+ {
+ $last_input_file = pop @queued_input_files;
+ }
+
+ # The file queue distributes all makefiles, the message queues
+ # collect all serializations needed for respective files.
+ my $file_queue = Thread::Queue->new;
+ my %msg_queues;
+ foreach my $file (@queued_input_files)
+ {
+ $msg_queues{$file} = Thread::Queue->new;
+ }
+
+ verb "spawning $nthreads worker threads";
+ my @threads = (1 .. $nthreads);
+ foreach my $t (@threads)
+ {
+ $t = threads->new (sub
+ {
+ while (my $file = $file_queue->dequeue)
+ {
+ verb "handling $file";
+ my $queue = $msg_queues{$file};
+ setup_channel_queue ($queue, QUEUE_MESSAGE);
+ $required_conf_file_queue = $queue;
+ handle_makefile ($file);
+ $queue->enqueue (undef);
+ setup_channel_queue (undef, undef);
+ $required_conf_file_queue = undef;
+ }
+ return $exit_code;
+ });
+ }
+
+ # Queue all normal makefiles.
+ verb "queuing " . @queued_input_files . " input files";
+ $file_queue->enqueue (@queued_input_files, (undef) x @threads);
+
+ # Collect and process serializations.
+ foreach my $file (@queued_input_files)
+ {
+ verb "dequeuing messages for " . $file;
+ reset_local_duplicates ();
+ my $queue = $msg_queues{$file};
+ while (my $key = $queue->dequeue)
+ {
+ if ($key eq QUEUE_MESSAGE)
+ {
+ pop_channel_queue ($queue);
+ }
+ elsif ($key eq QUEUE_CONF_FILE)
+ {
+ require_queued_conf_file ($queue);
+ }
+ else
+ {
+ prog_error "unexpected key $key";
+ }
+ }
+ }
+
+ foreach my $t (@threads)
+ {
+ my @exit_thread = $t->join;
+ $exit_code = $exit_thread[0]
+ if ($exit_thread[0] > $exit_code);
+ }
+
+ # The master processes the last file.
+ if ($automake_will_process_aux_dir)
+ {
+ verb "processing last input file";
+ handle_makefile ($last_input_file);
+ }
+}
+
################################################################
# Parse the WARNINGS environment variable.
fatal ("no `Makefile.am' found for any configure output$msg");
}
-# Now do all the work on each file.
-foreach my $file (@input_files)
- {
- ($am_file = $file) =~ s/\.in$//;
- if (! -f ($am_file . '.am'))
- {
- error "`$am_file.am' does not exist";
- }
- else
- {
- # Any warning setting now local to this Makefile.am.
- dup_channel_setup;
+my $nthreads = get_number_of_threads ();
- generate_makefile ($am_file . '.am', $file);
-
- # Back out any warning setting.
- drop_channel_setup;
- }
+if ($perl_threads && $nthreads >= 1)
+ {
+ handle_makefiles_threaded ($nthreads);
+ }
+else
+ {
+ handle_makefiles_serial ();
}
exit $exit_code;