将FetchContent_Declare与CMAKE_ARGS一起使用 [英] Using FetchContent_Declare together with CMAKE_ARGS

查看:1195
本文介绍了将FetchContent_Declare与CMAKE_ARGS一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 cmake v3.13,我想为 SEAL 更改我的 ExternalProject_Add()库到:

I'm using cmake v3.13 and I want to change my ExternalProject_Add() for the SEAL library to:

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() 仅下载库。

When I was using ExternalProject_Add() I've used CMAKE_ARGS -DBUILD_SHARED_LIBS=ON and this doesn't work with FetchContent_Declare() that only downloads the library.

SEAL v3.5.2 CMakeLists.txt 使用它来检查共享库是否需要构建:

The SEAL v3.5.2 CMakeLists.txt uses this to check if a shared library needs to be built:

# 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()

有没有一种方法可以使用 FetchContent_Declare()下载 SEAL CMakeLists 设置在构建时将 CMAKE_ARGS -DBUILD_SHARED_LIBS = ON 参数传递给下载的库吗?

Is there a way to download the SEAL library using FetchContent_Declare() and then use some CMakeLists setting to pass the CMAKE_ARGS -DBUILD_SHARED_LIBS=ON argument to the downloaded library when building it?

推荐答案

顶级构建某些项目时,可以使用命令行选项将参数传递给它

When build some project at the top-level, you may pass a parameter to it using command line option

-D<VARIABLE>=<VALUE>

ExternalProject_Add 构建项目就像

使用子项目构建某些项目时> add_subdirectory 方法,则可以使用相同的命令行选项

When build some project as a subproject using add_subdirectory approach, you may use the same command line option

-D<VARIABLE>=<VALUE>

用于顶级项目,并且此参数为也传播到子项目

如果不需要将参数传递给顶级项目,则可以进行仿真 CMakeLists.txt 中的参数设置,使用设置(缓存内部)命令流:

If passing the parameter to the top-level project is not desired, then you may emulate the parameter setting inside CMakeLists.txt using set(CACHE INTERNAL) command flow:

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

确保此行是在之前 add_subdirectory()调用发出的(否则不会影响子项目)。

Make sure this line is issued before add_subdirectory() call (otherwise it won't affect the subproject).

因此,在您的情况下,您可以使用以下代码:

So in your case you may use following code:

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()






当顶级项目不使用为子项目设置参数。


All above works perfectly when top-level project doesn't use the parameter set for subproject.

如果顶级项目和子项目都受同一参数的影响,而您只想对该子项目的参数进行硬编码,那么事情就变成了更复杂。您需要在 add_subdirectory 调用后恢复参数:

If both top-level project and subproject are affected by the same parameter, and you want to hardcode the parameter for the subdproject only, then things become more complicated. You need to restore the parameter after add_subdirectory call:

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)

注意,在恢复参数的情况下,<使用code> set(CACHE TYPE FORCE)命令流代替 set(CACHE INTERNAL)。这样不仅可以恢复CACHE变量的值,还可以恢复其类型(如CMake GUI中所示)。

Note, that in case of restoring parameter, set(CACHE TYPE FORCE) command flow is used instead of set(CACHE INTERNAL). This restores not only a value of the CACHE variable, but also its type, which is shown in CMake GUI.

这篇关于将FetchContent_Declare与CMAKE_ARGS一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆