CMake устанавливает одну и ту же переменную два раза?

Я исследовал файл 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?

Почему мы устанавливаем переменную SRC_FILES два раза? Предпочтение пользователя. Вы можете перечислить все исходные файлы в первый раз. это ошибка? Нет

drescherjm 18.05.2023 14:50

После того, как у вас есть цель с add_library(lib_name ${SRC_FILES}), вы даже можете добавить дополнительные источники к цели lib_name с помощью https://cmake.org/cmake/help/latest/command/target_sources.h‌​tml

drescherjm 18.05.2023 14:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
59
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Второй «набор» присваивает 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.

Friedrich 19.05.2023 08:20

@Фридрих Спасибо! Это интересное и полезное руководство.

vvv444 19.05.2023 10:15
Ответ принят как подходящий

Да, в 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», и это действительно все, что нужно сказать.

Другие вопросы по теме