Hello Richard, Apologies for the long delay, and thanks for the patience. * Richard B. Kreckel wrote on Tue, Dec 04, 2007 at 04:53:37PM CET:
On 2007-07-16, you wrote:
Consider this code snippet:
extern "C" void func () {} __asm__("\t.globl " "_GLOBAL__I_" "func"); static struct S { inline S () { } } S;
On x86_64, with `g++-4.2 -fPIC -c a.cc', this results in | 0000000000000032 T _GLOBAL__I_func
with mainline GCC (what will eventually be 4.3 or some other number), it has | 0000000000000032 t _GLOBAL__I_a.cc
(and of course that will be `T' with the appropriate .globl directive).
This affects .libs/cl_DF_globals.o and some of the other globals objects, and causes a link failure of the examples due to the CL_REQUIRE undefined references (global constructor keyed to ...).
The hack below makes things work with mainline, but still needs to be redone properly, with a configure-time check and so on to not regress on g++ <= 4.2. If you like I can take a stab at writing so; I assume the test should make use of $lt_compiler_pic_CXX and the header file provide different defines based on whether -DPIC was given? (I'm not all that experienced with this stuff, so pointers are greatly appreciated.)
Can you write such a patch? I'm a little confused how to do the switch properly. Would it be bad to just combine #ifdef PIC and a test for __GNUC__ and __GNUC_MINOR__ inside modules.h?
A feature-based test seems nicer to me.
What is $lt_compiler_pic_CXX? It doesn't seem to exist.
Oh sorry, that should've been lt_prog_compiler_pic_CXX, and is set by AC_PROG_LIBTOOL. Here's a proposed patch that seems to do the right thing for me, and otherwise uses the same Autoconf macro style as the other code already in c++-constructors.m4. The macro as of now is fairly CLN-centric in that it hard-codes "cl_module__" and "__firstglobalfun" into the cached value. I tried it with Autoconf 2.59 and HEAD. I will try to build CLN with this, with GCC 4.1.1 and svn HEAD on GNU/Linux x86, but results may take up to a couple of days (so if you're in a hurry you may want to test yourself). Cheers, Ralf 2007-12-16 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> Cater to the fact that g++ 4.3 will use a different naming for the global constructor suffix. * m4/c++-constructors.m4 (CL_GLOBAL_CONSTRUCTORS): Add test for the global constructor suffix, define CL_GLOBAL_CONSTRUCTOR_SUFFIX appropriately. * include/cln/config.h.in: Provide template to be filled in by configure. * include/cln/modules.h (CL_PROVIDE, CL_REQUIRE): Use CL_GLOBAL_CONSTRUCTOR_SUFFIX. Index: include/cln/config.h.in =================================================================== RCS file: /home/cvs/cln/include/cln/config.h.in,v retrieving revision 1.10 diff -u -r1.10 config.h.in --- include/cln/config.h.in 13 Jun 2006 18:31:18 -0000 1.10 +++ include/cln/config.h.in 16 Dec 2007 19:13:38 -0000 @@ -141,6 +141,10 @@ /* Define if a module's global constructor function and global destructor function need to be exported in order to be accessible from other modules. */ #undef CL_NEED_GLOBALIZE_CTORDTOR +/* Define as the suffix of the name of a module's global constructor function */ +#ifndef CL_GLOBAL_CONSTRUCTOR_SUFFIX +#undef CL_GLOBAL_CONSTRUCTOR_SUFFIX +#endif /* CL_CHAR_UNSIGNED */ #ifndef __CHAR_UNSIGNED__ Index: include/cln/modules.h =================================================================== RCS file: /home/cvs/cln/include/cln/modules.h,v retrieving revision 1.20 diff -u -r1.20 modules.h --- include/cln/modules.h 18 Sep 2007 21:56:18 -0000 1.20 +++ include/cln/modules.h 16 Dec 2007 19:13:38 -0000 @@ -231,7 +231,7 @@ CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend) \ CL_GLOBALIZE_CTORDTOR_LABEL( \ ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \ - "cl_module__" #module "__firstglobalfun") \ + CL_GLOBAL_CONSTRUCTOR_SUFFIX(module)) \ static int cl_module__##module##__counter; \ struct cl_module__##module##__controller { \ inline cl_module__##module##__controller () \ @@ -249,7 +249,7 @@ #define CL_REQUIRE(module) \ extern "C" void cl_module__##module##__ctor (void) \ __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \ - "cl_module__" #module "__firstglobalfun"); \ + CL_GLOBAL_CONSTRUCTOR_SUFFIX(module)); \ struct _CL_REQUIRE_CLASSNAME(module,__LINE__) { \ inline _CL_REQUIRE_CLASSNAME(module,__LINE__) () \ { cl_module__##module##__ctor (); } \ Index: m4/c++-constructors.m4 =================================================================== RCS file: /home/cvs/cln/m4/c++-constructors.m4,v retrieving revision 1.1 diff -u -r1.1 c++-constructors.m4 --- m4/c++-constructors.m4 29 Aug 2005 13:18:40 -0000 1.1 +++ m4/c++-constructors.m4 16 Dec 2007 19:13:38 -0000 @@ -95,6 +95,23 @@ if test "$cl_cv_cplusplus_ctorexport" = yes; then AC_DEFINE(CL_NEED_GLOBALIZE_CTORDTOR) fi +AC_CACHE_CHECK([for the global constructor function suffix], +cl_cv_cplusplus_ctorsuffix, [ +cat > conftest.cc << EOF +extern "C" void func () {} +static struct S { + inline S () { } +} S; +EOF +AC_TRY_COMMAND(${CXX-g++} $CXXFLAGS ${lt_prog_compiler_pic_CXX-"-fPIC"} -S conftest.cc) >/dev/null 2>&1 +if grep "${cl_cv_cplusplus_ctorprefix}conftest\.cc" conftest.s >/dev/null; then + cl_cv_cplusplus_ctorsuffix='#module ".cc"' +else + cl_cv_cplusplus_ctorsuffix='"cl_module__" #module "__firstglobalfun"' +fi +rm -f conftest* +]) +AC_DEFINE_UNQUOTED([CL_GLOBAL_CONSTRUCTOR_SUFFIX(module)], [$cl_cv_cplusplus_ctorsuffix]) fi fi ])