使用cmake构建一个动态库的例子
接触cmake很多年了,但是从来没自己写一个完整的CMakeLists.txt构建过自己的动态库,因为工作以来动态库我都是用别人开源的,基本没有构建自己动态库的需求。今天需要将一个使用automake构建的老库替换为cmake来构建于是了解了一些相关细节,准备迁移过来。
极简例子
以C语言为例,一个动态库至少要包含两个源文件,一个.c,一个.h。为啥?.c包含函数实现,.h给别人#include。源码例子如下:
library.h
#ifndef CSHAREDLIB_LIBRARY_H
#define CSHAREDLIB_LIBRARY_H
void hello(void);
#endif //CSHAREDLIB_LIBRARY_H
library.c
#include "library.h"
#include <stdio.h>
void hello(void)
{
printf("Hello, World!\n");
}
CMakeLists.txt
#指定cmake最低版本要求,因为可能这个CMakeLists.txt中引用的特性,内置函数,语法是特定版本才开始引入的
cmake_minimum_required(VERSION 3.22)
project(MyShared)
#构建动态库的关键一句,其中第二个参数SHARED是关键字,表示生成动态库,也可以是STATIC或者省略,表示生成静态库(.a)。
add_library(MyShared SHARED library.c library.h)
执行cmake生成Makefile,良好的习惯是把构建过程中的中间文件放在一个单独的目录,不和源码目录混在一起:
mkdir build
cd build
cmake ..
make
于是动态库libMyShared.so被编译出来了。这样就完了吗?如果你是比较狂野的人,这样确实完了。如果你把这个优秀的库放到github上供别人使用,别人编译完后,还需要手动拷贝动态库和头文件到系统默认的位置(例如/usr/local/lib /usr/local/include)。更好的做法是在cmake中添加安装动作,以便生成出来的makefile有install目标。修改后的CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.22)
project(MyShared)
add_library(MyShared SHARED library.c library.h)
set(INCLUDE_FILES "${CMAKE_SOURCE_DIR}/library.h")
set(CMAKE_INSTALL_PREFIX /usr/local)
install(TARGETS MyShared DESTINATION lib)
install(FILES ${INCLUDE_FILES} DESTINATION include/MyShared)
为了方便测试,不污染系统目录,我们可以暂时将安装目录CMAKE_INSTALL_PREFIX修改为你可以随意折腾的目录,如当前源码下的install_dir目录:
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install_dir)
修改后删除build目录里面所有内容,重新编译和安装:
cd build
rm * -rf
cmake ..
make
make install
install_dir会自动创建,tree查看下:
tree install_dir
install_dir
├── include
│ └── MyShared
│ └── library.h
└── lib
└── libMyShared.so

浙公网安备 33010602011771号