# pkg\_check\_modules in FindPkgConfig creates interface library

**URL:** <https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847>\
**Category:** Code\
**Created:** [January 13, 2022, 9:27pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847 "2022-01-13T21:27:14Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![lguez](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lguez/32/2115_2.png) [@lguez](https://discourse.cmake.org/u/lguez)\
**Post date:** [January 13, 2022, 9:27pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/1 "2022-01-13T21:27:14Z")

</div>

When called with the `IMPORTED_TARGET` argument, the command `pkg_check_modules` in the module FindPkgConfig creates an interface library. From the code of `FindPkgConfig.cmake`:

> add\_library(PkgConfig::${\_prefix} INTERFACE IMPORTED ${\_global\_opt})

What is the point of making this an interface library? Why not just create an imported library? Making an interface library is inconvenient because we cannot link it to another target with the PRIVATE keyword.

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [January 16, 2022, 6:04pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/2 "2022-01-16T18:04:38Z")

</div>

> [@lguez](#):
>
> Making an interface library is inconvenient because we cannot link it to another target with the PRIVATE keyword.

Huh? Linking to `INTERFACE` libraries as `PRIVATE` works just fine. Do you have an actual reproducer case available?

---

<div class="post-metadata">

**Author:** ![lguez](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lguez/32/2115_2.png) [@lguez](https://discourse.cmake.org/u/lguez)\
**Post date:** [January 17, 2022, 8:12am UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/3 "2022-01-17T08:12:17Z")

</div>

Hello. I mean the other way around. We cannot do:

> target\_link\_libraries(PkgConfig::${\_prefix} PRIVATE some\_other\_target)

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [January 17, 2022, 12:27pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/4 "2022-01-17T12:27:38Z")

</div>

What are you trying to do? This seems…odd.

---

<div class="post-metadata">

**Author:** ![lguez](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lguez/32/2115_2.png) [@lguez](https://discourse.cmake.org/u/lguez)\
**Post date:** [January 17, 2022, 4:29pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/5 "2022-01-17T16:29:37Z")

</div>

Well, I have an executable, E, that links to a library, netcdf-fortran. I try to find netcdf-fortran with pkg-config:

> find\_package(PkgConfig)  
> pkg\_check\_modules(netcdff IMPORTED\_TARGET netcdf-fortran)  
> target\_link\_libraries(E PRIVATE PkgConfig::netcdff)

I know that netcdf-fortran has a private dependency on another library, netcdf-c. So I am tempted to find netcdf-c (I have a find module for it) and declare this dependency:

> find\_package(netCDF)  
> target\_link\_libraries(PkgConfig::netcdff PRIVATE netCDF::netcdf)

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [January 17, 2022, 4:48pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/6 "2022-01-17T16:48:44Z")

</div>

Just append to its `INTERFACE_LINK_LIBRARIES` property. `IMPORTED` targets don’t support being on the left-hand side of `target_*` commands anyways (`INTERFACE` or not).

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [January 17, 2022, 9:18pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/7 "2022-01-17T21:18:23Z")

</div>

Eh, you _sure_ an imported library can’t be on the left-hand side of `target_*()` commands with `INTERFACE`? It seems to be permitted with the following small test project:

```cmake
cmake_minimum_required(VERSION 3.20)
project(ImportedLibTest)

add_library(MyThing STATIC IMPORTED)
target_link_libraries(MyThing INTERFACE /path/to/libsomething.a)
target_include_directories(MyThing INTERFACE /another/path/to/include)

```

---

<div class="post-metadata">

**Author:** ![lguez](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lguez/32/2115_2.png) [@lguez](https://discourse.cmake.org/u/lguez)\
**Post date:** [January 17, 2022, 9:42pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/8 "2022-01-17T21:42:22Z")

</div>

I confirm what Craig Scott said. Putting the imported pkg-config target on the left-hand side of `target_link_libraries` with the INTERFACE keyword seems to work. Also when I try to replace INTERFACE by PRIVATE, the error message is:

> INTERFACE library can only be used with the INTERFACE keyword of  
> target\_link\_libraries

So it does not say that the problem lies with the IMPORTED property.

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [January 17, 2022, 11:49pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/9 "2022-01-17T23:49:09Z")

</div>

Huh. I remember wanting to do that long ago and ended up just using the property modifications directly. Guess something changed at some point? Anyways, yes, `INTERFACE` is limited to `INTERFACE` usage requirements; it makes no sense to have `PRIVATE` or `PUBLIC` links because there’s the former is completely useless (for non-`STATIC` libraries, but then if you use `$<LINK_ONLY>` and you’re the same there too) and the latter is equivalent to `INTERFACE` since there’s no “self” to apply it to anyways.

Looking back at release notes, this functionality was added in CMake 3.11.

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [January 18, 2022, 12:15am UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/10 "2022-01-18T00:15:14Z")

</div>

> [@lguez](#):
>
> So it does not say that the problem lies with the IMPORTED property.

The code also enforces that `IMPORTED` libraries can only use `INTERFACE` as well:

```c++
    this->Makefile.IssueMessage(                                                                                                                                                                                                      
      MessageType::FATAL_ERROR,                                                                                                                                                                                                       
      "IMPORTED library can only be used with the INTERFACE keyword of "                                                                                                                                                              
      "target_link_libraries");  

```

---

<div class="post-metadata">

**Author:** ![lguez](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lguez/32/2115_2.png) [@lguez](https://discourse.cmake.org/u/lguez)\
**Post date:** [January 18, 2022, 7:04am UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/11 "2022-01-18T07:04:32Z")

</div>

OK, thank you. So, going back to my use case, are you suggesting that I do:

> target\_link\_libraries(PkgConfig::netcdff INTERFACE $\<LINK\_ONLY:netCDF::netcdf\>)

or are you saying this is useless anyway because it is redundant with the information that comes from pkg-config?

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [January 18, 2022, 12:17pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/12 "2022-01-18T12:17:38Z")

</div>

I think `FindPkgConfig` is currently needing some work for static libraries, so the `$<LINK_ONLY>` is what I would do for this case.

---

<div class="post-metadata">

**Author:** ![lguez](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lguez/32/2115_2.png) [@lguez](https://discourse.cmake.org/u/lguez)\
**Post date:** [January 19, 2022, 3:22pm UTC](https://discourse.cmake.org/t/pkg-check-modules-in-findpkgconfig-creates-interface-library/4847/13 "2022-01-19T15:22:32Z")

</div>

OK, thank you.
