Mathieu, based on your reaction on the other thread, I reworked my patch.
This supersedes my other patch, "[PATCH] new option: object-shortname".
It is functionally the
same but does not introduce a new option, but ties the behavior to
subdir-objects instead. In
addition I made an additional bug fix and extended the test suite.
Please merge.
Commit message follows:
With the %reldir% feature, object file names can become very long,
because the file names
are prefixed with the %canon_reldir% substitution. The reason is to
achieve unique object
file names when target-specific CFLAGS or similar are used. When
subdir-objects is also
in effect, these long file names are also placed in potentially deep
subdirectories.
But with subdir-objects this is unecessary, since uniqueness of the
object file names
is already achieved by placing them next to the unique source files.
Therefore, this changes strips paths components, that are caused by
%canon_reldir% or
otherwise, from the object file names. The object file name is prefixed
by the target in
case of target-specific CFLAGS. As a result, the build tree looks less
scary and many
cases where $var_SHORTNAME was necessary can now be avoided. Remember
that the use of
$var_SHORTNAME is discouraged (and is not always an option since it does
not work inside
conditionals).
Example:
previously:
sub/Makefile.am:
AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS += %D%/foo
%C%_foo_CFLAGS = $(AM_CFLAGS) -g
resulted in objects:
sub/sub_foo-foo.o
now object file name is:
sub/foo-foo.o
From 893ec001bf04a64e3f0ce56906e75590db17fa9c Mon Sep 17 00:00:00 2001
From: Thomas Martitz <kugel@rockbox.org>
Date: Mon, 13 Mar 2017 12:41:59 +0100
Subject: [PATCH] Shorter object file names under subdir-objects
With the %reldir% feature, object file names can become very long, because the file names
are prefixed with the %canon_reldir% substitution. The reason is to achieve unique object
file names when target-specific CFLAGS or similar are used. When subdir-objects is also
in effect, these long file names are also placed in potentially deep subdirectories.
But with subdir-objects this is unecessary, since uniqueness of the object file names
is already achieved by placing them next to the unique source files.
Therefore, this changes strips paths components, that are caused by %canon_reldir% or
otherwise, from the object file names. The object file name is prefixed by the target in
case of target-specific CFLAGS. As a result, the build tree looks less scary and many
cases where $var_SHORTNAME was necessary can now be avoided. Remember that the use of
$var_SHORTNAME is discouraged (and is not always an option since it does not work inside
conditionals).
Example:
previously:
sub/Makefile.am:
AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS += %D%/foo
%C%_foo_CFLAGS = $(AM_CFLAGS) -g
resulted in objects:
sub/sub_foo-foo.o
now object file name is:
sub/foo-foo.o
---
NEWS | 6 +++
bin/automake.in | 31 +++++++++++++-
t/list-of-tests.mk | 1 +
t/subdir-objects-objname.sh | 100 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 137 insertions(+), 1 deletion(-)
create mode 100644 t/subdir-objects-objname.sh
diff --git a/NEWS b/NEWS
index af904d4..1d564e9 100644
--- a/NEWS
+++ b/NEWS
@@ -64,6 +64,12 @@
New in 1.16:
+* Miscellaneous changes
+
+ - When subdir-objects is in effect, Automake will now construct shorter
+ object file names. This should make the use of $var_SHORTNAME is unecessary
+ in many cases. $var_SHORTNAME is discouraged anyway.
+
* Bugs fixed:
- Automatic dependency tracking has been fixed to work also when the
diff --git a/bin/automake.in b/bin/automake.in
index 09a1c95..44255a0 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -1562,6 +1562,16 @@ sub check_libobjs_sources
}
}
+# http://linux.seindal.dk/2005/09/09/longest-common-prefix-in-perl/
+sub longest_common_prefix {
+ my $prefix = shift;
+
+ for (@_)
+ {
+ chop $prefix while (! /^$prefix/);
+ }
+ return $prefix;
+}
# @OBJECTS
# handle_single_transform ($VAR, $TOPPARENT, $DERIVED, $OBJ, $FILE, %TRANSFORM)
@@ -1710,8 +1720,27 @@ sub handle_single_transform
# name that is too long for losing systems, in
# some situations. So we provide _SHORTNAME to
# override.
-
+ # If subdir-object is in effect, it's not necessary to
+ # use the complete 'DERIVED_OBJECT' since objects are
+ # placed next to their source file. Therefore it is already
+ # unique (within that directory). Thus, we strip the directory
+ # components of 'DERIVED_OBJECT' (that quite likely the result from
+ # %canon_reldir%/%C% usage). This enables avoiding explicit _SHORTNAME
+ # unecessary in many cases.
my $dname = $derived;
+ if ($directory ne '' && option 'subdir-objects')
+ {
+ # At this point, we don't clear information about what parts
+ # of $derived are truly path components. We can determine
+ # by comparing against the canonicalization of $directory.
+ # And if $directory is empty there is nothing to strip anyway.
+ my $canon_dirname = canonicalize ($directory) . "_";
+ my @names = ($derived, $canon_dirname);
+ my $prefix = longest_common_prefix (@names);
+ # After canonicalization, "_" separates directories, thus use
+ # everything after the the last separator.
+ $dname = substr ($derived, rindex ($prefix, "_")+1);
+ }
my $var = var ($derived . '_SHORTNAME');
if ($var)
{
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index defca13..1e9f86f 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -1046,6 +1046,7 @@ t/subdir-with-slash.sh \
t/subdir-subsub.sh \
t/subdir-distclean.sh \
t/subdir-keep-going-pr12554.sh \
+t/subdir-objects-objname.sh \
t/subobj.sh \
t/subobj2.sh \
t/subobj4.sh \
diff --git a/t/subdir-objects-objname.sh b/t/subdir-objects-objname.sh
new file mode 100644
index 0000000..6839aef
--- /dev/null
+++ b/t/subdir-objects-objname.sh
@@ -0,0 +1,100 @@
+#! /bin/sh
+# Copyright (C) 1996-2015 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 <http://www.gnu.org/licenses/>.
+
+# Test to make sure the object-shortname option works as advertised
+
+. test-init.sh
+
+mkdir -p one/one one/two/sub one/three
+
+cat >> configure.ac << 'END'
+AC_PROG_CC
+AC_OUTPUT
+END
+
+# Files required because we are using '--gnu'.
+: > INSTALL
+: > NEWS
+: > README
+: > COPYING
+: > AUTHORS
+: > ChangeLog
+
+cat > Makefile.am << 'END'
+AUTOMAKE_OPTIONS = subdir-objects
+include one/Makefile.inc
+END
+
+cat > one/Makefile.inc << 'END'
+noinst_PROGRAMS =
+include %D%/one/Makefile.inc
+include %D%/two/Makefile.inc
+include %D%/three/Makefile.inc
+END
+
+cat > one/one/Makefile.inc << 'END'
+noinst_PROGRAMS += %D%/test
+%C%_test_CFLAGS = $(AM_CFLAGS)
+%C%_test_SOURCES = %D%/test.c
+END
+
+cat > one/one/test.c << 'END'
+int main()
+{
+ return 0;
+}
+END
+
+cat > one/two/Makefile.inc << 'END'
+noinst_PROGRAMS += %D%/test
+%C%_test_CFLAGS = $(AM_CFLAGS)
+%C%_test_SOURCES = %D%/test.c
+%C%_test_SOURCES += %D%/sub/test.c
+END
+
+cat > one/two/test.c << 'END'
+int main()
+{
+ return 0;
+}
+END
+
+: > one/two/sub/test.c
+
+cat > one/three/Makefile.inc << 'END'
+noinst_PROGRAMS += %D%/my_test
+%C%_my_test_CFLAGS = $(AM_CFLAGS)
+%C%_my_test_SOURCES = %D%/my_test.c
+END
+
+cat > one/three/my_test.c << 'END'
+int main()
+{
+ return 0;
+}
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE --gnu
+
+./configure
+$MAKE -f Makefile \
+ && test -f one/one/test-test.o && test ! -f one/one/one_two_test-test.o \
+ && test -f one/two/test-test.o && test ! -f one/two/one_two_test-test.o \
+ && test -f one/two/sub/test-test.o && test ! -f one/two/sub/one_two_test-test.o \
+ && test -f one/three/my_test-my_test.o && test ! -f one/three/one_three_my_test-my_test.o
+$MAKE -f Makefile clean
--
2.7.4