始终指定所需的最低版本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
文件。此文件允许第三方应用程序轻松导入您的库:
创建一个名为的模板文件mylib.pc.in
(有关更多信息,请参见pc(5)手册页 ):
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
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)
您也可以使用cmakeEXPORT
功能。但是,这个功能只兼容,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)
编辑
正如评论中提到的,为了符合标准,您应该能够生成静态库和共享库。这个过程有点复杂,与最初的问题不匹配。但值得一提的是,这里有很大的解释。