如何正确配置 FetchContent_Declare 以静态构建依赖项

问题描述 投票:0回答:1

在我的 CMake 项目(Win10、VS2017)的依赖项

subdirectory
中,我通过
FetchContent_Declare()
/
FetchContent_MakeAvailable()
机制检索和构建了多个库。我确实有一个问题
libcurl
虽然我在获取之前设置的一些选项似乎不会影响库的构建类型。

CMakeLists.txt(libcurl)

message(STATUS "Fetching dependency curl...")
set(BUILD_SHARED_LIBS OFF CACHE BOOL INTERNAL "Build shared libraries")
set(BUILD_CURL_EXE OFF CACHE BOOL INTERNAL "Build curl EXE")
# Only FILE and HTTP support required so deactivate the rest
set(CURL_ENABLE_SSL OFF CACHE BOOL INTERNAL "Enable SSL support")
set(CURL_DISABLE_FTP ON CACHE BOOL INTERNAL "Disable FTP support")
set(CURL_DISABLE_LDAP ON CACHE BOOL INTERNAL "Disable LDAP support")
set(CURL_DISABLE_POP3 ON CACHE BOOL INTERNAL "Disable POP3 support")
set(CURL_DISABLE_IMAP ON CACHE BOOL INTERNAL "Disable IMAP support")
set(CURL_DISABLE_SMB ON CACHE BOOL INTERNAL "Disable SMB support")
set(CURL_DISABLE_SMTP ON CACHE BOOL INTERNAL "Disable SMTP support")
set(CURL_DISABLE_RTSP ON CACHE BOOL INTERNAL "Disable RTSP support")
set(CURL_DISABLE_MQTT ON CACHE BOOL INTERNAL "Disable MQTT support")
set(CURL_DISABLE_TELNET ON CACHE BOOL INTERNAL "Disable TELNET support")
set(CURL_DISABLE_TFTP ON CACHE BOOL INTERNAL "Disable TFTP support")
set(CURL_DISABLE_DICT ON CACHE BOOL INTERNAL "Disable DICT support")
set(CURL_DISABLE_GOPHER ON CACHE BOOL INTERNAL "Disable GOPHER support")
# ZLIB should be avoided since 1)it's not required for OpenWeather calls and 2)because it cannot
# be integrated with FetchContent
if(WIN32)
    add_definitions("-DCURL_STATICLIB")
    set(ENABLE_UNICODE ON CACHE BOOL INTERNAL "Set to ON to use the Unicode version of the Windows API functions")
endif()
FetchContent_Declare(curl
    GIT_REPOSITORY https://github.com/curl/curl.git
    GIT_TAG origin/master
    GIT_SHALLOW TRUE
    SUBBUILD_DIR "${DEPS_ARTIFACTS}/build/curl/"
    TMP_DIR "${DEPS_ARTIFACTS}/tmp/curl/"
    STAMP_DIR "${DEPS_ARTIFACTS}/stamp/curl/"
    LOG_DIR "${DEPS_ARTIFACTS}/log/curl/"
    BINARY_DIR "${DEPS_ARTIFACTS}/deps_builds/curl"
)
FetchContent_MakeAvailable(curl)

当我运行

cmake
时,我看到以下信息:

Fetching dependency curl...
curl version=[7.85.0-DEV]
Could NOT find Perl (missing: PERL_EXECUTABLE) 
Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR) 
Could NOT find LibPSL (missing: LIBPSL_LIBRARY LIBPSL_INCLUDE_DIR) 
Could NOT find LibSSH2 (missing: LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR) 
Enabled features: IPv6 unixsockets AsynchDNS Largefile alt-svc HSTS NTLM unicode
Enabled protocols: FILE HTTP
Enabled SSL backends: 

...

至少功能选择(仅

FILE
HTTP
协议支持)似乎有效。然而,一旦一切都构建完成,我可以清楚地看到我的二进制文件所在的构建目录中的两件事:

  • libcurl.dll
  • curl.exe

同样的问题似乎影响了我的

jsoncpp
依赖性:

CMakeLists.txt(jsoncpp)

message(STATUS "Fetching dependency jsoncpp...")
set(JSONCPP_WITH_EXAMPLE OFF CACHE BOOL INTERNAL "Compile JsonCpp example")
set(JSONCPP_WITH_TESTS OFF CACHE BOOL INTERNAL "Compile and (for jsoncpp_check) run JsonCpp test executables")
set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF CACHE BOOL INTERNAL "Automatically run unit-tests as a post build step")
set(BUILD_OBJECT_LIBS OFF CACHE BOOL INTERNAL "Build jsoncpp_lib object files.")
set(BUILD_STATIC_LIBS ON CACHE BOOL INTERNAL "Build jsoncpp_lib as a static library.")
set(BUILD_SHARED_LIBS OFF CACHE BOOL INTERNAL "Build jsoncpp_lib as a shared library.")
FetchContent_Declare(jsoncpp
    QUIET
    GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp.git
    GIT_TAG origin/master
    GIT_SHALLOW TRUE
    SUBBUILD_DIR "${DEPS_ARTIFACTS}/build/jsoncpp/"
    TMP_DIR "${DEPS_ARTIFACTS}/tmp/jsoncpp/"
    STAMP_DIR "${DEPS_ARTIFACTS}/stamp/jsoncpp/"
    LOG_DIR "${DEPS_ARTIFACTS}/log/jsoncpp/"
    BINARY_DIR "${DEPS_ARTIFACTS}/deps_builds/jsoncpp"
)
FetchContent_MakeAvailable(jsoncpp)

我再次得到输出

  • jsoncpp.dll
  • jsontestrunner_exe.exe
  • jsoncpp_test.exe

即使我已经禁用了

JSONCPP_WITH_TESTS
。有趣的是,我找不到任何正在构建的示例,所以我想这可行......

由于这会影响我的多个依赖项,我认为我错误地使用了

FetchContent_Declare()
,尽管两者并非不可能与此机制不兼容(这里的一个很好的例子是
zlib
)。

我尝试使用

CMAKE_ARGS
,根据
ExternalProject_Add()
的文档,它应该会传递到底层
FetchContent_Declared()
,但没有显示出哪怕是最轻微的改进。

c++ cmake static-libraries static-linking fetchcontent
1个回答
0
投票

我自己正在寻找这个,我无法为实际的 OP 示例提供答案 - 但这就是我的情况:我想使用 CMake FetchContent 来获取

restbed
,并静态链接到它。

基本上,我所做的只是按照 https://discourse.cmake.org/t/how-to-statically-link-external-library-by-target-link-libraries/1718/2 中的示例进行操作 - 我在调用

add_library
之后添加了
FetchContent_MakeAvailable
CMake 调用,用于静态和导入库;如果您有 IMPORTED 库,则必须使用
set_target_properties
来指定路径。所以我最终在我的 CMakeLists.txt 中包含了:

# ...
FetchContent_Declare(
  restbed
  GIT_REPOSITORY https://github.com/Corvusoft/restbed
  GIT_PROGRESS   TRUE
  GIT_TAG        0c99284 # Oct 3, 2022, latest in Jan 2024
)
FetchContent_MakeAvailable(restbed)
add_library(restbed STATIC IMPORTED)
set_target_properties(restbed PROPERTIES IMPORTED_LOCATION ${restbed_BINARY_DIR}/librestbed.a)
# ...
target_link_libraries(${PROJECT_NAME} PUBLIC ... restbed) # a lot more dependencies in my actual case, were dropped
# ...

不确定这是否是对 CMake 中使用 FetchContent 的工作方式的正确理解,但上述内容对我有用。

© www.soinside.com 2019 - 2024. All rights reserved.