始终指定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")
声明一个新的库目标。请避免使用文件(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"这样的相对路径不太方便。因此,在包含的目录中传递一个top目录:
target_include_directories(mylib PRIVATE .)
or
target_include_directories(mylib PRIVATE include)
target_include_directories(mylib PRIVATE src)
为库创建安装规则。我建议使用GNUInstallDirs中定义的变量CMAKE_INSTALL_*DIR:
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) manpage):
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 ask to 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)
EDIT
正如评论中提到的,为了符合标准,您应该能够生成静态库和共享库。这个过程有点复杂,与最初的问题不匹配。但值得一提的是,这里对此进行了大量解释。