"Martin v. Löwis" firstname.lastname@example.org writes:
David Abrahams wrote:
When I looked into this problem I saw that configure in fact builds a test executable that included an object file compiled with g++. If the link step with gcc succeeds then LINKCC is set as above, otherwise CXX is used. Obviously, on my system this test was successful so configure decided to link with gcc. However, minimal changes to the source of the test program caused the link step to fail. It was not obvious to me at all why the latter source code should cause a dependency on the C++ runtime if the original code does not. My conclusion was that this test is fragile and should be skipped.
Sounds like it. I have never understood what the test was really checking for since the moment it was first described to me, FWIW.
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.
Okay, I understand that. What I have never understood is why that should be an appropriate thing to test for the Python executable. There's no reason to compile any of Python with a C++ compiler.
If Python is built with --with-cxx then it should be linked with CXX as well.
Wrong. The test was introduced in response to complaints that Python unnecessarily links with libstdc++ on some Linux systems.
Apparently it still does.
On these Linux systems, it was well possible to build main() with a C++ compiler
Nobody would need to build Python's main() with a C++ compiler, if you'd just comment out the 'extern "C"'.
and still link the entire thing with gcc. Since main() doesn't use any libstdc++ functionality, and since collect2/__main isn't used, one would indeed expect that linking with CXX is not necessary.
(On ELF based Linux/x86, at least.) That leaves me wondering
- when is --with-cxx really necessary?
I think it's plausible that if you set sys.dlopenflags
This has no relationship at all. --with-cxx is much older than sys.dlopenflags. It is used on systems where main() must be a C++ program for C++ extension modules to work (e.g. some Linux systems).
I have tested Boost.Python and C++ extension modules on a wide variety of Linux systems, and have seen this phenomenon. Everyone who is testing it on Linux is finding that if they build Python --without-cxx, everything works. And, yes, the mechanisms at the very *core* of Boost.Python rely on static initializers being run properly, so if there were anything wrong with that mechanism the tests would be breaking left and right.
I think either the ELF Linux loader changed substantially since 1995, or whoever introduced this test was just confused.
C++ extension modules get their static initializers run when they are loaded by dlopen (or, strictly speaking, sometime between then and the time their code begins to execute) which happens long after main or __main are invoked. The executable doesn't know about these extension modules until they are loaded, and when it loads them it can't get its hooks into anything other than the initmodulename entry point. The executable does not trigger the static initializers; the dynamic loader does. Therefore, it doesn't matter whether the executable is linked with the C++ runtime. An appropriate C++ runtime is linked to the extension module and that is what gets invoked when the module is loaded.