# How to generate .pc (pkg-config) file supporting --prefix of the cmake --install?

**URL:** https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109
**Category:** Code
**Created:** [September 18, 2021, 12:01am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109 "2021-09-18T00:01:32Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Adam\_Badura](https://discourse.cmake.org/user_avatar/discourse.cmake.org/adam_badura/32/1058_2.png) [@Adam\_Badura](https://discourse.cmake.org/u/Adam_Badura)
#### Post date: [September 18, 2021, 12:01am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/1 "2021-09-18T00:01:32Z")

</div>

**The typical approach**

It seems to me that the common way of generating a `.pc` (`pkg-config`) file is to use [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) command. For example, something like this:

```cmake
configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/share/pkgconfig/${PROJECT_NAME}.pc.in
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
    @ONLY
)

```

where the `share/pkgconfig/${PROJECT_NAME}.pc.in` file might look like this:

```plaintext
prefix=@CMAKE_INSTALL_PREFIX@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@

Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
URL: @PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
Cflags: -I"${includedir}"

```

Then the `.pc` file is installed for example like this:

```cmake
install(
    FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
    DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
)

```

_As a side note, I’m not sure if `CMAKE_INSTALL_FULL_...` variables shouldn’t be used instead due to special cases mentioned by [`GNUInstallDirs`](https://cmake.org/cmake/help/git-master/module/GNUInstallDirs.html). Yet, while important in general, it is out of scope for this question._

Then, when you [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem), [build](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#build-a-project), and [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) like:

```bash
cmake -D "CMAKE_BUILD_TYPE=<config>" -D "CMAKE_INSTALL_PREFIX=<prefix>" -S "<source>" -B "<bin>"
cmake --build "<bin>" --config "<config>"
cmake --install "<bin>" --config "<config>"

```

it all works perfectly!

**The problem**

However, the problem with this approach is that it doesn’t work with setting prefix (by the `--prefix` command-line argument) in the [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step above. If I do something like:

```bash
cmake --instal "<bin>" --config "<config>" --prefix "<other-prefix>"

```

all seems to work fine with the exception that the `.pc` file has a wrong value of the `prefix` variable. It has the value provided (or defaulted by CMake itself) in the [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html) variable during the [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem) step. The value from the `--prefix` command-line argument is not used since the `.pc` file was already generated during the [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem) step!

**A possible solution**

The approach I found so far is to do [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) twice. The first run is done during [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem) step as before, however, it keeps “variable” for the `prefix`. The second run is done with [`install(CODE)`](https://cmake.org/cmake/help/git-master/command/install.html#custom-installation-logic) where the [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html) has the new value.

So, instead of the [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) above we would have something like this:

```cmake
set(DEFERED_CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/share/pkgconfig/${PROJECT_NAME}.pc.in.in
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc.in
    @ONLY
)
install(
    CODE "configure_file(\"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc.in\" \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc\" @ONLY)"
)

```

while the `share/pkgconfig/${PROJECT_NAME}.pc.in.in` file is the same as before with the exception of the first line that now is:

```plaintext
prefix=@DEFERED_CMAKE_INSTALL_PREFIX@
(...)

```

For the record, a few important points on this solution:

1. `DEFERED_CMAKE_INSTALL_PREFIX` is needed because it seems [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) doesn’t have any way of escaping the `@`. One could think that using `@@CMAKE_INSTALL_PREFIX@@` will do the trick since the first run will change it to `@CMAKE_INSTALL_PREFIX@` and the second run will finish off. However, this doesn’t work. Nor does `\@`. I expect there is no way and we need a custom variable for this.
2. Two runs are needed since during the second run (in [`install(CODE)`](https://cmake.org/cmake/help/git-master/command/install.html#custom-installation-logic)) all the other variables no longer exist. The second run is executed from the `cmake_install.cmake`.
3. Quoting of arguments in the `CODE` argument is needed (unlike with “ordinary CMake”) since the values are replaced during the [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem) step and the code ending in `cmake_install.cmake` has just a raw string. Any space in that string breaks the argument from the [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) point of view.

**Another approach**

I haven’t tried it, but I expect we could keep the original approach and only add an [`install(CODE)`](https://cmake.org/cmake/help/git-master/command/install.html#custom-installation-logic) that would modify the `${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc` file by rewriting the `prefix=` line. It could do so either in-place or by making a new file and installing it instead.

However, somehow I like this even less than the above approach. Especially with the in-place modification alternative.

**Is there any better approach?**

The above approaches are significantly more verbose and not so obvious - at least in my opinion. So, an obvious question is: _is there any better solution?_

There is [`CMakePackageConfigHelpers`](https://cmake.org/cmake/help/git-master/module/CMakePackageConfigHelpers.html) with its [`configure_package_config_file`](https://cmake.org/cmake/help/git-master/module/CMakePackageConfigHelpers.html#command:configure_package_config_file) commnad. The documentation there says:

> This has the effect that the resulting `FooConfig.cmake` file would work poorly under Windows and OSX, where users are used to choose the install location of a binary package at install time, independent from how [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html#variable:CMAKE_INSTALL_PREFIX) was set at build/cmake time.

which is _exactly_ what I’m trying to address here.

However, the [`configure_package_config_file`](https://cmake.org/cmake/help/git-master/module/CMakePackageConfigHelpers.html#command:configure_package_config_file) command is dedicated for creating package `...Config.cmake` files and doesn’t apply to any arbitrary files, like the `.pc` file here.

So, is there anything else?

Or at least is there a “canonical guideline” on this? Since to my surprise. I didn’t find much on this. As if only I had this problem - so maybe in the end I’m just making this up? Maybe Windows users aren’t using `pkg-config` that much (even though they could) while \*nix users are used to pick the [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html) in [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem) step…

---

<div class="post-metadata">

### Author: ![sera](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/a88e4f/32.png) [@sera](https://discourse.cmake.org/u/sera)
#### Post date: [September 18, 2021, 9:29am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/2 "2021-09-18T09:29:48Z")

</div>

> [@Adam\_Badura](#):
>
> The value from the `--prefix` command-line argument is not used since the `.pc` file was already generated during the [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem) step!

If you somehow “make it work” for the install step you will break installing into a staging directory. The pc file should only ever use values defined in the configure/generate step.

---

<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: [September 18, 2021, 11:00am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/3 "2021-09-18T11:00:09Z")

</div>

I agree with @sera here. Additionally, on Windows, pkg-config behaves differently by automatically picking the prefix from the file location

---

<div class="post-metadata">

### Author: ![Adam\_Badura](https://discourse.cmake.org/user_avatar/discourse.cmake.org/adam_badura/32/1058_2.png) [@Adam\_Badura](https://discourse.cmake.org/u/Adam_Badura)
#### Post date: [September 18, 2021, 7:45pm UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/5 "2021-09-18T19:45:27Z")

</div>

@sera, @hsattler, I _did_ make it work. It’s only I’m not sure if this is the best way to do it, since it seems somewhat verbose.

@hsattler, I know about that `pkg-config` behavior. In fact, you can have it on \*nix as well by adding `--define-prefix` command-line argument. (Or block it on Windows by adding `--dont-define-prefix`.) I regrat that the `--define-prefix` behavior is not the default one on \*nix as well.

@sera, @hsattler, I’m not sure what do you mean by “_installing into a staging directory_”. It seems to me that “staging” is done by using [`DESTDIR`](https://cmake.org/cmake/help/git-master/envvar/DESTDIR.html). (A good read on the topic is also [7.2.4 `DESTDIR`: Support for Staged Installs](https://www.gnu.org/prep/standards/html_node/DESTDIR.html).)

Whereas the `--prefix` command-line argument to [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step says:

> Override the installation prefix, [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html#variable:CMAKE_INSTALL_PREFIX).

So, it doesn’t seem to infer with staging done by [`DESTDIR`](https://cmake.org/cmake/help/git-master/envvar/DESTDIR.html). The only difference is that in this “mode” the [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html) is provided not during [generate](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#generate-a-project-buildsystem) step but instead during [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step.

If that would “_break installing_” then why do we have the `--prefix` command-line argument in the [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step? Or why the [`configure_package_config_file`](https://cmake.org/cmake/help/git-master/module/CMakePackageConfigHelpers.html#command:configure_package_config_file) command explicitly addresses this issue?

---

<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: [September 18, 2021, 10:38pm UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/6 "2021-09-18T22:38:04Z")

</div>

Consider the case where someone creates a tarball archive of your project rather than installing directly from the build tree (e.g.via `cmake --install`). They might unpack that tarball anywhere, which is both a desirable capability and common practice. In that scenario, you can’t hard-code the absolute path of the install location in the .pc file.

Perhaps a better solution might be to define your `prefix=...` line in terms of the `${pcfiledir}` variable, something like `prefix=${pcfiledir}/../..`. The following link might be helpful:

[https://bugs.freedesktop.org/show\_bug.cgi?id=62018](https://bugs.freedesktop.org/show_bug.cgi?id=62018)

---

<div class="post-metadata">

### Author: ![Adam\_Badura](https://discourse.cmake.org/user_avatar/discourse.cmake.org/adam_badura/32/1058_2.png) [@Adam\_Badura](https://discourse.cmake.org/u/Adam_Badura)
#### Post date: [September 19, 2021, 7:32am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/7 "2021-09-19T07:32:57Z")

</div>

To support a “no installation mode” a component must be well-prepared. For example, a component might have a different headers tree for its internal use and restructure (possibly also stripping) it in the installation step. Such a component would be broken by the “no installation mode” and I think I’m OK with that.

As to `${pcfiledir}`, I am aware of this variable and how it works. However, it seems to be a kind of workaround for the problem. A good one, but applying only to `.pc` files.

While the problem of [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) command fixing to [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html) from the generation step is a generic problem as shown by existence of the [`configure_package_config_file`](https://cmake.org/cmake/help/git-master/module/CMakePackageConfigHelpers.html#command:configure_package_config_file) command. Although perhaps in practis those are the only two (`.pc` and `...Config.cmake`) typical cases where it matters.

---

<div class="post-metadata">

### Author: ![Adam\_Badura](https://discourse.cmake.org/user_avatar/discourse.cmake.org/adam_badura/32/1058_2.png) [@Adam\_Badura](https://discourse.cmake.org/u/Adam_Badura)
#### Post date: [October 22, 2021, 10:04am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/8 "2021-10-22T10:04:07Z")

</div>

I have been exploring this topic somewhat more. A side finding (besides a typo in `DEFERED`…) is that

```cmake
set(DEFERED_CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")

```

is a so-so idea. A much more flexible one is to do it like this:

```cmake
set(DEFERRED "@")

```

and then use it like this:

```nohighlight
prefix=@DEFERRED@CMAKE_INSTALL_PREFIX@DEFERRED@
(...)

```

This way we can defer the replacement of any variable by any number of iteration without introducing more and more `DEFERRED_...` variables.

Of course, it would be better if [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) could handle it natively.

---

<div class="post-metadata">

### Author: ![Adam\_Badura](https://discourse.cmake.org/user_avatar/discourse.cmake.org/adam_badura/32/1058_2.png) [@Adam\_Badura](https://discourse.cmake.org/u/Adam_Badura)
#### Post date: [October 22, 2021, 12:12pm UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/9 "2021-10-22T12:12:15Z")

</div>

Further work on this topic indicates some more doubts around [`GNUInstallDirs`](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) interaction with the [`install`](https://cmake.org/cmake/help/git-master/command/install.html) command.

It seems the [`install`](https://cmake.org/cmake/help/git-master/command/install.html) command prefers that either `DESTINATION` parameter is a _relative_ path (like `CMAKE_INSTALL_<dir>` instead of `CMAKE_INSTALL_FULL_<dir>`) or even `TYPE` be used instead (that seems in effect do the same).

**Relative `DESTINATION` or `TYPE`**

For a concrete example, if we have CMake code to install the headers of a library:

```cmake
install(
    DIRECTORY include/
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

```

or like this:

```cmake
install(
    DIRECTORY include/
    TYPE INCLUDE
)

```

the resulting `cmake_install.cmake` has the following block:

```cmake
if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT)
  file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include" TYPE DIRECTORY FILES "<SOURCE-DIR>/include/")
endif()

```

and the `--prefix` argument of the [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step works as expected.

**Absolute `DESTINATION` (with `_FULL_`)**

However, if our CMake would be doing it like this (use of `_FULL_` version):

```cmake
install(
    DIRECTORY include/
    DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}
)

```

the resulting `cmake_install.cmake` has the following:

```cmake
if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT)
  list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES
   "/usr/include/")
  if(CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)
    message(WARNING "ABSOLUTE path INSTALL DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}")
  endif()
  if(CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)
    message(FATAL_ERROR "ABSOLUTE path INSTALL DESTINATION forbidden (by caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}")
  endif()
file(INSTALL DESTINATION "/usr/include" TYPE DIRECTORY FILES "<SOURCE-DIR>/include/")
endif()

```

In the `_FULL_` version there is no `${CMAKE_INSTALL_PREFIX}` in the path, instead, there is a raw string. Hence, the `--prefix` argument of the [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step doesn’t work.

**Special cases**

The include directory in the examples above is simple to understand but less interesting since `CMAKE_INSTALL_FULL_INCLUDEDIR` (unless overridden by the user) will be always `${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}`.

However, [`GNUInstallDirs`](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) lists special cases. Depending on what `CMAKE_INSTALL_PREFIX` is the `_FULL_` versions of `SYSCONFDIR`, `LOCALSTATEDIR`, and `RUNSTATEDIR` are different than the above concatenation.

For example, if we use `SYSCONFDIR` (`SYSCONF` for `TYPE`) instead, while also having `CMAKE_INSTALL_PREFIX` set to `/usr`, the `_FULL_` version ends up installing to `/etc` whereas the relative version (and the `TYPE` version) install to `${CMAKE_INSTALL_PREFIX}/etc`.

It seems I’m not the only one to notice this issue. For example, we have issue [#21150: Extend GNUInstallDirs to preserve the ability to create relocatable packages with EXPORT](https://gitlab.kitware.com/cmake/cmake/-/issues/21150) with a related topic.

**CPack**

To make things worse, the `DESTINATION` documentation in [`install`](https://cmake.org/cmake/help/git-master/command/install.html) command mentions:

> As absolute paths are not supported by [`cpack`](https://cmake.org/cmake/help/git-master/manual/cpack.1.html#manual:cpack(1)) installer generators, it is preferable to use relative paths throughout. In particular, there is no need to make paths absolute by prepending [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/git-master/variable/CMAKE_INSTALL_PREFIX.html#variable:CMAKE_INSTALL_PREFIX); this prefix is used by default if the DESTINATION is a relative path.

**Conclusions?**

It seems there are two ways here:

1. The way of [`GNUInstallDirs`](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) module
  - Use `_FULL_` paths in [`install`](https://cmake.org/cmake/help/git-master/command/install.html) command to support special cases of [`GNUInstallDirs`](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html).
  - Use `DESRDIR` environment variable to make “staged installation”.

```bash
DESTDIR="<install-dir>" cmake --install "<build-dir>" --config "<config>"

```

or system generic

```bash
cmake -E env DESTDIR="<install-dir>" cmake --install "<build-dir>" --config "<config>"

```

  - Don’t use `--prefix` argument of the [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step as it will not work anyway. Whatever you provided (or defaulted) as `CMAKE_INSTALL_PREFIX` during configuration lasts forever.
  - You cannot use CPack.

2. The way of [`install`](https://cmake.org/cmake/help/git-master/command/install.html) command
  - Use relative paths in `DESTINATION` or even `TYPE` to avoid explicit paths altogether.
  - You still _may_ use `DESRDIR` environment variable to make “staged installation”, however, keep in mind it is prepended to the `CMAKE_INSTALL_PREFIX`.
  - You _may_ use `--prefix` argument of the [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step to establish `CMAKE_INSTALL_PREFIX` at the time of installation (overriding the value from configuration).
  - You can use CPack.

_A side note: I’m not sure how universal the `DESTDIR` is. I expect only Makefiles/Ninja support it or at least not all generators support it. Is there a universal approach?_

**But what about the [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) command and `.pc` files?**

Well… It doesn’t fit perfectly in either approach. However, the first is still significantly simpler.

The first thing to notice is that making a `.pc` file by a call to [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) doesn’t support the “late binding” of `CMAKE_INSTALL_PREFIX` from the second approach. To make it work in that scenario we would need to use the tricks I described in the question itself.

The second thing to notice is that making `.pc` files that are well-behaved still requires extra work even with the first approach. A tempting idea could be to do something like:

```plaintext
prefix=@CMAKE_INSTALL_PREFIX@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
sysconfdir=${prefix}/@CMAKE_INSTALL_SYSCONFDIR@

(...)

```

However, this would totally defeat the way of [`GNUInstallDirs`](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) module. Not only it would not take into account special cases but it would also ignore user-overridden `_FULL_` paths!

A better approach would be to do:

```plaintext
prefix=@CMAKE_INSTALL_PREFIX@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
sysconfdir=@CMAKE_INSTALL_FULL_SYSCONFDIR@

(...)

```

However, such a file “breaks” the `pkg-config` `--define-variable=<var>=<value>` argument. The `--define-prefix` still works, since it is handled in a special way (and this is why the `prefix=` variable is needed even if not referred to!). But since the `prefix` is not referred to explicitly it will not be noticed by `--define-variable`. Not a big issue - I haven’t yet met a use case for `--define-variable`… - but still a feature that got broken.

For a perfectly cooperating `.pc` file we would need extra processing during the generation of the `.pc` file that based on the `_FULL_` value would either use it (if it is not related to prefix) or replace it with `${prefix}/...` otherwise. But this calls for a dedicated `configure_pc_file` that is much “smarter”. And only to cover the exotic `--define-variable` feature (and perhaps the subjective feel of the elegance of the resulting `.pc` file).

**What else?**

The `CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION` (and `_ERROR_`) parts are pretty disturbing. It looks like those warnings do not take into account the use of `DESTDIR`. Why?

Wouldn’t it be nice if [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step had `--destdir` argument next to (or even instead of? - see below) `--prefix` argument. It could provide the functionality in a system-independent way (without verbosity of `cmake -E`) and a generator-independent way.

What is the point of the `--prefix` argument in the [install](https://cmake.org/cmake/help/git-master/manual/cmake.1.html#install-a-project) step? While it does offer reasonable (not sure how useful) functionality it silently breaks other functionalities (like the [`configure_file`](https://cmake.org/cmake/help/git-master/command/configure_file.html) referring to install paths, like with `.pc` file). And from the comments above I assume this functionality should really be used as it may also break other things. Then why was it added in the first place? (While `--destdir` wasn’t! - see above.)

Could we have something that covers all the cases and isn’t too verbose? I think the [#21150: Extend GNUInstallDirs to preserve the ability to create relocatable packages with EXPORT] asked for the same.

---

<div class="post-metadata">

### Author: ![Adam\_Badura](https://discourse.cmake.org/user_avatar/discourse.cmake.org/adam_badura/32/1058_2.png) [@Adam\_Badura](https://discourse.cmake.org/u/Adam_Badura)
#### Post date: [January 5, 2022, 7:51am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/10 "2022-01-05T07:51:20Z")

</div>

Another thing to take into account is the [`CMAKE_STAGING_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_STAGING_PREFIX.html) variable.

The `cmake_install.cmake` file starts with a block:

```cmake
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
  set(CMAKE_INSTALL_PREFIX "<path>")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")

```

Now, it seems that the `<path>` here is set to what [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html) was upon configuration. _Unless_ [`CMAKE_STAGING_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_STAGING_PREFIX.html) was also defined, in which case that value is used instead.

However, as discussed above, the value of `CMAKE_INSTALL_PREFIX` within `cmake_install.cmake` is used _only if_ [`install`](https://cmake.org/cmake/help/latest/command/install.html) commands used relative paths (so, for example, [`CMAKE_INSTALL_INCLUDEDIR`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_FULL_INCLUDEDIR.html) instead of [`CMAKE_INSTALL_INCLUDEDIR`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_FULL_INCLUDEDIR.html)).

---

<div class="post-metadata">

### Author: ![petk](https://discourse.cmake.org/user_avatar/discourse.cmake.org/petk/32/4555_2.png) [@petk](https://discourse.cmake.org/u/petk)
#### Post date: [September 16, 2024, 1:49pm UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/11 "2024-09-16T13:49:39Z")

</div>

> [@Adam\_Badura](#):
>
> Further work on this topic indicates some more doubts

Perhaps the `--prefix` option of the `cmake --install` command should be simply deprecated as it makes handling this install prefix handling very difficult when using configure\_file. All solutions to the configure\_file where template needs to have the install prefix are non-standard and non-documented hacks. Not having the option to change the install prefix in the cmake --install step would resolve all of these issued. Otherwise, probably CMake should somehow resolve this in the future.

---

<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: [September 17, 2024, 7:20am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/12 "2024-09-17T07:20:34Z")

</div>

> [@petk](#):
>
> Not having the option to change the install prefix in the cmake --install step would resolve all of these issued.

That certainly won’t happen. It is very common to want to install to somewhere different to the default install prefix specified at configure time. Even `cpack` itself relies on the ability to do this.

Taking a step back, you cannot know at CMake configure time where the project might be installed. The project only has control over the relative layout of things below the base install point, and it can provide a _default_ install prefix, but that’s all.

---

<div class="post-metadata">

### Author: ![petk](https://discourse.cmake.org/user_avatar/discourse.cmake.org/petk/32/4555_2.png) [@petk](https://discourse.cmake.org/u/petk)
#### Post date: [September 18, 2024, 11:48am UTC](https://discourse.cmake.org/t/how-to-generate-pc-pkg-config-file-supporting-prefix-of-the-cmake-install/4109/13 "2024-09-18T11:48:32Z")

</div>

I understand completely. And it seems like a useful option to be able to override this path. However, another issue that got missed when this was added. All projects that once had the prefix “hardcoded” in the header files as part of the build now also ideally should refactor their code to have the prefix dynamical for the install phase. It seems to me that this `cmake --install ... --prefix` acts more like a DESTDIR. Or at least what the Autotools or Meson based projects are used to. Yes, of course deprecating this is now almost to near impossible, but it is not exactly ideal solution.
