cmake: linking against STATIC IMPORTED library fai

2019-01-15 21:52发布

问题:

I have a vendor provided static library.

I have added it as a STATIC IMPORTED library target, and set properties on the target:

add_library(
    lime_api 
        STATIC 
        IMPORTED
    )

set_target_properties(
    lime_api 
        PROPERTIES 
        IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/trading/limeTradingApi.a"
    )

# users include "api/trading/limeTradingApi.h"
set_target_properties(
    lime_api 
        PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/.."
    )

elsewhere in my source tree I try to link against lime_api, and I get an error:

/usr/bin/ld: cannot find -llime_api

My source tree looks like this:

src
|
+--- api
|    | 
|    +--- trading
|    |       - limeTradingApi.a
|    |       - limeTradingApi.h
|    |
|    +--- examples
|         |
|         +--- trading
|
+--- order
     |
     +--- example

The strange thing is that there is a vendor provided example which links against this library, and that works fine:

api/examples/trading/CMakeLists.txt:

add_executable       (trading_demo exampleClient.cc)
target_link_libraries(trading_demo lime_api)           <-- this works

However, when I try linking against my own library which includes the lime_api I get the linker error.

order/CMakeLists.txt:

add_library(
        order
            STATIC
            ${SRCS}
        )
target_link_libraries(order lime_api)                  <-- this doesn't work

order/example/CMakeLists.txt:

add_executable       (order_example main.cpp)
target_link_libraries(order_example order)

Question:

Why doesn't CMake "convert" the linked target lime_api into -llimeTradingApi.a for my executable?

回答1:

I suspect that you ran into a visibility problem with the IMPORTED library target. According to the documentation:

An IMPORTED library target references a library file located outside the
project. ... The target name has scope in the directory in which it is
created and below, but the GLOBAL option extends visibility.

That's why the correct library path is used for the inner trading_demo target, but not for the outer order_example target. To fix the problem, adding the GLOBAL option should be sufficient:

add_library(lime_api STATIC IMPORTED GLOBAL)


标签: c++ cmake