Я исследовал файл 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 два раза? это ошибка?
Я проверял значение переменной
message(SOURCES = "${SRC_FILES}")
и он печатает
ИСТОЧНИКИ="./file1.cpp./file2.cpp
Является ли это допустимым файлом CMake?
После того, как у вас есть цель с add_library(lib_name ${SRC_FILES}), вы даже можете добавить дополнительные источники к цели lib_name с помощью https://cmake.org/cmake/help/latest/command/target_sources.html





Второй «набор» присваивает SRC_FILES комбинированное значение ${SRC_FILES} ./file2.cpp. Таким образом, он эффективно добавляет переменную. Таким образом, окончательный результат SRC_FILES содержит и файл1, и файл2.
Это полностью правильный файл 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)
Поскольку вы упомянули Modern CMake в своем ответе, вы будете знать, почему следует избегать пользовательских переменных в аргументах команд проекта. Решение Modern CMake состоит в том, чтобы вообще не иметь переменной SRC_FILES.
@Фридрих Спасибо! Это интересное и полезное руководство.
Да, в cmake можно переназначить переменную. Обратите внимание, что вы могли бы (и имхо должны) использовать либо
list(APPEND SRC_FILES ./file1.cpp ./file2.cpp)
или
set(SRC_FILES ./file1.cpp ./file2.cpp)
вместо этого для более удобного чтения/более короткой логики.
Используйте последнее, если вы ожидаете, что переменная SRC_FILES будет пустой до вашей логики. В 99% случаев вы не будете передавать уже существующую переменную из родительского каталога cmake, поэтому обычно лучше использовать вторую. В противном случае вы можете получить источники из других целей среди исходных файлов вашей библиотеки.
Помните, когда вы начали программировать и увидели такую строку:
x = x + 1
То, что вы нашли, — это подход CMake к этому шаблону.
Команда set CMake создаст список, если она вызывается с более чем двумя аргументами.
Таким образом, первый set создает строковую переменную SRC_FILES, ничего не содержащую (CMake по умолчанию оценивает неустановленные переменные как ничего), а "./file1.cpp", а второй set создает список строк из SRC_FILES содержимого и "./file2.cpp".
В других ответах указаны другие способы установки SRC_FILES того же значения. Чего они не смогли прояснить, так это того, что SRC_FILES совершенно лишний. Он даже считается анти-шаблоном в Modern CMake. См. пункт Избегайте пользовательских переменных в аргументах команд проекта.
Примечание: пути указаны относительно текущего файла CMake, поэтому нет необходимости в ./.
Таким образом, чистый, читаемый и идиоматический код будет
add_library(library_name file1.cpp file2.cpp)
В нем говорится «создать библиотеку имя_библиотеки из файлов file1.cpp и file2.cpp», и это действительно все, что нужно сказать.
Почему мы устанавливаем переменную SRC_FILES два раза? Предпочтение пользователя. Вы можете перечислить все исходные файлы в первый раз. это ошибка? Нет