CMakeLists: добавление исходных файлов из Github с ExternalProject - PullRequest
1 голос
/ 17 января 2020

Я пишу небольшую оболочку-пух для библиотеки Beckhoff ADS. Я хотел бы установить файлы из папки AdsLib, но без использования файла CMake от Beckhoff.

Я просто хочу скопировать файлы, чтобы добавить их в мою библиотеку в моих собственных 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 - это форма catkin_simple для add_library и target_link_libraries.

Обновление: приближение ... адаптация решения из @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

Ответы [ 2 ]

2 голосов
/ 18 января 2020

Ошибка CMake Cannot find source file означает простую вещь: CMake ничего не говорит о том, что данный исходный файл создан , а сам файл отсутствует.

Поскольку файл создан в ExternalProject_Add, вам нужно настроить соответствие target-level зависимость:

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 должен быть достаточно умен для добавления зависимостей целевого уровня (эффект add_dependency(ads_catkin ads)) автоматически , когда он видит соответствующие Опция BYPRODUCTS Но эта функция описана только для версии 3.16, и я не знаю, работает ли она в более старых версиях.

0 голосов
/ 22 января 2020

В конце концов, даже при хорошей помощи @Tsyvarev я не смог заставить его работать с помощью ExternalProject_Add. Часть решения состоит в том, чтобы вручную экспортировать библиотеку с cs_export(INCLUDE_DIRS ${ads}), которая не работала с ExternalProject_Add, потому что файлы не были доступны в это время.

В конце я включил DownloadProject модуль , который является предшественником FetchContent, в моем пакете. Это делает то, что должно.

...