From 0cc8f00e6b9ff70c3414ed69042a0b02f098b8c1 Mon Sep 17 00:00:00 2001 From: 15daksh-2003 Date: Sun, 6 Sep 2026 15:59:26 +0530 Subject: [PATCH] FindPkgConfig: support GNU ld -l: exact-file syntax Some .pc files (e.g. DPDK) use -l:libfoo.a for an exact library file, but we passed the colon to find_library and it never resolved. Strip it for lookup, keep the token so an unresolved lib still falls back to -l:. Fixes: #27452 --- Modules/FindPkgConfig.cmake | 22 +++++++---- .../FindPkgConfig_IMPORTED_TARGET.cmake | 38 +++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index 837c14a518..6a163b3d2c 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -756,18 +756,26 @@ function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path) continue() endif() + # "-l:" is GNU ld's exact-file syntax; keep the colon-bearing token so + # an unresolved lib still falls back to a linker-usable "-l:". + if (_pkg_search MATCHES "^:(.+)$") + set(_pkg_find_names "${CMAKE_MATCH_1}") + else() + set(_pkg_find_names "${_pkg_search}") + endif() + if(_search_paths) # Firstly search in -L paths - find_library(pkgcfg_lib_${_prefix}_${_pkg_search} - NAMES ${_pkg_search} + find_library(pkgcfg_lib_${_prefix}_${_pkg_find_names} + NAMES ${_pkg_find_names} HINTS ${_search_paths} NO_DEFAULT_PATH) endif() - find_library(pkgcfg_lib_${_prefix}_${_pkg_search} - NAMES ${_pkg_search} + find_library(pkgcfg_lib_${_prefix}_${_pkg_find_names} + NAMES ${_pkg_find_names} ${_find_opts}) - mark_as_advanced(pkgcfg_lib_${_prefix}_${_pkg_search}) - if(pkgcfg_lib_${_prefix}_${_pkg_search}) - list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}") + mark_as_advanced(pkgcfg_lib_${_prefix}_${_pkg_find_names}) + if(pkgcfg_lib_${_prefix}_${_pkg_find_names}) + list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_find_names}}") else() list(APPEND _libs ${_pkg_search}) endif() diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake index 223dec848e..39678285ef 100644 --- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake +++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake @@ -150,3 +150,41 @@ if (NOT c_opts STREQUAL expected_c_opts) "expected: \"${expected_c_opts}\", got \"${c_opts}\"" ) endif () + +# GNU ld's "-l:" exact-file syntax: a named file resolves via +# find_library(); an unresolved one keeps its ":". +file(WRITE ${fakePkgDir}/lib/libcmakeinternalfakeexact.a "") +file(WRITE ${fakePkgDir}/lib/cmakeinternalfakeexactnoprefix.a "") +set(pname fakeexactpackage) +file(WRITE ${fakePkgDir}/lib/pkgconfig/${pname}.pc +"Name: FakeExactPackage +Description: Dummy package for FindPkgConfig -l: exact-file test +Version: 1.2.3 +Libs: -l:libcmakeinternalfakeexact.a -l:cmakeinternalfakeexactnoprefix.a -l:libcmakeinternalfakemissing.a -lcmakeinternalfakepackage2 +") + +pkg_check_modules(FakeExactPackage REQUIRED QUIET IMPORTED_TARGET fakeexactpackage) + +# check that the "-l:" exact-file form resolves to a full library path +list(FIND FakeExactPackage_LINK_LIBRARIES "${fakePkgDir}/lib/libcmakeinternalfakeexact.a" idx) +if (idx EQUAL -1) + message(FATAL_ERROR "-l: exact file not resolved: ${FakeExactPackage_LINK_LIBRARIES}") +endif() + +# check that a non-conventional exact file (no lib prefix) also resolves +list(FIND FakeExactPackage_LINK_LIBRARIES "${fakePkgDir}/lib/cmakeinternalfakeexactnoprefix.a" idx) +if (idx EQUAL -1) + message(FATAL_ERROR "-l: non-conventional exact file not resolved: ${FakeExactPackage_LINK_LIBRARIES}") +endif() + +# check that an unresolved exact file keeps its ":" token for the linker +list(FIND FakeExactPackage_LINK_LIBRARIES ":libcmakeinternalfakemissing.a" idx) +if (idx EQUAL -1) + message(FATAL_ERROR "-l: unresolved exact file did not preserve its token: ${FakeExactPackage_LINK_LIBRARIES}") +endif() + +# check that a conventional -l entry still resolves alongside -l: entries +list(FIND FakeExactPackage_LINK_LIBRARIES "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a" idx) +if (idx EQUAL -1) + message(FATAL_ERROR "conventional -l entry not resolved alongside -l: entries: ${FakeExactPackage_LINK_LIBRARIES}") +endif()