Need to list the installed libraries on a Unix system? Want to use a library in C and don’t know the linker flags to use? Need to find where header files are located for a package? This post answers these questions.
An example from the beginning
Let’s say I want to write a C program that uses libxml2
. We know we’re going to need #include
directives for the libxml2
package to refer to the header files. When we compile the program we need to have a linker flag with -l
to link in it’s shared library. Keep this example in mind as you read this post. Here are the steps to arrive with what we need:
- Is the
libxml2
library installed? - What are the header files we need and where are they located?
- What are the linker flags?
Follow along and it will be easy to answer these 3 questions.
The pkg-config tool
The pkg-config
tool will return metainformation about installed libraries on a system. This program finds information by looking at metadata files with a .pc
extension named after a package. It looks in some default places. The search path can be altered by setting the PKG_CONFIG_PATH
environment variable.
Let’s start out by listing all the install packages on my Raspberry Pi.
$ pkg-config --list-all
systemd systemd - systemd System and Service Manager
libpng libpng - Loads and saves PNG files
libpng16 libpng - Loads and saves PNG files
libsystemd systemd - systemd Library
m17n-db m17n-db - The m17n database used by the m17n library.
xkeyboard-config XKeyboardConfig - X Keyboard configuration data
adwaita-icon-theme gnome-icon-theme - A collection of icons used as the basis for GNOME themes
freetype2 FreeType 2 - A free, high-quality, and portable font engine.
zlib zlib - zlib compression library
poppler-data poppler-data - Encoding files for use with poppler
udev udev - udev
bash-completion bash-completion - programmable completion for the bash shell
alsa alsa - Advanced Linux Sound Architecture (ALSA) - Library
libgpiod libgpiod - Library and tools for the Linux GPIO chardev
valgrind Valgrind - A dynamic binary instrumentation framework
libmnl libmnl - Minimalistic Netlink communication library
iso-codes iso-codes - ISO country, language, script and currency codes and translations
shared-mime-info shared-mime-info - Freedesktop common MIME database
First a Note about Installed Libraries
You may have libraries on your system that are installed but don’t have header files and libraries you can link against. Let me show you an example.
$ apt search libxml
...
libxml2/stable,now 2.9.4+dfsg1-7+deb10u1 armhf [installed,automatic]
GNOME XML library
...
libxml2-dbg/stable 2.9.4+dfsg1-7+deb10u1 armhf
Debugging symbols for the GNOME XML library
libxml2-dev/stable 2.9.4+dfsg1-7+deb10u1 armhf
Development files for the GNOME XML library
libxml2-doc/stable 2.9.4+dfsg1-7+deb10u1 all
Documentation for the GNOME XML library
....
From this we can see that only libxml2
is installed but other packages are available. Using pkg-config
do we have C flags and shared libraries?
$ pkg-config --list-all | grep xml
$
It’s not there, pkg-config
doesn’t show libxml2
as a package? We need to install the dev
libraries typically for this.
$ sudo apt install libxml2-dev libxml2-doc
Once the development package is installed we can see the package is present.
$ pkg-config --list-all | grep xml
libxml-2.0 libXML - libXML library version2.
Listing
Ok now that libxml-2.0
is installed let’s list C flags and shared libraries we would use for compilation and linkage.
$ pkg-config --cflags --libs libxml-2.0
-I/usr/include/libxml2 -lxml2
If we look now at the /usr/include/libxml2
directory we can see all the header files we have available to use.
Another Example with curl
What if we want to create a program that uses curl
. Let’s sum this up, note you need to infer some things using apt search curl
:
$ apt install libcurl4-doc libcurl4-openssl-dev
Now we can see:
$ pkg-config --cflags --libs libcurl
-I/usr/include/arm-linux-gnueabihf -lcurl
Closing
I leave you with a question. If we go all the way back where I had the following on my system:
$ apt search libxml
...
libxml2/stable,now 2.9.4+dfsg1-7+deb10u1 armhf [installed,automatic]
GNOME XML library
...
When pkg-config
doesn’t show it listed then how is this package used? Let’s look deeper into it?
$ apt search libxml
...
libxml2/stable,now 2.9.4+dfsg1-7+deb10u1 armhf [installed,automatic]
GNOME XML library
...
$ dpkg -l | grep libxml2 1 ↵
ii libxml2:armhf 2.9.4+dfsg1-7+deb10u1 armhf GNOME XML library
ii libxml2-dev:armhf 2.9.4+dfsg1-7+deb10u1 armhf Development files for the GNOME XML library
ii libxml2-doc
dpkg -L libxml2:armhf
/.
/usr
/usr/lib
/usr/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabihf/libxml2.so.2.9.4
/usr/share
/usr/share/doc
/usr/share/doc/libxml2
/usr/share/doc/libxml2/AUTHORS
/usr/share/doc/libxml2/README
/usr/share/doc/libxml2/README.Debian
/usr/share/doc/libxml2/changelog.Debian.gz
/usr/share/doc/libxml2/changelog.gz
/usr/share/doc/libxml2/copyright
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/libxml2
/usr/lib/arm-linux-gnueabihf/libxml2.so.2
/usr/share/doc/libxml2/NEWS.gz
From here we can see a shared library libxml2.so.2.9.4
which other programs could dynamically link in. They’d have a challenge though if they needed to be locally built on the machine. Thus, this library is for pre-compiled programs that alreday know how to link this shared library in.