CMake 和外部依赖
CMake and external dependency
我想为我的项目添加一个外部依赖项。我要添加的是 Leptonica 库作为子模块。
我的项目有以下目录结构:
|根
CMakeLists.txt
|-bin
|-建造
|-构建系统
|-可执行文件
|-轻音
|--CMakeLists.txt
|--cmake
|---Configure.cmake
|-生产
在我的根 CMakeLists.txt
文件中,我添加了
ADD_SUBDIRECTORY(${ROOT_DIR}/leptonica)
不幸的是,CMake 没有在正确的目录中搜索 Configure.cmake
:
CMake Error at leptonica/CMakeLists.txt:107 (include):
include could not find load file:
Configure
CMake Error: File
<root>/cmake/templates/LeptonicaConfig-version.cmake.in does not exist.
CMake Error at leptonica/CMakeLists.txt:113 (configure_file):
configure_file Problem configuring file
当我自己构建项目时,一切正常。在我看来,问题出在 CMAKE_SOURCE_DIR
上。当使用 add_subdirectory
时,它具有 ROOT
CMake 的值而不是 ROOT/leptonica
,因此它正在搜索错误的路径 - 正如您在 Leptonica CMake 中看到的那样,它用于确定其文件的路径。
解决此问题的正确方法是什么 - 我应该在调用 add_subdirectory
之前将 CMAKE_SOURCE_DIR
设置为 ROOT/leptonica
并在完成后将其设置回去,还是执行其他操作,存在更优雅的解决方案?
并非每个 CMake 项目都适合通过 add_subdirectory
包含。
其中有使用 CMAKE_SOURCE_DIR
或 CMAKE_BINARY_DIR
变量的项目。
但是,通过 ExternalProject_Add
包含(可选地用 execute_process
包装)始终有效。
修改变量 CMAKE_SOURCE_DIR
(以及 CMAKE_BINARY_DIR
也是)是一个 坏主意 :这个变量只能由 CMake 本身更改。否则你可能会得到奇怪的错误。
相反,您可以用另一个变量替换(自动,使用一些脚本)对变量的所有引用,该变量未在项目中使用。您可以在进入子项目之前安全地设置这个新变量。
${CMAKE_SOURCE_DIR}
和${CMAKE_BINARY_DIR}
是相对于顶层CMakeLists.txt设置的。如果您需要与当前 CMakeLists.txt (leptonica) 相关的内容,请使用 ${CMAKE_CURRENT_SOURCE_DIR}
和 ${CMAKE_CURRENT_BINARY_DIR}
。
如果您无法找到像 LeptonicaConfig-version.cmake.in
这样的 cmake 文件,请尝试将适当的目录附加到 ${CMAKE_MODULE_DIR}
。
list(APPEND ${CMAKE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates)
与 ${CMAKE_SOURCE_DIR}
相比,我更愿意在任何一天使用 ${CMAKE_CURRENT_SOURCE_DIR}
,因为如果您稍后尝试将其集成到超级构建中,使用后者会破坏您的构建。如果我需要将我当前的顶级目录传递给子目录,那么我会执行以下操作并稍后在链中使用它。
set( LEPTONICA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
我想为我的项目添加一个外部依赖项。我要添加的是 Leptonica 库作为子模块。
我的项目有以下目录结构:
|根
CMakeLists.txt
|-bin
|-建造
|-构建系统
|-可执行文件
|-轻音
|--CMakeLists.txt
|--cmake
|---Configure.cmake
|-生产
在我的根 CMakeLists.txt
文件中,我添加了
ADD_SUBDIRECTORY(${ROOT_DIR}/leptonica)
不幸的是,CMake 没有在正确的目录中搜索 Configure.cmake
:
CMake Error at leptonica/CMakeLists.txt:107 (include):
include could not find load file:
Configure
CMake Error: File
<root>/cmake/templates/LeptonicaConfig-version.cmake.in does not exist.
CMake Error at leptonica/CMakeLists.txt:113 (configure_file):
configure_file Problem configuring file
当我自己构建项目时,一切正常。在我看来,问题出在 CMAKE_SOURCE_DIR
上。当使用 add_subdirectory
时,它具有 ROOT
CMake 的值而不是 ROOT/leptonica
,因此它正在搜索错误的路径 - 正如您在 Leptonica CMake 中看到的那样,它用于确定其文件的路径。
解决此问题的正确方法是什么 - 我应该在调用 add_subdirectory
之前将 CMAKE_SOURCE_DIR
设置为 ROOT/leptonica
并在完成后将其设置回去,还是执行其他操作,存在更优雅的解决方案?
并非每个 CMake 项目都适合通过 add_subdirectory
包含。
其中有使用 CMAKE_SOURCE_DIR
或 CMAKE_BINARY_DIR
变量的项目。
但是,通过 ExternalProject_Add
包含(可选地用 execute_process
包装)始终有效。
修改变量 CMAKE_SOURCE_DIR
(以及 CMAKE_BINARY_DIR
也是)是一个 坏主意 :这个变量只能由 CMake 本身更改。否则你可能会得到奇怪的错误。
相反,您可以用另一个变量替换(自动,使用一些脚本)对变量的所有引用,该变量未在项目中使用。您可以在进入子项目之前安全地设置这个新变量。
${CMAKE_SOURCE_DIR}
和${CMAKE_BINARY_DIR}
是相对于顶层CMakeLists.txt设置的。如果您需要与当前 CMakeLists.txt (leptonica) 相关的内容,请使用 ${CMAKE_CURRENT_SOURCE_DIR}
和 ${CMAKE_CURRENT_BINARY_DIR}
。
如果您无法找到像 LeptonicaConfig-version.cmake.in
这样的 cmake 文件,请尝试将适当的目录附加到 ${CMAKE_MODULE_DIR}
。
list(APPEND ${CMAKE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates)
与 ${CMAKE_SOURCE_DIR}
相比,我更愿意在任何一天使用 ${CMAKE_CURRENT_SOURCE_DIR}
,因为如果您稍后尝试将其集成到超级构建中,使用后者会破坏您的构建。如果我需要将我当前的顶级目录传递给子目录,那么我会执行以下操作并稍后在链中使用它。
set( LEPTONICA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )