Wrong implicit link flags detected under Ninja generator while using G++
CMakeDetermineCompilerABI
detects the wrong implicitly linked libraries for G++ when using the Ninja generator, namely omitting libstdc++
and libm
whereas the exact same configuration works with the Makefile generator.
The reason for this is as follows: Unlike the Makefile generator, Ninja makes heavy usage of GCC response files. For whatever reason GCC's collect2
link wrapper does not add libstdc++
and libm
to its verbose output when using response files. I'm getting on my local machine with an hello world C++ source:
-
Using
g++ -v @test.rsp -o test
(test.rsp just contains test.o as it does in the case ofCMakeDetermineCompilerABI
)[...] -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1/../../.. @/tmp/ccBcxraE -lgcc_s -lgcc -lc -lgcc_s -lgcc [...]
-
Using
g++ -v test.o -o test
:[...] -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1/../../.. test.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc [...]
I've omitted the remainder of the output as it's identical. I was able to reproduce this behavior using Scientific Linux 7's default GCC 4.8.5, a self compiled GCC 5.4.0, and the default GCC 6.3 binary from ArchLinux. However, the collect2
compile wrapper uses libstdc++
in either case, which can be verified by passing the -Wl,--verbose
flag.
Naturally, the way CMake parses the link flags out of the verbose output in CMakeParseImplicitLinkInfo
will cause it to not detect -lstdc++ -lm
. I haven't been able to find any documentation on such behavior in the GCC manual, it just states that the commands read from the @file should be inserted in its place, but the behavior concerning collect2
or its parameters doesn't seem to be documented. Therefore, I'm not sure whether this qualifies as a bug in GCC (I guess it does?), but given the wide range of affected G++ builds (i.e. all I could try out), I suppose it might be worth it to disable the rspfile
commands for CMakeDetermineCompilerABI
and pass the link line directly instead. By doing that, the output generated from the procedure are identical between the Ninja and Makefile generators.