diff options
Diffstat (limited to 'bin/automake.in')
-rw-r--r-- | bin/automake.in | 102 |
1 files changed, 85 insertions, 17 deletions
diff --git a/bin/automake.in b/bin/automake.in index 8db874cc7..d126836a0 100644 --- a/bin/automake.in +++ b/bin/automake.in @@ -74,6 +74,7 @@ use Automake::Wrap 'makefile_wrap'; use Automake::Language; use File::Basename; use File::Spec; +use List::Util 'none'; use Carp; ## ----------------------- ## @@ -472,6 +473,15 @@ my %dep_files; # This is a list of all targets to run during "make dist". my @dist_targets; +# List of all programs, libraries and ltlibraries as returned +# by am_install_var +my @proglist; +my @liblist; +my @ltliblist; +# Blacklist of targets (as canonical base name) for which object file names +# may not be automatically shortened +my @dup_shortnames; + # Keep track of all programs declared in this Makefile, without # $(EXEEXT). @substitutions@ are not listed. my %known_programs; @@ -592,6 +602,11 @@ sub initialize_per_input () @dist_common = (); $handle_dist_run = 0; + @proglist = (); + @liblist = (); + @ltliblist = (); + @dup_shortnames = (); + %known_programs = (); %known_libraries = (); @@ -1704,14 +1719,48 @@ sub handle_single_transform # 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; + # 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 attempt to shorten automatically under + # subdir-objects, and provide _SHORTNAME to override as a last + # resort. If subdir-object is in effect, it's usually + # unnecessary to use the complete 'DERIVED_OBJECT' (that is + # often the result from %canon_reldir%/%C% usage) since objects + # are placed next to their source file. Generally, this means + # it is already unique within that directory (see below for an + # exception). Thus, we try to avoid unnecessarily long file + # names by stripping the directory components of + # 'DERIVED_OBJECT'. This allows avoiding explicit _SHORTNAME + # usage in many cases. EXCEPTION: If two (or more) targets in + # different directories but with the same base name (after + # canonicalization), using target-specific FLAGS, link the same + # object, then this logic clashes. Thus, we don't strip if + # this is detected. + my $dname = $derived; + if ($directory ne '' + && option 'subdir-objects' + && none { $dname =~ /$_$/ } @dup_shortnames) + { + # At this point, we don't clear information about what + # parts of $derived are truly file name components. We can + # determine that by comparing against the canonicalization + # of $directory. + my $dir = $directory . "/"; + my $cdir = canonicalize ($dir); + my $dir_len = length ($dir); + # Make sure we only strip full file name components. This + # is done by repeatedly trying to find cdir at the + # beginning. Each iteration removes one file name + # component from the end of cdir. + while ($dir_len > 0 && index ($derived, $cdir) != 0) + { + # Eventually $dir_len becomes 0. + $dir_len = rindex ($dir, "/", $dir_len - 2) + 1; + $cdir = substr ($cdir, 0, $dir_len); + } + $dname = substr ($derived, $dir_len); + } my $var = var ($derived . '_SHORTNAME'); if ($var) { @@ -2432,12 +2481,33 @@ sub handle_libtool () LTRMS => join ("\n", @libtool_rms)); } +# Check for duplicate targets +sub handle_targets () +{ + my %seen = (); + my @dups = (); + @proglist = am_install_var ('progs', 'PROGRAMS', + 'bin', 'sbin', 'libexec', 'pkglibexec', + 'noinst', 'check'); + @liblist = am_install_var ('libs', 'LIBRARIES', + 'lib', 'pkglib', 'noinst', 'check'); + @ltliblist = am_install_var ('ltlib', 'LTLIBRARIES', + 'noinst', 'lib', 'pkglib', 'check'); + + # Record duplications that may arise after canonicalization of the + # base names, in order to prevent object file clashes in the presence + # of target-specific *FLAGS + my @targetlist = (@proglist, @liblist, @ltliblist); + foreach my $pair (@targetlist) + { + my $base = canonicalize (basename (@$pair[1])); + push (@dup_shortnames, $base) if ($seen{$base}); + $seen{$base} = $base; + } +} sub handle_programs () { - my @proglist = am_install_var ('progs', 'PROGRAMS', - 'bin', 'sbin', 'libexec', 'pkglibexec', - 'noinst', 'check'); return if ! @proglist; $must_handle_compiled_objects = 1; @@ -2524,8 +2594,6 @@ sub handle_programs () sub handle_libraries () { - my @liblist = am_install_var ('libs', 'LIBRARIES', - 'lib', 'pkglib', 'noinst', 'check'); return if ! @liblist; $must_handle_compiled_objects = 1; @@ -2634,9 +2702,7 @@ sub handle_libraries () sub handle_ltlibraries () { - my @liblist = am_install_var ('ltlib', 'LTLIBRARIES', - 'noinst', 'lib', 'pkglib', 'check'); - return if ! @liblist; + return if ! @ltliblist; $must_handle_compiled_objects = 1; my @prefix = am_primary_prefixes ('LTLIBRARIES', 0, 'lib', 'pkglib', @@ -2729,7 +2795,7 @@ sub handle_ltlibraries () skip_ac_subst => 1); } - foreach my $pair (@liblist) + foreach my $pair (@ltliblist) { my ($where, $onelib) = @$pair; @@ -7793,6 +7859,8 @@ sub generate_makefile handle_configure ($makefile_am, $makefile_in, $makefile, @inputs); handle_gettext; + + handle_targets; handle_libraries; handle_ltlibraries; handle_programs; |