看来CMake ExternalProject
始终假定外部项目的根目录 为源目录。但如果不是 的情况呢?CMake ExternalProject:如何指定根CMakeLists.txt的相对路径?
考虑下面的例子:
外部项目使用此目录的布局:
libfoo.git <--- ExternalProject assumes this as source dir.
├── ...
└── libfoo <--- However, the actual source directory is this!
├── CMakeLists.txt
└── ...
在根据项目libfoo
被配置是这样的:
ExternalProject_Add(libfoo
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/EP_libfoo"
GIT_REPOSITORY "<link to remote which hosts libfoo.git>"
GIT_TAG "<some hash>"
)
构建然后将失败,并以下错误消息:
$ cmake -H/path/to/source-dir -B/path/to/build-dir
...
$ cmake --build /path/to/build-dir/ --target all
...
CMake Error: The source directory "/path/to/build-dir/EP_libfoo/src/libfoo" does not appear to contain CMakeLists.txt.
...
$
所以,在上面的目录布局中指出,CMake的认为 外部项目的根是
/path/to/build-dir/EP_libfoo/src/libfoo
的时候,其实,它是
/path/to/build-dir/EP_libfoo/src/libfoo/libfoo
我尝试解决此问题:
不幸的是,更改
SOURCE_DIR
的参数ExternalProject
确实 不起作用,因为此变量的值用作 的位置,其中libfoo
的git存储库被克隆到该位置。这导致了一个不能被破坏的递归依赖性地狱。更改
libfoo
的目录布局以符合ExternalProject
。 很明显,这会起作用,但它可能不适用于其他(只读) 第三方库。滥用
ExternalProject
的更新/补丁步骤,例如,通过指定set(EP_LIBFOO_DIR "${CMAKE_CURRENT_BINARY_DIR}/EP_libfoo") ExternalProject_Add(libfoo PREFIX "${EP_LIBFOO_DIR}" GIT_REPOSITORY "<link to remote which hosts libfoo.git>" GIT_TAG "<some hash>" # Copy the content of `<...>/libfoo/libfoo` into `<...>/libfoo`. # Note to self: using symlinks instead copying is too platform-specific. PATCH_COMMAND ${CMAKE_COMMAND} -E copy_directory "${EP_LIBFOO_DIR}/src/libfoo/libfoo" "${EP_LIBFOO_DIR}/src/libfoo" )
这个工程,但它是hackish,很容易失败与其他外部项目。
建立在solution to another problem上:在CMake假设的位置添加一个临时的
CMakeLists.txt
。这个临时文件 则包括实际CMakeLists.txt
:set(EP_LIBFOO_DIR "${CMAKE_CURRENT_BINARY_DIR}/EP_libfoo") set(GENERATED_DIR "${CMAKE_BINARY_DIR}/generated") file(MAKE_DIRECTORY ${GENERATED_DIR}) file(WRITE ${GENERATED_DIR}/CMakeLists.txt "cmake_minimum_required(VERSION 3.0)\n" "add_subdirectory(libfoo)\n" ) ExternalProject_Add(libfoo PREFIX "${EP_LIBFOO_DIR}" GIT_REPOSITORY "<link to remote which hosts libfoo.git>" GIT_TAG "<some hash>" # Copy the UPDATE_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generated/CMakeLists.txt ${EP_LIBFOO_DIR}/src/libfoo )
这工作以及和感觉比以前更好的解决方案。
然而,做了更优雅存在做?
该功能已被接受,并可从CMake 3.7获得:https://cmake.org/cmake/help/v3.7/module/ExternalProject.html – Matthew