Есть директория с компонентами, все из которых являются статическими библиотеками.
Они лежат в общей папке, каждая компонента имеет свой CMakeLists.txt и может собраться отдельно через CMake.
Также есть несколько утилит, каждая из которых может тянуть свои зависимости.
Пример иерархия папок:
[ git ]
- libraries
- strings
- my_math
- media_converter
- logger
- utilities
- calc
- video_player
Примеры CMakeLists.txt:
Для библиотеки:
project( library_name )
add_library( ${PROJECT_NAME} STATIC < .. > )
Для утилиты:
project( utility_name )
add_executable( ${PROJECT_NAME} < .. > )
# import components :
add_subdirectory( <..> ) # компонента еще не собрана, собираем ее
target_include_directories( <..> ) # добавляю пути к заголовкам компоненты
target_link_libraries( <..> ) # линкуем к таргету 'utility_name' библиотеки компоненты
Таким образом, если одна из импортируемых компонент тянет что-нибудь еще, например, media_converter тянет за собой ffmpeg и когда я добавлю media_converter к video_player, то в CMakeLists.txt у video_player придется добавить конструкции типа "find_library( ffmpeg )", "target_link ..", чтобы разрешить все зависимости.
Вопрос в следующем. Как посредством CMake в скрипте для статической библиотеки указать утилите, которой ее использует, сразу подтягивать внешние зависимости компоненты?
Я попытался в CMakeLists.txt для компоненты использовать такую конструкцию:
project( library_name )
add_library( ${PROJECT_NAME} STATIC < .. > )
target_link_libraries( ${CMAKE_PROJECT_NAME} < .. > )
По документации CMAKE_PROJECT_NAME - это название проекта для которого вызван CMake, т.е. в моем случае - это video_player. Но при таком раскладе у меня возникает ошибка - я пытаюсь слинковать компоненту с несуществующим таргетом.
Кто-нибудь сталкивался с такой проблемой? Пока не смог найти решение самостоятельно.
Ответ
Структура
├── libs
│ └── media_converter
│ ├── CMakeLists.txt
│ └── main.cpp
└── utils
└── video_player
├── CMakeLists.txt
└── main.cpp
media_converter
Сшздаём статическую библиотеку media_converter, находим и линкуем к ней зависимости. Обрати внимание, что зависимости публичные (PUBLIC).
cmake_minimum_required(VERSION 3.10)
project(media_converter CXX)
add_library(${PROJECT_NAME} STATIC main.cpp)
find_library(MPG123_LIB mpg123)
target_link_libraries(${PROJECT_NAME} PUBLIC ${MPG123_LIB})
target_include_directories(${PROJECT_NAME} PUBLIC /some/secret/path/to/mpg123)
video_player
Создаём приложение video_player и линкуемся с media_converter. Это автоматически добавит все публичные зависимости media_converter к video_player
cmake_minimum_required(VERSION 3.10)
project(video_player CXX)
add_executable(${PROJECT_NAME} main.cpp)
add_subdirectory(../../libs/media_converter media_converter)
target_link_libraries(${PROJECT_NAME} media_converter)
Проверка
$ cmake ../utils/video_player/
...
Build files have been written to: .../build
$ make VERBOSE=1
...
[ 75%] Building CXX object CMakeFiles/video_player.dir/main.cpp.o
/usr/bin/c++ -I/some/secret/path/to/mpg123 -o CMakeFiles/video_player.dir/main.cpp.o -c .../utils/video_player/main.cpp
[100%] Linking CXX executable video_player
/usr/bin/cmake -E cmake_link_script CMakeFiles/video_player.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/video_player.dir/main.cpp.o -o video_player media_converter/libmedia_converter.a /usr/lib64/libmpg123.so
Как видно, video_player компилируется с -I/some/secret/path/to/mpg123 и линкуется с /usr/lib64/libmpg123.so
Комментариев нет:
Отправить комментарий