Den 2011-06-23 11:22 skrev Vadim Zeitlin: > Charles Wilson <libtool <at> cwilson.fastmail.fm> writes: > >> On 6/21/2011 8:29 AM, Vadim Zeitlin wrote: >>> Charles Wilson <don't feed spammers> writes: >>>> No, I think --disable-static, if specified, should actually *disable >>>> static*. That should be sufficient. >>>> >>>> If it's not doing that, then it's a bug IMO. >>> >>> Just to confirm: no, currently it doesn't do this. The example of my >>> original message came from libxml2 build configured with --disable-static. >>> >>> So should I try to create a patch making libtool fail in this case? >> >> I think so. > > So I did try. Unfortunately I didn't succeed because after looking closer > at libtool sources, things turned out to be much more complicated than I > thought -- or at least very different from what I thought that would be. > > I naively expected the presence of "-no-undefined" in foo_la_LDFLAGS to > result in passing the equivalent of "-Wl,-no-undefined" to the compiler for > the platforms where shared libraries with undefined symbols are supported > (i.e. allow_undefind_flag != "unsupported"). But this is not at all what > happens. In fact, libtool doesn't seem to have any logic for actually > ensuring that shared libraries with -no-undefined actually have no > undefined symbols! Indeed, just look at this transcript: > > % cat configure.ac > AC_INIT([foo],[1.0]) > AM_INIT_AUTOMAKE > AC_CONFIG_SRCDIR([foo.c]) > > LT_INIT([disable-static]) > AC_PROG_CC > > AC_CONFIG_FILES([Makefile]) > AC_OUTPUT > % cat Makefile.am > lib_LTLIBRARIES = libfoo.la > libfoo_la_SOURCES = foo.c > libfoo_la_LDFLAGS = -no-undefined > % cat foo.c > extern void foo(); > void foo2() > { > foo(); > foo(); > } > % mkdir build && cd $_ > % ../configure >/dev/null > % make -s > libtool: compile: gcc -DPACKAGE_NAME=\"foo\" -DPACKAGE_TARNAME=\"foo\" > -DPACKAGE_VERSION=\"1.0\" "-DPACKAGE_STRING=\"foo 1.0\"" > -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"foo\" > -DVERSION=\"1.0\" > -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 > -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 > -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" > -I. > -I.. -g -O2 -MT foo.lo -MD -MP -MF .deps/foo.Tpo -c ../foo.c -fPIC -DPIC -o > .libs/foo.o > libtool: link: gcc -shared -fPIC -DPIC .libs/foo.o -O2 > -Wl,-soname > -Wl,libfoo.so.0 -o .libs/libfoo.so.0.0.0 > libtool: link: (cd ".libs" && rm -f "libfoo.so.0" && ln -s > "libfoo.so.0.0.0" > "libfoo.so.0") > libtool: link: (cd ".libs" && rm -f "libfoo.so" && ln -s > "libfoo.so.0.0.0" > "libfoo.so") > libtool: link: ( cd ".libs" && rm -f "libfoo.la" && ln -s "../libfoo.la" > "libfoo.la" ) > > > I.e. it created a shared library with undefined symbols without any > problems because it never actually passed -no-undefined to g++/ld. > > I have no idea whether -no-undefined is supposed to work like this but in > any case it seems to me that it's perfectly useless right now. It's not > checked at all under normal Unix systems so it can't be used to ensure that > a shared library actually doesn't have any undefined symbols and so could > be created under Windows too. And it *must* be always specified under > Windows as otherwise DLL are never created at all.
If you really are targeting Windows (or some other platform which needs -no-undefined to build libtool libraries) then you really do get a failure if there are undefined symbols. > And setting allow_undefined to "yes" in the beginning of func_mode_link() > (after commenting out the line above that sets it to "no") illustrates the > same point: all this logic is at best useless and at worst broken as long > as libtool doesn't have any support for actually determining whether a > library has any undefined symbols because the *only* reasonable thing to do > for any project that targets Windows is to use -no-undefined in LDFLAGS and > hope for the best. In particular, the default case of having an LTLIBRARY > that does not include -no-undefined in its LDFLAGS does not work at all > under Windows as it will never actually create a DLL. > > Frankly, more I think about it, less I understand how could this be done > intentionally. Am I misunderstanding something fundamental here or is all > this just one big horrible bug? > > In any case, I'm afraid I simply don't understand the current code well > enough (this is an euphemism, actually it doesn't make any sense at all to > me...) to provide any useful patches. Quoting the docs for the libtool -no-undefined option: `-no-undefined' Declare that OUTPUT-FILE does not depend on any libraries other than the ones listed on the command line, i.e., after linking, it will not have unresolved symbols. Some platforms require all symbols in shared libraries to be resolved at library creation (*note Inter-library dependencies::), and using this parameter allows `libtool' to assume that this will not happen. I.e. no mention of any actual check if there were any undefined symbols. Compare with the GNU ld option --no-undefined (which is not the same option). --no-undefined -z defs Report unresolved symbol references from regular object files. This is done even if the linker is creating a non-symbolic shared library. The switch --[no-]allow-shlib-undefined controls the be‐ haviour for reporting unresolved references found in shared libraries being linked in. I.e. the libtool option is there to let packages that *know* that there are no undefined symbols declare that fact, so that libtool need not attempt to build any shared library if it is not going to work. However, I agree that it is awkward. If this was done today, with no backwards compatibility in mind, I'd say that -no-undefined should be the default and any packages that truly needed undefined symbols should somehow declare that instead, since that is more of a special case (IMHO). But it is as it is. Cheers, Peter _______________________________________________ https://lists.gnu.org/mailman/listinfo/libtool