Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use pkg-config to link a library statically

I'd like to link libpng found by pkg-config statically.

pkg-config --libs --static libpng

outputs

-L/usr/local/Cellar/libpng/1.6.15/lib -lpng16 -lz

I have both libpng16.a libpng16.dylib in that directory, and if I use these flags the library gets linked dynamically.

How can I tell either pkg-config or the linker (preferably in some portable-ish way) that I really want it linked statically?

I've tried adding -static before pkg-config's flags, but that makes clang's ld try and fail to link "crt0.o".

like image 737
Kornel Avatar asked Dec 21 '14 03:12

Kornel


2 Answers

The pkg-config --static option relies on proper tagging in the .pc files. If providing the --static option does not return correct information necessary to link against the libpng archive, then you cannot use pkg-config for that purpose.

I suspect libpng (along with a majority of other packages) dropped support for static linking some time after libpng 1.2. They may still provide a library archive, but the libpng pkg-config file is no longer properly tagged to support a static link. You will have to manually tell ld to use the static lib.

like image 200
David C. Rankin Avatar answered Jan 04 '23 13:01

David C. Rankin


Try:

-L/usr/local/Cellar/libpng/1.6.15/lib -l:libpng16.a -lz

Using -l with a : character allows you to specify the filename extension.

The -l: option is documented in the GNU ld 2.24 manual:

-l namespec

--library=namespec

Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search the library path for a file called libnamespec.a.

On systems which support shared libraries, ld may also search for files other than libnamespec.a. Specifically, on ELF and SunOS systems, ld will search a directory for a library called libnamespec.so before searching for one called libnamespec.a. (By convention, a .so extension indicates a shared library.) Note that this behavior does not apply to :filename, which always specifies a file called filename.

like image 21
Quip Yowert Avatar answered Jan 04 '23 13:01

Quip Yowert