简体   繁体   中英

How to handle header-only thirdparties with CMake?

In a project, we use ExternalProject_add to manage regular third parties and drive their download and build process (some come from regular URL, others from a git repository)

Recently, I came across the need to add an extra thirdparty. It is so far the only header-only thirdparty we would have. For those interested, it is kvasir_mpl .

However, when I try to target_link_libraries with kvasir_mpl , CMake always considers it as a regular library and in the end the build fails:

[ 83%] Linking CXX executable app
/usr/bin/ld: cannot find -lkvasir_mpl

I devised a minimal example to reproduce the problem:

./CMakeLists.txt:

cmake_minimum_required( VERSION 3.7.0 )

project( Test CXX )

add_subdirectory( kvasir )
add_subdirectory( app )

./app/CMakeLists.txt:

project( App CXX )

add_executable( app main.cpp )

target_link_libraries( app kvasir_mpl )

kvasirmpl/CMakeLists.txt:

cmake_minimum_required( VERSION 3.7.0 )

project( KvasirMpl )

include( ExternalProject )

ExternalProject_Add(
    3rdparty_kvasirmpl

    GIT_REPOSITORY https://github.com/kvasir-io/mpl
    GIT_TAG origin/development
    INSTALL_COMMAND ""
    BUILD_COMMAND "" )

Note that if I use the keyword signature target_link_libraries( app INTERFACE kvasir_mpl ) my issue is resolved. However in our real use case, the target_link_libraries is run through custom CMake functions and can be passed anything from a regular library file to a CMake target forcing us to use the plain signature.

Is there a way to make the plain signature work in this case?

In kvasirmpl/CMakeLists.txt, add the following lines:

add_library(kvasir_mpl INTERFACE)
target_include_directories(kvasir_mpl PUBLIC <includedirs>)
set_target_properties(kvasir_mpl PROPERTIES LINKER_LANGUAGE CXX)

This tells CMake there is a library not built by CMake (Interface), what the include directories are when linking with that library... You could also add extra compile flags etc. The linker language must be specified because CMake wishes to know whether it's C or C++, and won't deduct that in a header-only library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM