7524 lines
216 KiB
Perl
Executable File
7524 lines
216 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
||
# -*- perl -*-
|
||
# Generated from automake.in; do not edit by hand.
|
||
|
||
eval 'case $# in 0) exec /usr/bin/perl -S "$0";; *) exec /usr/bin/perl -S "$0" "$@";; esac'
|
||
if 0;
|
||
|
||
# automake - create Makefile.in from Makefile.am
|
||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||
# 2003, 2004, 2005 Free Software Foundation, Inc.
|
||
|
||
# This program is free software; you can redistribute it and/or modify
|
||
# it under the terms of the GNU General Public License as published by
|
||
# the Free Software Foundation; either version 2, or (at your option)
|
||
# any later version.
|
||
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
# GNU General Public License for more details.
|
||
|
||
# You should have received a copy of the GNU General Public License
|
||
# along with this program; if not, write to the Free Software
|
||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||
# 02111-1307, USA.
|
||
|
||
# Originally written by David Mackenzie <djm@gnu.ai.mit.edu>.
|
||
# Perl reimplementation by Tom Tromey <tromey@redhat.com>.
|
||
|
||
package Language;
|
||
|
||
BEGIN
|
||
{
|
||
my $perllibdir = $ENV{'perllibdir'} || '/usr/local/share/automake19';
|
||
unshift @INC, (split ':', $perllibdir);
|
||
|
||
# Override SHELL. This is required on DJGPP so that system() uses
|
||
# bash, not COMMAND.COM which doesn't quote arguments properly.
|
||
# Other systems aren't expected to use $SHELL when Automake
|
||
# runs, but it should be safe to drop the `if DJGPP' guard if
|
||
# it turns up other systems need the same thing. After all,
|
||
# if SHELL is used, ./configure's SHELL is always better than
|
||
# the user's SHELL (which may be something like tcsh).
|
||
$ENV{'SHELL'} = '/bin/sh' if exists $ENV{'DJGPP'};
|
||
}
|
||
|
||
use Automake::Struct;
|
||
struct (# Short name of the language (c, f77...).
|
||
'name' => "\$",
|
||
# Nice name of the language (C, Fortran 77...).
|
||
'Name' => "\$",
|
||
|
||
# List of configure variables which must be defined.
|
||
'config_vars' => '@',
|
||
|
||
'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.
|
||
'pure' => "\$",
|
||
|
||
'autodep' => "\$",
|
||
|
||
# Name of the compiling variable (COMPILE).
|
||
'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' => "@",
|
||
|
||
# Any tag to pass to libtool while compiling.
|
||
'libtool_tag' => "\$",
|
||
|
||
# The file to use when generating rules for this language.
|
||
# The default is 'depend2'.
|
||
'rule_file' => "\$",
|
||
|
||
# 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' => "\$",
|
||
|
||
# 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
|
||
# compiled.
|
||
'_target_hook' => "\$");
|
||
|
||
|
||
sub finish ($)
|
||
{
|
||
my ($self) = @_;
|
||
if (defined $self->_finish)
|
||
{
|
||
&{$self->_finish} ();
|
||
}
|
||
}
|
||
|
||
sub target_hook ($$$$%)
|
||
{
|
||
my ($self) = @_;
|
||
if (defined $self->_target_hook)
|
||
{
|
||
&{$self->_target_hook} (@_);
|
||
}
|
||
}
|
||
|
||
package Automake;
|
||
|
||
use strict;
|
||
use Automake::Config;
|
||
use Automake::General;
|
||
use Automake::XFile;
|
||
use Automake::Channels;
|
||
use Automake::ChannelDefs;
|
||
use Automake::Configure_ac;
|
||
use Automake::FileUtils;
|
||
use Automake::Location;
|
||
use Automake::Condition qw/TRUE FALSE/;
|
||
use Automake::DisjConditions;
|
||
use Automake::Options;
|
||
use Automake::Version;
|
||
use Automake::Variable;
|
||
use Automake::VarDef;
|
||
use Automake::Rule;
|
||
use Automake::RuleDef;
|
||
use Automake::Wrap 'makefile_wrap';
|
||
use File::Basename;
|
||
use Carp;
|
||
|
||
## ----------- ##
|
||
## Constants. ##
|
||
## ----------- ##
|
||
|
||
# Some regular expressions. One reason to put them here is that it
|
||
# makes indentation work better in Emacs.
|
||
|
||
# Writing singled-quoted-$-terminated regexes is a pain because
|
||
# perl-mode thinks of $' as the ${'} variable (instead of a $ followed
|
||
# by a closing quote. Letting perl-mode think the quote is not closed
|
||
# leads to all sort of misindentations. On the other hand, defining
|
||
# regexes as double-quoted strings is far less readable. So usually
|
||
# we will write:
|
||
#
|
||
# $REGEX = '^regex_value' . "\$";
|
||
|
||
my $IGNORE_PATTERN = '^\s*##([^#\n].*)?\n';
|
||
my $WHITE_PATTERN = '^\s*' . "\$";
|
||
my $COMMENT_PATTERN = '^#';
|
||
my $TARGET_PATTERN='[$a-zA-Z_.@%][-.a-zA-Z0-9_(){}/$+@%]*';
|
||
# A rule has three parts: a list of targets, a list of dependencies,
|
||
# and optionally actions.
|
||
my $RULE_PATTERN =
|
||
"^($TARGET_PATTERN(?:(?:\\\\\n|\\s)+$TARGET_PATTERN)*) *:([^=].*|)\$";
|
||
|
||
# Only recognize leading spaces, not leading tabs. If we recognize
|
||
# leading tabs here then we need to make the reader smarter, because
|
||
# otherwise it will think rules like `foo=bar; \' are errors.
|
||
my $ASSIGNMENT_PATTERN = '^ *([^ \t=:+]*)\s*([:+]?)=\s*(.*)' . "\$";
|
||
# This pattern recognizes a Gnits version id and sets $1 if the
|
||
# release is an alpha release. We also allow a suffix which can be
|
||
# used to extend the version number with a "fork" identifier.
|
||
my $GNITS_VERSION_PATTERN = '\d+\.\d+([a-z]|\.\d+)?(-[A-Za-z0-9]+)?';
|
||
|
||
my $IF_PATTERN = '^if\s+(!?)\s*([A-Za-z][A-Za-z0-9_]*)\s*(?:#.*)?' . "\$";
|
||
my $ELSE_PATTERN =
|
||
'^else(?:\s+(!?)\s*([A-Za-z][A-Za-z0-9_]*))?\s*(?:#.*)?' . "\$";
|
||
my $ENDIF_PATTERN =
|
||
'^endif(?:\s+(!?)\s*([A-Za-z][A-Za-z0-9_]*))?\s*(?:#.*)?' . "\$";
|
||
my $PATH_PATTERN = '(\w|[+/.-])+';
|
||
# This will pass through anything not of the prescribed form.
|
||
my $INCLUDE_PATTERN = ('^include\s+'
|
||
. '((\$\(top_srcdir\)/' . $PATH_PATTERN . ')'
|
||
. '|(\$\(srcdir\)/' . $PATH_PATTERN . ')'
|
||
. '|([^/\$]' . $PATH_PATTERN . '))\s*(#.*)?' . "\$");
|
||
|
||
# Match `-d' as a command-line argument in a string.
|
||
my $DASH_D_PATTERN = "(^|\\s)-d(\\s|\$)";
|
||
# Directories installed during 'install-exec' phase.
|
||
my $EXEC_DIR_PATTERN =
|
||
'^(?:bin|sbin|libexec|sysconf|localstate|lib|pkglib|.*exec.*)' . "\$";
|
||
|
||
# Values for AC_CANONICAL_*
|
||
use constant AC_CANONICAL_BUILD => 1;
|
||
use constant AC_CANONICAL_HOST => 2;
|
||
use constant AC_CANONICAL_TARGET => 3;
|
||
|
||
# Values indicating when something should be cleaned.
|
||
use constant MOSTLY_CLEAN => 0;
|
||
use constant CLEAN => 1;
|
||
use constant DIST_CLEAN => 2;
|
||
use constant MAINTAINER_CLEAN => 3;
|
||
|
||
# Libtool files.
|
||
my @libtool_files = qw(ltmain.sh config.guess config.sub);
|
||
# ltconfig appears here for compatibility with old versions of libtool.
|
||
my @libtool_sometimes = qw(ltconfig ltcf-c.sh ltcf-cxx.sh ltcf-gcj.sh);
|
||
|
||
# Commonly found files we look for and automatically include in
|
||
# DISTFILES.
|
||
my @common_files =
|
||
(qw(ABOUT-GNU ABOUT-NLS AUTHORS BACKLOG COPYING COPYING.DOC COPYING.LIB
|
||
COPYING.LESSER ChangeLog INSTALL NEWS README THANKS TODO
|
||
ansi2knr.1 ansi2knr.c compile config.guess config.rpath config.sub
|
||
depcomp elisp-comp install-sh libversion.in mdate-sh missing
|
||
mkinstalldirs py-compile texinfo.tex ylwrap),
|
||
@libtool_files, @libtool_sometimes);
|
||
|
||
# Commonly used files we auto-include, but only sometimes. This list
|
||
# is used for the --help output only.
|
||
my @common_sometimes =
|
||
qw(aclocal.m4 acconfig.h config.h.top config.h.bot configure
|
||
configure.ac configure.in stamp-vti);
|
||
|
||
# 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));
|
||
|
||
# Copyright on generated Makefile.ins.
|
||
my $gen_copyright = "\
|
||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||
# 2003, 2004, 2005 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.
|
||
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||
# PARTICULAR PURPOSE.
|
||
";
|
||
|
||
# These constants are returned by 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 LANG_IGNORE => 0;
|
||
use constant LANG_PROCESS => 1;
|
||
use constant LANG_SUBDIR => 2;
|
||
|
||
# These are used when keeping track of whether an object can be built
|
||
# by two different paths.
|
||
use constant COMPILE_LIBTOOL => 1;
|
||
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.
|
||
use constant INTERNAL => new Automake::Location;
|
||
|
||
|
||
## ---------------------------------- ##
|
||
## Variables related to the options. ##
|
||
## ---------------------------------- ##
|
||
|
||
# TRUE if we should always generate Makefile.in.
|
||
my $force_generation = 1;
|
||
|
||
# From the Perl manual.
|
||
my $symlink_exists = (eval 'symlink ("", "");', $@ eq '');
|
||
|
||
# TRUE if missing standard files should be installed.
|
||
my $add_missing = 0;
|
||
|
||
# TRUE if we should copy missing files; otherwise symlink if possible.
|
||
my $copy_missing = 0;
|
||
|
||
# TRUE if we should always update files that we know about.
|
||
my $force_missing = 0;
|
||
|
||
|
||
## ---------------------------------------- ##
|
||
## Variables filled during files scanning. ##
|
||
## ---------------------------------------- ##
|
||
|
||
# Name of the configure.ac file.
|
||
my $configure_ac;
|
||
|
||
# Files found by scanning configure.ac for LIBOBJS.
|
||
my %libsources = ();
|
||
|
||
# Names used in AC_CONFIG_HEADER call.
|
||
my @config_headers = ();
|
||
|
||
# Names used in AC_CONFIG_LINKS call.
|
||
my @config_links = ();
|
||
|
||
# Directory where output files go. Actually, output files are
|
||
# relative to this directory.
|
||
my $output_directory;
|
||
|
||
# List of Makefile.am's to process, and their corresponding outputs.
|
||
my @input_files = ();
|
||
my %output_files = ();
|
||
|
||
# Complete list of Makefile.am's that exist.
|
||
my @configure_input_files = ();
|
||
|
||
# List of files in AC_CONFIG_FILES/AC_OUTPUT without Makefile.am's,
|
||
# and their outputs.
|
||
my @other_input_files = ();
|
||
# 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 = ();
|
||
|
||
# Directory to search for configure-required files. This
|
||
# will be computed by &locate_aux_dir and can be set using
|
||
# AC_CONFIG_AUX_DIR in configure.ac.
|
||
# $CONFIG_AUX_DIR is the `raw' directory, valid only in the source-tree.
|
||
my $config_aux_dir = '';
|
||
my $config_aux_dir_set_in_configure_ac = 0;
|
||
# $AM_CONFIG_AUX_DIR is prefixed with $(top_srcdir), so it can be used
|
||
# in Makefiles.
|
||
my $am_config_aux_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;
|
||
|
||
# Lists of tags supported by Libtool.
|
||
my %libtool_tags = ();
|
||
|
||
# Most important AC_CANONICAL_* macro seen so far.
|
||
my $seen_canonical = 0;
|
||
# Location of that macro.
|
||
my $canonical_location;
|
||
|
||
# Where AM_MAINTAINER_MODE appears.
|
||
my $seen_maint_mode;
|
||
|
||
# Actual version we've seen.
|
||
my $package_version = '';
|
||
|
||
# Where version is defined.
|
||
my $package_version_location;
|
||
|
||
# TRUE if we've seen AC_ENABLE_MULTILIB.
|
||
my $seen_multilib = 0;
|
||
|
||
# TRUE if we've seen AM_PROG_CC_C_O
|
||
my $seen_cc_c_o = 0;
|
||
|
||
# Where AM_INIT_AUTOMAKE is called;
|
||
my $seen_init_automake = 0;
|
||
|
||
# TRUE if we've seen AM_AUTOMAKE_VERSION.
|
||
my $seen_automake_version = 0;
|
||
|
||
# Hash table of discovered configure substitutions. Keys are names,
|
||
# values are `FILE:LINE' strings which are used by error message
|
||
# generation.
|
||
my %configure_vars = ();
|
||
|
||
# Files included by $configure_ac.
|
||
my @configure_deps = ();
|
||
|
||
# Greatest timestamp of configure's dependencies.
|
||
my $configure_deps_greatest_timestamp = 0;
|
||
|
||
# Hash table of AM_CONDITIONAL variables seen in configure.
|
||
my %configure_cond = ();
|
||
|
||
# This maps extensions onto language names.
|
||
my %extension_map = ();
|
||
|
||
# List of the DIST_COMMON files we discovered while reading
|
||
# configure.in
|
||
my $configure_dist_common = '';
|
||
|
||
# This maps languages names onto objects.
|
||
my %languages = ();
|
||
|
||
# List of targets we must always output.
|
||
# FIXME: Complete, and remove falsely required targets.
|
||
my %required_targets =
|
||
(
|
||
'all' => 1,
|
||
'dvi' => 1,
|
||
'pdf' => 1,
|
||
'ps' => 1,
|
||
'info' => 1,
|
||
'install-info' => 1,
|
||
'install' => 1,
|
||
'install-data' => 1,
|
||
'install-exec' => 1,
|
||
'uninstall' => 1,
|
||
|
||
# FIXME: Not required, temporary hacks.
|
||
# Well, actually they are sort of required: the -recursive
|
||
# targets will run them anyway...
|
||
'dvi-am' => 1,
|
||
'pdf-am' => 1,
|
||
'ps-am' => 1,
|
||
'info-am' => 1,
|
||
'install-data-am' => 1,
|
||
'install-exec-am' => 1,
|
||
'installcheck-am' => 1,
|
||
'uninstall-am' => 1,
|
||
|
||
'install-man' => 1,
|
||
);
|
||
|
||
# Set to 1 if this run will create the Makefile.in that distribute
|
||
# the files in config_aux_dir.
|
||
my $automake_will_process_aux_dir = 0;
|
||
|
||
# The name of the Makefile currently being processed.
|
||
my $am_file = 'BUG';
|
||
|
||
|
||
################################################################
|
||
|
||
## ------------------------------------------ ##
|
||
## Variables reset by &initialize_per_input. ##
|
||
## ------------------------------------------ ##
|
||
|
||
# Basename and relative dir of the input file.
|
||
my $am_file_name;
|
||
my $am_relative_dir;
|
||
|
||
# Same but wrt Makefile.in.
|
||
my $in_file_name;
|
||
my $relative_dir;
|
||
|
||
# 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.
|
||
# 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;
|
||
|
||
# This is the conditional stack, updated on if/else/endif, and
|
||
# used to build Condition objects.
|
||
my @cond_stack;
|
||
|
||
# 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;
|
||
my @check_tests;
|
||
|
||
# Keys in this hash table are files to delete. The associated
|
||
# value tells when this should happen (MOSTLY_CLEAN, DIST_CLEAN, etc.)
|
||
my %clean_files;
|
||
|
||
# Keys in this hash table are object files or other files in
|
||
# subdirectories which need to be removed. This only holds files
|
||
# which are created by compilations. The value in the hash indicates
|
||
# when the file should be removed.
|
||
my %compile_clean_files;
|
||
|
||
# Keys in this hash table are directories where we expect to build a
|
||
# libtool object. We use this information to decide what directories
|
||
# to delete.
|
||
my %libtool_clean_directories;
|
||
|
||
# Value of `$(SOURCES)', used by tags.am.
|
||
my @sources;
|
||
# Sources which go in the distribution.
|
||
my @dist_sources;
|
||
|
||
# This hash maps object file names onto their corresponding source
|
||
# file names. This is used to ensure that each object is created
|
||
# by a single source file.
|
||
my %object_map;
|
||
|
||
# This hash maps object file names onto an integer value representing
|
||
# whether this object has been built via ordinary compilation or
|
||
# libtool compilation (the COMPILE_* constants).
|
||
my %object_compilation_map;
|
||
|
||
|
||
# This keeps track of the directories for which we've already
|
||
# created dirstamp code.
|
||
my %directory_map;
|
||
|
||
# All .P files.
|
||
my %dep_files;
|
||
|
||
# This is a list of all targets to run during "make dist".
|
||
my @dist_targets;
|
||
|
||
# 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;
|
||
|
||
# This is random scratch space for the language finish functions.
|
||
# Don't randomly overwrite it; examine other uses of keys first.
|
||
my %language_scratch;
|
||
|
||
# We keep track of which objects need special (per-executable)
|
||
# handling on a per-language basis.
|
||
my %lang_specific_files;
|
||
|
||
# This is set when `handle_dist' has finished. Once this happens,
|
||
# we should no longer push on dist_common.
|
||
my $handle_dist_run;
|
||
|
||
# Used to store a set of linkers needed to generate the sources currently
|
||
# under consideration.
|
||
my %linkers_used;
|
||
|
||
# True if we need `LINK' defined. This is a hack.
|
||
my $need_link;
|
||
|
||
# Was get_object_extension run?
|
||
# FIXME: This is a hack. a better switch should be found.
|
||
my $get_object_extension_was_run;
|
||
|
||
# Record each file processed by make_paragraphs.
|
||
my %transformed_files;
|
||
|
||
################################################################
|
||
|
||
# var_SUFFIXES_trigger ($TYPE, $VALUE)
|
||
# ------------------------------------
|
||
# This is called by Automake::Variable::define() when SUFFIXES
|
||
# is defined ($TYPE eq '') or appended ($TYPE eq '+').
|
||
# The work here needs to be performed as a side-effect of the
|
||
# macro_define() call because SUFFIXES definitions impact
|
||
# on $KNOWN_EXTENSIONS_PATTERN which is used used when parsing
|
||
# the input am file.
|
||
sub var_SUFFIXES_trigger ($$)
|
||
{
|
||
my ($type, $value) = @_;
|
||
accept_extensions (split (' ', $value));
|
||
}
|
||
Automake::Variable::hook ('SUFFIXES', \&var_SUFFIXES_trigger);
|
||
|
||
################################################################
|
||
|
||
## --------------------------------- ##
|
||
## Forward subroutine declarations. ##
|
||
## --------------------------------- ##
|
||
sub register_language (%);
|
||
sub file_contents_internal ($$$%);
|
||
sub define_files_variable ($\@$$);
|
||
|
||
|
||
# &initialize_per_input ()
|
||
# ------------------------
|
||
# (Re)-Initialize per-Makefile.am variables.
|
||
sub initialize_per_input ()
|
||
{
|
||
reset_local_duplicates ();
|
||
|
||
$am_file_name = '';
|
||
$am_relative_dir = '';
|
||
|
||
$in_file_name = '';
|
||
$relative_dir = '';
|
||
|
||
$output_deps_greatest_timestamp = 0;
|
||
|
||
$output_rules = '';
|
||
$output_vars = '';
|
||
$output_trailer = '';
|
||
$output_all = '';
|
||
$output_header = '';
|
||
|
||
Automake::Options::reset;
|
||
Automake::Variable::reset;
|
||
Automake::Rule::reset;
|
||
|
||
@cond_stack = ();
|
||
|
||
@include_stack = ();
|
||
|
||
%dist_dirs = ();
|
||
|
||
@all = ();
|
||
@check = ();
|
||
@check_tests = ();
|
||
|
||
%clean_files = ();
|
||
|
||
@sources = ();
|
||
@dist_sources = ();
|
||
|
||
%object_map = ();
|
||
%object_compilation_map = ();
|
||
|
||
%directory_map = ();
|
||
|
||
%dep_files = ();
|
||
|
||
@dist_targets = ();
|
||
|
||
%de_ansi_files = ();
|
||
|
||
$all_target = '';
|
||
|
||
%extension_seen = ();
|
||
|
||
%language_scratch = ();
|
||
|
||
%lang_specific_files = ();
|
||
|
||
$handle_dist_run = 0;
|
||
|
||
$need_link = 0;
|
||
|
||
$get_object_extension_was_run = 0;
|
||
|
||
%compile_clean_files = ();
|
||
|
||
# We always include `.'. This isn't strictly correct.
|
||
%libtool_clean_directories = ('.' => 1);
|
||
|
||
%transformed_files = ();
|
||
}
|
||
|
||
|
||
################################################################
|
||
|
||
# Initialize our list of languages that are internally supported.
|
||
|
||
# C.
|
||
register_language ('name' => 'c',
|
||
'Name' => 'C',
|
||
'config_vars' => ['CC'],
|
||
'ansi' => 1,
|
||
'autodep' => '',
|
||
'flags' => ['CFLAGS', 'CPPFLAGS'],
|
||
'compiler' => 'COMPILE',
|
||
'compile' => '$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)',
|
||
'lder' => 'CCLD',
|
||
'ld' => '$(CC)',
|
||
'linker' => 'LINK',
|
||
'link' => '$(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'compile_flag' => '-c',
|
||
'libtool_tag' => 'CC',
|
||
'extensions' => ['.c'],
|
||
'_finish' => \&lang_c_finish);
|
||
|
||
# C++.
|
||
register_language ('name' => 'cxx',
|
||
'Name' => 'C++',
|
||
'config_vars' => ['CXX'],
|
||
'linker' => 'CXXLINK',
|
||
'link' => '$(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'autodep' => 'CXX',
|
||
'flags' => ['CXXFLAGS', 'CPPFLAGS'],
|
||
'compile' => '$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)',
|
||
'compiler' => 'CXXCOMPILE',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'libtool_tag' => 'CXX',
|
||
'lder' => 'CXXLD',
|
||
'ld' => '$(CXX)',
|
||
'pure' => 1,
|
||
'extensions' => ['.c++', '.cc', '.cpp', '.cxx', '.C']);
|
||
|
||
# Objective C.
|
||
register_language ('name' => 'objc',
|
||
'Name' => 'Objective C',
|
||
'config_vars' => ['OBJC'],
|
||
'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)',
|
||
'compiler' => 'OBJCCOMPILE',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'lder' => 'OBJCLD',
|
||
'ld' => '$(OBJC)',
|
||
'pure' => 1,
|
||
'extensions' => ['.m']);
|
||
|
||
# Headers.
|
||
register_language ('name' => 'header',
|
||
'Name' => 'Header',
|
||
'extensions' => ['.h', '.H', '.hxx', '.h++', '.hh',
|
||
'.hpp', '.inc'],
|
||
# No output.
|
||
'output_extensions' => sub { return () },
|
||
# Nothing to do.
|
||
'_finish' => sub { });
|
||
|
||
# Yacc (C & C++).
|
||
register_language ('name' => 'yacc',
|
||
'Name' => 'Yacc',
|
||
'config_vars' => ['YACC'],
|
||
'flags' => ['YFLAGS'],
|
||
'compile' => '$(YACC) $(YFLAGS) $(AM_YFLAGS)',
|
||
'compiler' => 'YACCCOMPILE',
|
||
'extensions' => ['.y'],
|
||
'output_extensions' => sub { (my $ext = $_[0]) =~ tr/y/c/;
|
||
return ($ext,) },
|
||
'rule_file' => 'yacc',
|
||
'_finish' => \&lang_yacc_finish,
|
||
'_target_hook' => \&lang_yacc_target_hook);
|
||
register_language ('name' => 'yaccxx',
|
||
'Name' => 'Yacc (C++)',
|
||
'config_vars' => ['YACC'],
|
||
'rule_file' => 'yacc',
|
||
'flags' => ['YFLAGS'],
|
||
'compiler' => 'YACCCOMPILE',
|
||
'compile' => '$(YACC) $(YFLAGS) $(AM_YFLAGS)',
|
||
'extensions' => ['.y++', '.yy', '.yxx', '.ypp'],
|
||
'output_extensions' => sub { (my $ext = $_[0]) =~ tr/y/c/;
|
||
return ($ext,) },
|
||
'_finish' => \&lang_yacc_finish,
|
||
'_target_hook' => \&lang_yacc_target_hook);
|
||
|
||
# Lex (C & C++).
|
||
register_language ('name' => 'lex',
|
||
'Name' => 'Lex',
|
||
'config_vars' => ['LEX'],
|
||
'rule_file' => 'lex',
|
||
'flags' => ['LFLAGS'],
|
||
'compile' => '$(LEX) $(LFLAGS) $(AM_LFLAGS)',
|
||
'compiler' => 'LEXCOMPILE',
|
||
'extensions' => ['.l'],
|
||
'output_extensions' => sub { (my $ext = $_[0]) =~ tr/l/c/;
|
||
return ($ext,) },
|
||
'_finish' => \&lang_lex_finish,
|
||
'_target_hook' => \&lang_lex_target_hook);
|
||
register_language ('name' => 'lexxx',
|
||
'Name' => 'Lex (C++)',
|
||
'config_vars' => ['LEX'],
|
||
'rule_file' => 'lex',
|
||
'flags' => ['LFLAGS'],
|
||
'compile' => '$(LEX) $(LFLAGS) $(AM_LFLAGS)',
|
||
'compiler' => 'LEXCOMPILE',
|
||
'extensions' => ['.l++', '.ll', '.lxx', '.lpp'],
|
||
'output_extensions' => sub { (my $ext = $_[0]) =~ tr/l/c/;
|
||
return ($ext,) },
|
||
'_finish' => \&lang_lex_finish,
|
||
'_target_hook' => \&lang_lex_target_hook);
|
||
|
||
# Assembler.
|
||
register_language ('name' => 'asm',
|
||
'Name' => 'Assembler',
|
||
'config_vars' => ['CCAS', 'CCASFLAGS'],
|
||
|
||
'flags' => ['CCASFLAGS'],
|
||
# Users can set AM_ASFLAGS to includes DEFS, INCLUDES,
|
||
# or anything else required. They can also set AS.
|
||
'compile' => '$(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)',
|
||
'compiler' => 'CCASCOMPILE',
|
||
'compile_flag' => '-c',
|
||
'extensions' => ['.s', '.S'],
|
||
|
||
# With assembly we still use the C linker.
|
||
'_finish' => \&lang_c_finish);
|
||
|
||
# Fortran 77
|
||
register_language ('name' => 'f77',
|
||
'Name' => 'Fortran 77',
|
||
'linker' => 'F77LINK',
|
||
'link' => '$(F77LD) $(AM_FFLAGS) $(FFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'flags' => ['FFLAGS'],
|
||
'compile' => '$(F77) $(AM_FFLAGS) $(FFLAGS)',
|
||
'compiler' => 'F77COMPILE',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'libtool_tag' => 'F77',
|
||
'lder' => 'F77LD',
|
||
'ld' => '$(F77)',
|
||
'pure' => 1,
|
||
'extensions' => ['.f', '.for']);
|
||
|
||
# Fortran
|
||
register_language ('name' => 'fc',
|
||
'Name' => 'Fortran',
|
||
'linker' => 'FCLINK',
|
||
'link' => '$(FCLD) $(AM_FCFLAGS) $(FCFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'flags' => ['FCFLAGS'],
|
||
'compile' => '$(FC) $(AM_FCFLAGS) $(FCFLAGS)',
|
||
'compiler' => 'FCCOMPILE',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'lder' => 'FCLD',
|
||
'ld' => '$(FC)',
|
||
'pure' => 1,
|
||
'extensions' => ['.f90', '.f95']);
|
||
|
||
# Preprocessed Fortran
|
||
register_language ('name' => 'ppfc',
|
||
'Name' => 'Preprocessed Fortran',
|
||
'config_vars' => ['FC'],
|
||
'linker' => 'FCLINK',
|
||
'link' => '$(FCLD) $(AM_FCFLAGS) $(FCFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'lder' => 'FCLD',
|
||
'ld' => '$(FC)',
|
||
'flags' => ['FCFLAGS', 'CPPFLAGS'],
|
||
'compiler' => 'PPFCCOMPILE',
|
||
'compile' => '$(FC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_FCFLAGS) $(FCFLAGS)',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'libtool_tag' => 'FC',
|
||
'pure' => 1,
|
||
'extensions' => ['.F90','.F95']);
|
||
|
||
# Preprocessed Fortran 77
|
||
#
|
||
# The current support for preprocessing Fortran 77 just involves
|
||
# passing `$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS)
|
||
# $(CPPFLAGS)' as additional flags to the Fortran 77 compiler, since
|
||
# this is how GNU Make does it; see the `GNU Make Manual, Edition 0.51
|
||
# for `make' Version 3.76 Beta' (specifically, from info file
|
||
# `(make)Catalogue of Rules').
|
||
#
|
||
# A better approach would be to write an Autoconf test
|
||
# (i.e. AC_PROG_FPP) for a Fortran 77 preprocessor, because not all
|
||
# Fortran 77 compilers know how to do preprocessing. The Autoconf
|
||
# macro AC_PROG_FPP should test the Fortran 77 compiler first for
|
||
# preprocessing capabilities, and then fall back on cpp (if cpp were
|
||
# available).
|
||
register_language ('name' => 'ppf77',
|
||
'Name' => 'Preprocessed Fortran 77',
|
||
'config_vars' => ['F77'],
|
||
'linker' => 'F77LINK',
|
||
'link' => '$(F77LD) $(AM_FFLAGS) $(FFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'lder' => 'F77LD',
|
||
'ld' => '$(F77)',
|
||
'flags' => ['FFLAGS', 'CPPFLAGS'],
|
||
'compiler' => 'PPF77COMPILE',
|
||
'compile' => '$(F77) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_FFLAGS) $(FFLAGS)',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'libtool_tag' => 'F77',
|
||
'pure' => 1,
|
||
'extensions' => ['.F']);
|
||
|
||
# Ratfor.
|
||
register_language ('name' => 'ratfor',
|
||
'Name' => 'Ratfor',
|
||
'config_vars' => ['F77'],
|
||
'linker' => 'F77LINK',
|
||
'link' => '$(F77LD) $(AM_FFLAGS) $(FFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'lder' => 'F77LD',
|
||
'ld' => '$(F77)',
|
||
'flags' => ['RFLAGS', 'FFLAGS'],
|
||
# FIXME also FFLAGS.
|
||
'compile' => '$(F77) $(AM_FFLAGS) $(FFLAGS) $(AM_RFLAGS) $(RFLAGS)',
|
||
'compiler' => 'RCOMPILE',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'libtool_tag' => 'F77',
|
||
'pure' => 1,
|
||
'extensions' => ['.r']);
|
||
|
||
# Java via gcj.
|
||
register_language ('name' => 'java',
|
||
'Name' => 'Java',
|
||
'config_vars' => ['GCJ'],
|
||
'linker' => 'GCJLINK',
|
||
'link' => '$(GCJLD) $(AM_GCJFLAGS) $(GCJFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@',
|
||
'autodep' => 'GCJ',
|
||
'flags' => ['GCJFLAGS'],
|
||
'compile' => '$(GCJ) $(AM_GCJFLAGS) $(GCJFLAGS)',
|
||
'compiler' => 'GCJCOMPILE',
|
||
'compile_flag' => '-c',
|
||
'output_flag' => '-o',
|
||
'libtool_tag' => 'GCJ',
|
||
'lder' => 'GCJLD',
|
||
'ld' => '$(GCJ)',
|
||
'pure' => 1,
|
||
'extensions' => ['.java', '.class', '.zip', '.jar']);
|
||
|
||
################################################################
|
||
|
||
# Error reporting functions.
|
||
|
||
# err_am ($MESSAGE, [%OPTIONS])
|
||
# -----------------------------
|
||
# Uncategorized errors about the current Makefile.am.
|
||
sub err_am ($;%)
|
||
{
|
||
msg_am ('error', @_);
|
||
}
|
||
|
||
# err_ac ($MESSAGE, [%OPTIONS])
|
||
# -----------------------------
|
||
# Uncategorized errors about configure.ac.
|
||
sub err_ac ($;%)
|
||
{
|
||
msg_ac ('error', @_);
|
||
}
|
||
|
||
# msg_am ($CHANNEL, $MESSAGE, [%OPTIONS])
|
||
# ---------------------------------------
|
||
# Messages about about the current Makefile.am.
|
||
sub msg_am ($$;%)
|
||
{
|
||
my ($channel, $msg, %opts) = @_;
|
||
msg $channel, "${am_file}.am", $msg, %opts;
|
||
}
|
||
|
||
# msg_ac ($CHANNEL, $MESSAGE, [%OPTIONS])
|
||
# ---------------------------------------
|
||
# Messages about about configure.ac.
|
||
sub msg_ac ($$;%)
|
||
{
|
||
my ($channel, $msg, %opts) = @_;
|
||
msg $channel, $configure_ac, $msg, %opts;
|
||
}
|
||
|
||
################################################################
|
||
|
||
# subst ($TEXT)
|
||
# -------------
|
||
# Return a configure-style substitution using the indicated text.
|
||
# We do this to avoid having the substitutions directly in automake.in;
|
||
# when we do that they are sometimes removed and this causes confusion
|
||
# and bugs.
|
||
sub subst ($)
|
||
{
|
||
my ($text) = @_;
|
||
return '@' . $text . '@';
|
||
}
|
||
|
||
################################################################
|
||
|
||
|
||
# $BACKPATH
|
||
# &backname ($REL-DIR)
|
||
# --------------------
|
||
# If I `cd $REL-DIR', then to come back, I should `cd $BACKPATH'.
|
||
# For instance `src/foo' => `../..'.
|
||
# Works with non strictly increasing paths, i.e., `src/../lib' => `..'.
|
||
sub backname ($)
|
||
{
|
||
my ($file) = @_;
|
||
my @res;
|
||
foreach (split (/\//, $file))
|
||
{
|
||
next if $_ eq '.' || $_ eq '';
|
||
if ($_ eq '..')
|
||
{
|
||
pop @res;
|
||
}
|
||
else
|
||
{
|
||
push (@res, '..');
|
||
}
|
||
}
|
||
return join ('/', @res) || '.';
|
||
}
|
||
|
||
################################################################
|
||
|
||
|
||
# Handle AUTOMAKE_OPTIONS variable. Return 1 on error, 0 otherwise.
|
||
sub handle_options
|
||
{
|
||
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)))
|
||
{
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
if ($strictness == GNITS)
|
||
{
|
||
set_option ('readme-alpha', INTERNAL);
|
||
set_option ('std-options', INTERNAL);
|
||
set_option ('check-news', INTERNAL);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
# shadow_unconditionally ($varname, $where)
|
||
# -----------------------------------------
|
||
# Return a $(variable) that contains all possible values
|
||
# $varname can take.
|
||
# If the VAR wasn't defined conditionally, return $(VAR).
|
||
# Otherwise we create a am__VAR_DIST variable which contains
|
||
# all possible values, and return $(am__VAR_DIST).
|
||
sub shadow_unconditionally ($$)
|
||
{
|
||
my ($varname, $where) = @_;
|
||
my $var = var $varname;
|
||
if ($var->has_conditional_contents)
|
||
{
|
||
$varname = "am__${varname}_DIST";
|
||
my @files = uniq ($var->value_as_list_recursive);
|
||
define_pretty_variable ($varname, TRUE, $where, @files);
|
||
}
|
||
return "\$($varname)"
|
||
}
|
||
|
||
# get_object_extension ($EXTENSION)
|
||
# ---------------------------------
|
||
# Prefix $EXTENSION with $U if ansi2knr is in use.
|
||
sub get_object_extension ($)
|
||
{
|
||
my ($extension) = @_;
|
||
|
||
# Check for automatic de-ANSI-fication.
|
||
$extension = '$U' . $extension
|
||
if option 'ansi2knr';
|
||
|
||
$get_object_extension_was_run = 1;
|
||
|
||
return $extension;
|
||
}
|
||
|
||
|
||
# Call finish function for each language that was used.
|
||
sub handle_languages
|
||
{
|
||
if (! option 'no-dependencies')
|
||
{
|
||
# Include auto-dep code. Don't include it if DEP_FILES would
|
||
# be empty.
|
||
if (&saw_sources_p (0) && keys %dep_files)
|
||
{
|
||
# Set location of depcomp.
|
||
&define_variable ('depcomp',
|
||
"\$(SHELL) $am_config_aux_dir/depcomp",
|
||
INTERNAL);
|
||
&define_variable ('am__depfiles_maybe', 'depfiles', INTERNAL);
|
||
|
||
require_conf_file ("$am_file.am", FOREIGN, 'depcomp');
|
||
|
||
my @deplist = sort keys %dep_files;
|
||
# Generate each `include' individually. Irix 6 make will
|
||
# not properly include several files resulting from a
|
||
# variable expansion; generating many separate includes
|
||
# seems safest.
|
||
$output_rules .= "\n";
|
||
foreach my $iter (@deplist)
|
||
{
|
||
$output_rules .= (subst ('AMDEP_TRUE')
|
||
. subst ('am__include')
|
||
. ' '
|
||
. subst ('am__quote')
|
||
. $iter
|
||
. subst ('am__quote')
|
||
. "\n");
|
||
}
|
||
|
||
# Compute the set of directories to remove in distclean-depend.
|
||
my @depdirs = uniq (map { dirname ($_) } @deplist);
|
||
$output_rules .= &file_contents ('depend',
|
||
new Automake::Location,
|
||
DEPDIRS => "@depdirs");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
&define_variable ('depcomp', '', INTERNAL);
|
||
&define_variable ('am__depfiles_maybe', '', INTERNAL);
|
||
}
|
||
|
||
my %done;
|
||
|
||
# Is the c linker needed?
|
||
my $needs_c = 0;
|
||
foreach my $ext (sort keys %extension_seen)
|
||
{
|
||
next unless $extension_map{$ext};
|
||
|
||
my $lang = $languages{$extension_map{$ext}};
|
||
|
||
my $rule_file = $lang->rule_file || 'depend2';
|
||
|
||
# Get information on $LANG.
|
||
my $pfx = $lang->autodep;
|
||
my $fpfx = ($pfx eq '') ? 'CC' : $pfx;
|
||
|
||
my ($AMDEP, $FASTDEP) =
|
||
(option 'no-dependencies' || $lang->autodep eq 'no')
|
||
? ('FALSE', 'FALSE') : ('AMDEP', "am__fastdep$fpfx");
|
||
|
||
my %transform = ('EXT' => $ext,
|
||
'PFX' => $pfx,
|
||
'FPFX' => $fpfx,
|
||
'AMDEP' => $AMDEP,
|
||
'FASTDEP' => $FASTDEP,
|
||
'-c' => $lang->compile_flag || '',
|
||
'MORE-THAN-ONE'
|
||
=> (count_files_for_language ($lang->name) > 1));
|
||
|
||
# Generate the appropriate rules for this extension.
|
||
if (((! option 'no-dependencies') && $lang->autodep ne 'no')
|
||
|| defined $lang->compile)
|
||
{
|
||
# Some C compilers don't support -c -o. Use it only if really
|
||
# needed.
|
||
my $output_flag = $lang->output_flag || '';
|
||
$output_flag = '-o'
|
||
if (! $output_flag
|
||
&& $lang->name eq 'c'
|
||
&& option 'subdir-objects');
|
||
|
||
# Compute a possible derived extension.
|
||
# This is not used by depend2.am.
|
||
my $der_ext = (&{$lang->output_extensions} ($ext))[0];
|
||
|
||
# When we output an inference rule like `.c.o:' we
|
||
# have two cases to consider: either subdir-objects
|
||
# is used, or it is not.
|
||
#
|
||
# In the latter case the rule is used to build objects
|
||
# in the current directory, and dependencies always
|
||
# go into `./$(DEPDIR)/'. We can hard-code this value.
|
||
#
|
||
# In the former case the rule can be used to build
|
||
# 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.
|
||
#
|
||
# DEPBASE holds the name of this directory, plus the
|
||
# basename part of the object file (extensions Po, TPo,
|
||
# Plo, TPlo will be added later as appropriate). It is
|
||
# either hardcoded, or a shell variable (`$depbase') that
|
||
# will be computed by the rule.
|
||
my $depbase =
|
||
option ('subdir-objects') ? '$$depbase' : '$(DEPDIR)/$*';
|
||
$output_rules .=
|
||
file_contents ($rule_file,
|
||
new Automake::Location,
|
||
%transform,
|
||
GENERIC => 1,
|
||
|
||
'DERIVED-EXT' => $der_ext,
|
||
|
||
DEPBASE => $depbase,
|
||
BASE => '$*',
|
||
SOURCE => '$<',
|
||
OBJ => '$@',
|
||
OBJOBJ => '$@',
|
||
LTOBJ => '$@',
|
||
|
||
COMPILE => '$(' . $lang->compiler . ')',
|
||
LTCOMPILE => '$(LT' . $lang->compiler . ')',
|
||
-o => $output_flag,
|
||
SUBDIROBJ => !! option 'subdir-objects');
|
||
}
|
||
|
||
# Now include code for each specially handled object with this
|
||
# language.
|
||
my %seen_files = ();
|
||
foreach my $file (@{$lang_specific_files{$lang->name}})
|
||
{
|
||
my ($derived, $source, $obj, $myext, %file_transform) = @$file;
|
||
|
||
# We might see a given object twice, for instance if it is
|
||
# used under different conditions.
|
||
next if defined $seen_files{$obj};
|
||
$seen_files{$obj} = 1;
|
||
|
||
prog_error ("found " . $lang->name .
|
||
" in handle_languages, but compiler not defined")
|
||
unless defined $lang->compile;
|
||
|
||
my $obj_compile = $lang->compile;
|
||
|
||
# Rewrite each occurrence of `AM_$flag' in the compile
|
||
# rule into `${derived}_$flag' if it exists.
|
||
for my $flag (@{$lang->flags})
|
||
{
|
||
my $val = "${derived}_$flag";
|
||
$obj_compile =~ s/\(AM_$flag\)/\($val\)/
|
||
if set_seen ($val);
|
||
}
|
||
|
||
my $libtool_tag = '';
|
||
if ($lang->libtool_tag && exists $libtool_tags{$lang->libtool_tag})
|
||
{
|
||
$libtool_tag = '--tag=' . $lang->libtool_tag . ' '
|
||
}
|
||
|
||
my $obj_ltcompile =
|
||
"\$(LIBTOOL) $libtool_tag--mode=compile $obj_compile";
|
||
|
||
# We _need_ `-o' for per object rules.
|
||
my $output_flag = $lang->output_flag || '-o';
|
||
|
||
my $depbase = dirname ($obj);
|
||
$depbase = ''
|
||
if $depbase eq '.';
|
||
$depbase .= '/'
|
||
unless $depbase eq '';
|
||
$depbase .= '$(DEPDIR)/' . basename ($obj);
|
||
|
||
# Support for deansified files in subdirectories is ugly
|
||
# enough to deserve an explanation.
|
||
#
|
||
# A Note about normal ansi2knr processing first. On
|
||
#
|
||
# AUTOMAKE_OPTIONS = ansi2knr
|
||
# bin_PROGRAMS = foo
|
||
# foo_SOURCES = foo.c
|
||
#
|
||
# we generate rules similar to:
|
||
#
|
||
# foo: foo$U.o; link ...
|
||
# foo$U.o: foo$U.c; compile ...
|
||
# foo_.c: foo.c; ansi2knr ...
|
||
#
|
||
# this is fairly compact, and will call ansi2knr depending
|
||
# on the value of $U (`' or `_').
|
||
#
|
||
# It's harder with subdir sources. On
|
||
#
|
||
# AUTOMAKE_OPTIONS = ansi2knr
|
||
# bin_PROGRAMS = foo
|
||
# foo_SOURCES = sub/foo.c
|
||
#
|
||
# we have to create foo_.c in the current directory.
|
||
# (Unless the user asks 'subdir-objects'.) This is important
|
||
# in case the same file (`foo.c') is compiled from other
|
||
# directories with different cpp options: foo_.c would
|
||
# be preprocessed for only one set of options if it were
|
||
# put in the subdirectory.
|
||
#
|
||
# Because foo$U.o must be built from either foo_.c or
|
||
# sub/foo.c we can't be as concise as in the first example.
|
||
# Instead we output
|
||
#
|
||
# foo: foo$U.o; link ...
|
||
# foo_.o: foo_.c; compile ...
|
||
# foo.o: sub/foo.c; compile ...
|
||
# foo_.c: foo.c; ansi2knr ...
|
||
#
|
||
# This is why we'll now transform $rule_file twice
|
||
# if we detect this case.
|
||
# A first time we output the compile rule with `$U'
|
||
# replaced by `_' and the source directory removed,
|
||
# and another time we simply remove `$U'.
|
||
#
|
||
# Note that at this point $source (as computed by
|
||
# &handle_single_transform) is `sub/foo$U.c'.
|
||
# This can be confusing: it can be used as-is when
|
||
# subdir-objects is set, otherwise you have to know
|
||
# it really means `foo_.c' or `sub/foo.c'.
|
||
my $objdir = dirname ($obj);
|
||
my $srcdir = dirname ($source);
|
||
if ($lang->ansi && $obj =~ /\$U/)
|
||
{
|
||
prog_error "`$obj' contains \$U, but `$source' doesn't."
|
||
if $source !~ /\$U/;
|
||
|
||
(my $source_ = $source) =~ s/\$U/_/g;
|
||
# Output an additional rule if _.c and .c are not in
|
||
# the same directory. (_.c is always in $objdir.)
|
||
if ($objdir ne $srcdir)
|
||
{
|
||
(my $obj_ = $obj) =~ s/\$U/_/g;
|
||
(my $depbase_ = $depbase) =~ s/\$U/_/g;
|
||
$source_ = basename ($source_);
|
||
|
||
$output_rules .=
|
||
file_contents ($rule_file,
|
||
new Automake::Location,
|
||
%transform,
|
||
GENERIC => 0,
|
||
|
||
DEPBASE => $depbase_,
|
||
BASE => $obj_,
|
||
SOURCE => $source_,
|
||
OBJ => "$obj_$myext",
|
||
OBJOBJ => "$obj_.obj",
|
||
LTOBJ => "$obj_.lo",
|
||
|
||
COMPILE => $obj_compile,
|
||
LTCOMPILE => $obj_ltcompile,
|
||
-o => $output_flag,
|
||
%file_transform);
|
||
$obj =~ s/\$U//g;
|
||
$depbase =~ s/\$U//g;
|
||
$source =~ s/\$U//g;
|
||
}
|
||
}
|
||
|
||
$output_rules .=
|
||
file_contents ($rule_file,
|
||
new Automake::Location,
|
||
%transform,
|
||
GENERIC => 0,
|
||
|
||
DEPBASE => $depbase,
|
||
BASE => $obj,
|
||
SOURCE => $source,
|
||
# Use $myext and not `.o' here, in case
|
||
# we are actually building a new source
|
||
# file -- e.g. via yacc.
|
||
OBJ => "$obj$myext",
|
||
OBJOBJ => "$obj.obj",
|
||
LTOBJ => "$obj.lo",
|
||
|
||
COMPILE => $obj_compile,
|
||
LTCOMPILE => $obj_ltcompile,
|
||
-o => $output_flag,
|
||
%file_transform);
|
||
}
|
||
|
||
# The rest of the loop is done once per language.
|
||
next if defined $done{$lang};
|
||
$done{$lang} = 1;
|
||
|
||
# Load the language dependent Makefile chunks.
|
||
my %lang = map { uc ($_) => 0 } keys %languages;
|
||
$lang{uc ($lang->name)} = 1;
|
||
$output_rules .= file_contents ('lang-compile',
|
||
new Automake::Location,
|
||
%transform, %lang);
|
||
|
||
# If the source to a program consists entirely of code from a
|
||
# `pure' language, for instance C++ for Fortran 77, then we
|
||
# don't need the C compiler code. However if we run into
|
||
# something unusual then we do generate the C code. There are
|
||
# probably corner cases here that do not work properly.
|
||
# People linking Java code to Fortran code deserve pain.
|
||
$needs_c ||= ! $lang->pure;
|
||
|
||
define_compiler_variable ($lang)
|
||
if ($lang->compile);
|
||
|
||
define_linker_variable ($lang)
|
||
if ($lang->link);
|
||
|
||
require_variables ("$am_file.am", $lang->Name . " source seen",
|
||
TRUE, @{$lang->config_vars});
|
||
|
||
# Call the finisher.
|
||
$lang->finish;
|
||
|
||
# Flags listed in `->flags' are user variables (per GNU Standards),
|
||
# they should not be overridden in the Makefile...
|
||
my @dont_override = @{$lang->flags};
|
||
# ... and so is LDFLAGS.
|
||
push @dont_override, 'LDFLAGS' if $lang->link;
|
||
|
||
foreach my $flag (@dont_override)
|
||
{
|
||
my $var = var $flag;
|
||
if ($var)
|
||
{
|
||
for my $cond ($var->conditions->conds)
|
||
{
|
||
if ($var->rdef ($cond)->owner == VAR_MAKEFILE)
|
||
{
|
||
msg_cond_var ('gnu', $cond, $flag,
|
||
"`$flag' is a user variable, "
|
||
. "you should not override it;\n"
|
||
. "use `AM_$flag' instead.");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
# If the project is entirely C++ or entirely Fortran 77 (i.e., 1
|
||
# suffix rule was learned), don't bother with the C stuff. But if
|
||
# anything else creeps in, then use it.
|
||
$needs_c = 1
|
||
if $need_link || suffix_rules_count > 1;
|
||
|
||
if ($needs_c)
|
||
{
|
||
&define_compiler_variable ($languages{'c'})
|
||
unless defined $done{$languages{'c'}};
|
||
define_linker_variable ($languages{'c'});
|
||
}
|
||
}
|
||
|
||
# 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
|
||
# do this check.
|
||
sub check_libobjs_sources
|
||
{
|
||
my ($one_file, $unxformed) = @_;
|
||
|
||
foreach my $prefix ('', 'EXTRA_', 'dist_', 'nodist_',
|
||
'dist_EXTRA_', 'nodist_EXTRA_')
|
||
{
|
||
my @files;
|
||
my $varname = $prefix . $one_file . '_SOURCES';
|
||
my $var = var ($varname);
|
||
if ($var)
|
||
{
|
||
@files = $var->value_as_list_recursive;
|
||
}
|
||
elsif ($prefix eq '')
|
||
{
|
||
@files = ($unxformed . '.c');
|
||
}
|
||
else
|
||
{
|
||
next;
|
||
}
|
||
|
||
foreach my $file (@files)
|
||
{
|
||
err_var ($prefix . $one_file . '_SOURCES',
|
||
"automatically discovered file `$file' should not" .
|
||
" be explicitly mentioned")
|
||
if defined $libsources{$file};
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
# @OBJECTS
|
||
# handle_single_transform ($VAR, $TOPPARENT, $DERIVED, $OBJ, $FILE, %TRANSFORM)
|
||
# -----------------------------------------------------------------------------
|
||
# Does much of the actual work for handle_source_transform.
|
||
# Arguments are:
|
||
# $VAR is the name of the variable that the source filenames come from
|
||
# $TOPPARENT is the name of the _SOURCES variable which is being processed
|
||
# $DERIVED is the name of resulting executable or library
|
||
# $OBJ is the object extension (e.g., `$U.lo')
|
||
# $FILE the source file to transform
|
||
# %TRANSFORM contains extras arguments to pass to file_contents
|
||
# when producing explicit rules
|
||
# Result is a list of the names of objects
|
||
# %linkers_used will be updated with any linkers needed
|
||
sub handle_single_transform ($$$$$%)
|
||
{
|
||
my ($var, $topparent, $derived, $obj, $_file, %transform) = @_;
|
||
my @files = ($_file);
|
||
my @result = ();
|
||
my $nonansi_obj = $obj;
|
||
$nonansi_obj =~ s/\$U//g;
|
||
|
||
# Turn sources into objects. We use a while loop like this
|
||
# because we might add to @files in the loop.
|
||
while (scalar @files > 0)
|
||
{
|
||
$_ = shift @files;
|
||
|
||
# Configure substitutions in _SOURCES variables are errors.
|
||
if (/^\@.*\@$/)
|
||
{
|
||
my $parent_msg = '';
|
||
$parent_msg = "\nand is referred to from `$topparent'"
|
||
if $topparent ne $var->name;
|
||
err_var ($var,
|
||
"`" . $var->name . "' includes configure substitution `$_'"
|
||
. $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.
|
||
|
||
# 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);
|
||
|
||
# This records whether we've seen a derived source file (e.g.
|
||
# yacc output).
|
||
my $derived_source = 0;
|
||
|
||
# This holds the `aggregate context' of the file we are
|
||
# currently examining. If the file is compiled with
|
||
# per-object flags, then it will be the name of the object.
|
||
# Otherwise it will be `AM'. This is used by the target hook
|
||
# language function.
|
||
my $aggregate = 'AM';
|
||
|
||
$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);
|
||
|
||
# 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);
|
||
# 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;
|
||
|
||
my $this_obj_ext;
|
||
if (defined $source_extension)
|
||
{
|
||
$this_obj_ext = $source_extension;
|
||
$derived_source = 1;
|
||
}
|
||
elsif ($lang->ansi)
|
||
{
|
||
$this_obj_ext = $obj;
|
||
}
|
||
else
|
||
{
|
||
$this_obj_ext = $nonansi_obj;
|
||
}
|
||
$object = $base . $this_obj_ext;
|
||
|
||
# Do we have per-executable flags for this executable?
|
||
my $have_per_exec_flags = 0;
|
||
foreach my $flag (@{$lang->flags})
|
||
{
|
||
if (set_seen ("${derived}_$flag"))
|
||
{
|
||
$have_per_exec_flags = 1;
|
||
last;
|
||
}
|
||
}
|
||
|
||
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 also require
|
||
# the `compile' program to deal with compilers
|
||
# where `-c -o' does not work.
|
||
|
||
# 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;
|
||
|
||
require_conf_file ("$am_file.am", FOREIGN, 'compile')
|
||
if $lang->name eq 'c';
|
||
|
||
prog_error ($lang->name . " flags defined without compiler")
|
||
if ! defined $lang->compile;
|
||
|
||
$renamed = 1;
|
||
}
|
||
|
||
# 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
|
||
# inference rule: we need an explicit rule.
|
||
#
|
||
# If the source is in a subdirectory and the object is in
|
||
# the current directory, we also need an explicit rule.
|
||
#
|
||
# If both source and object files are in a subdirectory
|
||
# (this happens when the subdir-objects option is used),
|
||
# then the inference will work.
|
||
#
|
||
# The latter case deserves a historical note. When the
|
||
# subdir-objects option was added on 1999-04-11 it was
|
||
# 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
|
||
# 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
|
||
# 2200+ subdir objects was reported to have a 9MB
|
||
# Makefile), so we now rely on inference rules again.
|
||
# Maybe we'll run across the same issue as in the past,
|
||
# but at least this time we can document it. However since
|
||
# dependency tracking has evolved it is possible that
|
||
# our old problem no longer exists.
|
||
# 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 ||
|
||
($directory ne '' && ! option 'subdir-objects'))
|
||
{
|
||
my $obj_sans_ext = substr ($object, 0,
|
||
- length ($this_obj_ext));
|
||
my $full_ansi = $full;
|
||
if ($lang->ansi && option 'ansi2knr')
|
||
{
|
||
$full_ansi =~ s/$KNOWN_EXTENSIONS_PATTERN$/\$U$&/;
|
||
$obj_sans_ext .= '$U';
|
||
}
|
||
|
||
my @specifics = ($full_ansi, $obj_sans_ext,
|
||
# 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'));
|
||
|
||
# If we renamed the object then we want to use the
|
||
# per-executable flag name. But if this is simply a
|
||
# subdir build then we still want to use the AM_ flag
|
||
# name.
|
||
if ($renamed)
|
||
{
|
||
unshift @specifics, $derived;
|
||
$aggregate = $derived;
|
||
}
|
||
else
|
||
{
|
||
unshift @specifics, 'AM';
|
||
}
|
||
|
||
# Each item on this list is a reference to a list consisting
|
||
# of four values followed by additional transform flags for
|
||
# file_contents. The four values are the derived flag prefix
|
||
# (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}},
|
||
[@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.
|
||
# 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;
|
||
}
|
||
|
||
err_am "object `$object' created by `$full' and `$object_map{$object}'"
|
||
if (defined $object_map{$object}
|
||
&& $object_map{$object} ne $full);
|
||
|
||
my $comp_val = (($object =~ /\.lo$/)
|
||
? COMPILE_LIBTOOL : COMPILE_ORDINARY);
|
||
(my $comp_obj = $object) =~ s/\.lo$/.\$(OBJEXT)/;
|
||
if (defined $object_compilation_map{$comp_obj}
|
||
&& $object_compilation_map{$comp_obj} != 0
|
||
# Only see the error once.
|
||
&& ($object_compilation_map{$comp_obj}
|
||
!= (COMPILE_LIBTOOL | COMPILE_ORDINARY))
|
||
&& $object_compilation_map{$comp_obj} != $comp_val)
|
||
{
|
||
err_am "object `$comp_obj' created both with libtool and without";
|
||
}
|
||
$object_compilation_map{$comp_obj} |= $comp_val;
|
||
|
||
if (defined $lang)
|
||
{
|
||
# Let the language do some special magic if required.
|
||
$lang->target_hook ($aggregate, $object, $full, %transform);
|
||
}
|
||
|
||
if ($derived_source)
|
||
{
|
||
prog_error ($lang->name . " has automatic dependency tracking")
|
||
if $lang->autodep ne 'no';
|
||
# Make sure this new source file is handled next. That will
|
||
# make it appear to be at the right place in the list.
|
||
unshift (@files, $object);
|
||
# Distribute derived sources unless the source they are
|
||
# derived from is not.
|
||
&push_dist_common ($object)
|
||
unless ($topparent =~ /^(?:nobase_)?nodist_/);
|
||
next;
|
||
}
|
||
|
||
$linkers_used{$linker} = 1;
|
||
|
||
push (@result, $object);
|
||
|
||
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
|
||
|
||
# For Java, the way we're handling it right now, a
|
||
# `..' component doesn't make sense.
|
||
if ($lang->name eq 'java' && $object =~ /(\/|^)\.\.\//)
|
||
{
|
||
err_am "`$full' should not contain a `..' component";
|
||
}
|
||
|
||
# Make sure object is removed by `make mostlyclean'.
|
||
$compile_clean_files{$object} = MOSTLY_CLEAN;
|
||
# If we have a libtool object then we also must remove
|
||
# the ordinary .o.
|
||
if ($object =~ /\.lo$/)
|
||
{
|
||
(my $xobj = $object) =~ s,lo$,\$(OBJEXT),;
|
||
$compile_clean_files{$xobj} = MOSTLY_CLEAN;
|
||
|
||
# Remove any libtool object in this directory.
|
||
$libtool_clean_directories{$directory} = 1;
|
||
}
|
||
|
||
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.
|
||
push (@dep_list,
|
||
require_build_directory ($directory . '/$(DEPDIR)'))
|
||
unless option 'no-dependencies';
|
||
}
|
||
|
||
&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;
|
||
}
|
||
}
|
||
|
||
return @result;
|
||
}
|
||
|
||
|
||
# $LINKER
|
||
# define_objects_from_sources ($VAR, $OBJVAR, $NODEFINE, $ONE_FILE,
|
||
# $OBJ, $PARENT, $TOPPARENT, $WHERE, %TRANSFORM)
|
||
# ---------------------------------------------------------------------------
|
||
# Define an _OBJECTS variable for a _SOURCES variable (or subvariable)
|
||
#
|
||
# Arguments are:
|
||
# $VAR is the name of the _SOURCES variable
|
||
# $OBJVAR is the name of the _OBJECTS variable if known (otherwise
|
||
# it will be generated and returned).
|
||
# $NODEFINE is a boolean: if true, $OBJVAR will not be defined (but
|
||
# work done to determine the linker will be).
|
||
# $ONE_FILE is the canonical (transformed) name of object to build
|
||
# $OBJ is the object extension (i.e. either `.o' or `.lo').
|
||
# $TOPPARENT is the _SOURCES variable being processed.
|
||
# $WHERE context into which this definition is done
|
||
# %TRANSFORM extra arguments to pass to file_contents when producing
|
||
# rules
|
||
#
|
||
# Result is a pair ($LINKER, $OBJVAR):
|
||
# $LINKER is a boolean, true if a linker is needed to deal with the objects
|
||
sub define_objects_from_sources ($$$$$$$%)
|
||
{
|
||
my ($var, $objvar, $nodefine, $one_file,
|
||
$obj, $topparent, $where, %transform) = @_;
|
||
|
||
my $needlinker = "";
|
||
|
||
transform_variable_recursively
|
||
($var, $objvar, 'am__objects', $nodefine, $where,
|
||
# The transform code to run on each filename.
|
||
sub {
|
||
my ($subvar, $val, $cond, $full_cond) = @_;
|
||
my @trans = handle_single_transform ($subvar, $topparent,
|
||
$one_file, $obj, $val,
|
||
%transform);
|
||
$needlinker = "true" if @trans;
|
||
return @trans;
|
||
});
|
||
|
||
return $needlinker;
|
||
}
|
||
|
||
|
||
# handle_source_transform ($CANON_TARGET, $TARGET, $OBJEXT, $WHERE, %TRANSFORM)
|
||
# -----------------------------------------------------------------------------
|
||
# Handle SOURCE->OBJECT transform for one program or library.
|
||
# Arguments are:
|
||
# canonical (transformed) name of target to build
|
||
# actual target of object to build
|
||
# 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.
|
||
# Empty return means just use `LINK'.
|
||
sub handle_source_transform ($$$$%)
|
||
{
|
||
# one_file is canonical name. unxformed is given name. obj is
|
||
# object extension.
|
||
my ($one_file, $unxformed, $obj, $where, %transform) = @_;
|
||
|
||
my ($linker) = '';
|
||
|
||
# No point in continuing if _OBJECTS is defined.
|
||
return if reject_var ($one_file . '_OBJECTS',
|
||
$one_file . '_OBJECTS should not be defined');
|
||
|
||
my %used_pfx = ();
|
||
my $needlinker;
|
||
%linkers_used = ();
|
||
foreach my $prefix ('', 'EXTRA_', 'dist_', 'nodist_',
|
||
'dist_EXTRA_', 'nodist_EXTRA_')
|
||
{
|
||
my $varname = $prefix . $one_file . "_SOURCES";
|
||
my $var = var $varname;
|
||
next unless $var;
|
||
|
||
# We are going to define _OBJECTS variables using the prefix.
|
||
# Then we glom them all together. So we can't use the null
|
||
# prefix here as we need it later.
|
||
my $xpfx = ($prefix eq '') ? 'am_' : $prefix;
|
||
|
||
# Keep track of which prefixes we saw.
|
||
$used_pfx{$xpfx} = 1
|
||
unless $prefix =~ /EXTRA_/;
|
||
|
||
push @sources, "\$($varname)";
|
||
push @dist_sources, shadow_unconditionally ($varname, $where)
|
||
unless (option ('no-dist') || $prefix =~ /^nodist_/);
|
||
|
||
$needlinker |=
|
||
define_objects_from_sources ($varname,
|
||
$xpfx . $one_file . '_OBJECTS',
|
||
$prefix =~ /EXTRA_/,
|
||
$one_file, $obj, $varname, $where,
|
||
DIST_SOURCE => ($prefix !~ /^nodist_/),
|
||
%transform);
|
||
}
|
||
if ($needlinker)
|
||
{
|
||
$linker ||= &resolve_linker (%linkers_used);
|
||
}
|
||
|
||
my @keys = sort keys %used_pfx;
|
||
if (scalar @keys == 0)
|
||
{
|
||
# The default source for libfoo.la is libfoo.c, but for
|
||
# backward compatibility we first look at libfoo_la.c
|
||
my $old_default_source = "$one_file.c";
|
||
(my $default_source = $unxformed) =~ s,(\.[^./\\]*)?$,.c,;
|
||
if ($old_default_source ne $default_source
|
||
&& (rule $old_default_source
|
||
|| rule '$(srcdir)/' . $old_default_source
|
||
|| rule '${srcdir}/' . $old_default_source
|
||
|| -f $old_default_source))
|
||
{
|
||
my $loc = $where->clone;
|
||
$loc->pop_context;
|
||
msg ('obsolete', $loc,
|
||
"the default source for `$unxformed' has been changed "
|
||
. "to `$default_source'.\n(Using `$old_default_source' for "
|
||
. "backward compatibility.)");
|
||
$default_source = $old_default_source;
|
||
}
|
||
# If a rule exists to build this source with a $(srcdir)
|
||
# prefix, use that prefix in our variables too. This is for
|
||
# the sake of BSD Make.
|
||
if (rule '$(srcdir)/' . $default_source
|
||
|| rule '${srcdir}/' . $default_source)
|
||
{
|
||
$default_source = '$(srcdir)/' . $default_source;
|
||
}
|
||
|
||
&define_variable ($one_file . "_SOURCES", $default_source, $where);
|
||
push (@sources, $default_source);
|
||
push (@dist_sources, $default_source);
|
||
|
||
%linkers_used = ();
|
||
my (@result) =
|
||
handle_single_transform ($one_file . '_SOURCES',
|
||
$one_file . '_SOURCES',
|
||
$one_file, $obj,
|
||
$default_source, %transform);
|
||
$linker ||= &resolve_linker (%linkers_used);
|
||
define_pretty_variable ($one_file . '_OBJECTS', TRUE, $where, @result);
|
||
}
|
||
else
|
||
{
|
||
@keys = map { '$(' . $_ . $one_file . '_OBJECTS)' } @keys;
|
||
define_pretty_variable ($one_file . '_OBJECTS', TRUE, $where, @keys);
|
||
}
|
||
|
||
# If we want to use `LINK' we must make sure it is defined.
|
||
if ($linker eq '')
|
||
{
|
||
$need_link = 1;
|
||
}
|
||
|
||
return $linker;
|
||
}
|
||
|
||
|
||
# handle_lib_objects ($XNAME, $VAR)
|
||
# ---------------------------------
|
||
# Special-case ALLOCA and LIBOBJS substitutions in _LDADD or _LIBADD variables.
|
||
# Also, generate _DEPENDENCIES variable if appropriate.
|
||
# Arguments are:
|
||
# transformed name of object being built, or empty string if no object
|
||
# name of _LDADD/_LIBADD-type variable to examine
|
||
# Returns 1 if LIBOBJS seen, 0 otherwise.
|
||
sub handle_lib_objects
|
||
{
|
||
my ($xname, $varname) = @_;
|
||
|
||
my $var = var ($varname);
|
||
prog_error "handle_lib_objects: `$varname' undefined"
|
||
unless $var;
|
||
prog_error "handle_lib_objects: unexpected variable name `$varname'"
|
||
unless $varname =~ /^(.*)(?:LIB|LD)ADD$/;
|
||
my $prefix = $1 || 'AM_';
|
||
|
||
my $seen_libobjs = 0;
|
||
my $flagvar = 0;
|
||
|
||
transform_variable_recursively
|
||
($varname, $xname . '_DEPENDENCIES', 'am__DEPENDENCIES',
|
||
! $xname, INTERNAL,
|
||
# Transformation function, run on each filename.
|
||
sub {
|
||
my ($subvar, $val, $cond, $full_cond) = @_;
|
||
|
||
if ($val =~ /^-/)
|
||
{
|
||
# Skip -lfoo and -Ldir silently; these are explicitly allowed.
|
||
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
|
||
# libraries or programs, for which -dlopen and -dlopreopen
|
||
# are pure non-sence. Diagnosting this doesn't seems very
|
||
# important: the developer will quickly get complaints from
|
||
# the linker.)
|
||
$val !~ /^-dl(?:pre)?open$/ &&
|
||
# Only get this error once.
|
||
! $flagvar)
|
||
{
|
||
$flagvar = 1;
|
||
# FIXME: should display a stack of nested variables
|
||
# as context when $var != $subvar.
|
||
err_var ($var, "linker flags such as `$val' belong in "
|
||
. "`${prefix}LDFLAGS");
|
||
}
|
||
return ();
|
||
}
|
||
elsif ($val !~ /^\@.*\@$/)
|
||
{
|
||
# Assume we have a file of some sort, and output it into the
|
||
# dependency variable. Autoconf substitutions are not output;
|
||
# rarely is a new dependency substituted into e.g. foo_LDADD
|
||
# -- but bad things (e.g. -lX11) are routinely substituted.
|
||
# Note that LIBOBJS and ALLOCA are exceptions to this rule,
|
||
# and handled specially below.
|
||
return $val;
|
||
}
|
||
elsif ($val =~ /^\@(LT)?LIBOBJS\@$/)
|
||
{
|
||
handle_LIBOBJS ($subvar, $cond, $1);
|
||
$seen_libobjs = 1;
|
||
return $val;
|
||
}
|
||
elsif ($val =~ /^\@(LT)?ALLOCA\@$/)
|
||
{
|
||
handle_ALLOCA ($subvar, $cond, $1);
|
||
return $val;
|
||
}
|
||
else
|
||
{
|
||
return ();
|
||
}
|
||
});
|
||
|
||
return $seen_libobjs;
|
||
}
|
||
|
||
sub handle_LIBOBJS ($$$)
|
||
{
|
||
my ($var, $cond, $lt) = @_;
|
||
$lt ||= '';
|
||
my $myobjext = ($1 ? 'l' : '') . 'o';
|
||
|
||
$var->requires_variables ("\@${lt}LIBOBJS\@ used", $lt . 'LIBOBJS')
|
||
if ! keys %libsources;
|
||
|
||
foreach my $iter (keys %libsources)
|
||
{
|
||
if ($iter =~ /\.[cly]$/)
|
||
{
|
||
&saw_extension ($&);
|
||
&saw_extension ('.c');
|
||
}
|
||
|
||
if ($iter =~ /\.h$/)
|
||
{
|
||
require_file_with_macro ($cond, $var, FOREIGN, $iter);
|
||
}
|
||
elsif ($iter ne 'alloca.c')
|
||
{
|
||
my $rewrite = $iter;
|
||
$rewrite =~ s/\.c$/.P$myobjext/;
|
||
$dep_files{'$(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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
sub handle_ALLOCA ($$$)
|
||
{
|
||
my ($var, $cond, $lt) = @_;
|
||
my $myobjext = ($lt ? 'l' : '') . 'o';
|
||
$lt ||= '';
|
||
$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');
|
||
}
|
||
|
||
# Canonicalize the input parameter
|
||
sub canonicalize
|
||
{
|
||
my ($string) = @_;
|
||
$string =~ tr/A-Za-z0-9_\@/_/c;
|
||
return $string;
|
||
}
|
||
|
||
# Canonicalize a name, and check to make sure the non-canonical name
|
||
# is never used. Returns canonical name. Arguments are name and a
|
||
# list of suffixes to check for.
|
||
sub check_canonical_spelling
|
||
{
|
||
my ($name, @suffixes) = @_;
|
||
|
||
my $xname = &canonicalize ($name);
|
||
if ($xname ne $name)
|
||
{
|
||
foreach my $xt (@suffixes)
|
||
{
|
||
reject_var ("$name$xt", "use `$xname$xt', not `$name$xt'");
|
||
}
|
||
}
|
||
|
||
return $xname;
|
||
}
|
||
|
||
|
||
# handle_compile ()
|
||
# -----------------
|
||
# Set up the compile suite.
|
||
sub handle_compile ()
|
||
{
|
||
return
|
||
unless $get_object_extension_was_run;
|
||
|
||
# Boilerplate.
|
||
my $default_includes = '';
|
||
if (! option 'nostdinc')
|
||
{
|
||
$default_includes = ' -I. -I$(srcdir)';
|
||
|
||
my $var = var 'CONFIG_HEADER';
|
||
if ($var)
|
||
{
|
||
foreach my $hdr (split (' ', $var->variable_value))
|
||
{
|
||
$default_includes .= ' -I' . dirname ($hdr);
|
||
}
|
||
}
|
||
}
|
||
|
||
my (@mostly_rms, @dist_rms);
|
||
foreach my $item (sort keys %compile_clean_files)
|
||
{
|
||
if ($compile_clean_files{$item} == MOSTLY_CLEAN)
|
||
{
|
||
push (@mostly_rms, "\t-rm -f $item");
|
||
}
|
||
elsif ($compile_clean_files{$item} == DIST_CLEAN)
|
||
{
|
||
push (@dist_rms, "\t-rm -f $item");
|
||
}
|
||
else
|
||
{
|
||
prog_error 'invalid entry in %compile_clean_files';
|
||
}
|
||
}
|
||
|
||
my ($coms, $vars, $rules) =
|
||
&file_contents_internal (1, "$libdir/am/compile.am",
|
||
new Automake::Location,
|
||
('DEFAULT_INCLUDES' => $default_includes,
|
||
'MOSTLYRMS' => join ("\n", @mostly_rms),
|
||
'DISTRMS' => join ("\n", @dist_rms)));
|
||
$output_vars .= $vars;
|
||
$output_rules .= "$coms$rules";
|
||
|
||
# Check for automatic de-ANSI-fication.
|
||
if (option 'ansi2knr')
|
||
{
|
||
my ($ansi2knr_filename, $ansi2knr_where) = @{option 'ansi2knr'};
|
||
my $ansi2knr_dir = '';
|
||
|
||
require_variables ($ansi2knr_where, "option `ansi2knr' is used",
|
||
TRUE, "ANSI2KNR", "U");
|
||
|
||
# topdir is where ansi2knr should be.
|
||
if ($ansi2knr_filename eq 'ansi2knr')
|
||
{
|
||
# Only require ansi2knr files if they should appear in
|
||
# this directory.
|
||
require_file ($ansi2knr_where, FOREIGN,
|
||
'ansi2knr.c', 'ansi2knr.1');
|
||
|
||
# ansi2knr needs to be built before subdirs, so unshift it.
|
||
unshift (@all, '$(ANSI2KNR)');
|
||
}
|
||
else
|
||
{
|
||
$ansi2knr_dir = dirname ($ansi2knr_filename);
|
||
}
|
||
|
||
$output_rules .= &file_contents ('ansi2knr',
|
||
new Automake::Location,
|
||
'ANSI2KNR-DIR' => $ansi2knr_dir);
|
||
|
||
}
|
||
}
|
||
|
||
# handle_libtool ()
|
||
# -----------------
|
||
# Handle libtool rules.
|
||
sub handle_libtool
|
||
{
|
||
return unless var ('LIBTOOL');
|
||
|
||
# Libtool requires some files, but only at top level.
|
||
require_conf_file_with_macro (TRUE, 'LIBTOOL', FOREIGN, @libtool_files)
|
||
if $relative_dir eq '.';
|
||
|
||
my @libtool_rms;
|
||
foreach my $item (sort keys %libtool_clean_directories)
|
||
{
|
||
my $dir = ($item eq '.') ? '' : "$item/";
|
||
# .libs is for Unix, _libs for DOS.
|
||
push (@libtool_rms, "\t-rm -rf ${dir}.libs ${dir}_libs");
|
||
}
|
||
|
||
# Output the libtool compilation rules.
|
||
$output_rules .= &file_contents ('libtool',
|
||
new Automake::Location,
|
||
LTRMS => join ("\n", @libtool_rms));
|
||
}
|
||
|
||
# handle_programs ()
|
||
# ------------------
|
||
# Handle C programs.
|
||
sub handle_programs
|
||
{
|
||
my @proglist = &am_install_var ('progs', 'PROGRAMS',
|
||
'bin', 'sbin', 'libexec', 'pkglib',
|
||
'noinst', 'check');
|
||
return if ! @proglist;
|
||
|
||
my $seen_global_libobjs =
|
||
var ('LDADD') && &handle_lib_objects ('', 'LDADD');
|
||
|
||
foreach my $pair (@proglist)
|
||
{
|
||
my ($where, $one_file) = @$pair;
|
||
|
||
my $seen_libobjs = 0;
|
||
my $obj = get_object_extension '.$(OBJEXT)';
|
||
|
||
# Strip any $(EXEEXT) suffix the user might have added, or this
|
||
# will confuse &handle_source_transform and &check_canonical_spelling.
|
||
# We'll add $(EXEEXT) back later anyway.
|
||
$one_file =~ s/\$\(EXEEXT\)$//;
|
||
|
||
# Canonicalize names and check for misspellings.
|
||
my $xname = &check_canonical_spelling ($one_file, '_LDADD', '_LDFLAGS',
|
||
'_SOURCES', '_OBJECTS',
|
||
'_DEPENDENCIES');
|
||
|
||
$where->push_context ("while processing program `$one_file'");
|
||
$where->set (INTERNAL->get);
|
||
|
||
my $linker = &handle_source_transform ($xname, $one_file, $obj, $where,
|
||
NONLIBTOOL => 1, LIBTOOL => 0);
|
||
|
||
if (var ($xname . "_LDADD"))
|
||
{
|
||
$seen_libobjs = &handle_lib_objects ($xname, $xname . '_LDADD');
|
||
}
|
||
else
|
||
{
|
||
# User didn't define prog_LDADD override. So do it.
|
||
&define_variable ($xname . '_LDADD', '$(LDADD)', $where);
|
||
|
||
# This does a bit too much work. But we need it to
|
||
# generate _DEPENDENCIES when appropriate.
|
||
if (var ('LDADD'))
|
||
{
|
||
$seen_libobjs = &handle_lib_objects ($xname, 'LDADD');
|
||
}
|
||
}
|
||
|
||
reject_var ($xname . '_LIBADD',
|
||
"use `${xname}_LDADD', not `${xname}_LIBADD'");
|
||
|
||
set_seen ($xname . '_DEPENDENCIES');
|
||
set_seen ($xname . '_LDFLAGS');
|
||
|
||
# Determine program to use for link.
|
||
my $xlink;
|
||
if (var ($xname . '_LINK'))
|
||
{
|
||
$xlink = $xname . '_LINK';
|
||
}
|
||
else
|
||
{
|
||
$xlink = $linker ? $linker : 'LINK';
|
||
}
|
||
|
||
# If the resulting program lies into a subdirectory,
|
||
# make sure this directory will exist.
|
||
my $dirstamp = require_build_directory_maybe ($one_file);
|
||
|
||
$output_rules .= &file_contents ('program',
|
||
$where,
|
||
PROGRAM => $one_file,
|
||
XPROGRAM => $xname,
|
||
XLINK => $xlink,
|
||
DIRSTAMP => $dirstamp,
|
||
EXEEXT => '$(EXEEXT)');
|
||
|
||
if ($seen_libobjs || $seen_global_libobjs)
|
||
{
|
||
if (var ($xname . '_LDADD'))
|
||
{
|
||
&check_libobjs_sources ($xname, $xname . '_LDADD');
|
||
}
|
||
elsif (var ('LDADD'))
|
||
{
|
||
&check_libobjs_sources ($xname, 'LDADD');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
# handle_libraries ()
|
||
# -------------------
|
||
# Handle libraries.
|
||
sub handle_libraries
|
||
{
|
||
my @liblist = &am_install_var ('libs', 'LIBRARIES',
|
||
'lib', 'pkglib', 'noinst', 'check');
|
||
return if ! @liblist;
|
||
|
||
my @prefix = am_primary_prefixes ('LIBRARIES', 0, 'lib', 'pkglib',
|
||
'noinst', 'check');
|
||
|
||
if (@prefix)
|
||
{
|
||
my $var = rvar ($prefix[0] . '_LIBRARIES');
|
||
$var->requires_variables ('library used', 'RANLIB');
|
||
}
|
||
|
||
&define_variable ('AR', 'ar', INTERNAL);
|
||
&define_variable ('ARFLAGS', 'cru', INTERNAL);
|
||
|
||
foreach my $pair (@liblist)
|
||
{
|
||
my ($where, $onelib) = @$pair;
|
||
|
||
my $seen_libobjs = 0;
|
||
# Check that the library fits the standard naming convention.
|
||
my $bn = basename ($onelib);
|
||
if ($bn !~ /^lib.*\.a$/)
|
||
{
|
||
$bn =~ s/^(?:lib)?(.*?)(?:\.[^.]*)?$/lib$1.a/;
|
||
my $suggestion = dirname ($onelib) . "/$bn";
|
||
$suggestion =~ s|^\./||g;
|
||
msg ('error-gnu/warn', $where,
|
||
"`$onelib' is not a standard library name\n"
|
||
. "did you mean `$suggestion'?")
|
||
}
|
||
|
||
$where->push_context ("while processing library `$onelib'");
|
||
$where->set (INTERNAL->get);
|
||
|
||
my $obj = get_object_extension '.$(OBJEXT)';
|
||
|
||
# Canonicalize names and check for misspellings.
|
||
my $xlib = &check_canonical_spelling ($onelib, '_LIBADD', '_SOURCES',
|
||
'_OBJECTS', '_DEPENDENCIES',
|
||
'_AR');
|
||
|
||
if (! var ($xlib . '_AR'))
|
||
{
|
||
&define_variable ($xlib . '_AR', '$(AR) $(ARFLAGS)', $where);
|
||
}
|
||
|
||
# Generate support for conditional object inclusion in
|
||
# libraries.
|
||
if (var ($xlib . '_LIBADD'))
|
||
{
|
||
if (&handle_lib_objects ($xlib, $xlib . '_LIBADD'))
|
||
{
|
||
$seen_libobjs = 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
&define_variable ($xlib . "_LIBADD", '', $where);
|
||
}
|
||
|
||
reject_var ($xlib . '_LDADD',
|
||
"use `${xlib}_LIBADD', not `${xlib}_LDADD'");
|
||
|
||
# Make sure we at look at this.
|
||
set_seen ($xlib . '_DEPENDENCIES');
|
||
|
||
&handle_source_transform ($xlib, $onelib, $obj, $where,
|
||
NONLIBTOOL => 1, LIBTOOL => 0);
|
||
|
||
# If the resulting library lies into a subdirectory,
|
||
# make sure this directory will exist.
|
||
my $dirstamp = require_build_directory_maybe ($onelib);
|
||
|
||
$output_rules .= &file_contents ('library',
|
||
$where,
|
||
LIBRARY => $onelib,
|
||
XLIBRARY => $xlib,
|
||
DIRSTAMP => $dirstamp);
|
||
|
||
if ($seen_libobjs)
|
||
{
|
||
if (var ($xlib . '_LIBADD'))
|
||
{
|
||
&check_libobjs_sources ($xlib, $xlib . '_LIBADD');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
# handle_ltlibraries ()
|
||
# ---------------------
|
||
# Handle shared libraries.
|
||
sub handle_ltlibraries
|
||
{
|
||
my @liblist = &am_install_var ('ltlib', 'LTLIBRARIES',
|
||
'noinst', 'lib', 'pkglib', 'check');
|
||
return if ! @liblist;
|
||
|
||
my @prefix = am_primary_prefixes ('LTLIBRARIES', 0, 'lib', 'pkglib',
|
||
'noinst', 'check');
|
||
|
||
if (@prefix)
|
||
{
|
||
my $var = rvar ($prefix[0] . '_LTLIBRARIES');
|
||
$var->requires_variables ('Libtool library used', 'LIBTOOL');
|
||
}
|
||
|
||
my %instdirs = ();
|
||
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 $var = rvar ($key . '_LTLIBRARIES');
|
||
|
||
# We reject libraries which are installed in several places
|
||
# in the same condition, because we can only specify one
|
||
# `-rpath' option.
|
||
$var->traverse_recursively
|
||
(sub
|
||
{
|
||
my ($var, $val, $cond, $full_cond) = @_;
|
||
my $hcond = $full_cond->human;
|
||
my $where = $var->rdef ($cond)->location;
|
||
# A library cannot be installed in different directory
|
||
# in overlapping conditions.
|
||
if (exists $instconds{$val})
|
||
{
|
||
my ($msg, $acond) =
|
||
$instconds{$val}->ambiguous_p ($val, $full_cond);
|
||
|
||
if ($msg)
|
||
{
|
||
error ($where, $msg, partial => 1);
|
||
|
||
my $dirtxt = "installed in `$dir'";
|
||
$dirtxt = "built for `$dir'"
|
||
if $dir eq 'EXTRA' || $dir eq 'noinst' || $dir eq 'check';
|
||
my $dircond =
|
||
$full_cond->true ? "" : " in condition $hcond";
|
||
|
||
error ($where, "`$val' should be $dirtxt$dircond ...",
|
||
partial => 1);
|
||
|
||
my $hacond = $acond->human;
|
||
my $adir = $instdirs{$val}{$acond};
|
||
my $adirtxt = "installed in `$adir'";
|
||
$adirtxt = "built for `$adir'"
|
||
if ($adir eq 'EXTRA' || $adir eq 'noinst'
|
||
|| $adir eq 'check');
|
||
my $adircond = $acond->true ? "" : " in condition $hacond";
|
||
|
||
my $onlyone = ($dir ne $adir) ?
|
||
("\nLibtool libraries can be built for only one "
|
||
. "destination.") : "";
|
||
|
||
error ($liblocations{$val}{$acond},
|
||
"... and should also be $adirtxt$adircond.$onlyone");
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$instconds{$val} = new Automake::DisjConditions;
|
||
}
|
||
$instdirs{$val}{$full_cond} = $dir;
|
||
$liblocations{$val}{$full_cond} = $where;
|
||
$instconds{$val} = $instconds{$val}->merge ($full_cond);
|
||
},
|
||
sub
|
||
{
|
||
return ();
|
||
},
|
||
skip_ac_subst => 1);
|
||
}
|
||
|
||
foreach my $pair (@liblist)
|
||
{
|
||
my ($where, $onelib) = @$pair;
|
||
|
||
my $seen_libobjs = 0;
|
||
my $obj = get_object_extension '.lo';
|
||
|
||
# Canonicalize names and check for misspellings.
|
||
my $xlib = &check_canonical_spelling ($onelib, '_LIBADD', '_LDFLAGS',
|
||
'_SOURCES', '_OBJECTS',
|
||
'_DEPENDENCIES');
|
||
|
||
# Check that the library fits the standard naming convention.
|
||
my $libname_rx = '^lib.*\.la';
|
||
my $ldvar = var ("${xlib}_LDFLAGS") || var ('AM_LDFLAGS');
|
||
my $ldvar2 = var ('LDFLAGS');
|
||
if (($ldvar && grep (/-module/, $ldvar->value_as_list_recursive))
|
||
|| ($ldvar2 && grep (/-module/, $ldvar2->value_as_list_recursive)))
|
||
{
|
||
# Relax name checking for libtool modules.
|
||
$libname_rx = '\.la';
|
||
}
|
||
|
||
my $bn = basename ($onelib);
|
||
if ($bn !~ /$libname_rx$/)
|
||
{
|
||
my $type = 'library';
|
||
if ($libname_rx eq '\.la')
|
||
{
|
||
$bn =~ s/^(lib|)(.*?)(?:\.[^.]*)?$/$1$2.la/;
|
||
$type = 'module';
|
||
}
|
||
else
|
||
{
|
||
$bn =~ s/^(?:lib)?(.*?)(?:\.[^.]*)?$/lib$1.la/;
|
||
}
|
||
my $suggestion = dirname ($onelib) . "/$bn";
|
||
$suggestion =~ s|^\./||g;
|
||
msg ('error-gnu/warn', $where,
|
||
"`$onelib' is not a standard libtool $type name\n"
|
||
. "did you mean `$suggestion'?")
|
||
}
|
||
|
||
$where->push_context ("while processing Libtool library `$onelib'");
|
||
$where->set (INTERNAL->get);
|
||
|
||
# Make sure we look at these.
|
||
set_seen ($xlib . '_LDFLAGS');
|
||
set_seen ($xlib . '_DEPENDENCIES');
|
||
|
||
# Generate support for conditional object inclusion in
|
||
# libraries.
|
||
if (var ($xlib . '_LIBADD'))
|
||
{
|
||
if (&handle_lib_objects ($xlib, $xlib . '_LIBADD'))
|
||
{
|
||
$seen_libobjs = 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
&define_variable ($xlib . "_LIBADD", '', $where);
|
||
}
|
||
|
||
reject_var ("${xlib}_LDADD",
|
||
"use `${xlib}_LIBADD', not `${xlib}_LDADD'");
|
||
|
||
|
||
my $linker = &handle_source_transform ($xlib, $onelib, $obj, $where,
|
||
NONLIBTOOL => 0, LIBTOOL => 1);
|
||
|
||
# Determine program to use for link.
|
||
my $xlink;
|
||
if (var ($xlib . '_LINK'))
|
||
{
|
||
$xlink = $xlib . '_LINK';
|
||
}
|
||