Ответ 1
Всегда указывайте минимально необходимую версию cmake
cmake_minimum_required(VERSION 3.9)
Вы должны объявить проект. cmake
говорит, что это обязательно, и он будет определять удобные переменные PROJECT_NAME
, PROJECT_VERSION
и PROJECT_DESCRIPTION
(эта последняя переменная требует cmake 3.9):
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
Объявите новую библиотечную цель. Пожалуйста, избегайте использования file(GLOB ...)
. Эта функция не обеспечивает мастерства в процессе компиляции. Если вы ленивый, скопируйте и вставьте вывод ls -1 sources/*.cpp
:
add_library(mylib SHARED
sources/animation.cpp
sources/buffers.cpp
[...]
)
Установите свойство VERSION
(необязательно, но это хорошая практика):
set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION})
Вы также можете установить SOVERSION
на основной номер VERSION
. Так что libmylib.so.1
будет символической ссылкой на libmylib.so.1.0.0
.
set_target_properties(mylib PROPERTIES SOVERSION 1)
Объявите публичный API вашей библиотеки. Этот API будет установлен для стороннего приложения. Рекомендуется изолировать его в дереве проекта (например, поместить его в каталог include/
). Обратите внимание, что частные заголовки не следует устанавливать, и я настоятельно рекомендую размещать их вместе с исходными файлами.
set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h)
Если вы работаете с подкаталогами, не очень удобно включать относительный путь, например "../include/mylib.h"
. Итак, передайте верхний каталог во включенные каталоги:
target_include_directories(mylib PRIVATE .)
или
target_include_directories(mylib PRIVATE include)
target_include_directories(mylib PRIVATE src)
Создайте правило установки для своей библиотеки. Я предлагаю использовать переменные CMAKE_INSTALL_*DIR
, определенные в GNUInstallDirs
:
include(GNUInstallDirs)
И объявить файлы для установки:
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
Вы также можете экспортировать файл pkg-config
. Эти файлы позволяют стороннему приложению легко импортировать вашу библиотеку:
- с Makefile, см.
pkg-config
- с помощью Autotools см.
PKG_CHECK_MODULES
- с помощью cmake, см.
pkg_check_modules
Создайте файл шаблона с именем mylib.pc.in
(см. справочную страницу pc (5) для получения дополнительной информации):
[email protected][email protected]
[email protected][email protected]
libdir=${exec_prefix}/@[email protected]
includedir=${prefix}/@[email protected]
Name: @[email protected]
Description: @[email protected]
Version: @[email protected]
Requires:
Libs: -L${libdir} -lmylib
Cflags: -I${includedir}
В свой CMakeLists.txt
добавьте правило для расширения макроса @
(@ONLY
просит cmake не расширять переменные вида ${VAR}
):
configure_file(mylib.pc.in mylib.pc @ONLY)
И, наконец, установите сгенерированный файл:
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
Вы также можете использовать функцию cmake EXPORT
. Однако эта функция совместима только с cmake
, и мне трудно ее использовать.
Наконец, весь CMakeLists.txt
должен выглядеть следующим образом:
cmake_minimum_required(VERSION 3.9)
project(mylib VERSION 1.0.1 DESCRIPTION "mylib description")
include(GNUInstallDirs)
add_library(mylib SHARED src/mylib.c)
set_target_properties(mylib PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
PUBLIC_HEADER api/mylib.h)
configure_file(mylib.pc.in mylib.pc @ONLY)
target_include_directories(mylib PRIVATE .)
install(TARGETS mylib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${CMAKE_BINARY_DIR}/mylib.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)