Subject: bug#13378: [IMPORTANT] Make the 'subdir-objects' setup the default, and only available one

From: Stefano Lattarini <[email-masked]>
Date: Tue, 08 Jan 2013 20:20:35 +0100

[+cc automake-patches]

Reference:
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13378#44>

On 01/08/2013 05:00 PM, Nick Bowler wrote:
> On 2013-01-08 16:15 +0100, Stefano Lattarini wrote:
>> On 01/08/2013 03:53 PM, Nick Bowler wrote:
> [...]
>>> I don't think AM_PROG_CC_C_O is optional at all when subdir-objects is
>>> enabled.
>>
>> I seem to recall differently (in fact, in Automake-NG, 'subdir-objects'
>> has already been made mandatory, and that didn't require adding
>> AM_PROG_CC_C_O to all the configure.ac of tests doing compilation of
>> C files).  To be really sure, though, I'll have to double-check.  If
>> you are right, we should try to avoid requiring AM_PROG_CC_C_O for
>> projects that do not actually need it (that is, that don't use per-target
>> flags and don't have sources in subdirectories, independently of whether
>> they set the 'subdir-objects' option or not).
> 
> That would be fine, but I wonder if the code to "optimize" subdir-objects
> would actually be any simpler than just keeping subdir-objects as an
> option...
>
I think yes.  Also, this discussion has already uncovered at least one
bug in automake (see below), so it's good keeping the ball rolling on
this, IMO.

>>> Even with a single source file in a the same directory as the
>>> Makefile, Automake is generating a suffix rule that looks like this:
>>>
>>>   .c.o:
>>>   [...]
>>>   @am__fastdepCC_FALSE@	$(COMPILE) -c -o $@ $<
>>>
>>> which looks like it's using -c and -o together to me.
>>
>> This seems indeed wrong.  Can you send a minimal reproducer for this
>> issue?
> 
> Well, the rule itself does not look wrong.  The -o $@ is required for
> this suffix rule to work properly with subdir-objects -- otherwise, the
> suffix rule would have the compiler place its output in the working
> directory which is even more wrong.
> 
Unless the source is in the the current directory.  Which is why, even
when the 'subdir-objects' option was active, Automake didn't complain
if AM_PROG_CC_C_O wasn't invoked, *if* it could determine that all the
source files were in the "current" directory.  Good in theory, but as
you've discovered below, wrong in practice ...

> But anyway, here's the test case I used (I've not had a chance to
> install 1.13 yet, so I only tested it on 1.11.6 and 1.12.6):
> 
>   % cat >configure.ac <<'EOF'
> AC_INIT([test], [0])
> AM_INIT_AUTOMAKE([foreign subdir-objects])
> AC_PROG_CC
> AC_CONFIG_FILES([Makefile])
> AC_OUTPUT
> EOF
>
Yeah, I can reproduce the issue :-(  See test case below, which I
will commit shortly (comments are welcome).

It is indeed a bug that Automake does not require AM_PROG_CC_C_O but
uses "-c -o" anyway in the generated rules.  This should be fixed in
1.13.2.  I will elaborate further in the upcoming reply to Eric's
last message.

>   % cat >Makefile.am <<'EOF'
> bin_PROGRAMS = foo
> EOF
> 
>   % cat >foo.c <<'EOF'
> int main(void) { return 0; }
> EOF
> 
>>> So if subdir-objects is made mandatory, AM_PROG_CC_C_O will become
>>> mandatory as well, so AM_INIT_AUTOMAKE may as well just call it
>>> automatically.
>>
>> That would be overkill, since AM_PROG_CC_C_O is only required by
>> projects doing C compilation.  Also, IIRC, that macro needs to be
>> called after AC_PROG_CC, while AM_INIT_AUTOMAKE is typically invoked
>> before AC_PROG_CC.
> 
> These are very good points that I had not considered.  But I don't
> think they are unsurmountable.  It should be straightforward to have
> AM_INIT_AUTOMAKE arrange (using AC_CONFIG_COMMANDS_PRE) for
> AM_PROG_CC_C_O to be called later, and only if it's appropriate to
> do so.  I can probably cook up an example later.
>
If you feel like doing so, it would be welcome.  A patch would be
even more so ;-)

>> In addition, AM_PROG_CC_C_O is not required by projects that don't
>> care about catering to inferior compilers.
> 
> Since the AC_PROG_CC_C_O test is so trivial, I don't think Automake
> should should care about catering to projects that don't care about
> catering to inferior compilers.
>
After reviewing the AC_PROG_CC_C_O implementation, I agree.

> If such projects really, really want to
> avoid the test, they can do m4_define([AM_PROG_CC_C_O]).
>
Agreed.

>> In conclusion, even if you are right in the first part of your mail,
>> the sanest policy is to simply continue to give a warning in the
>> "portability" category if AM_PROG_CC_C_O is not used in a project
>> doing C compilation.
> 
> Hm, I think the sanest policy is for Automake to automatically do the
> right thing when it is possible to do so.
> 
Alas, you are right again -- more work for us to do :-)

Thanks,
  Stefano

---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ----

>From d3b48d5e1d9c50972340a978a0c9cea2154b562e Mon Sep 17 00:00:00 2001
Message-Id: <d3b48d5e1[email-masked]>
From: Stefano Lattarini <[email-masked]>
Date: Tue, 8 Jan 2013 20:19:04 +0100
Subject: [PATCH] coverage: compile rules used "-c -o" also with losing
 compilers

If the 'subdir-objects' option is used, Automake-generated rules for
C compilation pass both the "-c" and "-o" options to the C compiler,
*unconditionally*.  There are some compilers that choke on such an
usage, but the AM_PROG_CC_C_O macro takes care of them (it does so by
redefining $CC to use the Automake-provided 'compile' wrapper script
automatically, if a losing compiler is detected at configure runtime).

Unfortunately, in case the 'subdir-objects' option is specified in a
Makefile.am, but all the source files resided anyway in the top-level
directory (relative to the Makefile.am), Automake do *not* complain
if AM_PROG_CC_C_O wasn't invoked in 'configure.ac' -- all the while
still passing "-c -o" to the compiler invocations.  This could cause
compilation failures with losing compilers if the user forget to call
AM_PROG_CC_C_O in 'configure.ac' (and Automake would not warn him of
the issue).

Expose this bug in the testsuite.

Issue identified by Nick Bowler in the discussion on automake bug#13378:
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13378#35>
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13378#44>

* t/ccnoco4.sh: New test.
* t/list-of-tests.mk: List it.

Signed-off-by: Stefano Lattarini <[email-masked]>
---
 t/ccnoco4.sh       | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 t/list-of-tests.mk |  1 +
 2 files changed, 71 insertions(+)
 create mode 100755 t/ccnoco4.sh

diff --git a/t/ccnoco4.sh b/t/ccnoco4.sh
new file mode 100755
index 0000000..54b857a
--- /dev/null
+++ b/t/ccnoco4.sh
@@ -0,0 +1,70 @@
+#! /bin/sh
+# Copyright (C) 2001-2013 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/>.
+
+# Check that Automake doesn't pass "-c -o" to  losing compiler when
+# the 'subdir-objects' is used but sources are only present in the
+# top-level directory.  Reported by Nick Bowler in the discussion on
+# automake bug#13378:
+# <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13378#35>
+# <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13378#44>
+
+required=gcc
+. test-init.sh
+
+# We deliberately do not call AM_PROG_CC_C_O here.
+cat >> configure.ac << 'END'
+AC_PROG_CC
+$CC --version; $CC -v; # For debugging.
+AC_OUTPUT
+END
+
+cat > Makefile.am << 'END'
+AUTOMAKE_OPTIONS = subdir-objects
+bin_PROGRAMS = foo bar
+bar_SOURCES = foo.c
+END
+
+echo 'int main (void) { return 0; }' > foo.c
+
+cat > Mycomp << END
+#!/bin/sh
+
+case " \$* " in
+ *\ -c*\ -o* | *\ -o*\ -c*)
+    exit 1
+    ;;
+esac
+
+# Use '$CC', not 'gcc', to honour the compiler chosen
+# by the testsuite setup.
+exec $CC "\$@"
+END
+
+chmod +x Mycomp
+
+# Make sure the compiler doesn't understand '-c -o'.
+CC=$(pwd)/Mycomp
+export CC
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE --copy --add-missing
+
+./configure
+$MAKE
+$MAKE distcheck
+
+:
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index f3e9963..e0d86b7 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -209,6 +209,7 @@ t/canon-name.sh \
 t/ccnoco.sh \
 t/ccnoco2.sh \
 t/ccnoco3.sh \
+t/ccnoco4.sh \
 t/check.sh \
 t/check2.sh \
 t/check4.sh \
-- 
1.8.1.rc3.192.g2d0029e