cmake共享库编译及连接
当项目比较大的时候,我们希望将基础的源文件打包成库,静态库或者共享库都可以。
首先看一下我们的项目目录
cmaths是我自己写的一些数学计算包,我希望把它打成包,在多个项目中共享
根目录的CMakeLists.txt在上图没有显示,我把内容贴出来
CMakeLists.txt
cmake_minimum_required(VERSION 2.8) project(system_program_notes C) set(CMAKE_C_STANDARD 11) add_subdirectory(cmaths) add_subdirectory(cmaths_static_test) add_subdirectory(cmaths_shared_test) #cmaths_static_test需要用到静态库,cmaths_shared_test需要依赖共享库,所以在需要在cmaths目录先执行cmake . && make 即可在cmaths/lib子目录生成libfunc_static.a,libfunc_shared.so库文件 #然后再在根目录执行cmake . && make ,cmaths_static_test,cmaths_shared_test即可成功找到库文件
一、共享库源码及配置
func.h
#ifndef SYSTEM_PROGRAM_NOTES_FUNC_H #define SYSTEM_PROGRAM_NOTES_FUNC_H int square(int a,int b); double sqrt(double x); #endif //SYSTEM_PROGRAM_NOTES_FUNC_H
func.c
#include "func.h" int square(int a,int b){ return a*a+b*b; } double sqrt(double x){ if (x <= 0) { return 0; } double result; double delta; result = x; int i; for (i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } delta = x - (result * result); result = result + 0.5 * delta / result; } return result; }
cmaths/CMakeLists.txt
add_library(func_static STATIC func.c) add_library(func_shared SHARED func.c) #设置最终生成库的名称,静态库=func_static,共享库=func_shared set_target_properties (func_static PROPERTIES OUTPUT_NAME "func_static") set_target_properties (func_shared PROPERTIES OUTPUT_NAME "func_shared") #实践发现库会生成到当前目录的lib目录下 set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) #首先在当前目录下执行cmake . && make 即可在当前目录的lib子目录生成libfunc_static.a静态库文件和libfunc_shared.so #然后再在根目录执行cmake . && make ,即可
二、链接静态库
cmaths_static_test模块需要引用静态库func_static
cmaths_static_test/test.c
#include <stdio.h> #include "func.h" int main(int argc, char *argv[]){ printf("%f\n", sqrt(36)); printf("%d\n", square(2,3)); }
cmaths_static_test/CMakeLists.txt
#指定路径,用于找到cmaths/func.h include_directories(../cmaths ) #查找静态库,参数分别是:变量名、库名、HINTS、路径 find_library(FUNC_LIB func_static HINTS ${PROJECT_SOURCE_DIR}/cmaths/lib) #编译目标文件 add_executable(test test.c) #链接到静态库 target_link_libraries(test PUBLIC ${FUNC_LIB})
三、链接共享库
cmaths_shared_test/test1.c
#include <stdio.h> #include "func.h" int main(int argc, char *argv[]){ printf("%f\n", sqrt(36)); printf("%d\n", square(2,3)); }
cmaths_shared_test/CMakeLists.txt
#找到func.h include_directories(../cmaths ) #指定共享库目录 link_directories(${PROJECT_SOURCE_DIR}/cmaths/lib) #编译目标文件 add_executable(test1 test1.c) #链接目标和共享库文件 target_link_libraries(test1 PUBLIC libfunc_shared.so)
四、编译构建
在linux系统,首先在cmaths目录下执行cmake . && make 即可在cmaths的lib子目录生成libfunc_static.a静态库文件和libfunc_shared.so共享库文件
然后再在根目录执行cmake . && make ,即可
然后cd到cmaths_static_test即可发现test可执行文件
cmaths_shared_test即可发现test1可执行文件。
执行无误,说明我们的目标文件成功链接到了库文件
五、安装
平常我们在构建源码安装包的时候,一般是先make,然后make install
make可以从一个名为makefile的文件中获得如何构建你所写程序的依赖关系,并执行编译,可以认为是加强版的gcc
make install也是从makefile读取配置,将make生成的目标文件安装到指定目录
坦率的说makefile不太好写,所以cmake横空出世,让我们可以以比较简单的方式生成makefile。
上面的内容,我们已经可以生成可执行文件和各种库文件,下面我们来将这些文件安装到指定目录
对cmaths/func.c略作修改
#include <stdio.h> #include "func.h" int square(int a,int b){ return a*a+b*b; } double sqrt(double x){ if (x <= 0) { return 0; } double result; double delta; result = x; int i; for (i = 0; i < 10; ++i) { if (result <= 0) { result = 0.1; } delta = x - (result * result); result = result + 0.5 * delta / result; } return result; } int main(int argc, char *argv[]){ printf("%f\n", sqrt(36)); printf("%d\n", square(2,3)); }
然后修改cmaths/CMakeLists.txt
add_library(func_static STATIC func.c) add_library(func_shared SHARED func.c) #设置最终生成库的名称,静态库=func_static,共享库=func_shared set_target_properties (func_static PROPERTIES OUTPUT_NAME "func_static") set_target_properties (func_shared PROPERTIES OUTPUT_NAME "func_shared") #实践发现库会生成到当前目录的lib目录下 set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) add_executable(func func.c) #首先在当前目录下执行cmake . && make 即可在当前目录的lib子目录生成libfunc_static.a静态库文件和libfunc_shared.so #然后再在根目录执行cmake . && make ,即可 #最后执行make install 可进行安装工作 #install执行日志,共享库默认被安装到了/usr/local/lib目录下,头文件默认被安装到/usr/local/include目录下 #-- Installing: /usr/local/bin/func #-- Installing: /usr/local/lib/libfunc_shared.so #-- Installing: /usr/local/lib/libfunc_static.a #-- Installing: /usr/local/include/func.h #安装的目标,后面一行指不同的目标类型要被安装到什么目录 install(TARGETS func func_shared func_static RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) #安装普通文件 install(FILES func.h DESTINATION include)
最后是执行指令,在cmaths目录执行cmake . &&make && make install
可以看到库文件默认被安装到了/usr/local/lib目录下,头文件默认被安装到/usr/local/include目录下,可执行文件被安装到了/usr/local/bin目录下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2020-04-27 python内置函数