将 FetchContent_Declare 与 CMAKE_ARGS 一起使用
Using FetchContent_Declare together with CMAKE_ARGS
我正在使用 cmake v3.13,我想将 SEAL 库的 ExternalProject_Add()
更改为:
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()
有没有办法使用 FetchContent_Declare()
下载 SEAL 库,然后使用一些 CMakeLists 设置来传递 CMAKE_ARGS -DBUILD_SHARED_LIBS=ON
构建时下载的库的参数?
在顶级构建一些项目时,您可以使用命令行选项
向它传递一个参数
-D<VARIABLE>=<VALUE>
(ExternalProject_Add
构建项目 "as if" 顶层,因此选项传递在技术上是相同的)。
当使用 add_subdirectory
方法将某些项目构建为 子项目 时,您可以使用相同的命令行选项
-D<VARIABLE>=<VALUE>
用于顶级项目,此参数将传播到子项目也是。
如果不需要将参数传递给顶层项目,那么您可以使用set(CACHE INTERNAL) 命令流程模拟CMakeLists.txt
中的参数设置:
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 TYPE FORCE)
命令流而不是 set(CACHE INTERNAL)
。这不仅恢复了 CACHE 变量的值,还恢复了它的类型,这在 CMake GUI 中显示。
我正在使用 cmake v3.13,我想将 SEAL 库的 ExternalProject_Add()
更改为:
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()
有没有办法使用 FetchContent_Declare()
下载 SEAL 库,然后使用一些 CMakeLists 设置来传递 CMAKE_ARGS -DBUILD_SHARED_LIBS=ON
构建时下载的库的参数?
在顶级构建一些项目时,您可以使用命令行选项
向它传递一个参数-D<VARIABLE>=<VALUE>
(ExternalProject_Add
构建项目 "as if" 顶层,因此选项传递在技术上是相同的)。
当使用 add_subdirectory
方法将某些项目构建为 子项目 时,您可以使用相同的命令行选项
-D<VARIABLE>=<VALUE>
用于顶级项目,此参数将传播到子项目也是。
如果不需要将参数传递给顶层项目,那么您可以使用set(CACHE INTERNAL) 命令流程模拟CMakeLists.txt
中的参数设置:
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 TYPE FORCE)
命令流而不是 set(CACHE INTERNAL)
。这不仅恢复了 CACHE 变量的值,还恢复了它的类型,这在 CMake GUI 中显示。