在cmake中为INTERFACE库设置LINK_FLAGS

时间:2018-11-19 12:40:43

标签: c++ c++11 cmake cmake-modules

我正在研究使用现代CMake的仅标头C ++ 11库。 “现代”,我的意思是不仅要使用CMake v3.0+,而且还要尝试尽可能多地使用Daniel Pfeifer的talk中的最佳实践。

我已经对我的问题进行了一些研究,但是答案大多是关于直接在全球范围内修改LINK_FLAGS,而我不想这样做。现在,由于我正在使用某些功能,在我的项目中,我要求最低版本的3.9.0 CMake。

我的问题是是否/如何添加LINK_FLAGS来自我的两个依赖:BLAS和LAPACK。基本上,我摘自CMakeLists.txt文件的以下摘录:

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}
)

据我从FindBLASFindLAPACK模块的文档中了解到的,我需要至少通知{BLAS,LAPACK}_LIBRARIES{BLAS,LAPACK}_LINKER_FLAGS的用户。对于前者,我认为我已经妥善处理了这个问题。但是,对于后者,我需要使用set_target_propertiesset_property。在这两者之间,后者似乎为我提供了更简洁的解决方案,因为我可以将Find{BLAS,LAPACK}模块中的两个变量一起使用。当我尝试使用上述解决方案构建库时,出现了明显的错误:

CMake Error at src/CMakeLists.txt:32 (set_property):
  INTERFACE_LIBRARY targets may only have whitelisted properties.  The
  property "LINK_FLAGS" is not allowed.

我的问题有两个方面:

  1. 我应该完全使用来自模块的*_LINKER_FLAGS吗,
  2. 如果是,我应该如何将它们整洁地集成到我的CMake项目中?

对于上面的2.,我已经看到了一些使用target_link_libraries的建议/答案,但是我不确定这是否是一个选择。

谢谢您的时间!

2 个答案:

答案 0 :(得分:1)

首先,我向cross posting问题向社区道歉。

马修(Matthieu)尝试通过以下两种方法来帮助我:

  1. 提供一个辅助函数,以便库的使用者可以调用该函数以正确处理LINK_FLAGS,并且,
  2. IMPORTED库选项,他将其保留为最终答案(请查看此处的注释以获取动机)。

不幸的是,这些解决方案似乎都不起作用。第一种方法不是一种向消费者通知您的依赖项的干净方法。第二个版本似乎可以与INTERFACE库一起使用,但是任何依赖INTERFACE库来构建对象的使用者,例如,仅头文件库的C-API可以构建对象。 SHARED库,在构建和安装IMPORTED库时遇到问题。

解决方案似乎是使用CMake v3.13及更高版本,截至发布日期,该版本处于候选发布(rc3)状态。 Apparently,CMake v3.13将为此目的引入INTERFACE_LINK_OPTIONS

编辑。 CMake v3.13已经released

答案 1 :(得分:0)

令人高兴的是,您可以为他们提供一个帮助器.cmake(称为polo-config.cmake)。

.cmake文件中的一个选项是创建一个IMPORTED library,您可以在其中保留所需的标志,这次可能是PUBLIC,以便将其传播给下一个用户。 / p>

当然,您需要正确添加库,设置包含路径,库的路径...