
On Sun, Jul 10, 2005 at 09:45:25AM +0200, "Martin v. Löwis" wrote:
Christoph Ludwig wrote:
I'll describe it once more: *If* a program is compiled with the C++ compiler, is it *then* possible to still link it with the C compiler? This is the question this test tries to answer.
The keyword here is "tries"
Any such test would only "try": to really determine whether this is necessary for all possible programs, one would have to test all possible programs. Since there is an infinite number of programs, this test could take a while.
Sure. You cannot write a test that gives the correct result for all platforms you can think of, covering every compiler / linker quirk. I never claimed that is possible. My point is: The test implemented in the 2.4.1 configure script gives a wrong result if your platform happens to be x86 Linux with ELF binaries and g++ 4.0.
The original test, on the original system, would cause __main to be undefined, and then decide to use C++. For a long time, on systems that don't use collect2, the test *correctly* determined that linking with g++ was not necessary.
It is only recent changes to g++ that break the test, namely the introduction of this __gxx_personality_v0 thing.
The test broke due to a change in GCC 4.0, but the "__gxx_personality_v0 thing" was introduced long before. It is merely a symptom. I ran the tests with GCC 3.3.1, 3.4.2, and 4.0.0. Here are the results: GCC version 1 TU 2 TUs 3.3.1 g++ g++ 3.4.2 g++ g++ 4.0.0 gcc g++ (1 TU: test with one translation unit, as in Python 2.4.1. 2 TUs: test with two translation units, as in my last posting. g++ / gcc: test indicates linking the executable requires g++ / gcc, respectively.) With GCC 3.3.1 and 3.4.2, linking of the executable conftest in the 1 TU test fails because of an unresolved symbol __gxx_personality_v0. Therefore, python is linked with g++. The change that makes GCC 4.0.0 break the 1 TU test is that the compiler apparently does a better job eliminating unreachable code. In the 1 TU test, it recognizes __gxx_personality_v0 (or the code that refers to this symbol) is unreachable and removes it. It seems there are no other symbols left that depend on libstdc++ so suddenly conftest can be linked with gcc.
- my bug report #1189330 exihibts that the test fails to do its job. And looking at the test that's certainly no surprise:
However, it *is* a surprise that your modified test fixes the problem.
Note that there is *no* reference to any symbol in another TU. The compiler can detect that foo() won't throw any exceptions, that there is no need for RTTI and whatever else the C++ runtime provides. Consequently, the object file produced by g++ does not contain any reference to symbols in libstdc++.
You are assuming implementation details here. I have seen implementations of C++ (eg. g++ with collect2) where the test determines that linking with C++ is necessary (because __main was undefined), as well as systems where the test decides *correctly* that linking with C++ is not necessary (e.g. gcc 2.x on an ELF system). That some C++ compiler introduces the C++ runtime if some C function may throw an exception is a very specific detail of this C++ compiler.
I am not aware of any rule that makes the following program ill-formed: // in a.cc: extern "C" void foo(); int main() { foo(); } // in b.cc extern "C" void foo() { throw 1; } Provided the compiler does not do optimizations across translation units, it has no way to determine in a.cc whether foo() is really a C function (i.e., compiled by a C compiler) or a C++ function with "C" linkage. I think a conforming C++ compiler has to provide for the case that foo() might throw. It was a very specific detail of gcc 2.x if it failed to do so. (A venial omission, I admit.) But I digress. It's not that important for our discussion whether a C++ compiler must / should / is allowed to add exception handling code to the call of an extern "C" function. The point is that some do *unless* they see the function definition. I contend the test involving two TUs matches more closely the situation with ccpython.cc than the current test. I do not claim the 2 TUs test will cover all possible scenarios. I am not even sure this decision should be left to an automated test. Because if the test breaks for some reason then the user is left with a linker error that is time-consuming to track down.
Of course, if you insist on this "dependency optimization" then you can try to fix Python's configure.in by using the second test above. But I would still not trust it to cover all configurations on all platforms supported by Python.
Of couse not. This is just autoconf: it does not allow magical porting to all possible future operating systems. Instead, from time to time, explicit porting activity is necessary. This is not just about this specific detail, but about many other details. Each new operation system, library, or compiler version might break the build process.
Instead of having yet another test in configure.in that may break on a new platform and that needs maintenance wouldn't it be better to assume that --with-cxx implies linking with the C++ compiler and telling users how to override this assumption? Would it cause so much inconvenience to users provided the explanation of --with-cxx in the README would be modified? I think of an explanation along the lines of: --with-cxx=<compiler>: If you plan to use C++ extension modules, then on some platform you need to compile python's main() function with the C++ compiler. With this option, make will use <compiler> to compile main() *and* to link the python executable. It is likely that the resulting executable depends on the C++ runtime library of <compiler>. Note there are platforms that do not require you to build Python with a C++ compiler in order to use C++ extension modules. E.g., x86 Linux with ELF shared binaries and GCC 3.x, 4.x is such a platform. We recommend that you configure Python --without-cxx on those platforms to avoid unnecessary dependencies. If you need to compile main() with <compiler>, but your platform does not require that you also link the python executable with <compiler> (e.g., <example platform>), then set LINKCC='$(PURIFY) $(CC)' prior to calling make. Then the python executable will not depend on the C++ runtime library of <compiler>. BTW, I'd also change the short explanation output by `configure --help'. Something like: AC_HELP_STRING(--with-cxx=<compiler>, use <compiler> to compile and link main()) In Python 2.4.1, the help message says "enable C++ support". That made me use this option even though it turned out it is not necessary on my platform. Regards Christoph -- http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/cludwig.html LiDIA: http://www.informatik.tu-darmstadt.de/TI/LiDIA/Welcome.html