When provided with a spurious header filename on the command line, gcc updates the output file's timestamp even if compilation fails. Re-invoking make consequently produces a message that the target is up to date. The target may be a shared library or executable. This problem was previously reported to binutils (http://sourceware.org/bugzilla/show_bug.cgi?id=11977) and closed as invalid, "not a binutils bug". Consider two files: ldtest.h (empty, not included), and ldtest.C: $ cat ldtest.C int main( int argc, char *argv[] ) { return 0; } Build it, ruin the source, build it (fails), build it again (succeeds): $ make ldtest.borked c++ -o ldtest.borked ldtest.C ldtest.h $ make break <ldtest.C sed 's/return/r eturn/' > ldtest.c mv ldtest.c ldtest.C $ make ldtest.borked c++ -o ldtest.borked ldtest.C ldtest.h ldtest.C: In function ‘int main(int, char**)’: ldtest.C:4: error: ‘r’ was not declared in this scope ldtest.C:4: error: expected `;' before ‘eturn’ make: *** [ldtest.borked] Error 1 $ make ldtest.borked make: `ldtest.borked' is up to date. $ stat ldtest.C ldtest.borked | grep -E 'ldtest|Change' File: `ldtest.C' Change: 2010-09-03 12:56:18.140130000 -0400 File: `ldtest.borked' Change: 2010-09-03 12:56:24.168658000 -0400 If ldtest.h is not on the command line, the binary is not updated: $ make fix <ldtest.C sed 's/r eturn/return/' > ldtest.c mv ldtest.c ldtest.C $ make ldtest c++ -o ldtest ldtest.C $ make break <ldtest.C sed 's/return/r eturn/' > ldtest.c mv ldtest.c ldtest.C $ make ldtest c++ -o ldtest ldtest.C ldtest.C: In function ‘int main(int, char**)’: ldtest.C:4: error: ‘r’ was not declared in this scope ldtest.C:4: error: expected `;' before ‘eturn’ make: *** [ldtest] Error 1 $ make ldtest c++ -o ldtest ldtest.C ldtest.C: In function ‘int main(int, char**)’: ldtest.C:4: error: ‘r’ was not declared in this scope ldtest.C:4: error: expected `;' before ‘eturn’ make: *** [ldtest] Error 1 $ stat ldtest.C ldtest | grep -E 'ldtest|Change' File: `ldtest.C' Change: 2010-09-03 13:05:18.469643000 -0400 File: `ldtest' Change: 2010-09-03 13:05:15.407893000 -0400 "c++ -v" doesn't show collect2 being invoked. The problem might be caused by the way gcc invokes cc1plus. I wonder about "--output-pch= ldtest", below: $ c++ -o ldtest ldtest.C ldtest.h -v Using built-in specs. Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux Thread model: posix gcc version 4.1.2 20080704 (Red Hat 4.1.2-44) /usr/libexec/gcc/x86_64-redhat-linux/4.1.2/cc1plus -quiet -v -D_GNU_SOURCE ldtest.C -quiet -dumpbase ldtest.C -mtune=generic -auxbase ldtest -version -o /tmp/ccI315nM.s ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../x86_64-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2 /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/x86_64-redhat-linux /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/backward /usr/local/include /usr/lib/gcc/x86_64-redhat-linux/4.1.2/include /usr/include End of search list. GNU C++ version 4.1.2 20080704 (Red Hat 4.1.2-44) (x86_64-redhat-linux) compiled by GNU C version 4.1.2 20080704 (Red Hat 4.1.2-44). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 2d02d8750f9b337bb19a7dd5b4e2167e ldtest.C: In function ‘int main(int, char**)’: ldtest.C:4: error: ‘r’ was not declared in this scope ldtest.C:4: error: expected `;' before ‘eturn’ /usr/libexec/gcc/x86_64-redhat-linux/4.1.2/cc1plus -quiet -v -D_GNU_SOURCE ldtest.h -quiet -dumpbase ldtest.h -mtune=generic -auxbase ldtest -version -o /tmp/ccI315nM.s --output-pch= ldtest ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../x86_64-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2 /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/x86_64-redhat-linux /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/backward /usr/local/include /usr/lib/gcc/x86_64-redhat-linux/4.1.2/include /usr/include End of search list. GNU C++ version 4.1.2 20080704 (Red Hat 4.1.2-44) (x86_64-redhat-linux) compiled by GNU C version 4.1.2 20080704 (Red Hat 4.1.2-44). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 2d02d8750f9b337bb19a7dd5b4e2167e While one might argue GIGO, including extra filenames on the command line is an easy mistake to make. I submit gcc should make every effort not to produce invalid binaries.
Please provide a complete testcase, including Makefile.
The problem is the specs is producing the output file for the PCH. [andrew-pinskis-computer:~] apinski% file t.out t.out: GCC precompiled header (version 013) for C Related to PR 33980.
This has enough information to reproduce the bug. Thanks again for the testcase.
(In reply to comment #1) > Please provide a complete testcase, including Makefile. The description has enough information to produce the issue. The driver is producing a PCH and an executable with the same output filename.
This is a driver issue. The driver should reject the case where you have a .h file and a source file on the command line.