automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: Fix handling of per-target flags in link rules


From: Alexandre Duret-Lutz
Subject: FYI: Fix handling of per-target flags in link rules
Date: Mon, 03 Jan 2005 22:33:13 +0100
User-agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (gnu/linux)

I'm installing this on HEAD, as discussed in
http://lists.gnu.org/archive/html/automake/2004-12/msg00085.html

2005-01-03  Alexandre Duret-Lutz  <address@hidden>

        Fix handling of per-target flags in link rules.
        * automake.in (define_per_target_linker_variable): New function.
        (handle_programs, handle_ltlibraries): Use it.
        (%link_languages): New map.
        (register_language): Fill it.
        * lib/am/ltlibrary.am (%LTLIBRARY%): Do not append
        $(%XLTLIBRARY%_LDFLAGS) to the command, this is now done by
        define_per_target_linker_variable if needed.
        * lib/am/program.am (%PROGRAM%%EXEEXT%): Likewise with
        $(%XPROGRAM%_LDFLAGS).
        * doc/automake.texi (Program and Library Variables): Mention
        AM_LDFLAGS and AM_LIBTOOLFLAGS in the definition of maude_LDFLAGS
        and maude_LIBTOOLFLAGS.
        * tests/libtool9.test: New file.
        * tests/Makefile.am (TESTS): Add it.
        * NEWS: Explain the backward incompatibility.
        Report from Akim Demaille.

Index: NEWS
===================================================================
RCS file: /cvs/automake/automake/NEWS,v
retrieving revision 1.294
diff -u -r1.294 NEWS
--- NEWS        1 Jan 2005 17:16:57 -0000       1.294
+++ NEWS        3 Jan 2005 20:00:06 -0000
@@ -19,6 +19,37 @@
 
   - aclocal now also supports -Wmumble and -Wno-mumble options.
 
+  - Per-target flags are now correctly handled in link rules.
+
+    For instance maude_CFLAGS correctly overrides AM_CFLAGS; likewise
+    for maude_LDFLAGS and AM_LDFLAGS.  Previous versions bogusly
+    preferred AM_CFLAGS over maude_CFLAGS while linking, and they
+    used both AM_LDFLAGS and maude_LDFLAGS on the same link command.
+
+    The fix for compiler flags (i.e., using maude_CFLAGS instead of
+    AM_CFLAGS) should not hurt any package since that is how _CFLAGS
+    is expected to work (and actually works during compilation).
+
+    However using maude_LDFLAGS "instead of" AM_LDFLAGS rather than
+    "in addition to" breaks backward compatibility with older versions.
+    If your package used both variables, as in
+
+      AM_LDFLAGS = common flags
+      bin_PROGRAMS = a b c
+      a_LDFLAGS = more flags
+      ...
+
+    and assumed *_LDFLAGS would sum up, you should rewrite it as
+
+      AM_LDFLAGS = common flags
+      bin_PROGRAMS = a b c
+      a_LDFLAGS = $(AM_LDFLAGS) more flags
+      ...
+
+    This new behavior of *_LDFLAGS is more coherent with other
+    per-target variables, and the way *_LDFLAGS variables were
+    considered internally.
+
   - New targets mandated by GNU Coding Standards:
       install-dvi
       install-html
Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1596
diff -u -r1.1596 automake.in
--- automake.in 1 Jan 2005 17:16:57 -0000       1.1596
+++ automake.in 3 Jan 2005 20:00:07 -0000
@@ -403,6 +403,8 @@
 
 # This maps languages names onto objects.
 my %languages = ();
+# Maps each linker variable onto a language object.
+my %link_languages = ();
 
 # List of targets we must always output.
 # FIXME: Complete, and remove falsely required targets.
@@ -1923,7 +1925,7 @@
     # object extension.
     my ($one_file, $unxformed, $obj, $where, %transform) = @_;
 
-    my ($linker) = '';
+    my $linker = '';
 
     # No point in continuing if _OBJECTS is defined.
     return if reject_var ($one_file . '_OBJECTS',
@@ -2353,15 +2355,7 @@
       set_seen ($xname . '_LDFLAGS');
 
       # Determine program to use for link.
-      my $xlink;
-      if (var ($xname . '_LINK'))
-       {
-         $xlink = $xname . '_LINK';
-       }
-      else
-       {
-         $xlink = $linker ? $linker : 'LINK';
-       }
+      my $xlink = &define_per_target_linker_variable ($linker, $xname);
 
       # If the resulting program lies into a subdirectory,
       # make sure this directory will exist.
@@ -2648,15 +2642,7 @@
                                             NONLIBTOOL => 0, LIBTOOL => 1);
 
       # Determine program to use for link.
-      my $xlink;
-      if (var ($xlib . '_LINK'))
-       {
-         $xlink = $xlib . '_LINK';
-       }
-      else
-       {
-         $xlink = $linker ? $linker : 'LINK';
-       }
+      my $xlink = &define_per_target_linker_variable ($linker, $xlib);
 
       my $rpathvar = "am_${xlib}_rpath";
       my $rpath = "\$($rpathvar)";
@@ -5574,6 +5560,20 @@
   # Fill indexes.
   $extension_map{$_} = $lang->name foreach @{$lang->extensions};
   $languages{$lang->name} = $lang;
+  my $link = $lang->linker;
+  if ($link)
+    {
+      if (exists $link_languages{$link})
+       {
+         prog_error ("`$link' has different definitions in "
+                     . $lang->name . " and " . $link_languages{$link}->name)
+           if $lang->link ne $link_languages{$link}->link;
+       }
+      else
+       {
+         $link_languages{$link} = $lang;
+       }
+    }
 
   # Update the pattern of known extensions.
   accept_extensions (@{$lang->extensions});
@@ -5821,7 +5821,6 @@
 {
     my ($lang) = @_;
 
-    my ($var, $value) = ($lang->lder, $lang->ld);
     my $libtool_tag = '';
     $libtool_tag = '--tag=' . $lang->libtool_tag . ' '
       if $lang->libtool_tag && exists $libtool_tags{$lang->libtool_tag};
@@ -5836,6 +5835,53 @@
                      INTERNAL);
 }
 
+sub define_per_target_linker_variable ($$)
+{
+  my ($linker, $target) = @_;
+
+  # If the user wrote a custom link command, we don't define ours.
+  return "${target}_LINK"
+    if set_seen "${target}_LINK";
+
+  my $xlink = $linker ? $linker : 'LINK';
+
+  my $lang = $link_languages{$xlink};
+  prog_error "Unknown language for linker variable `$xlink'"
+    unless $lang;
+
+  my $link_command = $lang->link;
+  if (var 'LIBTOOL')
+    {
+      my $libtool_tag = '';
+      $libtool_tag = '--tag=' . $lang->libtool_tag . ' '
+       if $lang->libtool_tag && exists $libtool_tags{$lang->libtool_tag};
+
+      $link_command =
+       "\$(LIBTOOL) $libtool_tag\$(AM_LIBTOOLFLAGS) \$(LIBTOOLFLAGS) "
+       . "--mode=link " . $link_command;
+    }
+
+  # Rewrite each occurrence of `AM_$flag' in the link
+  # command into `${derived}_$flag' if it exists.
+  my $orig_command = $link_command;
+  my @flags = (@{$lang->flags}, 'LDFLAGS');
+  push @flags, 'LIBTOOLFLAGS' if var 'LIBTOOL';
+  for my $flag (@flags)
+    {
+      my $val = "${target}_$flag";
+      $link_command =~ s/\(AM_$flag\)/\($val\)/
+       if set_seen ($val);
+    }
+
+  # If the computed command is the same as the generic command, use
+  # the command linker variable.
+  return $lang->linker
+    if $link_command eq $orig_command;
+
+  &define_variable ("${target}_LINK", $link_command, INTERNAL);
+  return "${target}_LINK";
+}
+
 ################################################################
 
 # &check_trailing_slash ($WHERE, $LINE)
Index: doc/automake.texi
===================================================================
RCS file: /cvs/automake/automake/doc/automake.texi,v
retrieving revision 1.83
diff -u -r1.83 automake.texi
--- doc/automake.texi   1 Jan 2005 17:16:58 -0000       1.83
+++ doc/automake.texi   3 Jan 2005 20:00:09 -0000
@@ -3694,10 +3694,11 @@
 
 @item maude_LDFLAGS
 This variable is used to pass extra flags to the link step of a program
-or a shared library.
+or a shared library.  It overrides the global @code{AM_LDFLAGS} variable.
 
 @item maude_LIBTOOLFLAGS
 This variable is used to pass extra options to @command{libtool}.
+It overrides the global @code{AM_LIBTOOLFLAGS} variable.
 These options are output before @command{libtool}'s @code{--mode=MODE}
 option, so they should not be mode-specific options (those belong to
 the compiler or linker flags).  @xref{Libtool Flags}.
Index: lib/am/ltlibrary.am
===================================================================
RCS file: /cvs/automake/automake/lib/am/ltlibrary.am,v
retrieving revision 1.6
diff -u -r1.6 ltlibrary.am
--- lib/am/ltlibrary.am 2 Jun 2003 07:08:40 -0000       1.6
+++ lib/am/ltlibrary.am 3 Jan 2005 20:00:09 -0000
@@ -1,5 +1,5 @@
 ## automake - create Makefile.in from Makefile.am
-## Copyright (C) 1994, 1995, 1996, 2003 Free Software Foundation, Inc.
+## Copyright (C) 1994, 1995, 1996, 2003, 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
@@ -16,4 +16,4 @@
 ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 ## 02111-1307, USA.
 %LTLIBRARY%: $(%XLTLIBRARY%_OBJECTS) $(%XLTLIBRARY%_DEPENDENCIES) %DIRSTAMP%
-       $(%XLINK%) %RPATH% $(%XLTLIBRARY%_LDFLAGS) $(%XLTLIBRARY%_OBJECTS) 
$(%XLTLIBRARY%_LIBADD) $(LIBS)
+       $(%XLINK%) %RPATH% $(%XLTLIBRARY%_OBJECTS) $(%XLTLIBRARY%_LIBADD) 
$(LIBS)
Index: lib/am/program.am
===================================================================
RCS file: /cvs/automake/automake/lib/am/program.am,v
retrieving revision 1.24
diff -u -r1.24 program.am
--- lib/am/program.am   2 Jun 2003 07:08:40 -0000       1.24
+++ lib/am/program.am   3 Jan 2005 20:00:09 -0000
@@ -1,5 +1,5 @@
 ## automake - create Makefile.in from Makefile.am
-## Copyright (C) 1994, 1995, 1996, 1997, 2001, 2003
+## Copyright (C) 1994, 1995, 1996, 1997, 2001, 2003, 2005
 ## Free Software Foundation, Inc.
 
 ## This program is free software; you can redistribute it and/or modify
@@ -23,4 +23,4 @@
 ## Or maybe not... sadly, incremental linkers are rarer than losing
 ## systems.
        @rm -f %PROGRAM%%EXEEXT%
-       $(%XLINK%) $(%XPROGRAM%_LDFLAGS) $(%XPROGRAM%_OBJECTS) 
$(%XPROGRAM%_LDADD) $(LIBS)
+       $(%XLINK%) $(%XPROGRAM%_OBJECTS) $(%XPROGRAM%_LDADD) $(LIBS)
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.am,v
retrieving revision 1.577
diff -u -r1.577 Makefile.am
--- tests/Makefile.am   1 Jan 2005 17:16:59 -0000       1.577
+++ tests/Makefile.am   3 Jan 2005 20:00:09 -0000
@@ -302,6 +302,7 @@
 libtool6.test \
 libtool7.test \
 libtool8.test \
+libtool9.test \
 license.test \
 link_c_cxx.test        \
 link_dist.test \
Index: tests/libtool9.test
===================================================================
RCS file: tests/libtool9.test
diff -N tests/libtool9.test
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/libtool9.test 3 Jan 2005 20:00:09 -0000
@@ -0,0 +1,107 @@
+#! /bin/sh
+# Copyright (C) 2005  Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake 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.
+#
+# GNU Automake 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 Automake; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Make sure xxx_LINK is defined for each target that requires specific
+# flags.
+# Quite similar to libtool7.test, using AM_LDFLAGS in addition to xxx_LDFLAGS.
+
+required='libtoolize gcc'
+. ./defs || exit 1
+
+set -e
+
+cat >> configure.in << 'END'
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_LIBTOOL_DLOPEN
+AM_PROG_LIBTOOL
+AC_OUTPUT
+END
+
+cat > Makefile.am << 'END'
+AM_LDFLAGS = -module
+lib_LTLIBRARIES = libmod1.la mod2.la
+libmod1_la_SOURCES = mod1.c
+libmod1_la_LDFLAGS =
+libmod1_la_LIBADD = -dlopen mod2.la
+mod2_la_SOURCES = mod2.c
+
+bin_PROGRAMS = prg prg2
+prg_SOURCES = prg.c
+prg_LDADD = -dlopen libmod1.la -dlpreopen mod2.la
+prg_CPPFLAGS = -DXYZ=1
+prg2_SOURCES = prg.c
+prg2_CFLAGS =
+
+print:
+       @echo 1BEG: $(prg_DEPENDENCIES) :END1
+       @echo 2BEG: $(libmod1_la_DEPENDENCIES) :END2
+       @echo 3BEG: $(libmod1_la_LINK) :END3
+       @echo 4BEG: $(mod2_la_LINK) :END4
+       @echo 5BEG: $(prg_LINK) :END5
+       @echo 6BEG: $(prg2_LINK) :END6
+
+END
+
+mkdir liba
+
+cat > mod1.c << 'END'
+int
+mod1 ()
+{
+   return 1;
+}
+END
+
+cat > mod2.c << 'END'
+int
+mod2 ()
+{
+   return 2;
+}
+END
+
+cat > prg.c << 'END'
+int
+main ()
+{
+   return 0;
+}
+END
+
+libtoolize --force --copy
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE --add-missing --copy
+
+./configure
+env LDFLAGS=ldflags AM_LDFLAGS=am_ldflags libmod1_la_LDFLAGS=lm1_la_ldflags \
+    CFLAGS=cflags AM_CFLAGS=am_cflags prg2_CFLAGS=prg2_cflags \
+    $MAKE -e print >output 2>&1
+cat output
+grep '1BEG: libmod1.la mod2.la :END1' output
+grep '2BEG: mod2.la :END2' output
+grep '3BEG:.* am_cflags cflags .*lm1_la_ldflags ldflags.* :END3' output
+grep '3BEG: .*am_ldflags.* :END3' output && exit 1
+grep '4BEG: :END4' output
+grep '5BEG: :END5' output
+grep '6BEG:.* prg2_cflags cflags .*am_ldflags ldflags.* :END6' output
+grep '6BEG: .*am_cflags.* :END6' output && exit 1
+$MAKE


-- 
Alexandre Duret-Lutz





reply via email to

[Prev in Thread] Current Thread [Next in Thread]