Использование cmake для библиотеки шаблонов c ++ - PullRequest
0 голосов
/ 03 июня 2018

У меня есть проект, который использует cmake для сборки.В проекте есть несколько подмодулей, которые создаются как библиотеки.Структура выглядит следующим образом:

src
├── CMakeLists.txt
├── libA
│   ├── CMakeLists.txt
│   ├── include
│   │   └── A
│   │       └── A.h
│   └── src
│       └── A.cpp
│
├── libB
│   ├── CMakeLists.txt
│   ├── include
│   │   └── B
│   │       └── B.h
│   └── src
│       └── B.cpp
│
├── include
│   └── project.h
├── main
│   ├── CMakeLists.txt
│   └── main.cpp
└── other_main
    ├── CMakeLists.txt
    └── main.cpp

Теперь выясняется, что мне нужно преобразовать модуль B в основанный на шаблонах, а не в связываемом lib;т.е. я хочу экспортировать только заголовки из модуля B.

В настоящее время CMakeLists.txt модуля B содержит следующее:

add_library(B STATIC ${SOURCES})
target_include_directories(B 
    PUBLIC 
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        ... other include dirs ...
    PRIVATE 
        src)

    # B depends on A
    target_link_libraries(B A)

    export(
        TARGETS B
        FILE BLibraryConfig.cmake)

Какие минимальные изменения мне нужно внести в мои файлы CMakeLists (в модуле или области проекта), чтобы иметь возможность поддерживать B как библиотеку шаблонов, учитывая, что B все еще зависит от A, и оба моих главных проекта используют A и B?

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Как говорит другой ответ, вы можете объявить B как интерфейсную библиотеку .Этот подход имеет некоторые ограничения.Например, вы не можете установить пользовательские свойства в интерфейсных библиотеках.Кроме того, заголовки B могут неправильно отображаться IDE, например, QtCreator 4.6.1 не отображает их в дереве проекта.

Если это критично для вас, есть альтернатива.У вас может быть статическая библиотека, которая содержит только заголовки, но вам нужно вручную указать ее язык компоновщика.

add_library(B STATIC ${SOURCES})
target_include_directories(B 
  PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    ... other include dirs ...
)

# As B does not have any source files, you have to explicitly
# specify the linker language
set_target_properties(B PROPERTIES LINKER_LANGUAGE CXX)

# B depends on A
target_link_libraries(B A)

export(
    TARGETS B
    FILE BLibraryConfig.cmake)
0 голосов
/ 04 июня 2018

Вы можете объявить B как интерфейсную библиотеку , чтобы определить ее только для заголовка.Для этого потребуются незначительные изменения target_include_directories и target_link_libraries (вместо * public / private определите INTERFACE свойства)

add_library(B INTERFACE) # no sources
target_include_directories(B INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    # other include dirs ...
)

# B depends on A
target_link_libraries(B INTERFACE A)

export(
    TARGETS B
    FILE BLibraryConfig.cmake
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...