FindPkgConfig adds multiple /usr/lib* directories to PKG_CONFIG_PATH, leading to incorrect architecture selection
When the FindPkgConfig module collects potential paths for "*.pc" files, it looks for an architecture-specific library path (such as "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig" or "lib32/pkgconfig") to put in the search path (PKG_CONFIG_PATH
), but also unconditionally adds "lib/pkgconfig" to the path. The search order of PKG_CONFIG_PATH
is not defined, so if "lib/pkgconfig" refers to a different architecture than the build target, pkg-config may report the wrong library path, leading to link-time errors due to the differing object file architectures.
I've fixed this in my own environment using https://achurch.org/patch-pile/cmake/3.27.1/pkgconfig-libdir-fix.diff, which adds either an arch-specific directory or "lib" but not both, but I don't know the original reason for including both paths, so I don't know whether this will work correctly in all environments.
pkgconfig-libdir-fix.diff
diff -urN cmake-3.27.1-orig/Modules/FindPkgConfig.cmake cmake-3.27.1/Modules/FindPkgConfig.cmake
--- cmake-3.27.1-orig/Modules/FindPkgConfig.cmake 2023-07-26 02:58:09 +0900
+++ cmake-3.27.1/Modules/FindPkgConfig.cmake 2023-10-10 13:18:30 +0900
@@ -377,24 +377,25 @@
endif()
else()
# not debian, check the FIND_LIBRARY_USE_LIB32_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
+ set(_arch_lib_dir "lib")
get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
if(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
- list(APPEND _lib_dirs "lib32/pkgconfig")
+ set(_arch_lib_dir "lib32")
endif()
get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
if(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
- list(APPEND _lib_dirs "lib64/pkgconfig")
+ set(_arch_lib_dir "lib64")
endif()
get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
- list(APPEND _lib_dirs "libx32/pkgconfig")
+ set(_arch_lib_dir "libx32")
endif()
+ list(APPEND _lib_dirs "${_arch_lib_dir}/pkgconfig")
endif()
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND NOT CMAKE_CROSSCOMPILING)
list(APPEND _lib_dirs "libdata/pkgconfig")
endif()
- list(APPEND _lib_dirs "lib/pkgconfig")
list(APPEND _lib_dirs "share/pkgconfig")
# Check if directories exist and eventually append them to the