CMake 设置同一个变量两次?

问题描述 投票:0回答:3

我在调查 CMake 文件时发现了一个奇怪的行

cmake_minimum_required(VERSION 3.11)
project(Project1)

set(SRC_FILES ${SRC_FILES} ./file1.cpp)
set(SRC_FILES ${SRC_FILES} ./file2.cpp) # sets the same variable

add_library(lib_name ${SRC_FILES})

为什么我们要设置变量

SRC_FILES
两次?是bug吗?

我正在检查变量的值

message(SOURCES="${SRC_FILES}")

它打印

SOURCES="./file1.cpp./file2.cpp

它是有效的 CMake 文件吗?

cmake
3个回答
2
投票

第二个“集合”分配

SRC_FILES
${SRC_FILES} ./file2.cpp
的组合值。所以它有效地appends变量。因此,最终结果是
SRC_FILES
同时包含 file1 和 file2.

这是一个完全有效的 CMake 文件。当然,在这个具体示例中,像这样将两者分配在一起会更简单:

set(SRC_FILES
   ${SRC_FILES} # This can be dropped if SRC_FILES doesn't contain previous value
   ./file1.cpp
   ./file2.cpp
)

注意:在现代 CMake 中,像这样使用

list(APPEND <list> new_value)
是一种更优雅的方式:

list(APPEND SRC_FILES ./file2.cpp)

1
投票

是的,在cmake中重新赋值一个变量是完美的。请注意,尽管您可以(并且恕我直言)使用任一个

list(APPEND SRC_FILES ./file1.cpp ./file2.cpp)

set(SRC_FILES ./file1.cpp ./file2.cpp)

取而代之的是更容易阅读/更短的逻辑。

如果您希望

SRC_FILES
变量在您的逻辑之前为空,请使用后者。在 99% 的情况下,您不会从父 cmake 目录传递预先存在的变量,因此通常采用第二种方法。否则,您最终可能会在 lib 的源文件中找到来自其他目标的源代码。


0
投票

记住当你开始编码时看到这样一行:

x = x + 1

你发现的是 CMake 对这种模式的看法。

CMake 的

set
命令将创建一个列表,如果使用两个以上的参数调用。

所以第一个

set
创建一个包含
nothing
的字符串变量SRC_FILES(默认情况下CMake将未设置的变量评估为nothing)和
"./file1.cpp"
,第二个
set
SRC_FILES
内容创建一个字符串列表和
"./file2.cpp"
.

其他答案已经指出了将

SRC_FILES
设置为相同值的其他方法。他们没有说清楚的是
SRC_FILES
完全是多余的。它甚至被认为是现代 CMake 中的反模式。请参阅项目Avoid custom variables in the arguments of project commands.

旁注:路径是相对于当前 CMake 文件的,因此也不需要

./

所以干净、可读和惯用的代码将是

add_library(library_name file1.cpp file2.cpp)

它说“从 file1.cppfile2.cpp 创建一个库 library_name”,这就是所有需要说的。

© www.soinside.com 2019 - 2024. All rights reserved.