Dear Recipient,This is to inform you that the bug that you reported, bug#60508, has been resolved. The patch is attached for your convenience. Thank you for reporting.
-- With Valediction, Kamila Szewczyk (https://iczelia.net)
From c64b7e696a9f7abf9be1ed11f83255ec16aefaa1 Mon Sep 17 00:00:00 2001 From: Kamila Szewczyk <[email protected]> Date: Mon, 19 Oct 2026 00:42:45 +0200 Subject: [PATCH] automake: fix order-dependent object dependencies (bug#60508). * bin/automake.in (handle_link_dependencies): Generate dependencies after all target object lists are defined. (handle_lib_objects): Keep replacement-object handling separate. * t/ar-dependencies.sh: Add regression coverage. * t/list-of-tests.mk: Register it. * NEWS: Mention the fix. --- NEWS | 4 +++ bin/automake.in | 81 ++++++++++++++++++++++++++++---------------- t/ar-dependencies.sh | 73 +++++++++++++++++++++++++++++++++++++++ t/list-of-tests.mk | 1 + 4 files changed, 129 insertions(+), 30 deletions(-) create mode 100644 t/ar-dependencies.sh diff --git a/NEWS b/NEWS index a3731365b..afe4e3d13 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ New in 1.20 (????-??-??): * Bugs fixed + - Dependencies on another target's objects in LIBADD or LDADD are now + tracked regardless of the order in which targets are processed. + (bug#60508) + - distcheck now detects symbolic links left in the installation tree after uninstall, including dangling links. diff --git a/bin/automake.in b/bin/automake.in index 783469353..8c9f6e53e 100644 --- a/bin/automake.in +++ b/bin/automake.in @@ -99,6 +99,7 @@ sub handle_java (); sub handle_languages (); sub handle_libraries (); sub handle_libtool (); +sub handle_link_dependencies (); sub handle_ltlibraries (); sub handle_makefiles_serial (); sub handle_man_pages (); @@ -2277,17 +2278,15 @@ sub handle_source_transform } -# handle_lib_objects ($XNAME, $VAR) -# --------------------------------- +# handle_lib_objects ($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 ($varname) = @_; my $var = var ($varname); prog_error "'$varname' undefined" @@ -2299,11 +2298,8 @@ sub handle_lib_objects my $seen_libobjs = 0; my $flagvar = 0; - transform_variable_recursively - ($varname, $xname . '_DEPENDENCIES', 'am__DEPENDENCIES', - ! $xname, INTERNAL, - # Transformation function, run on each filename. - sub { + $var->traverse_recursively + (sub { my ($subvar, $val, $cond, $full_cond) = @_; if ($val =~ /^-/) @@ -2329,36 +2325,61 @@ sub handle_lib_objects } 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; + return (); } elsif ($val =~ /^\@(LT)?ALLOCA\@$/) { handle_ALLOCA ($subvar, $cond, $1); - return $val; + return (); } else { return (); } - }); + }, undef); return $seen_libobjs; } +# Generate link dependencies after all target _OBJECTS variables have been +# defined, so references to other targets do not depend on processing order. +sub handle_link_dependencies () +{ + foreach my $primary (['LIBADD', @liblist, @ltliblist], + ['LDADD', @proglist]) + { + my ($suffix, @targets) = @$primary; + foreach my $pair (@targets) + { + my $xname = canonicalize ($pair->[1]); + my $varname = $xname . '_' . $suffix; + my $def = rvar ($varname)->def (TRUE); + if ($def && $def->owner == VAR_AUTOMAKE) + { + # Libraries default to empty LIBADD; programs to LDADD. + next if $suffix eq 'LIBADD' || ! var ('LDADD'); + $varname = 'LDADD'; + } + transform_variable_recursively + ($varname, $xname . '_DEPENDENCIES', + 'am__DEPENDENCIES', 0, INTERNAL, + sub { + my ($subvar, $val) = @_; + # Omit linker flags and configure substitutions, except + # for the object lists handled by handle_lib_objects. + return () if $val =~ /^-/; + return () if $val =~ /^\@.*\@$/ + && $val !~ /^\@(LT)?(LIBOBJS|ALLOCA)\@$/; + return $val; + }); + } + } +} + # handle_LIBOBJS_or_ALLOCA ($VAR, $BASE) # -------------------------------------- # Definitions common to LIBOBJS and ALLOCA. @@ -2603,7 +2624,7 @@ sub handle_programs () $must_handle_compiled_objects = 1; my $seen_global_libobjs = - var ('LDADD') && handle_lib_objects ('', 'LDADD'); + var ('LDADD') && handle_lib_objects ('LDADD'); foreach my $pair (@proglist) { @@ -2627,18 +2648,17 @@ sub handle_programs () if (var ($xname . "_LDADD")) { - $seen_libobjs = handle_lib_objects ($xname, $xname . '_LDADD'); + $seen_libobjs = handle_lib_objects ($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. + # Check the default LDADD for replacement objects. if (var ('LDADD')) { - $seen_libobjs = handle_lib_objects ($xname, 'LDADD'); + $seen_libobjs = handle_lib_objects ('LDADD'); } } @@ -2743,7 +2763,7 @@ sub handle_libraries () # libraries. if (var ($xlib . '_LIBADD')) { - if (handle_lib_objects ($xlib, $xlib . '_LIBADD')) + if (handle_lib_objects ($xlib . '_LIBADD')) { $seen_libobjs = 1; } @@ -2947,7 +2967,7 @@ sub handle_ltlibraries () # libraries. if (var ($xlib . '_LIBADD')) { - if (handle_lib_objects ($xlib, $xlib . '_LIBADD')) + if (handle_lib_objects ($xlib . '_LIBADD')) { $seen_libobjs = 1; } @@ -8136,6 +8156,7 @@ sub generate_makefile handle_libraries; handle_ltlibraries; handle_programs; + handle_link_dependencies; handle_scripts; handle_silent; diff --git a/t/ar-dependencies.sh b/t/ar-dependencies.sh new file mode 100644 index 000000000..f57b9bfd3 --- /dev/null +++ b/t/ar-dependencies.sh @@ -0,0 +1,73 @@ +#! /bin/sh +# Copyright (C) 2023-2026 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# Object dependencies must not depend on library ordering (bug#60508). + +. test-init.sh + +cat >> configure.ac << 'END' +AC_PROG_CC +AC_SUBST([OTHER_LIBS]) +AM_PROG_AR +AC_PROG_RANLIB +AM_CONDITIONAL([COND], [test x = y]) +END + +cat > Makefile.am << 'END' +noinst_LIBRARIES = + +libmMID_a_SOURCES = source.c +if COND +libmMID_a_SOURCES += extra.c +endif +noinst_LIBRARIES += libmMID.a + +libaFIRST_a_SOURCES = +libaFIRST_a_LIBADD = $(common_objects) +common_objects = $(libmMID_a_OBJECTS) +noinst_LIBRARIES += libaFIRST.a + +libzLAST_a_SOURCES = +libzLAST_a_LIBADD = $(libmMID_a_OBJECTS) +noinst_LIBRARIES += libzLAST.a + +noinst_PROGRAMS = aFIRST mMID zLAST +mMID_SOURCES = main.c +aFIRST_SOURCES = +aFIRST_LDADD = $(mMID_OBJECTS) -lm @OTHER_LIBS@ +zLAST_SOURCES = +zLAST_LDADD = $(mMID_OBJECTS) + +noinst_LIBRARIES += liboverride.a +liboverride_a_SOURCES = +liboverride_a_LIBADD = $(libmMID_a_OBJECTS) +liboverride_a_DEPENDENCIES = explicit +END + +: > ar-lib + +$ACLOCAL +$AUTOMAKE + +# Make sure DEPENDENCIES is setup correctly. +grep '_a_DEPENDENCIES =' Makefile.in +grep '^libzLAST_a_DEPENDENCIES = $(libmMID_a_OBJECTS)' Makefile.in +grep '^libaFIRST_a_DEPENDENCIES = $(common_objects)$' Makefile.in +grep '^aFIRST_DEPENDENCIES = $(mMID_OBJECTS)$' Makefile.in +grep '^zLAST_DEPENDENCIES = $(mMID_OBJECTS)$' Makefile.in +grep '^liboverride_a_DEPENDENCIES = explicit$' Makefile.in + +: diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk index ee10b67e5..33edac37d 100644 --- a/t/list-of-tests.mk +++ b/t/list-of-tests.mk @@ -152,6 +152,7 @@ t/amopts-location.sh \ t/amopts-variable-expansion.sh \ t/amsubst.sh \ t/ansi2knr-no-more.sh \ +t/ar-dependencies.sh \ t/ar-lib.sh \ t/ar-lib2.sh \ t/ar-lib3.sh \ -- 2.53.0
OpenPGP_signature.asc
Description: OpenPGP digital signature
