CMakeLists: make daedalus-fourier.pc relocatable via ${pcfiledir}
The pkg-config file was generated at *configure* time with
`prefix=${CMAKE_INSTALL_PREFIX}`, which captured whatever
CMAKE_INSTALL_PREFIX happened to be set to at `cmake -B build`
time — typically the default `/usr/local`. `cmake --install
build --prefix /foo` then put the files under /foo but the .pc
still pointed pkg-config at /usr/local/include and /usr/local/lib,
which broke downstream consumers configuring against the install
tree.
Concrete bite encountered today on hertz: the daedalus-v4l2 daemon
CMake configure on a /tmp/df-prefix install tree resolved
DAEDALUS_FOURIER_INCLUDE_DIRS to /usr/local/include (empty path on
the test host), so main.c failed to find <daedalus.h>.
Fix: write the .pc with `prefix=${pcfiledir}/<rel>` where <rel> is
the configure-time-computed relative path from
<prefix>/<libdir>/pkgconfig back to <prefix>. pkg-config
substitutes ${pcfiledir} with the actual on-disk location of the
.pc at lookup time, so the resolved prefix tracks wherever the
install tree is moved to — including DESTDIR-staged builds, apt
package installs, and ad-hoc `cmake --install --prefix /tmp/foo`
test installs.
The relative-path computation handles GNUInstallDirs layouts that
add multiarch tuples (Debian's lib/aarch64-linux-gnu) without
hard-coding `../..`. Tested on hertz (Debian trixie, libdir=lib):
prefix=${pcfiledir}/../../
...
$ pkg-config --variable=prefix daedalus-fourier
/tmp/df-prefix-test/lib/pkgconfig/../../
# mv preserves relocation:
$ mv /tmp/df-prefix-test /tmp/df-prefix-moved
$ pkg-config --variable=prefix daedalus-fourier
/tmp/df-prefix-moved/lib/pkgconfig/../../
This unblocks the daedalus-v4l2 daemon out-of-tree builds against
local daedalus-fourier installs and is a prerequisite for tidy
test-rig deployments (per the hertz reload session 2026-05-23).
This commit is contained in:
+25
-1
@@ -419,9 +419,33 @@ endif()
|
||||
# pkg-config file. Vulkan goes in Requires.private (consumer's
|
||||
# pkg-config call gets it via --static). pthread + dl are needed
|
||||
# by the static archive's runtime helpers.
|
||||
#
|
||||
# `prefix` is derived from ${pcfiledir} so the .pc is relocatable:
|
||||
# pkg-config substitutes ${pcfiledir} with the directory holding the
|
||||
# .pc at lookup time, and the relative path from
|
||||
# <prefix>/<libdir>/pkgconfig back to <prefix> tells pkg-config the
|
||||
# install prefix without baking it in. This is why
|
||||
# `cmake --install build --prefix /foo` produces a .pc that correctly
|
||||
# resolves `prefix=/foo` instead of baking whatever CMAKE_INSTALL_PREFIX
|
||||
# was at *configure* time (default /usr/local). DESTDIR-staged
|
||||
# installs work too: at runtime pkg-config sees the .pc at its real
|
||||
# install path and computes the right prefix.
|
||||
#
|
||||
# Relative-path depth is computed from CMAKE_INSTALL_LIBDIR (and
|
||||
# whatever multiarch tuple GNUInstallDirs adds) so Debian-style
|
||||
# `lib/aarch64-linux-gnu/pkgconfig/...` resolves with the right number
|
||||
# of `..` components. Layouts where libdir is *not* under prefix are
|
||||
# not supported by this scheme; if a packager overrides libdir to an
|
||||
# absolute path the relative-path machinery falls back to the absolute
|
||||
# value (CMake's file(RELATIVE_PATH) prepends `..` until they meet),
|
||||
# which is also relocatable but no longer prefix-agnostic.
|
||||
file(RELATIVE_PATH PKGCONFIG_PCDIR_TO_PREFIX
|
||||
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig"
|
||||
"${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
set(PKGCONFIG_OUT ${CMAKE_CURRENT_BINARY_DIR}/daedalus-fourier.pc)
|
||||
file(WRITE ${PKGCONFIG_OUT}
|
||||
"prefix=${CMAKE_INSTALL_PREFIX}
|
||||
"prefix=\${pcfiledir}/${PKGCONFIG_PCDIR_TO_PREFIX}
|
||||
exec_prefix=\${prefix}
|
||||
libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}
|
||||
includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}
|
||||
|
||||
Reference in New Issue
Block a user