我想为我的项目添加一个外部依赖项。我尝试添加的是Leptonica库作为子模块。
我的项目具有以下目录结构:
|根
CMakeLists.txt |-bin
|-build
|-buildsystem
|-executable
|-leptonica
|--CMakeLists.txt
|--cmake |---Configure.cmake
|-production
在我的根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}
。
如果您在查找 cmake 文件(如LeptonicaConfig-version.cmake.in
)时遇到问题,请尝试将相应的目录附加到${CMAKE_MODULE_DIR}
。
list(APPEND ${CMAKE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates)
我更喜欢在任何一天使用${CMAKE_CURRENT_SOURCE_DIR}
而不是${CMAKE_SOURCE_DIR}
因为如果您稍后尝试将其集成到超级构建中,使用后者会破坏您的构建。 如果我需要将我当前的顶级目录传递给子目录,那么我会执行以下操作,稍后在链中使用它。
set( LEPTONICA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )