# How to create pkgconfig file

**URL:** https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337
**Category:** Code
**Created:** [March 9, 2024, 4:27pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337 "2024-03-09T16:27:05Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 9, 2024, 4:27pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/1 "2024-03-09T16:27:05Z")

</div>

I am trying to generate a pkg-config (.pc) file in cmake for my library.  
This requires finding the public compile flags and linker flags.  
I’m currently using

- `get_target_property(MYTARGET_LINK_LIBRARIES my_target INTERFACE_LINK_LIBRARIES)`
- `get_target_property(MYTARGET_INCLUDE_DIRECTORIES my_target INTERFACE_INCLUDE_DIRECTORIES)`
- and a few others

Then I use `configure_file` using the following .in file

```auto
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@

Name: @PROJECT_NAME@
Description: My special library
Version: @VERSION@
Libs: -L${libdir} -lmylib @MYTARGET_LINK_LIBRARIES@
Cflags: -I${includedir} @MYTARGET_LINK_LIBRARIES@

```

My problem is `MYTARGET_LINK_LIBRARIES` and `MYTARGET_LINK_LIBRARIES` still have generator expressions and `MYTARGET_LINK_LIBRARIES` references imported targets of the form `blah::blah` which of course pkg-config doesn’t understand.

How do I resolve the full linker and compiler options?

Thank you

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 9, 2024, 4:42pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/2 "2024-03-09T16:42:55Z")

</div>

It would also be really useful when generating cmake config files at installation to avoid having to use things like `find_dependency` and installing custom cmake module files.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 10, 2024, 6:47am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/3 "2024-03-10T06:47:52Z")

</div>

you may find an example here [docopt.pc.in](https://github.com/ClausKlein/docopt.cpp/blob/develop/docopt.pc.in)

```cmake
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docopt.pc.in ${CMAKE_CURRENT_BINARY_DIR}/docopt.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/docopt.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

```

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 7:16am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/4 "2024-03-10T07:16:36Z")

</div>

That has no library dependencies

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 10, 2024, 9:14am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/5 "2024-03-10T09:14:31Z")

</div>

> [@Peter\_Featherstone](#):
>
> It would also be really useful when generating cmake config files at installation to avoid having to use things like `find_dependency` and installing custom cmake module files

… but it export it `cmake config package`

see [Export cmake config set with namespace by ClausKlein · Pull Request #165 · docopt/docopt.cpp · GitHub](https://github.com/docopt/docopt.cpp/pull/165)

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 10, 2024, 9:24am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/6 "2024-03-10T09:24:14Z")

</div>

you need something like this:

```cmake
include(CMakeFindDependencyMacro)
find_dependency(GTest 1.14 CONFIG)

include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")

```

see i.e. [cmake-module-error/module-lib/CMakeLists.txt at develop · ClausKlein/cmake-module-error · GitHub](https://github.com/ClausKlein/cmake-module-error/blob/develop/module-lib/CMakeLists.txt)

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 9:42am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/7 "2024-03-10T09:42:00Z")

</div>

So the problem is with pkgConfig files not cmake config files, specifically when using generator expressions and imported targets. Neither configure\_file or install() resolves the generator expressions or converts imported targets like blah::blah down to compile options and linker options like -I and -L where blah::blah is a dependency of the library you’re trying to install

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 9:43am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/8 "2024-03-10T09:43:19Z")

</div>

I might write a complete reproducible example to illustrate the problem. Then you’ll see

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 10, 2024, 10:00am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/9 "2024-03-10T10:00:50Z")

</div>

I understand your problems, but I don’t know what you want?

- a `pkg config package`
- a `cmake config package`
- or both?

Note: `pkgconfig` files are not portable! (does not work on windows)

bash-5.2$ cat /usr/local/Cellar/openblas/0.3.26/lib/pkgconfig/openblas.pc

```pkgconfig
libdir=/usr/local/Cellar/openblas/0.3.26/lib
libsuffix=
includedir=/usr/local/Cellar/openblas/0.3.26/include
openblas_config= USE_64BITINT= DYNAMIC_ARCH=1 DYNAMIC_OLDER= NO_CBLAS= NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP=1 NEHALEM MAX_THREADS=56
version=0.3.26
extralib=-lpthread -lgfortran -lpthread -lgfortran -lgomp
Name: openblas
Description: OpenBLAS is an optimized BLAS library based on GotoBLAS2 1.13 BSD version
Version: ${version}
URL: https://github.com/xianyi/OpenBLAS
Libs: -L${libdir} -lopenblas${libsuffix}
Libs.private: ${extralib}
Cflags: -I${includedir}

```

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 10:09am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/10 "2024-03-10T10:09:35Z")

</div>

I’ve got a cmake config file working no problem. But I now want a pkg config file working as well.

---

<div class="post-metadata">

### Author: ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)
#### Post date: [March 10, 2024, 11:41am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/11 "2024-03-10T11:41:37Z")

</div>

> [@ClausKlein](#):
>
> Note: `pkgconfig` files are not portable! (does not work on windows)

Why do you think so? In fact they are (and even relocatable by default) but uncommon anyway.

Cross-compiler is a different thing but that only works for C anyway.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 10, 2024, 11:45am UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/12 "2024-03-10T11:45:08Z")

</div>

> [@Peter\_Featherstone](#):
>
> I’ve got a cmake config file working no problem. But I now want a pkg config file working as well.

OK, than first you should read `man pkg-config`

```auto
METADATA FILE SYNTAX
       To add a library to the set of packages pkg-config knows about, simply install a .pc file. You should install
       this file to libdir/pkgconfig.

       Here is an example file:
       # This is a comment
       prefix=/home/hp/unst # this defines a variable
       exec_prefix=${prefix} # defining another variable in terms of the first
       libdir=${exec_prefix}/lib
       includedir=${prefix}/include

       Name: GObject # human-readable name
       Description: Object/type system for GLib # human-readable description
       Version: 1.3.1
       URL: http://www.gtk.org
       Requires: glib-2.0 = 1.3.1
       Conflicts: foobar <= 4.5
       Libs: -L${libdir} -lgobject-1.3
       Libs.private: -lm
       Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib/include

```

You have add all your

- compiler flags
- link flags
- link libraies
- all dependencies,
- …

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 12:46pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/13 "2024-03-10T12:46:14Z")

</div>

Precisely so if my library has dependencies which have been linked like so:  
`target_link_libraries(my_library X11::X11 JPEG::JPEG PNG::PNG CUDA::cublas CUDA::curand MKL::MKL ...)`

how do i populate `Libs` and `Cflags` in the pkg config file?  
As i wrote in my original post i tried using:

```auto
get_target_property(MYTARGET_LINK_LIBRARIES my_library INTERFACE_LINK_LIBRARIES)
get_target_property(MYTARGET_INCLUDE_DIRECTORIES my_library INTERFACE_INCLUDE_DIRECTORIES)

```

and a few others then tried using `configure_file()` with

```auto
Libs: -L${libdir} -lmylib @MYTARGET_LINK_LIBRARIES@
Cflags: -I${includedir} @MYTARGET_INCLUDE_DIRECTORIES@

```

however, in the case of `MYTARGET_LINK_LIBRARIES` it populates the pkg config file with

```auto
Libs: -L${libdir} -lmylib X11::X11 JPEG::JPEG PNG::PNG CUDA::cublas CUDA::curand MKL::MKL 

```

which of course makes no sense for pkg config.  
So i need a way to resolve all the imported targets, generator expressions etc down to explicit compiler and linker flags

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 12:48pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/14 "2024-03-10T12:48:21Z")

</div>

At the end of the day, cmake should know how to do this because it has to generate makefiles build-ninja files etc which must use explicit compiler/linker flags. I just wish there was a way to expose this functionality at configure time.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 10, 2024, 12:57pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/15 "2024-03-10T12:57:04Z")

</div>

Normally you use `find_package(X11 v1.2.3)` or something like that in your cmake project files.

So you have a required entry for `package config` like in the man page.

You have to know your direct dependencies, write it in the package config file.

That’s all.

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 1:50pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/16 "2024-03-10T13:50:13Z")

</div>

Yeah that’s not sufficient.  
I think I’m gonna have to build a complete reproducible example to prove my point.  
Maybe I’m not being clear enough.

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 2:50pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/17 "2024-03-10T14:50:27Z")

</div>

[mylibrary.tgz](https://discourse.cmake.org/uploads/short-url/ayx9TgFvaUwEDLMYA60pSN5zKpw.tgz) (2.2 KB)

Unpack then run:

```auto
cd cmake_bug
cmake lib/ -B build -DCMAKE_INSTALL_PREFIX=./install
cmake --build build
cmake --install build/
cmake example/ -B build2 -DCMAKE_PREFIX_PATH=./install
cmake --build build2

```

You will get error:  
`/usr/bin/ld: cannot find PNG::PNG: No such file or directory`

If you look at the contents of installed `mylibrary.pc` file you will see something like:

```auto
libdir=/home/pf/Downloads/repos/cmake_bug/install/lib
includedir=/home/pf/Downloads/repos/cmake_bug/install/include

Name: mylibrary
Description: PNG reader
Version: 
Libs: -L${libdir} -lmylibrary PNG::PNG
Cflags: -I${includedir} $<BUILD_INTERFACE:/home/pf/Downloads/repos/cmake_bug/lib>

```

This line is the culprit:

```auto
Libs: -L${libdir} -lmylibrary PNG::PNG

```

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 3:08pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/18 "2024-03-10T15:08:16Z")

</div>

make sense now?

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 10, 2024, 6:17pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/19 "2024-03-10T18:17:34Z")

</div>

I dit understand you the whole time, but you expect that `CMake` is doing the work for you!

### It is an `usage error`, not a` CMake error`

```diff
bash-5.2$ git diff *.in
diff --git a/lib/mylibrary.pc.in b/lib/mylibrary.pc.in
index d073438..e7fa2e2 100644
--- a/lib/mylibrary.pc.in
+++ b/lib/mylibrary.pc.in
@@ -1,8 +1,11 @@
-libdir=@CMAKE_INSTALL_FULL_LIBDIR@
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
+# libdir=@CMAKE_INSTALL_FULL_LIBDIR@
+# includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
+libdir=${pcfiledir}/../@CMAKE_INSTALL_LIBDIR@
+includedir=${pcfiledir}/../../@CMAKE_INSTALL_INCLUDEDIR@
 
 Name: @PROJECT_NAME@
 Description: PNG reader
-Version: @VERSION@
-Libs: -L${libdir} -lmylibrary @MYLIBRARY_LINK_LIBRARIES@
-Cflags: -I${includedir} @MYLIBRARY_INCLUDE_DIRECTORIES@
+Version: @PROJECT_VERSION@
+Requires: libpng >= 1.6
+Libs: -L${libdir} -lmylibrary -lpng16 # XXX @MYLIBRARY_LINK_LIBRARIES@
+Cflags: -I${includedir} -I@PNG_INCLUDE_DIRECTORIES@ # -I/usr/local/opt/libpng/include/libpng16 # XXX @MYLIBRARY_INCLUDE_DIRECTORIES@

```

This works fine 🙂

see too [https://bugs.freedesktop.org/show\_bug.cgi?id=62018](https://bugs.freedesktop.org/show_bug.cgi?id=62018)  
and [How to generate .pc (pkg-config) file supporting --prefix of the cmake --install? - #6 by craig.scott](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/6)

---

<div class="post-metadata">

### Author: ![Peter\_Featherstone](https://discourse.cmake.org/user_avatar/discourse.cmake.org/peter_featherstone/32/4279_2.png) [@Peter\_Featherstone](https://discourse.cmake.org/u/Peter_Featherstone)
#### Post date: [March 10, 2024, 6:22pm UTC](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337/20 "2024-03-10T18:22:59Z")

</div>

What if libpng is an optional dependency in my library controlled by a cmake option ? That’s my use case. So you can’t guarantee it’s always a dependency.

[Next page](https://discourse.cmake.org/t/how-to-create-pkgconfig-file/10337.md?page=2)
