CMakeLists:使用 ExternalProject 从 Github 添加源文件
CMakeLists: Adding source files from Github with ExternalProject
我正在为 Beckhoff ADS 库编写一个小的 catkin 包装器。我想安装AdsLib文件夹中的文件,但不使用Beckhoff的CMake文件。
我只想复制文件,以便将它们添加到我自己的 CMakeList 中的库中。如果我手动复制文件,这工作正常。但我想直接使用 Github 源代码中的最新文件进行构建。
我尝试了在stackoverflow上可以找到的所有可能的组合,但不知何故无法使其工作。
cmake_minimum_required(VERSION 2.8.3)
project(ads_catkin)
find_package(catkin_simple REQUIRED)
catkin_simple()
include(ExternalProject)
ExternalProject_Add(ads
PREFIX ${CMAKE_BINARY_DIR}/ads
GIT_REPOSITORY https://github.com/Beckhoff/ADS.git
GIT_TAG master
CONFIGURE_COMMAND ""
#GIT_TAG 6b3a03009a757cf651fe44d8be7b6df698028f0e
UPDATE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(ads source_dir)
cs_add_library(${PROJECT_NAME}
${source_dir}/AdsLib/AdsDef.cpp
)
cs_install()
cs_export()
我第一次使用 catkin_tools 构建时,这给了我:
Errors << ads_catkin:cmake /home/xxx/xxx_ws/logs/ads_catkin/build.cmake.000.log
CMake Error at /home/xxx/xxx_ws/devel/share/catkin_simple/cmake/catkin_simple-extras.cmake:150 (add_library):
Cannot find source file:
/home/xxx/xxx/build/ads_catkin/ads/src/ads/AdsLib/AdsDef.cpp
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
Call Stack (most recent call first):
CMakeLists.txt:23 (cs_add_library)
CMake Error: CMake can not determine linker language for target: ads_catkin
CMake Error: Cannot determine link language for target "ads_catkin".
然后,当我第二次对相同的代码运行构建工具时,文件实际上被克隆了,但我最终得到这个错误:
Errors << ads_catkin:make /home/xxx/xxx_ws/logs/ads_catkin/build.make.000.log
make[2]: *** No rule to make target 'CMakeFiles/ads_catkin.dir/build'. Stop.
make[1]: *** [CMakeFiles/ads_catkin.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
Cloning into 'ads'...
Already on 'master'
make: *** [all] Error 2
顺便说一句:cs_add_library是add_library和target_link_libraries catkin_simple形式。
更新: 越来越近...将解决方案从@Tsyvarev调整到我的文件:
cmake_minimum_required(VERSION 2.8.3)
project(ads_catkin)
find_package(catkin_simple REQUIRED)
catkin_simple()
include(ExternalProject)
ExternalProject_Add(ads
PREFIX ${CATKIN_DEVEL_PREFIX}/ads
GIT_REPOSITORY https://github.com/Beckhoff/ADS.git
GIT_TAG 6b3a03009a757cf651fe44d8be7b6df698028f0e
#GIT_TAG master
CONFIGURE_COMMAND ""
UPDATE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
BUILD_BYPRODUCTS
<SOURCE_DIR>/AdsLib/AdsDef.cpp
<SOURCE_DIR>/AdsLib/AdsLib.cpp
<SOURCE_DIR>/AdsLib/AmsConnection.cpp
<SOURCE_DIR>/AdsLib/AmsPort.cpp
<SOURCE_DIR>/AdsLib/AmsRouter.cpp
<SOURCE_DIR>/AdsLib/Frame.cpp
<SOURCE_DIR>/AdsLib/Log.cpp
<SOURCE_DIR>/AdsLib/NotificationDispatcher.cpp
<SOURCE_DIR>/AdsLib/Sockets.cpp
<SOURCE_DIR>/AdsLib/AdsDef.h
<SOURCE_DIR>/AdsLib/AdsLib.h
<SOURCE_DIR>/AdsLib/AdsNotification.h
<SOURCE_DIR>/AdsLib/AmsConnection.h
<SOURCE_DIR>/AdsLib/AmsHeader.h
<SOURCE_DIR>/AdsLib/AmsPort.h
<SOURCE_DIR>/AdsLib/AmsRouter.h
<SOURCE_DIR>/AdsLib/Frame.h
<SOURCE_DIR>/AdsLib/Log.h
<SOURCE_DIR>/AdsLib/NotificationDispatcher.h
<SOURCE_DIR>/AdsLib/RingBuffer.h
<SOURCE_DIR>/AdsLib/Router.h
<SOURCE_DIR>/AdsLib/Semaphore.h
<SOURCE_DIR>/AdsLib/Sockets.h
<SOURCE_DIR>/AdsLib/wrap_endian.h
<SOURCE_DIR>/AdsLib/wrap_socket.h
)
ExternalProject_Get_Property(ads SOURCE_DIR)
include_directories(
${SOURCE_DIR}/AdsLib
)
cs_add_library(AdsLib
${SOURCE_DIR}/AdsLib/AdsDef.cpp
${SOURCE_DIR}/AdsLib/AdsLib.cpp
${SOURCE_DIR}/AdsLib/AmsConnection.cpp
${SOURCE_DIR}/AdsLib/AmsPort.cpp
${SOURCE_DIR}/AdsLib/AmsRouter.cpp
${SOURCE_DIR}/AdsLib/Frame.cpp
${SOURCE_DIR}/AdsLib/Log.cpp
${SOURCE_DIR}/AdsLib/NotificationDispatcher.cpp
${SOURCE_DIR}/AdsLib/Sockets.cpp
)
add_dependencies(AdsLib ads)
cs_install()
install(DIRECTORY ${SOURCE_DIR}/AdsLib/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
PATTERN ".cpp" EXCLUDE
)
cs_export()
我试图将头文件包含在我的 AdsLib 库中。但是我仍然收到一个错误:
In file included from /home/xxx/xxx_ws/src/xxx/nav_controller/src/controller.cpp:19:0:
/home/xxx/xxx_ws/src/xxx/nav_controller/include/nav_controller/controller.h:27:10: fatal error: AdsLib.h: No such file or directory
#include "AdsLib.h"
^~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/nav_controller.dir/src/controller.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
In file included from /home/xxx/xxx_ws/src/xxx/nav_controller/src/test.cpp:22:0:
/home/xxx/xxx_ws/src/xxx/nav_controller/include/nav_controller/controller.h:27:10: fatal error: AdsLib.h: No such file or directory
#include "AdsLib.h"
^~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/nav_controller.dir/src/test.cpp.o] Error 1
make[1]: *** [CMakeFiles/nav_controller.dir/all] Error 2
make: *** [all] Error 2
CMake 错误Cannot find source file
意味着一件简单的事情:没有任何东西告诉 CMake 给定的源文件已生成并且文件本身不存在。
因为文件是在ExternalProject_Add
中生成的,所以需要调整对应的目标级依赖关系:
add_dependency(ads_catkin ads)
此命令应在创建相应目标的add_library()
和ExternalProject_Add
调用后发出。此命令告诉 CMake,只有在执行完外部项目的所有步骤后,才应生成库。
您仍然需要告诉 CMake 源文件已生成。有两种方法可以做到这一点。
设置生成属性:
set_source_files_properties(${source_dir}/AdsLib/AdsDef.cpp PROPERTIES GENERATED TRUE)
这可以防止 CMake 在配置阶段搜索文件。
在生成该文件的目标的
BYPRODUCTS
选项中列出文件。对于由ExternalProject_Add
命令创建的目标,这是通过该命令的附加选项来实现的BUILD_BYPRODUCTS <SOURCE_DIR>/AdsLib/AdsDef.cpp
这还会设置源文件的 GENERATED 属性,如第一种情况所示。但是 BYPRODUCTS 也使您的项目可供 Ninja 用户使用。
(在上面的选项中,表达式
<SOURCE_DIR>
是引用外部项目源目录的一种特殊方法。它可用于某些外部项目的选项,BUILD_BYPRODUCTS就是其中之一(。
从技术上讲,CMake 应该足够聪明,可以在看到相应的 BYPRODUCTS 选项时自动添加目标级依赖项(add_dependency(ads_catkin ads)
的效果(。但是此功能仅适用于 3.16 版本,我不知道它是否适用于旧版本。
最后,即使有@Tsyvarev的良好帮助,我也无法使用它ExternalProject_Add。 解决方案的一部分是使用cs_export(INCLUDE_DIRS ${ads})
手动导出库,这不适用于ExternalProject_Add,因为此时文件不可用。
最后,我在我的包中包含了DownloadProject模块,它是FetchContent的前身。这做了它应该做的。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 将QIcon添加到QTableView单元格
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- CMakeLists:使用 ExternalProject 从 Github 添加源文件
- 添加github库(BamTools)到c++使用cmake ExternalProject_Add