[CLN-list] future GCC 4.3 and modules.h

Richard B. Kreckel kreckel at ginac.de
Mon Dec 17 09:09:21 CET 2007


Hello Ralf,

Ralf Wildenhues wrote:
> * 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 at 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
>  ])

I don't see how your patch can work. With -fPIC, we'll have to write 
_GLOBAL__I_foo.cc, alright, but without -fPIC, we'll have to stick to 
_GLOBAL__I_func. Your patch defines the macro 
CL_GLOBAL_CONSTRUCTOR_SUFFIX(module) but does not distinguish between 
these two cases. So, if you ./configure --enable-shared --enable-static, 
as is the default, either the shared or the static library will not 
work. Somehow, we must distinguish between the two cases, and I don't 
see how it can be done without some #if defined(PIC) sections.

Can you try ./configure --disable-shared && make check, please?

Please do remote-beat me if it works and I should have tried.  :-/

Cheers
   -richy.
-- 
Richard B. Kreckel
<http://www.ginac.de/~kreckel/>


More information about the CLN-list mailing list