我应该如何在没有变量的情况下将相同的参数传递给 CMAKE 中的多个目标?

How am I supposed to pass along the same arguments to multiple targets in CMAKE with out variables?

本文关键字:CMAKE 参数传递 目标 我应该 情况下 变量      更新时间:2023-10-16

我正在重构一个cmake文件,以便将现代CMAKE实践用于个人项目。 但是,由于我不相信操作系统是作为通用变量出现的,为了在 CMAKE 中测试操作系统,我必须执行以下操作(基于此答案(:

if(UNIX AND NOT APPLE)
set(LINUX TRUE)
endif()
#...
if(LINUX)
set(MY_PROJECT_LINK_ARGUMENTS ...)
elseif(WIN32)
set(MY_PROJECT_LINK_ARGUMENTS ...)
else()
message( FATAL_ERROR "Unsupported operating system")
endif()
add_library(xxx STATIC)
#...
target_link_libraries(xxx INTERFACE ${MY_PROJECT_LINK_LIBRARIES} ...)
add_library(yyy STATIC)
#...
target_link_libraries(yyy INTERFACE ${MY_PROJECT_LINK_LIBRARIES} ...)
add_library(zzz STATIC)
#...
target_link_libraries(zzz INTERFACE ${MY_PROJECT_LINK_LIBRARIES} ...)

我感到困惑的是如何在惯用的现代基于目标的 CMAKE 中实现这一目标。 由于我不知道存在通常封装操作系统的 CMAKE 变量,因此我创建了一个操作系统变量。

if(UNIX AND NOT APPLE)
set(LINUX TRUE)
set(PROJECT_OS LINUX)
elseif(APPLE)
set(PROJECT_OS APPLE)
elseif(WIN32)
set(PROJECT_OS WIN32)
endif()

然后我创建一个生成器表达式

target_link_libraries(xxx INTERFACE
$<$<BOOL:$<PROJECT_OS:LINUX>>: ...> 
$<$<BOOL:$<PROJECT_OS:WIN32>>: ...>
...)

但是现在我已经创建了一个变量,如果我将相同的参数传递给每个目标(xxxyyyzzz(,我会多次重复相同的内容。

我看到解决这个问题的唯一方法是使用变量,但现代 CMAKE 指南显然说我们应该远离变量(示例 A、B 和 C(,那么我应该如何在没有变量的情况下完成这项任务呢?

变量本身并不是邪恶的。它们有两个主要的潜在问题:

  • 他们引入了全球性的状态,这可能会成为维护的噩梦。
  • 它们可能会导致 CMake 项目不完全导出,从而给需要在 CMake 系统中依赖您的项目的每个人带来问题。

创建项目全局变量以在操作系统之间进行更细粒度的区分非常简单,不会有这些问题。从维护的角度来看,将依赖于操作系统的链接参数放入变量中感觉很臭。我会保留操作系统变量并将依赖于操作系统的链接放入一个函数中,如下所示:

...
function(set_os_dependent_dependencies target_name)
if (LINUX)
target_link_libraries(${target_name} ...)
elseif(WIN32)
target_link_libraries(${target_name} ...)
endif()
endfunction()
add_library(xxx STATIC)
set_os_dependent_dependencies(xxx)
...