Hello Ralf, 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? What is $lt_compiler_pic_CXX? It doesn't seem to exist.
Index: include/cln/modules.h =================================================================== RCS file: /home/cvs/cln/include/cln/modules.h,v retrieving revision 1.19 diff -u -r1.19 modules.h --- include/cln/modules.h 7 May 2006 21:05:24 -0000 1.19 +++ include/cln/modules.h 26 May 2007 16:44:38 -0000 @@ -219,7 +219,7 @@ }; \ static _CL_REQUIRE_CLASSNAME(module,__LINE__) \ _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__); - #else + #elif 0 // gcc-3.0 -fuse-cxa-atexit doesn't have a single per-module destructor // function anymore. Instead, for each object's static constructor it // executes, it pushes the corresponding object's destructor onto a list. @@ -255,9 +255,42 @@ }; \ static _CL_REQUIRE_CLASSNAME(module,__LINE__) \ _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__); - #endif #define _CL_REQUIRE_CLASSNAME(module,line) __CL_REQUIRE_CLASSNAME(module,line) #define __CL_REQUIRE_CLASSNAME(module,line) cl_module__##module##__##line + #else + #define CL_PROVIDE(module) \ + extern "C" void cl_module__##module##__ctorend (void); \ + CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend) \ + CL_GLOBALIZE_CTORDTOR_LABEL( \ + ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \ + #module ".cc") \ + static int cl_module__##module##__counter; \ + struct cl_module__##module##__controller { \ + inline cl_module__##module##__controller () \ + { if (cl_module__##module##__counter++) \ + { CL_JUMP_TO(cl_module__##module##__ctorend); } \ + } \ + }; \ + static cl_module__##module##__controller cl_module__##module##__ctordummy; + #define CL_PROVIDE_END(module) \ + struct cl_module__##module##__destroyer { \ + inline cl_module__##module##__destroyer () \ + { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__ctorend"); } \ + }; \ + static cl_module__##module##__destroyer cl_module__##module##__dtordummy; + #define CL_REQUIRE(module) \ + extern "C" void cl_module__##module##__ctor (void) \ + __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX \ + #module ".cc"); \ + struct _CL_REQUIRE_CLASSNAME(module,__LINE__) { \ + inline _CL_REQUIRE_CLASSNAME(module,__LINE__) () \ + { cl_module__##module##__ctor (); } \ + }; \ + static _CL_REQUIRE_CLASSNAME(module,__LINE__) \ + _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__); + #define _CL_REQUIRE_CLASSNAME(module,line) __CL_REQUIRE_CLASSNAME(module,line) + #define __CL_REQUIRE_CLASSNAME(module,line) cl_module__##module##__##line +#endif #else #define CL_PROVIDE(module) #define CL_PROVIDE_END(module)
Cheers -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>