使用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
posted @   thammer  阅读(110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示