pkg-config

Software Category
Version
0.27.1

pkg-config

Introduction

pkg-config is a useful tool for making sure compiler options are correct when compiling and linking software. Very often with compilers, you will need to determine the proper paths to library header files and code in order to link them to your software project. Finding the correct paths to pass to the compiler for this can be a challenge. pkg-config is designed to assist with that.

Using pkg-config on RCC Systems

You do not need to load any environment modules to use pkg-config on RCC systems. Simply call the pkg-config program from the terminal with the proper options and it will work for you. The main options you will need are as follows:

--cflags  ## This option will give you the path for the -I (include) compiler option.  This is usually header files.
--libs    ## This option will give you the path for the -L (libs) compiler option.  This is needed to link compiled libraries to new code

Basic usage looks like the following, where LIBRARYNAME should be replaced by the name of whatever library you are looking to use (e.g.; netcdf, hdf5, etc).

pkg-config --libs --cflags LIBRARYNAME

This will output the paths detailed above in the following format:

-I/path/to/library/include/files -L/path/to/library/static/link/files -lLIBRARYNAME

This output can then be used to compile programs. You can do this either by copy/pasting the output from pkg-config or by assigning the output of pkg-config to a custom environment variable. To do the latter, refer to the example below (again, replace LIBRARYNAME by the name of whatever library you intend to use).

export COMPILER_PATHS=$(pkg-config --libs --cflags LIBRARYNAME)

This can all be wrapped up succinctly into a simple workflow for compiling programs and linking them to external libraries. This is as follows:

## only do this step if a module is needed to access the library you want to use
module load MODULENAME

## Again, should be a name like netcdf, hdf5 or some other lib
export COMPILER_PATHS=$(pkg-config --libs --cflags LIBRARYNAME)  

## Replace COMPILER with a compiler like icc or gcc and MYPROGRAM with the filename of your code
COMPILER -c MYPROGRAM ${COMPILER_PATHS}  

## Replace compiler with icc/gcc/etc and MYPROGRAM with the name of your code
COMPILER -o MYPROGRAM.x MYPROGRAM.o ${COMPILER_PATHS} 

Refer to the following section to see an example of pkg-config in action using this workflow.

Example: Compiling a netCDF Program using pkg-config

In this example, will use the simple_xy_wr.c program from UCAR This code can be downloaded from the UCAR website. To start, load the correct module (in this example, we'll use the default GNU compilers and libraries):

module load gnu

Next, call the pkg-config program with the --cflags and --libs options:

pkg-config --cflags --libs netcdf

Now we can use these paths in the compilation process. The best way to do that is to assign that output to a custom environment variable. This can be done as follows:

export COMPILER_PATHS=$(pkg-config --cflags --libs netcdf)

Now we can use that variable to compile and link the code. For our example, this would look like the following:

gcc -c simple_xy_wr.c ${COMPILER_PATHS}
gcc -o simple_xy_wr.x simple_xy_wr.o ${COMPILER_PATHS}

This should compile the program! In total, the full process would look like this:

module load gnu
export COMPILER_PATHS=$(pkg-config --cflags --libs netcdf)
gcc -c simple_xy_wr.c ${COMPILER_PATHS}
gcc -o simple_xy_wr.x simple_xy_wr.o ${COMPILER_PATHS}

Using pkg-config in Makefiles

pkg-config can also be a powerful tool to incorporate into build automation files such as Makefiles. We can use the same example as above as an example. To start, download the UCAR code from the UCAR website. Next, create a new makefile called Makefile in the SAME directory as where you downloaded the code.

touch Makefile

Then, open the makefile and type the following:

CFLAGS=-O2 $(shell pkg-config --cflags netcdf)
LDFLAGS=$(shell pkg-config --libs netcdf)
CC=gcc

simple_xy_wr: simple_xy_wr.o
simple_xy_wr.o: simple_xy_wr.c

Save this to the file, and then simply type make into the command line and your code should compile.

Troubleshooting

If you encounter an error such as the following ("test" is not a valid library name), make sure you have loaded the correct module, and make sure you have typed the name of the module correctly as well as the name of the library correctly in the call to pkg-config.

Package test was not found in the pkg-config search path.
Perhaps you should add the directory containing `test.pc'
to the PKG_CONFIG_PATH environment variable
No package 'test' found

If you still encounter this error, then feel free to contact RCC Support