Skip to content

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
Edited by Brad King
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information