簡體   English   中英

CMakeLists:使用 ExternalProject 從 Github 添加源文件

[英]CMakeLists: Adding source files from Github with ExternalProject

我正在為 Beckhoff ADS 庫編寫一個小的 catkin 包裝器。 我想安裝 AdsLib 文件夾中的文件,但不使用 Beckhoff 的 CMake 文件。

我只想復制這些文件,以便將它們添加到我自己的 CMakeLists 中的庫中。 如果我手動復制文件,這可以正常工作。 但我想直接使用 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 源文件已生成。 兩種方法可以做到這一點。

  1. 設置 GENERATED 屬性:

     set_source_files_properties(${source_dir}/AdsLib/AdsDef.cpp PROPERTIES GENERATED TRUE)

    這可以防止 CMake 在配置階段搜索文件。

  2. 生成它的目標的BYPRODUCTS選項中的列表文件。 對於由ExternalProject_Add命令創建的目標,這是通過該命令的附加選項實現的

    BUILD_BYPRODUCTS <SOURCE_DIR>/AdsLib/AdsDef.cpp

    這也為源文件設置了 GENERATED 屬性,就像在第一種情況下一樣。 但是 BYPRODUCTS 也使您的項目可供 Ninja 用戶使用。

    (在上面的選項中,表達式<SOURCE_DIR>是引用 ExternalProject 源目錄的一種特殊方式。它可用於某些 ExternalProject 的選項,而 BUILD_BYPRODUCTS 就是其中之一)。


從技術上講,CMake 應該足夠智能,可以在看到相應的 BYPRODUCTS 選項時自動添加目標級別的依賴項( add_dependency(ads_catkin ads)的效果add_dependency(ads_catkin ads) 但是這個功能只針對3.16版本進行了描述,不知道老版本是否有效。

最后,即使在@Tsyvarev 的良好幫助下,我也無法使用 ExternalProject_Add 使其工作。 部分解決方案是使用cs_export(INCLUDE_DIRS ${ads})手動導出庫,這不適用於 ExternalProject_Add,因為此時文件不可用。

最后,我在包中包含了DownloadProject 模塊,它是 FetchContent 的前身。 這做它應該做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM