Force CMake to use the full library path

2019-01-26 15:35发布

问题:

I have the following problem. I have a separate {bin,lib,include} tree on my Linux machine where CMake and all my libraries I need for my development work are installed. But only the PATH environment variable is set to this bin directory and for several reason I can not set the LD_LIBRARY_PATH. All programs inside this tree are build using RPATHs. The CMake 3.3.1 I am using is also inside this tree.

Now the problem I want to compile a program using libcurl and set up the following 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}) 

When I now run CMake the curl and the OpenSSL setup out of my personal software tree is found due to the fact that it resides inside the same prefix as CMake.

But when I build the project using make VERBOSE=1 I see the following linking command:

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

and the build executable refers to the system-wide installed curl and openssl libraries instead of the one cmake found during the configuration.

How can I force CMake to use the libraries it found when it performs the linking?

回答1:

Turning my comments into an answer

I was able to reproduce your problem - even without having the exact same environment - and found two possible solutions:

  1. You set policy CMP0060 to NEW

    cmake_policy(SET CMP0060 NEW)
    

    The NEW behavior for this policy is to link libraries by full path even if they are in implicit link directories.

  2. You can create a intermediate imported library and use IMPORTED_LOCATION (see [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)
    

    This worked for me, but according to CMake imported library behaviour you may need to also set IMPORTED_IMPLIB.

Background

Please check the setting of CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES because the paths listed there are taken as "implicit" search paths and full library paths are replaced accordingly (see cmComputeLinkInformation::CheckImplicitDirItem() and UnixPaths.cmake)

message("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES: ${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}")