Как создать библиотеку с CMakeLists.txt и включить ее в другую программу? - PullRequest
0 голосов
/ 15 мая 2019

Я новичок в разработке на C / C ++ и борюсь с CMakeLists.txt в IDE CLion.

Я не могу создать библиотеку (статическую или общую), которую я могу #include в другойпрограмма.

У меня такая структура:

src/
 |
 |---> utilities/
 |         |---> CMakeLists.txt
 |         |---> utilties.h
 |         |
 |         |---> file_utilities/
 |         |            |---> file_utilities.h
 |         |            |---> file_utilities.c
 |        ...
 |
 |---> my_app
          |---> CMakeLists.txt
          |---> main.c

Я создал libutilities.so и libutilities.a.В моем файле main.c он работает, если я делаю #include "../utilities/utilities.h" или #include "../utilities/file_utilities/file_utilities.h".

Хуже, если я создаю другой проект с другой программой и связываю свой libutilities.so, ссылка, кажется, работает, но все еще не может включать мои заголовки.

Я перепробовал много настроек, много опций в CMakeLists.txt, но до сих пор он не работал.

Вот CMakeLists.txt, которыйЯ использую для моей библиотеки.Я вполне уверен, что проблема в этом файле.

    cmake_minimum_required(VERSION 3.7)
    project(utilities VERSION 1.0.0)

    set(CMAKE_CXX_STANDARD 11)

    link_libraries(pthread)
    link_libraries(ssl)
    link_libraries(crypto)

    find_package(CURL REQUIRED)
    include_directories(${CURL_INCLUDE_DIRS})

    file(GLOB_RECURSE SOURCES RELATIVES "*.c")
    file(GLOB_RECURSE HEADERS RELATIVES "*.h")

    add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})

    set_target_properties(${PROJECT_NAME} PROPERTIES
            PUBLIC_HEADER "${HEADERS}"
            ARCHIVE_OUTPUT_DIRECTORY "lib"
            LIBRARY_OUTPUT_DIRECTORY "lib"
            OUTPUT_NAME ${PROJECT_NAME})

    target_include_directories(${PROJECT_NAME} PUBLIC .)

    target_link_libraries(${PROJECT_NAME} ${CURL_LIBRARIES})

    include(GNUInstallDirs)
    install(TARGETS ${PROJECT_NAME}
            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
            PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})

Я хотел бы иметь что-то более похожее на #include <utilities/utilties.h>, так как это библиотека.Но я не могу сделать так, чтобы это работало.

В приведенном мной примере библиотека представляет собой простую библиотеку "utils", но мне нужно создать больше, что мне нужно будет доставить и интегрировать в другую программу.чем мой.

Ответы [ 2 ]

0 голосов
/ 16 мая 2019

Ваш CMakeLists.txt внутри utilities. Попробуйте использовать это.

src/utilities/CMakeLists.txt

target_include_directories(${PROJECT_NAME}
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
)

Для приложения у вас должно быть что-то вроде: src/my_app/CMakeLists.txt:

target_link_libraries(${PROJECT_NAME} PRIVATE utilities)

и вы должны иметь простой src/CMakeLists.txt

add_subdirectory(utilities)
add_subdirectory(my_app)
0 голосов
/ 15 мая 2019

Я настоятельно рекомендую прочитать эту статью , в которой создается вымышленная библиотека, от структуры проекта до установки / экспорта. Насколько я понимаю, у автора точно такая же цель, как и у вас. Эта статья прояснила мне многое, когда я только начинал. Я также рекомендую структуру проекта, изложенную в.

Структура проекта:

libjsonutils
├── CMakeLists.txt
├── include
│   └── jsonutils
│       └── json_utils.h
├── src
│   ├── file_utils.h
│   └── json_utils.cpp
└── test
    ├── CMakeLists.txt
    └── src
        └── test_main.cpp

В частности, вы захотите взглянуть на Цели и свойства , где выражения генератора используются для разграничения между включаемым каталогом во время сборки и при установке:

target_include_directories(JSONUtils
    PUBLIC 
        $<INSTALL_INTERFACE:include>    
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

Процесс установки и экспорт / импорт целей объясняется немного позже в Вот как вы делаете CMake . Автор хочет использовать библиотеку в других проектах cmake (например, цель под названием «пример»), просто выполнив следующее:

find_package(JSONUtils 1.0 REQUIRED)
target_link_libraries(example JSONUtils::JSONUtils)

Для того, чтобы эта работа работала, вам необходимо установить и экспортировать библиотеку. Автор рекомендует это для установки:

include(GNUInstallDirs)
install(TARGETS JSONUtils
    EXPORT jsonutils-export
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

И это для экспорта:

install(EXPORT jsonutils-targets
  FILE
    JSONUtilsTargets.cmake
  NAMESPACE
    JSONUtils::
  DESTINATION
    ${CMAKE_INSTALL_LIBDIR}/cmake/JSONUtils
)

Экспорт поместит файл с именем findJsonUtils.cmake в указанное место назначения. Этот файл будет тем, что вам нужно для импорта библиотеки в другие проекты с помощью механизма find_package.

Все примеры кода в этом посте взяты из связанной статьи Пабло Ариаса.

...