[Python-Dev] [C++-sig] GCC version compatibility
Christoph Ludwig
cludwig at cdc.informatik.tu-darmstadt.de
Sun Jul 10 14:54:59 CEST 2005
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
More information about the Python-Dev
mailing list