CMake: add dependency to IMPORTED library

2019-02-09 13:59发布

问题:

I have a vendor supplied library archive which I have imported into my project:

add_library(
    lib_foo 
    STATIC 
    IMPORTED GLOBAL
    )

set_target_properties(
    lib_foo 
    PROPERTIES IMPORTED_LOCATION             
    "${CMAKE_CURRENT_LIST_DIR}/vendor/foo.a"
    )

set_target_properties(
    lib_foo 
    PROPERTIES INTERFACE_INCLUDE_DIRECTORIES 
    "${CMAKE_CURRENT_LIST_DIR}/vendor"
    )

When I try to link an application using this library, I get undefined reference to 'pthread_atfork' linker errors:

/usr/lib/libtcmalloc_minimal.a(libtcmalloc_minimal_internal_la-static_vars.o):
    In function `SetupAtForkLocksHandler':
    /tmp/gperftools-2.4/src/static_vars.cc:119: 
        undefined reference to `pthread_atfork'
        ../vendor/foo.a(platformLib.o): In function `foo::Thread::Impl::join()':

So vendor/foo.a has a dependency on pthread.

I tried target_link_libraries(lib_foo pthread) but that doesn't work because lib_foo is an IMPORTED target, rather than a built target

CMake Error at libfoo/CMakeLists.txt:41 (target_link_libraries):
  Attempt to add link library "pthread" to target "lib_foo"
  which is not built in this directory.

Question:

How do I link pthread to lib_foo, or specify that targets with a dependency on lib_foo also have a dependency on pthread?

回答1:

IMPORTED_LINK_INTERFACE_LIBRARIES:

There is an additional target property you can set, IMPORTED_LINK_INTERFACE_LIBRARIES

Transitive link interface of an IMPORTED target.

Set this to the list of libraries whose interface is included when an IMPORTED library target is linked to another target.

The libraries will be included on the link line for the target.

Unlike the LINK_INTERFACE_LIBRARIES property, this property applies to all imported target types, including STATIC libraries.

set_target_properties(lib_foo 
    PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES 
    pthread
    )

-pthread Compiler Flag:

However, in this particular case, pthread linking issues, the problem would likely be solved by adding -pthread to your compiler flags

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread" )

From man gcc:

-pthread Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.

It causes files to be compiled with -D_REENTRANT, and linked with -lpthread. On other platforms, this could differ. Use -pthread for most portability.

See this question for more information



标签: c++ cmake