#cmake #cmake-language #cmakelists-options
Вопрос:
Я новичок в CMake, и мне было интересно, есть ли возможность исключить определенные источники из target_sources()
на основе переменной.
Допустим, у меня есть это ниже
target_sources(myTarget
PUBLIC
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
myDir3/src/c.c
INTERFACE
)
target_include_directories(myTarget
PUBLIC
PRIVATE
myDir1/inc
myDir2/inc
myDir3/inc
INTERFACE
)
Я хотел бы исключить/включить источники/каталоги из myDir3 на основе флага, называемого myFlag
т. Е. Как я могу этого достичь?
target_sources(myTarget
PUBLIC
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
if(DEFINED myFlag)
myDir3/src/c.c
endif()
INTERFACE
)
target_include_directories(myTarget
PUBLIC
PRIVATE
myDir1/inc
myDir2/inc
if(DEFINED myFlag)
myDir3/inc
endif()
INTERFACE
)
Комментарии:
1. оооочень
if(DEFINED myFlag) target_sources(myTarget myDir3/src/c.c) endif()
? Нет смысла добавлять один и тот же каталог в обаPUBLIC
иPRIVATE
…2. @KamilCuk я удалю с публики тогда…
3. Ты определенно не хочешь
if(DEFINED myFlag)
здесь находиться… что, еслиmyFlag
установлено значениеOFF
?4. Нет смысла включать
PUBLIC
илиINTERFACE
если к ним ничего не добавляется
Ответ №1:
Вы не можете поместить операторы if в список аргументов команды. target_*
Команды не перезаписываются, а добавляются, поэтому самым простым решением является следующее:
target_sources(
myTarget
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
)
if (myFlag)
target_sources(myTarget PRIVATE myDir3/src/c.c)
endif ()
target_include_directories(
myTarget
PRIVATE
myDir1/inc
myDir2/inc
)
if (myFlag)
target_include_directories(myTarget PRIVATE myDir3/inc)
endif ()
Другим более декларативным вариантом было бы использование выражения генератора, например:
target_sources(
myTarget
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
lt;
lt;BOOL:${myFlag}>:myDir3/src/c.c>
)
Комментарии:
1. один вопрос, второй вариант, который вы разместили, декларативный вариант, включает или отключает использование
myDir3/src/c.c
ifmyFlag
, если он присутствует?2. Если myFlag оценит что-то истинное (например
1
,ON
TRUE
, и т.д.), Оно будет включено.3. Спасибо! Как я могу использовать эту опцию, если я хотел бы включить файл в случае, если флаг «myflag» равен «0», «Ложь» или » ВЫКЛЮЧЕН‘?
4.
$<NOT:$<BOOL:...>>
см.: cmake.org/cmake/help/latest/manual/…5. Видите разницу?
$<$<NOT:$<BOOL:${myFlag}>>:myDir3/src/c.c>
. Если вам нужна дополнительная помощь, пожалуйста, задайте новый вопрос.
Ответ №2:
В зависимости от того, почему вы пытаетесь это сделать, также может иметь смысл сохранить их в качестве исходных файлов (чтобы они отображались, например, в целевом представлении Visual Studio), но пометить их как заголовки, чтобы они не компилировались:
if (NOT myFlag)
set_source_files_properties(
srcfile1.cpp
srcfile2.cpp
PROPERTIES
HEADER_FILE_ONLY ON
)
endif()
Это даже рекомендуется в документации CMake для этой цели:
Это полезно, если у вас есть некоторые исходные файлы, которые вы каким-то образом предварительно обрабатываете, а затем добавляете эти предварительно обработанные источники с помощью add_library() или add_executable(). Обычно в IDE не было бы ссылок на исходные источники, только на эти предварительно обработанные источники. Поэтому, установив это свойство для всех исходных исходных файлов в значение ВКЛЮЧЕНО, а затем либо вызвав add_library (), либо add_executable() при передаче как предварительно обработанных источников, так и исходных источников, либо используя target_sources() для добавления исходных исходных файлов, я сделаю именно то, что можно было бы ожидать.e. исходные исходные файлы будут видны в среде IDE и не будут созданы.
Комментарии:
1. В современном мире Visual Studio может напрямую открывать проекты CMake, и это фактически предпочтительный рабочий процесс. Так что причин для этого очень мало.
2. @AlexReinking: Я знаю, что Visual Studio может открывать проекты CMake напрямую, но если вы это сделаете, в представлении цели будут отображаться только файлы, добавленные в цель. Если вы не добавите заголовки, они не будут отображаться. Аналогично, если вы только условно добавляете исходный файл в целевые источники, он не будет отображаться, если не установлен флаг. И то же самое верно для других IDE, таких как Qt Creator. И я не вижу никакого способа, как IDE могли бы надежно сделать что-то по-другому. В конце концов, заголовки могут быть включены из любого места, как среда разработки должна определять, в какую цель их добавлять?