Установка набора параметров компиляции в CMake неповторяющимся способом

#cmake

#cmake

Вопрос:

Я работаю над проектом, в котором есть множество параметров конфигурации. На данный момент код ожидает, что они будут переданы в командной строке через -D . Они жестко запрограммированы в старом скрипте сборки, я хочу предоставить их через CMake.

Для логических параметров я придумал эту конструкцию:

 option(FOO1 "" ON)
option(FOO2 "" ON)
option(FOO3 "" OFF)

target_compile_definitions(
        mylib
        PRIVATE


lt;


lt;BOOL:${FOO1}>:FOO1>


lt;


lt;BOOL:${FOO2}>:FOO2>


lt;


lt;BOOL:${FOO3}>:FOO3>
)

Кажется, это работает, но мне нужно писать FOO1 три раза, и это выглядит довольно уродливо. Затем в коде можно #ifdef FOO1 проверить это.

Для оцениваемых параметров у меня есть следующее:

 set(BAR1 default_value CACHE STRING "")
set(BAR2 default_value CACHE STRING "")

target_compile_definitions(
        mylib
        PRIVATE
        BAR1=${BAR1}
        BAR2=${BAR2}
)
 

Снова мне нужно написать BAR1 три раза. По крайней мере, в коде я могу просто использовать определения и не нужно явно определять их снова.

Я открыт для использования a config.h.in для этого. Но там мне пришлось бы написать FOO1 = "@FOO1@" или FOO1 = "${FOO1}" , снова указав опцию еще два раза.

Есть ли какой-нибудь более умный способ определить набор определений компиляции?

Комментарии:

1.«но мне нужно написать FOO1 три раза» — вы имеете в виду «написать FOO1 два раза»? У вас есть три строки, похожие $<$<BOOL:${FOO1}>:FOO1> , но название параметра отличается в каждой строке. Если вы не хотите повторять $<$<BOOL:${option}>:option> несколько раз для разных option имен, вы можете создать функцию / макрос для этой опции и вызвать просто вызовите эту функцию 3 раза. Или вызовы iterate ( foreach ) для этой функции для каждого имени параметра. Или выполните итерацию по именам параметров внутри функции… Слишком много подходов. Просто представьте себе способ, как вы собираетесь использовать функцию / макрос.

Ответ №1:

Просто используйте цикл для этой цели:

 foreach(_VAR IN ITEMS
    FOO1
    FOO2
    FOO3
    )

    if(${_VAR})
        target_compile_definitions(mylib PRIVATE "${_VAR}")
    endif()
endforeach()

foreach(_VAR IN ITEMS
    BAR1
    BAR2
    BAR3
    )

    target_compile_definitions(mylib PRIVATE "${_VAR}=${${_VAR}}")
endforeach()
 

К сожалению, это на самом деле длиннее, чем ваш код, но это позволяет избежать повторения. Для большего количества опций это было бы более целесообразно.

Комментарии:

1. Учитывая количество переменных, которые у меня есть, этот параметр все еще короче. И, что наиболее важно, проще в обслуживании. Большое спасибо!