强制CMake使用完整的库路径

8
我有一个问题。我在我的Linux机器上拥有一个单独的{bin、lib、include}目录树,其中安装了CMake和我需要进行开发工作所需的所有库。但是仅将PATH环境变量设置为此bin目录,并且由于几个原因我无法设置LD_LIBRARY_PATH。该目录树中的所有程序都使用RPATHs构建。我正在使用的CMake 3.3.1也位于此目录树中。
现在,我想编译一个使用libcurl的程序,并设置以下CMakeLists.txt。
PROJECT(EXAMPLE)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
FIND_PACKAGE(CURL REQUIRED)
FIND_PACKAGE(OpenSSL REQUIRED) 
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR})
SET(LIBS ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES}) 

ADD_EXECUTABLE(curl_ex src/curl_ex.c)
TARGET_LINK_LIBRARIES(curl_ex ${LIBS}) 

现在当我运行CMake时,由于它与curl和OpenSSL都位于相同的前缀下,因此可以找到我的个人软件树中的curl和OpenSSL设置。

但是当我使用make VERBOSE=1来构建项目时,我看到以下链接命令:

gcc CMakeFiles/curl_ex.dir/src/curl_ex.c.o  -o curl_ex -rdynamic -lcurl -lssl -lcrypto 

在生成可执行文件时,它会使用系统范围内已安装的curl和openssl库,而不是在配置期间CMake找到的库。

我该如何强制CMake在进行链接时使用它找到的库?


1
这可能与在政策CMP0060中描述的相同问题有关。它主要建议使用"IMPORTED library targets",在其中您可以在IMPORTED_LOCATION中提供完整路径,或者调用cmake_policy(SET CMP0060 NEW)(因为默认值是OLD)。 - Florian
1
请参阅CMake:使用完整路径库的TARGET_LINK_LIBRARIES。如果您真的想强制执行它,请使用target_link_libraries(curl_ex PRIVATE "-l$<JOIN:${LIBS}, -l>")(请参见此处)。 - Florian
1个回答

10

将我的评论转化为答案

我能够重现您的问题,即使没有完全相同的环境,并找到了两个可能的解决方案:

  1. 您可以将策略CMP0060设置为NEW

    cmake_policy(SET CMP0060 NEW)
    

    这个策略的新行为是使用完整路径链接库,即使它们在隐式链接目录中。

  2. 您可以创建一个中间导入的库,并使用IMPORTED_LOCATION(参见[CMake] TARGET_LINK_LIBRARIES with full path libraries

    add_library(curl UNKNOWN IMPORTED)
    set_property(TARGET curl PROPERTY IMPORTED_LOCATION "${CURL_LIBRARIES}")
    target_link_libraries(curl_ex curl)
    

    这对我来说有效,但根据CMake导入库的行为,您可能还需要设置IMPORTED_IMPLIB

  3. 背景

    请检查CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES的设置,因为其中列出的路径被视为“隐式”搜索路径,完整的库路径将相应替换(参见cmComputeLinkInformation::CheckImplicitDirItem()UnixPaths.cmake)。

    message("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES: ${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")
    

谢谢,CMP0060 解释了为什么我的第一个解决方案只适用于最新的 CMake 版本。 - M.K. aka Grisu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接