Re: g++ and -nostdlib
Le 09/11/13 07:44, Richard PALO a écrit : I believe Chuck is oriented in the right direction. A good example is with -fstack-protector. gcc/g++ knows how to link depending upon whether the platforms libc has SSP support or not. I doubt very much that libtool wants to figure out whether to add the specific libraries necessary for SSP to the link command. It *should* however pass through the provided flags to the compiler driver, and not strip in this case '-fstack-protector'; object of: Bug: linking shared libraries on Cygwin results in undefined references to __stack_chck_guard for code compiled with -fstack-protector In this particular worst case, '-fstack-protector' is stripped, and even if it passed through, the g++ '-nostdlib' defeats the purpose! Just a comment to keep this thread alive, I've been testing this patch since it came out adapted for solaris using libtool 2.4.2 on pkgsrc-current along with the following two patches: [PATCH] Fix linking with -fstack-protector bug#16452: opt_duplicate_compiler_generated_deps is harmful on Solaris The description is available on tech-...@netbsd.org in the thread: libtool, -fstack-protector, -nostdlib, and while we're at it -Bdirect on SunOS Earlier issues with perl and cups involving '-fstack-protector' seem resolved and, as indicated elsewhere, '-pthread' as well (albeit already worked around in many pkgsrc packages or the distros themselves. If there is/are any use case(s) that break with this patch (I believe as Bob feared) they should be explicitly detailed and examined for the cause, otherwise there seems to be more merit in pushing this patch than suffering the current side effects. cheers
Re: g++ and -nostdlib
[re-adding libtool@] On 2013-11-11 16:10, Bob Friesenhahn wrote: On Mon, 11 Nov 2013, Peter Rosin wrote: Quite a lot of effort went into making this work the way it currently does. I realize that, but if it really works or not is a different question :-) Yes, of course. It is obviously primarily working as demonstrated by the massive amount of software linked for years and years using libtool. Right, I wasn't really serious. I.e., as far as I can tell, $LD is not used for linking. $CXX is used, with -nostdlib and some manually detected libs/objects, which end up wrong if different flags (such as -pthread) are used when digging and actually linking. Yes, GCC has known bugs with reporting the libraries which would actually be used based on proposed arguments. It must be the case that GCC maintainers don't consider this to be a bug since GCC has not changed its behavior. Even if GCC did report dependent libs correctly (for the libtool version of correctly), libtool would have a difficult time replicating what libs to actually apply if one project builds a number of libraries/programs with different GCC options. It's a bit fragile by design. Googling a bit more turned up this old quote from Ralf [1] on this subject: BTW, I believe libtool does the -nostdlib stuff because, at least in the past, not using it could cause situations where later libstdc++ would not be found automatically. I think at least for dlopen'ed modules depending on C++ libraries this is still the case (completely untested). That was 8 years ago, even then it appears noone really knew why -nostdlib is used (which is interesting in itself). As far as I am aware, the issue is primarily due to some C++ standard libraries being delivered as static libraries (usually due to C++ exceptions problems) and therefore necessitating being linked to the dependent executable rather than into a shared library (which may then be linked with other shared libraries linked into an executable). This magic is done via information cached in the .la files. And why wouldn't the standard library be picked up again by the compiler driver when linking the dependent executable? Intuiting all the libraries which would be used has been a core tenant of libtool given that it attempts to record all the linkage dependencies in its .la files. I don't understand why it is necessary to relist dependencies that the compiler driver is going to find anyway. Why does libtool need this degree of control? So, someone needs to write some test cases that tries to build a library with --static-libgcc and then use that in a program w/o --static-libgcc (and vice versa), as well as doing some dlopen test with C++ modules to try to deduce if the above problem described by Ralf can still be reproduced (but his wording suggest that it might be subtle). And lastly we might need some test that tries to throw C++ exceptions over DLL boundaries, if that isn't already done by tests/exceptions.at... The tests/exceptions.at tests the ability to catch exceptions thrown from a DLL. It is not uncommon for it to fail with GCC for certain targets due to target-specific libtool bugs or GCC compiler bugs. Even with this test, it very difficult to tell if the C++ exceptions framework is really working. In my experience, C++ exceptions are reliably working with proprietary compilers and sometimes failing with GCC. Ok, so this test sometimes fails even if libtool tries to be clever. Maybe it fails because libtool is too clever? It would be interesting to know if the test continues to fail if libtool just trusts the compiler driver (i.e. with the patch applied). I can't tell, because the test works both with and without the patch for me. In my opinion, this topic is significant enough that it should be discussed on the general libtool list before any decision to rip out the existing special GCC support and treat GCC similar to other compilers. I didn't notice that libtool@ was dropped by Chuck. So, I'm switching to that list instead. Please drop libtool-patches@ next time. Anyway, when I started this thread, my main interest was to understand *why* libtool does the -nostdlib dance. But as I'm not personally affected by it, I'm not really pushing for my patch, it is mainly there to trigger discussion. What I would like to see is some test cases that actually fails when libtool simply trusts GCC to DTRT. Currently the test suite is clean with my patch, at least on Cygwin. If we have some test cases we know what is sacrificed if -nostdlib is dropped. If we can't construct a valid test case that works with -nostdlib, but fails without it, that would be quite telling though... So, can someone conjure up such a test case? I can't, I'd be fumbling and wouldn't know where to start. Cheers, Peter
Re: g++ and -nostdlib
$compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes @@ -6860,9 +6860,9 @@ if test yes != $_lt_caught_CXX_error; then if test yes,no = $GXX,$with_gnu_ld; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo { global: $lib.exp~cat $export_symbols | $SED -e s/\(.*\)/\1;/ $lib.exp~echo local: *; }; $lib.exp~ - $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what hidden libraries, object files and flags are used when @@ -6871,9 +6871,9 @@ if test yes != $_lt_caught_CXX_error; then else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $libobjs $deplibs $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo { global: $lib.exp~cat $export_symbols | $SED -e s/\(.*\)/\1;/ $lib.exp~echo local: *; }; $lib.exp~ - $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what hidden libraries, object files and flags are used when @@ -6979,7 +6979,9 @@ if test yes != $_lt_caught_CXX_error; then ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... -_LT_SYS_HIDDEN_LIBDEPS($1) +if test yes != $GXX; then + _LT_SYS_HIDDEN_LIBDEPS($1) +fi _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) -- 1.7.9
Re: g++ and -nostdlib
On Mon, 11 Nov 2013, Peter Rosin wrote: Quite a lot of effort went into making this work the way it currently does. I realize that, but if it really works or not is a different question :-) Yes, of course. It is obviously primarily working as demonstrated by the massive amount of software linked for years and years using libtool. I.e., as far as I can tell, $LD is not used for linking. $CXX is used, with -nostdlib and some manually detected libs/objects, which end up wrong if different flags (such as -pthread) are used when digging and actually linking. Yes, GCC has known bugs with reporting the libraries which would actually be used based on proposed arguments. It must be the case that GCC maintainers don't consider this to be a bug since GCC has not changed its behavior. Googling a bit more turned up this old quote from Ralf [1] on this subject: BTW, I believe libtool does the -nostdlib stuff because, at least in the past, not using it could cause situations where later libstdc++ would not be found automatically. I think at least for dlopen'ed modules depending on C++ libraries this is still the case (completely untested). That was 8 years ago, even then it appears noone really knew why -nostdlib is used (which is interesting in itself). As far as I am aware, the issue is primarily due to some C++ standard libraries being delivered as static libraries (usually due to C++ exceptions problems) and therefore necessitating being linked to the dependent executable rather than into a shared library (which may then be linked with other shared libraries linked into an executable). This magic is done via information cached in the .la files. Intuiting all the libraries which would be used has been a core tenant of libtool given that it attempts to record all the linkage dependencies in its .la files. So, someone needs to write some test cases that tries to build a library with --static-libgcc and then use that in a program w/o --static-libgcc (and vice versa), as well as doing some dlopen test with C++ modules to try to deduce if the above problem described by Ralf can still be reproduced (but his wording suggest that it might be subtle). And lastly we might need some test that tries to throw C++ exceptions over DLL boundaries, if that isn't already done by tests/exceptions.at... The tests/exceptions.at tests the ability to catch exceptions thrown from a DLL. It is not uncommon for it to fail with GCC for certain targets due to target-specific libtool bugs or GCC compiler bugs. Even with this test, it very difficult to tell if the C++ exceptions framework is really working. In my experience, C++ exceptions are reliably working with proprietary compilers and sometimes failing with GCC. In my opinion, this topic is significant enough that it should be discussed on the general libtool list before any decision to rip out the existing special GCC support and treat GCC similar to other compilers. Bob -- Bob Friesenhahn bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer,http://www.GraphicsMagick.org/
Re: g++ and -nostdlib
On Fri, 8 Nov 2013, Peter Rosin wrote: Hi! There seem to be a longstanding complaint that libtool is using -nostdlib when it links libraries using g++. It interferes with -pthread and I think I have also seen other issues. No one can give a satisfactory explanation why libtool does this, it seems Isn't it because libtool wants to control the order of the linking and assure that all dependencies (including static) are tracked/known and applied at the correct times? It wants to assure that static dependencies are linked into the dependent program rather than into some dependent shared library (and thus causing a problem). It was common (and perhaps still is) for the GNU C++ library to be delivered as a static library for Windows/MinGW because C++ exceptions were not handled properly when thrown by DLLs. Quite a lot of effort went into making this work the way it currently does. First libtool tries to take away all of the libraries which would be added automatically and then it applies the libraries that GCC says it would use at the correct time. Bob -- Bob Friesenhahn bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer,http://www.GraphicsMagick.org/
g++ and -nostdlib
$libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' +$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6383,7 +6383,7 @@ if test yes != $_lt_caught_CXX_error; then ;; *) if test yes = $GXX; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test x$output_objdir/$soname = x$lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test x$output_objdir/$soname = x$lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no @@ -6451,13 +6451,13 @@ if test yes != $_lt_caught_CXX_error; then if test no = $with_gnu_ld; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi @@ -6498,9 +6498,9 @@ if test yes != $_lt_caught_CXX_error; then *) if test yes = $GXX; then if test no = $with_gnu_ld; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n $verstring func_echo_all $wl-set_version $wl$verstring` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes @@ -6860,9 +6860,9 @@ if test yes != $_lt_caught_CXX_error; then if test yes,no = $GXX,$with_gnu_ld; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo { global: $lib.exp~cat $export_symbols | $SED -e s/\(.*\)/\1;/ $lib.exp~echo local: *; }; $lib.exp~ - $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what hidden libraries, object files and flags are used when @@ -6871,9 +6871,9 @@ if test yes != $_lt_caught_CXX_error; then else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags
Re: g++ and -nostdlib
On 11/8/2013 1:49 PM, Bob Friesenhahn wrote: Isn't it because libtool wants to control the order of the linking and assure that all dependencies (including static) are tracked/known and applied at the correct times? It wants to assure that static dependencies are linked into the dependent program rather than into some dependent shared library (and thus causing a problem). It was common (and perhaps still is) for the GNU C++ library to be delivered as a static library for Windows/MinGW because C++ exceptions were not handled properly when thrown by DLLs. Quite a lot of effort went into making this work the way it currently does. First libtool tries to take away all of the libraries which would be added automatically and then it applies the libraries that GCC says it would use at the correct time. One of my wishlist roundtuit items is to special-case this behavior for libtool + GNU toolchains. For that combo, instead of the procedure Bob outlines, and then using $LD to linkjust use the compiler driver (e.g. g++, or gfortran, or gcc) to link, WITHOUT -nostdlib [1]. We're already passing the ABI-modifying -m and -f flags anyway, and it would really REALLY simplify libtool's logic... [1] unless of course the end user put -nostdlib in $LDFLAGS or something. -- Chuck
Re: g++ and -nostdlib
Le 08/11/13 20:07, Charles Wilson a écrit : On 11/8/2013 1:49 PM, Bob Friesenhahn wrote: Isn't it because libtool wants to control the order of the linking and assure that all dependencies (including static) are tracked/known and applied at the correct times? It wants to assure that static dependencies are linked into the dependent program rather than into some dependent shared library (and thus causing a problem). It was common (and perhaps still is) for the GNU C++ library to be delivered as a static library for Windows/MinGW because C++ exceptions were not handled properly when thrown by DLLs. Quite a lot of effort went into making this work the way it currently does. First libtool tries to take away all of the libraries which would be added automatically and then it applies the libraries that GCC says it would use at the correct time. One of my wishlist roundtuit items is to special-case this behavior for libtool + GNU toolchains. For that combo, instead of the procedure Bob outlines, and then using $LD to linkjust use the compiler driver (e.g. g++, or gfortran, or gcc) to link, WITHOUT -nostdlib [1]. We're already passing the ABI-modifying -m and -f flags anyway, and it would really REALLY simplify libtool's logic... [1] unless of course the end user put -nostdlib in $LDFLAGS or something. -- Chuck I believe Chuck is oriented in the right direction. A good example is with -fstack-protector. gcc/g++ knows how to link depending upon whether the platforms libc has SSP support or not. I doubt very much that libtool wants to figure out whether to add the specific libraries necessary for SSP to the link command. It *should* however pass through the provided flags to the compiler driver, and not strip in this case '-fstack-protector'; object of: Bug: linking shared libraries on Cygwin results in undefined references to __stack_chck_guard for code compiled with -fstack-protector In this particular worst case, '-fstack-protector' is stripped, and even if it passed through, the g++ '-nostdlib' defeats the purpose!