在 CMakes "Add_External_Project" 函数中使用 cmake 作为配置工具 (CONFIGURE_COMMAND)

Using cmake as the configure tool (CONFIGURE_COMMAND) in CMakes "Add_External_Project" function

我遇到了 CMakes Add_External_Project 功能的问题(比其他任何事情都更让人烦恼)。具体来说,我不明白 CONFIGURE_COMMANDBUILD_COMMANDINSTALL_COMMAND.

在下面的(工作)示例中,下载 Google 的测试库,问题末尾的两个文件将确保下载和构建第三方库(没有安装)。

但是,当我尝试将配置和构建命令添加为 "CONFIGURE_COMMAND" 和 "BUILD_COMMAND"(cmake .cmake --build)而不是必须执行 execute_process CMake 出现错误消息:

[ 55%] Performing configure step for 'googletest'
/bin/sh: 1: cmake .: not found

我是否正在尝试做一些显然不在Add_External_Project功能范围内的事情?

示例文件:

CMakeLists.txt

cmake_minimum_required (VERSION 3.0)

project (Test VERSION 0.1.0.0 LANGUAGES CXX)

# Download and unpack googletest at configure time
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt" @ONLY)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download" )

execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/googletest-download")

add_subdirectory("${CMAKE_BINARY_DIR}/googletest-src" "${CMAKE_BINARY_DIR}/googletest-build")

CMakeLists.txt.in

cmake_minimum_required(VERSION 3.0)

project(third-party NONE)

include(ExternalProject)
ExternalProject_Add(googletest
  GIT_REPOSITORY    https://github.com/google/googletest.git
  GIT_TAG           master
  SOURCE_DIR        "@CMAKE_BINARY_DIR@/googletest-src"
  BINARY_DIR        "@CMAKE_BINARY_DIR@/googletest-build"
  CONFIGURE_COMMAND ""
  BUILD_COMMAND     ""
  INSTALL_COMMAND   ""
  TEST_COMMAND      ""
)

如果您根本不指定 CONFIGURE_COMMAND,它将假设一个 CMake 项目和 运行 适合您的 cmake 命令(适当的,我的意思是它将使用与您的主构建相同的 CMake 生成器等)。同样,如果您省略 BUILD_COMMAND,它也会假设一个 CMake 项目并为您执行 cmake --build。因此,在您的情况下,只需省略这两行,ExternalProject_Add() 就可以完全满足您的要求。

您可能将这两个选项指定为空字符串的主要原因是为了防止这些步骤执行任何操作。这可能很有用,例如,使用 ExternalProject_Add() 只是为了它的下载和解包功能。这种确切的情况被用于描述的技术 here for downloading the source of GoogleTest so it can be added to your project via add_subdirectory(), making it part of your build (see also this answer 和该问题的其他答案中的一些相关 material)。我怀疑这可能是您的代码的来源,因为结构看起来很相似。

为了完整起见,如果您发现自己处于 需要指定 CMake 命令的情况,请不要使用裸 cmake 来引用命令 运行。相反,请始终使用 CMake 提供的 ${CMAKE_COMMAND} 作为当前用于处理文件的 CMake 可执行文件的位置。使用此变量意味着 cmake 不必位于用户的 PATH 上,并且还确保如果开发人员选择 运行 与 [= 上的版本不同的 CMake 版本20=],相同的 cmake 仍将用于您要添加的命令。

您可以这样使用 PATCH_COMMAND

option(WITH_MBEDTLS "Build with mbedtls" OFF)
if(WITH_MBEDTLS)
  ExternalProject_Add(external-mbedtls
    URL https://github.com/ARMmbed/mbedtls/archive/mbedtls-2.16.1.tar.gz
    UPDATE_COMMAND ""
    PATCH_COMMAND ./scripts/config.pl set MBEDTLS_THREADING_C &&
                  ./scripts/config.pl set MBEDTLS_THREADING_PTHREAD
    CMAKE_ARGS
      -DCMAKE_INSTALL_PREFIX:PATH=${PROJECT_BINARY_DIR}/third_party/mbedtls
      -DCMAKE_TOOLCHAIN_FILE:PATH=${TOOLCHAIN_FILE}
      -DCMAKE_BUILD_TYPE:STRING=Debug
      -DENABLE_TESTING:BOOL=OFF
      -DENABLE_PROGRAMS:BOOL=ON
    TEST_COMMAND ""
    )
    set(MBEDTLS_PREFIX ${PROJECT_BINARY_DIR}/third_party/mbedtls PARENT_SCOPE)
endif(WITH_MBEDTLS)