Использование FetchContent_Declare вместе с CMAKE_ARGS - PullRequest
1 голос
/ 30 мая 2020

Я использую cmake v3.13 и хочу изменить свою ExternalProject_Add() для библиотеки SEAL на:

include(FetchContent)
# Get the seal library
set(SEAL "seal")
FetchContent_Declare(
        ${SEAL}
        GIT_REPOSITORY  https://github.com/microsoft/SEAL
        GIT_TAG         v3.5.2

)
FetchContent_GetProperties(${SEAL})
if(NOT ${SEAL}_POPULATED)
    FetchContent_Populate(${SEAL})
    add_subdirectory(${${SEAL}_SOURCE_DIR} ${${SEAL}_BINARY_DIR})
endif()

Когда я был с использованием ExternalProject_Add() Я использовал CMAKE_ARGS -DBUILD_SHARED_LIBS=ON, и это не работает с FetchContent_Declare(), который только загружает библиотеку.

SEAL v3.5.2 CMakeLists.txt использует это для проверки необходимости создания разделяемой библиотеки:

# Should we build also the shared library?
set(BUILD_SHARED_LIBS_STR "Build shared library")
option(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_STR} OFF)
if(MSVC AND BUILD_SHARED_LIBS)
    message(WARNING "This build system only supports a static build; disabling `BUILD_SHARED_LIBS`")
    set(BUILD_SHARED_LIBS OFF CACHE BOOL ${BUILD_SHARED_LIBS_STR} FORCE)
endif()

# Conditionally build the shared library
if(BUILD_SHARED_LIBS)
    add_library(seal_shared SHARED $<TARGET_OBJECTS:seal_obj>)
    set_target_properties(seal_shared PROPERTIES OUTPUT_NAME seal)
    seal_set_version(seal_shared)
    seal_set_soversion(seal_shared)
    seal_set_language(seal_shared)
    seal_set_include_directories(seal_shared)
    seal_link_threads(seal_shared)

    # Conditionally add MSGSL include directory to build interface
    if(SEAL_USE_MSGSL AND NOT MSVC)
        target_include_directories(seal_shared PUBLIC $<BUILD_INTERFACE:${MSGSL_INCLUDE_DIR}>)
    endif()

    if(SEAL_USE_ZLIB AND NOT MSVC)
        # In the shared build we link zlibstatic into the shared library
        target_link_libraries(seal_shared PRIVATE zlibstatic)
    endif()

    seal_install_target(seal_shared SEALTargets)
endif()

Есть ли способ загрузить библиотеку SEAL , используя FetchContent_Declare(), а затем использовать некоторые * 1024 Настройка * CMakeLists для передачи аргумента CMAKE_ARGS -DBUILD_SHARED_LIBS=ON загруженной библиотеке при ее сборке?

1 Ответ

2 голосов
/ 30 мая 2020

При сборке проекта на верхнем уровне вы можете передать ему параметр, используя параметр командной строки

-D<VARIABLE>=<VALUE>

(ExternalProject_Add строит проект «как если бы» верхнего уровня, поэтому передача параметров технически такая же).

При сборке какого-либо проекта как подпроекта с использованием подхода add_subdirectory вы можете использовать тот же параметр командной строки

-D<VARIABLE>=<VALUE>

для проекта верхнего уровня , и этот параметр будет распространен на подпроект тоже.

При передаче параметр в проект верхнего уровня нежелателен, тогда вы можете эмулировать настройку параметра внутри CMakeLists.txt, используя set (CACHE INTERNAL) поток команд:

set(<PARAMETER> <VALUE> CACHE INTERNAL "<some description>")

Убедитесь, что эта строка выдается перед вызовом add_subdirectory() (иначе это не повлияет на подпроект).

Итак, в вашем случае вы можете использовать следующий код:

if(NOT ${SEAL}_POPULATED)
    FetchContent_Populate(${SEAL})
    # Make subproject to use 'BUILD_SHARED_LIBS=ON' setting.
    set(BUILD_SHARED_LIBS ON CACHE INTERNAL "Build SHARED libraries")
    add_subdirectory(${${SEAL}_SOURCE_DIR} ${${SEAL}_BINARY_DIR})
endif()

Все вышеперечисленное отлично работает, когда проект верхнего уровня не использует набор параметров для подпроекта.

Если и на проект верхнего уровня, и на подпроект влияет один и тот же параметр, и вы хотите жестко закодировать параметр только для подпроекта, тогда все усложняется. Параметр необходимо восстановить после вызова add_subdirectory:

if(NOT ${SEAL}_POPULATED)
    FetchContent_Populate(${SEAL})

    # Store the old value of the 'BUILD_SHARED_LIBS'
    set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS})
    # Make subproject to use 'BUILD_SHARED_LIBS=ON' setting.
    set(BUILD_SHARED_LIBS ON CACHE INTERNAL "Build SHARED libraries")

    add_subdirectory(${${SEAL}_SOURCE_DIR} ${${SEAL}_BINARY_DIR})

    # Restore the old value of the parameter
    set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD} CACHE BOOL "Type of libraries to build" FORCE)
endif()

# ...

# The library will be created according to "original" value for BUILD_SHARED_LIBS option.
add_library(top_lib top_lib.c)

Обратите внимание, что в случае восстановления параметра вместо set(CACHE INTERNAL) используется поток команд set(CACHE TYPE FORCE). Это восстанавливает не только значение переменной CACHE, но и ее тип, который показан в CMake GUI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...