【发布时间】:2015-07-13 17:16:45
【问题描述】:
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 存储库被克隆到其中。这会导致无法打破的递归依赖地狱。更改
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" )这可行,但它很老套,而且很容易在其他外部项目中失败。
-
基于solution to another problem:添加一个临时
CMakeLists.txt在 CMake 假定它的位置。这个临时文件 然后包括实际的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 )这也很有效,感觉比以前的解决方案更好。
但是,是否有一个更优雅的可以做到这一点?
【问题讨论】:
标签: git build cmake build-process build-automation