似乎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上构建:添加一个临时的
{CM}假设的位置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
)
这也很有效,感觉比之前的解决方案更好。
但是,更优雅是否存在同样的效果?
答案 0 :(得分:10)
我已提交a merge request向SOURCE_SUBDIR
添加ExternalProject_Add
选项,以解决此用例问题。希望它将在CMake 3.7中提供。 (您也可以将ExternalProject*.cmake
本地复制到您自己的项目中,以便立即利用该功能。)
答案 1 :(得分:2)
您只需手动覆盖 cmake 命令蚂蚁设置路径到 CMakeLists.txt 即可。例如
ExternalProject_Add(libfoo
PREFIX "${EP_LIBFOO_DIR}"
GIT_REPOSITORY "<link to remote which hosts libfoo.git>"
GIT_TAG "<some hash>"
CONFIGURE_COMMAND ${CMAKE_COMMAND} -G${CMAKE_GENERATOR} "${EP_LIBFOO_DIR}/src/libfoo/libfoo")
答案 2 :(得分:1)
您可以使用
SOURCE_DIR /path/to/build-dir/EP_libfoo/src/libfoo/libfoo
ExternalProject_Add调用。这指定了实际的源目录。
答案 3 :(得分:0)
我一直在努力解决我正在进行的项目中的同一问题,这是我能够提出的解决方案。它导致不使用ExternalProject进行git处理,但结果却产生了相同的行为。
的CMakeLists.txt
include(ExternalProject)
set(libfoo_prefix ${CMAKE_HOME_DIRECTORY}/libfoo)
# during generation remove any previous repo and clone.
file(REMOVE_RECURSE ${libfoo_prefix})
execute_process(
COMMAND git clone <link to remote which hosts libfoo.git>
WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY})
# Add the external project.
ExternalProject_Add(libfoo
PREFIX ${libfoo_prefix}
SOURCE_DIR ${libfoo_prefix}/libfoo)
# As part of the pre-build step update the git repo.
add_custom_command(
TARGET libfoo
PRE_BUILD
COMMAND ${CMAKE_COMMAND} -P GitPull.cmake)
GitPull.cmake
execute_process(
COMMAND git pull origin master
WORKING_DIRECTORY ${CMAKE_SOURCE_DIRECTORY}/libfoo)
答案 4 :(得分:0)
这是一个简单的解决方案
MainPage
基本上你把它分成两部分。第一个是获取源代码,第二个是获取软件。我手动创建了标题的链接,因此kdevelop的解析器不必解析整个项目。
答案 5 :(得分:0)
对于那些仍在寻找答案的人:尝试指定CONFIGURE_COMMAND
:
ExternalProject_Add(libfoo
GIT_REPOSITORY "<link to remote which hosts libfoo.git>"
GIT_TAG "<some hash>"
SOURCE_DIR "where to put the source"
CONFIGURE_COMMAND
"${CMAKE_COMMAND}"
"-HPathToDirectoryWhereTheCMakeListsAre"
"-BWhereToBuild"
BUILD_COMMAND
"${CMAKE_COMMAND}" --build "Path to the directory where you are building (specified with -B flag in CONFIGURE_COMMAND)"
)