1

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?

Rerito
  • 5,886
  • 21
  • 47
  • It comes with headers only. These are included into your sources and will be compiled together with those. There is no library to link against, so you don't need `target_link_libraries` either for that one. Just make sure that the headers are found on include path. – Aconcagua Nov 08 '19 at 10:40
  • In that case `target_link_libraries` makes sure the headers are added to the proper build/install interfaces. It still is mandatory if I understand correctly. – Rerito Nov 08 '19 at 11:10
  • 1
    Wrong duplicate... I am not trying to create an interface target, I am trying to have CMake manage the download and then the creation of an interface target. The thirdparty I am refering to already does what is mentioned in https://stackoverflow.com/questions/5957134/how-do-i-set-up-cmake-to-generate-header-only-projects – Rerito Nov 08 '19 at 12:46

1 Answers1

0

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.

Arne J
  • 415
  • 2
  • 9
  • The point is to automate that step by using ExternalProject_add, which will in the end add the target `kvasir_mpl` (which is defined by the kvasir::mpl library) – Rerito Nov 08 '19 at 12:43