У меня работает следующее выражение генератора, которое устанавливает флаг /GS
, если компилятор MSVC, и устанавливает его для конфигураций сборки RelWithDebInfo
и Release
:
target_compile_options(mytarget PRIVATE "$<$<CONFIG:Release>:$<$<CXX_COMPILER_ID:MSVC>:/GS>>$<$<CONFIG:RelWithDebInfo>:$<$<CXX_COMPILER_ID:MSVC>:/GS>>")
Теперь я также хочу позволить пользователю настроить это, и я добавил option
: option(MYTARGET_ENABLE_GS "Enable /GS" OFF)
Итак, теперь я (очевидно) хочу включить /GS
флаг если пользователь включил эту опцию, и если они это сделали, я хочу добавить ее если компилятор MSVC, и он должен быть добавлен к Release
и RelWithDebInfo
конфигурации.
Это довольно много, и я не могу понять, как это правильно.Это насколько я получил:
target_compile_options(mytarget PRIVATE "$<$<BOOL:MYTARGET_ENABLE_GS>:$<$<CONFIG:Release>:$<$<CXX_COMPILER_ID:MSVC>:/GS>>$<$<CONFIG:RelWithDebInfo>:$<$<CXX_COMPILER_ID:MSVC>:/GS>>>")
Редактировать: Исправлено, см. Ниже.
Мне пришлось использовать $<$<BOOL:...>>
, потому что это "переводит"option
(который может быть вкл / выкл или true / false, до 0
или 1
, в котором нуждается выражение генератора. Однако вышеприведенная строка не работает: она не добавляет (или не добавляет)/GS
.
Я хотел бы знать:
1) Где моя ошибка?Как это сделать?И
2) Подобные вещи приводят к довольно запутанным вложенным выражениям, которые действительно трудно читать - представьте, что через 6 месяцев снова читаете эту строку кода, даже если это задокументировано.И это так просто - потерять >
или что-то в этом роде.Я мог бы, вероятно, использовать «ручной» if
s, чтобы сделать это более читабельным, но представьте, что у вас есть 5-10 таких опций - запись if
/ end
с target_compile_options
внутри приводит к 15-30 строкамif
/ end
код, на который тоже не очень приятно смотреть.Какой лучший способ сделать это?
Редактировать: Я был почти там.Переменные должны быть заключены в ${...}
в выражениях генератора.Так, например: target_compile_options(mytarget PRIVATE "$<$<BOOL:${MYTARGET_ENABLE_GS}>:$<$<CONFIG:Release>:$<$<CXX_COMPILER_ID:MSVC>:/GS>>$<$<CONFIG:RelWithDebInfo>:$<$<CXX_COMPILER_ID:MSVC>:/GS>>>")
, и это прекрасно работает.
Что все еще оставляет пункт "2)", о котором я бы хотел узнать.