Сборка нескольких подпроектов с библиотекой, имеющей внешнюю зависимость - PullRequest
0 голосов
/ 21 января 2019

Я борюсь с проектом, который включает в себя CMake (версия 3.11) и подкаталоги. Включает ITK в качестве внешней библиотеки.

Я хочу создать библиотеку, которую можно использовать в разных подкаталогах, таких как MyApp, для создания нескольких приложений, основанных на MyLib, и каждое изменение в MyLib обновляется в других приложениях. MyLib - это библиотека шаблонов только для заголовков. Кроме того, библиотеки такого типа не получают собственный проект в VisualStudio.

Мои вопросы:

  1. Как правильно использовать CMake в этом сценарии? Я искал и пробовал несколько примеров, но не смог. В идеале я могу самостоятельно создавать приложения в зависимости от MyLib. Верхний CMakeLists.txt может не извлекать включения из библиотеки. Это должно быть сделано приложениями.
  2. Что изменится, если MyLib станет библиотекой без заголовка? В будущем я могу добавить не шаблонные классы.

Бонусный вопрос:

  1. Как добавить библиотеку только для заголовков в VisualStudio? Это скорее вопрос удобства.

Любая помощь приветствуется, и я могу предоставить более подробную информацию, если это необходимо.

Исходная среда выглядит следующим образом:

ProjectDirectory
-  CMakeLists.txt
-- MyLib
   - CMakeLists.txt
   -- include
      - File1.h (template header)
      - File1.hxx (template body)
   -- src
      - (empty for now)
-- MyApp
   - CMakeLists.txt
   - AppFile1.cxx (File containing main function)

Это проект, построенный вне исходного кода. В идеале скомпилированные библиотеки и приложения должны находиться в таком каталоге (в Windows):

└── bin
    ├── Debug
    │   ├── MyApp.exe
    │   └── MyLib.lib
    └── Release
        ├── MyApp.exe
        └── MyLib.lib

ProjectDirectory CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(project_name)

# Setup build locations.
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
endif()
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
endif()
if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
endif()

add_subdirectory(MyLib)
add_subdirectory(MyApp)

MyLib CMakeLists.txt:

find_package(ITK REQUIRED
    COMPONENTS RTK ITKImageIO)
include(${ITK_USE_FILE})

set(HDRS
    ${CMAKE_CURRENT_SOURCE_DIR}/include/File1.h
    ${CMAKE_CURRENT_SOURCE_DIR}/include/File1.hxx
)

add_library(MyLib ${HDRS})

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

target_link_libraries(MyLib
    PUBLIC ${ITK_LIBRARIES})

export(TARGETS MyLib FILE MyLibConfig.cmake)

MyApp CMakeLists.txt

find_package(ITK REQUIRED
    COMPONENTS RTK ITKRegistrationMethodsv4 ITKTransformIO ITKImageIO)
include(${ITK_USE_FILE})

set(SRCS
    AppFile1.cxx)

add_executable(MyApp ${SRCS})
include_directories(${CMAKE_SOURCE_DIR}/MyLib/include)
target_link_libraries(MyApp
    ${ITK_LIBRARIES}
    MyLib)

Edit1: удалить проект (X) из MyLib и MyApp CMakeLists.txt и изменить цель на MyLib.

1 Ответ

0 голосов
/ 21 января 2019

Вы можете создать пустой проект, просто создайте пользовательскую цель:

add_custom_target(MyLib SOURCES ${CMAKE_MYLIB_SRC} ${CMAKE_MYLIB_HDR})

Поскольку ваш код имеет только заголовок, любая зависимая цель увидит изменения в файлах и будет перекомпилирована.Сверх этого нельзя сделать ничего .Вам не нужно создавать цель, хотя для вашего третьего вопроса это ответ.

Но если ITK является только вашей зависимостью, теперь, когда у вас есть цель, вы можете добавить к ней PUBLIC свойствКак и зависимые библиотеки, которые нужно связать с ней из-за вашей библиотеки.

В этом случае код для них необходимо добавить:

target_link_library(${NEWTARGET} PRIVATE MyLib) # PUBLIC/PRIVATE has to be tailored

Это ответ на вопрос 1.

Если ваша библиотека становится не заголовочной, просто измените вызов add_custom_target.

...