在 cmake 中为 INTERFACE 库设置 LINK_FLAGS

Set LINK_FLAGS for INTERFACE libraries in cmake

我正在开发一个使用现代 CMake 的 header-only C++11 库。 "modern," 我的意思不仅是使用 CMake v3.0+,而且还尝试尽可能多地使用 Daniel Pfeifer 的 talk.

中的最佳实践

我对我的问题做了一些研究,但答案主要是关于直接在全局级别修改 LINK_FLAGS,这是我不想看到的。现在,在我的项目中,由于我正在使用的某些功能,我需要最低版本的 CMake 3.9.0

我的问题是关于 whether/how 添加来自我的两个依赖项的 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}
)

据我从 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 的文档中了解到。在两者之间,后者似乎给了我一个更清晰的解决方案,因为我可以同时使用来自 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.,我看到一些 suggestions/answers 使用 target_link_libraries,但我不确定是否可以选择。

感谢您的宝贵时间!

好的是你可以为他们提供一个助手.cmake(称为polo-config.cmake)。

.cmake 文件中的一个选项是创建一个 IMPORTED library,您可以在其中保存您想要的标志,这次可能是 PUBLIC,以便将它们传播给下一个用户.

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

首先,对于 cross posting 这个问题,我向社区表示歉意。

Matthieu 尝试通过两个选项帮助我:

  1. 提供辅助函数,以便库的使用者可以调用该函数来正确处理 LINK_FLAGS,并且,
  2. IMPORTED 库选项,他将其保留为最终答案(动机请参阅那里的评论)。

不幸的是,这些解决方案似乎都不起作用。第一个不是告知消费者您的依赖项的干净方式。第二个版本似乎可以与 INTERFACE 库一起使用,但是任何依赖于构建 object 的 INTERFACE 库的消费者,例如 C-API header-only 构建 SHARED 库的库,在构建和安装 IMPORTED 库时遇到问题。

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

EDIT. CMake v3.13released.