Создайте цель CMake, только если зависимости удовлетворены

У меня есть проект CMake с несколькими библиотеками и исполняемыми файлами. Некоторые цели имеют зависимости, которые могут не удовлетворяться на всех платформах. В этом случае я бы хотел, чтобы CMake работал и генерировал файлы Makefile (или другие проекты сборки), которые имеют смысл.

Например:

  • libFOO -> зависит libX11 (сказать)
  • execBAR -> зависит libFOO
  • exexQUUX -> без депс

В системе с установленной libX11 все цели могут быть построены. В системе без, только execQUUX будет доступно для строительства.

На данный момент я делаю что-то вроде этого:

# work out if we can build this target
set(buildLibFOO LibX11_FOUND)

if (${buildLibFOO})
    add_library(libFOO ... )
    target_link_libraries(libFOO LibX11_LIBRARY)
endif()

set(buildExecBAR true)

# work out if we can build this target
if (NOT TARGET libFOO)
    set(buildExecBAR false)
endif()

if (${buildExecBAR})
    add_exec(execBAR ...)
    target_link_libraries(execBAR libFOO)
endif() 

# always build this one
add_exec(execQUUX ...)

Тем не менее, это выглядит немного глупо, так как мне нужно тщательно подумать о том, что проверять для каждой цели, вместо того, чтобы сказать CMake: "эти задержки необходимы для этих целей, если они отсутствуют, пропустите цель".

Есть ли более простой (или более правильный) способ сделать это?

1 ответ

Решение

эти депы необходимы для этих целей, если пропущены, пропустите цель

Насколько я знаю, в CMake такой функциональности нет.

Но вы можете создать функцию, которая добавляет библиотеку / исполняемый файл только тогда, когда ее зависимости удовлетворены. Что-то вроде этого:

include(CMakeParseArguments)

# Similar as *add_executable*, but additionally accepts DEPENDS option.
# All arguments after this option are treated as libraries targets for link with;
# executable is created only when these targets exist.
function(add_executable_depends name)
    cmake_parse_arguments(MY_EXEC "" "" "DEPENDS" ${ARGN})
    foreach(depend ${MY_EXEC_DEPENDS})
        if(NOT TARGET ${depend})
            return()
        endif()
    endforeach()
    add_executable(${name} ${MY_EXEC_UNPARSED_ARGUMENTS})
    target_link_libraries(${name} ${MY_EXEC_DEPENDS})
endfunction()

Пример использования:

# work out if we can build this target
set(buildLibFOO LibX11_FOUND)

if (${buildLibFOO})
    add_library(libFOO ... )
    target_link_libraries(libFOO LibX11_LIBRARY)
endif()

# Add executable (and link with libFOO) only when libFOO exists.
add_executable_depends(execBAR ... DEPENDS libFOO)

# always build this one(similar to add_executable)
add_executable_depends(execQUUX ...)
Другие вопросы по тегам