2

I'm trying to convert a project to autotools using libtool. The target is a shared library that links against a third party library. The original Makefile approach used the following command line:

i686-w64-mingw32-g++ -g -shared -o libmycomponent.dll obj/mycomponent.o -L/path/to/thirdpary -lthirdpary -lwinpthread -lws2_32 -liphlpapi

This links fine.

However, when converting to autotools/libtool, I have within my Makefile.am I have:

libmycomponent_la_LIBADD += -L/path/to/thirdparty -lthirdparty

Now, the thirdparty library name does not start with lib. The name is just simply thirdparty.lib. When linking, I get a command line like:

/bin/bash ./libtool  --tag=CXX   --mode=link i686-w64-mingw32-g++ -std=gnu++11 -I./include -g -O2 -shared -no-undefined --enable-runtime-pseudo-reloc -version-info 1:0:0 -L/path/to/thirdparty  -o libmycomponent.la -rpath /usr/local/lib src/libmycomponent_la-mycomponent.lo -lthirdcomponent -lwinpthread -liphlpapi -lws2_32

This fails to link with:

*** Warning: linker path does not have real file for library -lthirdpary.
*** I have the capability to make that library automatically link in when
*** you link to this library.  But I can only do this if you have a
*** shared version of the library, which you do not appear to have
*** because I did check the linker path looking for a file starting
*** with libthirdpary but no candidates were found. (...for file magic test)
*** The inter-library dependencies that have been dropped here will be
*** automatically added whenever a program is linked with this library
*** or is declared to -dlopen it.

*** Since this library must not contain undefined symbols,
*** because either the platform does not support them or
*** it was explicitly requested with -no-undefined,
*** libtool will only create a static version of it.

However, if I copy thirdparty.lib to libthirdparty.lib, it links fine.

How can I get libtool to use the library name unchanged? I tried pulling in the file directly, e.g.:

libmycomponent_la_LIBADD += /path/to/thirdparty.lib

But I end up with undefined symbols (as if it didn't even try to pull in the file--which makes sense since it isn't a libtool file).

I also tried doing:

libmycomponent_la_LIBADD += -L/path/to/thirdparty -l:thirdparty

As recommended here, but the message changes to being unable to find lib:thirdparty.lib.

PlayDough
  • 1,116
  • 8
  • 16
  • 1
    Possible duplicate of [How do I link a library file in GCC that does not start with lib?](https://stackoverflow.com/questions/10234208/how-do-i-link-a-library-file-in-gcc-that-does-not-start-with-lib) – Andrew Henle Mar 14 '18 at 22:04
  • @AndrewHenle Interestingly, I can do this just fine on the command line. The original pure Makefile approach links fine. I'll update the question with the example. – PlayDough Mar 14 '18 at 22:14
  • What's the final full value of variable `libmycomponent_la_LIBADD`? I can't tell from the fragment you present. If you end up with a different library order then that very likely explains your problem. – John Bollinger Mar 15 '18 at 02:31
  • @JohnBollinger It appears that libtool is somehow filtering things out. I added `set -x` to libtool, and I see it actively look for `libthirdparty`. libtool prepends 'lib' and then performs the search. – PlayDough Mar 15 '18 at 05:01

2 Answers2

0

"The only difference between using an -l option and specifying a file name is that -l surrounds library with ‘lib’ and ‘.a’ and searches several directories". Specify just file thirdparty.lib (without -l)

Werner
  • 281
  • 1
  • 12
  • Thanks for the tip. This does get rid of the error about not finding the real library. But now I get undefined references. I tried: `libmycomponent_la_LIBADD += -L/path/to/thirdparty thirdparty` and `libmycomponent_la_LIBADD += -L/path/to/thirdparty thirdparty.lib`. Both result in undefined references. – PlayDough Mar 14 '18 at 22:42
  • 1
    "It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded." . Please check the sequence. – Werner Mar 14 '18 at 22:51
  • This appears to be a libtool issue, not a linker issue. I know how `-l` works, but `-l` isn't even making it to the linker command line via libtool. If I link by hand, even using `-lthirdparty` it works fine. – PlayDough Mar 15 '18 at 05:02
  • Not solved. I’m trying to figure out how to convince libtool into not filtering out the third party library. – PlayDough Mar 17 '18 at 23:01
0

The solution is to sneak linker command line arguments past libtool. This is suggested here, and fully documented in the libtool FAQ. So, I tweaked my Makefile.am with:

libmycomponent_la_LIBADD += -Wl,-L/path/to/thirdparty -Wl,-lthirdparty

And now it happily links.

PlayDough
  • 1,116
  • 8
  • 16