Fix pkg-config paths when install dirs are absolute - #295
Conversation
`yyjson.pc.in` builds `libdir` and `includedir` by concatenating
`CMAKE_INSTALL_PREFIX` with `CMAKE_INSTALL_LIBDIR` / `CMAKE_INSTALL_INCLUDEDIR`.
That is only correct when those variables are relative.
GNUInstallDirs explicitly allows them to be absolute, and distributions do pass
absolute values. Nixpkgs, for example, passes them so a package can split its
headers and libraries into separate outputs. When that happens the prefix is
applied twice and the generated file contains paths like:
includedir=/nix/store/...-yyjson-0.12.0//nix/store/...-yyjson-0.12.0/include
`pkg-config --cflags yyjson` then reports a directory that does not exist, and
any consumer that discovers yyjson through pkg-config fails to compile with
"yyjson.h: No such file or directory".
GNUInstallDirs provides `CMAKE_INSTALL_FULL_LIBDIR` and
`CMAKE_INSTALL_FULL_INCLUDEDIR` for exactly this: they return the value as-is
when it is absolute and prepend the prefix when it is relative.
Verified both ways on the current master:
* absolute install dirs: paths are no longer doubled and `pkg-config` now
resolves `yyjson.h` correctly
* default relative install dirs: unchanged, including the `lib64` case
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Some extra context on why this went unnoticed for so long, in case it is useful. Nixpkgs actually has a guard for exactly this class of bug. Its CMake setup hook runs a The guard greps for the literal string
So the detector silently passes and a broken Nothing here changes the patch, just explaining why a fairly visible packaging bug stayed quiet. |
|
Thanks! Merged. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #295 +/- ##
=======================================
Coverage 98.47% 98.47%
=======================================
Files 2 2
Lines 7743 7743
=======================================
Hits 7625 7625
Misses 118 118
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Would appreciate a release so I can cleanup! |
I have a few more things to merge first, should have a new release out in a week or two. |
Problem
yyjson.pc.incomposeslibdirandincludedirby concatenating the prefix with the install dirs:That is correct only when
CMAKE_INSTALL_LIBDIRandCMAKE_INSTALL_INCLUDEDIRare relative. GNUInstallDirs explicitly allows them to be absolute, and distributions do pass absolute values. Nixpkgs passes them so a package can split headers and libraries into separate outputs.When that happens the prefix is applied twice:
pkg-config --cflags yyjsonthen reports a directory that does not exist, and any consumer discovering yyjson through pkg-config fails withfatal error: yyjson.h: No such file or directory. I hit this integrating yyjson into a C library via Meson'sdependency('yyjson').Fix
GNUInstallDirs provides
CMAKE_INSTALL_FULL_LIBDIRandCMAKE_INSTALL_FULL_INCLUDEDIRfor exactly this case. They return the value unchanged when it is absolute, and prepend the prefix when it is relative.include(GNUInstallDirs)already runs beforeconfigure_file(yyjson.pc.in ...), so the variables are available with no other change.Verification
Both cases tested against current
master(9365ddc):Absolute install dirs (
-DCMAKE_INSTALL_LIBDIR=$PFX/lib -DCMAKE_INSTALL_INCLUDEDIR=$PFX/include)Before:
After:
Default relative install dirs (regression check, resolved to
lib64on this machine)End to end, a Meson project using plain
dependency('yyjson')fails to compile against an absolute-install-dir build before this change and builds and runs after it.🤖 Generated with Claude Code
This PR was created by Claude Code. See cli/cli#13904 for context on why this note exists.