I am working on a header-only C++11 library which uses modern CMake. By "modern," I mean not only using CMake v3.0+ but also trying to use as much as possible the best practices in Daniel Pfeifer's talk.
I have done some research on my question, but the answers are mostly regarding modifying the LINK_FLAGS directly in the global level, which I do not want to have. Right now, in my project, I require a minimum version of 3.9.0 of CMake because of some features I am using.
My question is about whether/how to add LINK_FLAGS coming from two of my dependencies: BLAS and LAPACK. Basically, I have the following excerpt from my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.9.0)
project(polo VERSION 1.0.0 LANGUAGES C CXX)
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
add_library(polo INTERFACE)
add_library(polo::polo ALIAS polo)
target_compile_features(polo INTERFACE cxx_std_11)
target_include_directories(polo
INTERFACE
$<BUILD_INTERFACE:${polo_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(polo
INTERFACE
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
)
set_property(
TARGET
polo
PROPERTY LINK_FLAGS
${BLAS_LINKER_FLAGS}
${LAPACK_LINKER_FLAGS}
)
As far as I can understand from documentations of the FindBLAS and FindLAPACK modules, I need to inform my users at least about {BLAS,LAPACK}_LIBRARIES and {BLAS,LAPACK}_LINKER_FLAGS. For the former, I think I have handled the issue properly. However, for the latter, I need to use either set_target_properties or set_property. Between the two, the latter seems to give me a cleaner solution in that I can use both variables coming from Find{BLAS,LAPACK} modules together. When I try to build my library using the above solution, I get the obvious error:
CMake Error at src/CMakeLists.txt:32 (set_property):
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "LINK_FLAGS" is not allowed.
My question is two folds:
- Should I use
*_LINKER_FLAGScoming from the modules at all, and, - If yes, how should I integrate them cleanly into my CMake project?
As for the 2. above, I have seen some suggestions/answers for using target_link_libraries, but I am not sure whether that is the option to go for.
Thank you for your time!
First of all, I do apologize to the community for cross posting the issue.
Matthieu has tried helping me with two options:
LINK_FLAGS, and,IMPORTEDlibrary option, which he has kept as the final answer (please see the comments there for the motivation).Unfortunately, neither of these solutions seem to work. The first one is not a clean way of informing the consumer about your dependencies. The second version seems to work with
INTERFACElibraries, but any consumer that depends on theINTERFACElibrary that build an object, such as, e.g., a C-API of the header-only library that builds aSHAREDlibrary, has problems building and installing theIMPORTEDlibrary.The solution seems to be to use CMake
v3.13and above, which, as of the posting date, is in the release candidate (rc3) state. Apparently, CMakev3.13will be introducingINTERFACE_LINK_OPTIONSfor such purposes.EDIT. CMake
v3.13has been released.