static linking

Started by
6 comments, last by mike44 7 years, 3 months ago

Hi

how to link curl and sdl statically?

Building file: ../myList.cpp
Invoking: GCC C++ Compiler
g++ /usr/lib/x86_64-linux-gnu/libcurl.a /usr/lib/x86_64-linux-gnu/libSDL.a -fPIC -fvisibility=hidden -static -DCURL_STATICLIB -DLIN=1 -DLWM=0 -DREF=1 -DXPLM200 -DXPLM210 -DIBM=0 -DAPL=0 -I/usr/include/GL -I/usr/include/SDL -I/home/michael/CPP64/SDK/CHeaders/XPLM -O3 -Wall -c -fmessage-length=0 -pthread -std=c++11 -MMD -MP -MF"myList.d" -MT"myList.o" -o "myList.o" "../myList.cpp"
g++: warning: /usr/lib/x86_64-linux-gnu/libcurl.a: linker input file unused because linking not done
g++: warning: /usr/lib/x86_64-linux-gnu/libSDL.a: linker input file unused because linking not done
Finished building: ../myList.cpp

if I remove the -c I get:

Invoking: GCC C++ Compiler
g++ /usr/lib/x86_64-linux-gnu/libcurl.a /usr/lib/x86_64-linux-gnu/libSDL.a -fPIC -fvisibility=hidden -static -DCURL_STATICLIB -DLIN=1 -DLWM=0 -DREF=1 -DXPLM200 -DXPLM210 -DIBM=0 -DAPL=0 -I/usr/include/GL -I/usr/include/SDL -I/home/michael/CPP64/SDK/CHeaders/XPLM -O3 -Wall -fmessage-length=0 -pthread -std=c++11 -MMD -MP -MF"BitmapSupport.d" -MT"BitmapSupport.o" -o "BitmapSupport.o" "../BitmapSupport.cpp"
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
subdir.mk:24: recipe for target 'BitmapSupport.o' failed
collect2: error: ld returned 1 exit status
make: *** [BitmapSupport.o] Error 1

Many thanks and regards

Advertisement

You can only statically link a library into an application. It makes no sense to try to link it into an object file.

Stephen M. Webb
Professional Free Software Developer

You mean pass the *.a to the linker? That's what I've tried a long time ago without success. Should I need to pass all .a, around ten or so for curl alone, to the linker like above?

Building target: lin.xpl
Invoking: GCC C++ Linker
g++ /usr/lib/x86_64-linux-gnu/libcurl.a /usr/lib/x86_64-linux-gnu/libSDL.a -Wl,-Bdynamic,-rpath=. -shared -o "lin.xpl" ./BitmapSupport.o ./main.o ./myList.o -lopenal -lcurl -lSDL -lGL
Finished building target: lin.xpl

like this it compiles but is not statically linked like ldd shows:

libcurl-gnutls.so.4 => /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 (0x00007fbce28dd000)
libSDL-1.2.so.0 => /usr/lib/x86_64-linux-gnu/libSDL-1.2.so.0 (0x00007fbce2643000)

Thanks again

  1. Yes, you have to explicitly pass all statically linked libraries to the linker. It's not required with DSOs because they carry runtime link information for transient symbol resolution, but that's not true of static libraries. That means you have to statically link all libraries your static libraries link to (eg. libcurl-gnutls above).
  2. Order is important on the command line, especially in POSIX-compatible systems (and you're using a Debian-based system there, which is POSIX compatible). If you add libSDL.a early in the list then -lSDL later, you're going to get a whole slew of symbols resolving from the DSO instead of the static library (eg. the libSDL-1.2.so.0 above. You could look into -Wl,--whole-archive and friends to force the entire static library to get built in, or else you could explicitly make sure the order is correct for dependent symbol resolution.

What you're trying to do is not impossible, just a lot of tedious work and a knowledge of how compile-time symbol resolution works in your linker (probably ld or gold).

Stephen M. Webb
Professional Free Software Developer

An alternative here is to use libtool, which is part of the autotools. It understands building programs and libraries and will do the right thing(tm). Unfortunately, autotools has a somewhat steep learning curve. automake seems to be the simplest way in.

whole archive gets me closer than trying individual libs:

Building target: lin.xpl
Invoking: GCC C++ Linker
g++ -Wl,--whole-archive /usr/lib/x86_64-linux-gnu/libcurl.a -Wl,--no-whole-archive,-Bdynamic,-rpath=. -shared -o "lin.xpl" ./BitmapSupport.o ./main.o ./myList.o -lopenal -lSDL -lGL
Finished building target: lin.xpl

I get this runtime error:

undefined symbol: GSS_C_NT_HOSTBASED_SERVICE

Any idea? Probably exclude a lib somehow?

Thanks

PS: got it working compiling curl to tmp while disabling lots of stuff alike:

http://stackoverflow.com/questions/9648943/static-compile-of-libcurl-apps-linux-c-missing-library

undefined symbol: GSS_C_NT_HOSTBASED_SERVICE Any idea? Probably exclude a lib somehow?

That's a GSSAPI symbol from the Kerberos5 bindings, usually found in a library called (unsurprisingly) libgssapi_krb5. The symbol is an undefined reference in libcurl-gnutls which you're pulling in wholesale.

If you're going to pull in the entire archive using --whole-archive, you have to manually resolve all its undefined symbols by pulling all its dependent libraries, iteratively, until there are no more undefined symbols. There are no shortcuts. You can not leave symbols unresolved. You can resolve them by using a DSO instead of a static lib, but then you need to make sure the host system supplies the DSO or else ship all the DSOs with your application and provide a wrapper script to set LD_LIBRARY_PATH to pick them up.

What you're trying to do is not impossible, just a lot of tedious work and a knowledge of how compile-time symbol resolution works in your linker.

Stephen M. Webb
Professional Free Software Developer

Such static linking only seems to move down the Fedora runtime problems to now:

undefined symbol: zlibVersion

why such? Works fine on my development Ubuntu system.

PS: I had a HD crash and cannot find out my old login

This topic is closed to new replies.

Advertisement