libtool
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: libtool C++ link bug with -lm functions with Sun Workshop compiler


From: Tim Mooney
Subject: Re: libtool C++ link bug with -lm functions with Sun Workshop compiler
Date: Fri, 21 Mar 2008 14:08:51 -0500 (CDT)
User-agent: Alpine 1.10 (SOC 962 2008-03-14)

In regard to: Re: libtool C++ link bug with -lm functions with Sun Workshop...:

On Wed, Mar 19, 2008 at 07:03:38PM -0500, Tim Mooney wrote:

I think I have discovered a bug in libtool's link behavior with the
Sun Workshop C++ compiler when creating a C++ library that requires libm.
I observed it on x86_64-sun-solaris2.10, but it may also affect the
Workshop C++ compiler on Linux too.  I found it when trying to build
GNU aspell 0.60.5.

What version of Sun C++ are you using?

The C++ from Workshop 12 with patches applied:

$CC -V
CC: Sun C++ 5.9 SunOS_i386 Patch 124864-01 2007/07/25

To answer Bob's previous question, I generally upgrade any project I'm
building to use libtool 1.5.latest, so right now I'm using 1.5.26.

Here's an example.  If you call AC_CHECK_FUNCS(floor) in configure.ac,
configure ends up with shell code that essentially results in the
following in conftest.cpp:


/* Define $ac_func to an innocuous variant, in case <limits.h> declares
 * floor.
   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
#define floor innocuous_floor

/* System header to define __stub macros and hopefully few prototypes,
    which can conflict with char $ac_func (); below.
    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    <limits.h> exists even on freestanding compilers.  */

#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif

#undef floor

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char floor ();
/* The GNU C library defines this for functions which it implements
    to always fail with ENOSYS.  Some functions are actually named
    something starting with __ and the normal name is an alias.  */
#if defined __stub_floor || defined __stub___floor
choke me
#endif
int
main ()
{
return floor ();
  ;
  return 0;
}



If you compile that with CC -v, you'll see what libraries are
automatically added:

$CC -v -o conftest conftest.cpp
###     command line files and options (expanded):
### -v -o conftest conftest.cpp
### CC: Note: NLSPATH =
/opt/SUNWspro/prod/bin/../lib/locale/%L/LC_MESSAGES/%N.cat:/opt/SUNWspro/prod/bin/../../lib/locale/%L/LC_MESSAGES/%N.cat
/opt/SUNWspro/prod/bin/ccfe -y-o -yconftest.o -y-fbe -y/opt/SUNWspro/prod/bin/fbe 
-y-xarch=generic -y-xtab -y-verbose -O0 -ptf /tmp/16666%1.%2 -ptx /opt/SUNWspro/prod/bin/CC -ptk 
"-v  -xs " -D__SunOS_5_10 -D__SUNPRO_CC=0x590 -Dunix -Dsun -Di386 -D__i386 -D__unix 
-D__sun -D__SunOS -D__BUILTIN_VA_ARG_INCR -D__SVR4 -D__SUNPRO_CC_COMPAT=5 
-xdbggen=no%stabs+dwarf2 -y-s -xdbggen=incl -I-xbuiltin -xldscope=global 
-instlib=/opt/SUNWspro/prod/lib/libCstd.a -I/opt/SUNWspro/prod/include/CC/Cstd 
-I/opt/SUNWspro/prod/include/CC -I/opt/SUNWspro/prod/include/CC/rw7 
-I/opt/SUNWspro/prod/include/cc -y-comdat conftest.cpp -s /tmp/ccfe.16666.0.s 
>&/tmp/ccfe.16666.1.err
rm /tmp/ccfe.16666.0.s
### CC: Note: LD_LIBRARY_PATH = (null)
### CC: Note: LD_RUN_PATH     = (null)
### CC: Note: LD_OPTIONS = (null)
ln -s /opt/SUNWspro/prod/lib /tmp/lib_link.16666
ln -s /opt/SUNWspro/prod/lib /tmp/lib_base_link.16666
/usr/ccs/bin/ld -u __1cH__CimplKcplus_init6F_v_ 
-zld32=-S/tmp/lib_base_link.16666/libldstab_ws.so 
-zld64=-S/tmp/lib_base_link.16666/amd64/libldstab_ws.so 
-zld32=-S/tmp/lib_base_link.16666/libCCexcept.so.1 
-R/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib:/usr/ccs/lib:/lib:/usr/lib -o conftest 
/opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/CCrti.o 
/opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/values-xa.o -Y 
P,/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib/rw7:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib
 conftest.o -lCstd -lCrun -lm -lc /opt/SUNWspro/prod/lib/CCrtn.o 
/opt/SUNWspro/prod/lib/crtn.o >&/tmp/ld.16666.2.err 
/opt/SUNWspro/prod/bin/stdlibfilt -stderr </tmp/ccfe.16666.1.err 
/opt/SUNWspro/prod/bin/fbe -s -o conftest.o -warn=%none -Qy
/tmp/yabeAAANPayJG
rm /tmp/yabeAAANPayJG
rm /tmp/ccfe.16666.1.err
rm conftest.o
rm /tmp/lib_link.16666
rm /tmp/lib_base_link.16666
rm /tmp/ld.16666.2.err


If you compile the same file using -library=stlport4 (instead of Cstd), CC
still automatically adds -lm (and -lrt, much to my surprise):

$CC -library=stlport4 -v -o conftest conftest.cpp
###     command line files and options (expanded):
### -v -o conftest conftest.cpp -library=no%Cstd,stlport4
### CC: Note: NLSPATH =
/opt/SUNWspro/prod/bin/../lib/locale/%L/LC_MESSAGES/%N.cat:/opt/SUNWspro/prod/bin/../../lib/locale/%L/LC_MESSAGES/%N.cat
/opt/SUNWspro/prod/bin/ccfe -y-o -yconftest.o -y-fbe -y/opt/SUNWspro/prod/bin/fbe 
-y-xarch=generic -y-xtab -y-verbose -O0 -ptf /tmp/16672%1.%2 -ptx /opt/SUNWspro/prod/bin/CC -ptk 
"-library=stlport4 -v -xs " -D__SunOS_5_10 -D__SUNPRO_CC=0x590 -Dunix -Dsun -Di386 
-D__i386 -D__unix -D__sun -D__SunOS -D__BUILTIN_VA_ARG_INCR -D__SVR4 -D__SUNPRO_CC_COMPAT=5 
-xdbggen=no%stabs+dwarf2 -y-s -xdbggen=incl -I-xbuiltin -xldscope=global 
-instlib=/opt/SUNWspro/prod/lib/stlport4/libstlport.a -I/opt/SUNWspro/prod/include/CC/stlport4 
-I/opt/SUNWspro/prod/include/CC -I/opt/SUNWspro/prod/include/CC/rw7 
-I/opt/SUNWspro/prod/include/cc -y-comdat conftest.cpp -s /tmp/ccfe.16672.0.s 
>&/tmp/ccfe.16672.1.err
rm /tmp/ccfe.16672.0.s
### CC: Note: LD_LIBRARY_PATH = (null)
### CC: Note: LD_RUN_PATH     = (null)
### CC: Note: LD_OPTIONS = (null)
ln -s /opt/SUNWspro/prod/lib /tmp/lib_link.16672
ln -s /opt/SUNWspro/prod/lib /tmp/lib_base_link.16672
/usr/ccs/bin/ld -zld32=-S/tmp/lib_base_link.16672/libldstab_ws.so 
-zld64=-S/tmp/lib_base_link.16672/amd64/libldstab_ws.so 
-zld32=-S/tmp/lib_base_link.16672/libCCexcept.so.1 
-R/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib/stlport4:/opt/SUNWspro/lib:/usr/ccs/lib:/lib:/usr/lib
 -o conftest /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/CCrti.o 
/opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/values-xa.o -Y 
P,/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib/stlport4:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib/rw7:/opt/SUNWspro/prod/lib/stlport4:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib
 conftest.o -lstlport -lrt -lCrun -lm -lc /opt/SUNWspro/prod/lib/CCrtn.o 
/opt/SUNWspro/prod/lib/crtn.o >&/tmp/ld.16672.2.err 
/opt/SUNWspro/prod/bin/stdlibfilt -stderr </tmp/ccfe.16672.1.err 
/opt/SUNWspro/prod/bin/fbe -s -o conftest.o -warn=%none -Qy /tmp/yabeAAAHaaiKG
rm /tmp/yabeAAAHaaiKG
rm /tmp/ccfe.16672.1.err
rm conftest.o
rm /tmp/lib_link.16672
rm /tmp/lib_base_link.16672
rm /tmp/ld.16672.2.err


will always detect sqrt(), because the C++ compiler added `-lm -lc'
behind the scenes.

When libtool is called to generate a C++ library on Solaris, it doesn't
add -lm, though.  It only adds -lc.  That will result in link failures
if functions like sqrt(), floor(), etc. from libm are used by the C++
library.

But if Sun C++ automatically adds -lm -lc, why, with libtool using C++
to link the library, isn't -lm -lc automatically added? Because Sun C++
is creating a library and not a program?

I believe that's exactly correct.  Because a (shared) library is being
built by the C++ compiler, libtool is using "CC -G", and -G implies

               When you use the -G option, the compiler does not
               pass any default -l options to ld. If you want the
               shared library to have a dependency on another
               shared library, you must pass the necessary -l
               option on the command line. For example, if you
               want the shared library to be dependent upon lib-
               Crun, you must pass -lCrun on the command line.

libtool knows this, and there is code in place (which you authored)
to automatically add '-library=Cstd -library=Crun' plus -lc in the event
that '-library=stlport4' is NOT part of CXXFLAGS and you're doing a C++
link.

So although libtool is being very helpful by automatically adding
-library=Cstd -library=Crun -lc when creating a shared library, it is
not adding the same set of libraries that CC alone would add when linking a
program.

Tim
--
Tim Mooney                              address@hidden
Information Technology Services         (701) 231-1076 (Voice)
Room 242-J6, IACC Building              (701) 231-8541 (Fax)
North Dakota State University, Fargo, ND 58105-5164




reply via email to

[Prev in Thread] Current Thread [Next in Thread]