似乎CMake ExternalProject
始终假定为根目录
外部项目的源目录。但是如果不是这样的话
案子?
考虑以下示例:
外部项目使用以下目录布局:
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存储库克隆到其中。这将导致无法打破的递归依赖 hell 。 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"
)
这是可行的,但是它很扎实,并且很容易在其他外部项目中失败。
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
)
这也很好,并且比以前的解决方案感觉更好。
但是,是否存在更优雅的方法呢?
最佳答案
我已经提交a merge request来向SOURCE_SUBDIR
添加ExternalProject_Add
选项,以解决此用例。希望它将在CMake 3.7中可用。 (您也可以将ExternalProject*.cmake
本地复制到您自己的项目中,以立即利用该功能。)