当前位置: 首页 > news >正文

C语言—Linux环境下CMake设置库(动态/静态)

1. Yesterday Once More

由于昨日我们在VSCode设置了如何使用CMake构建与编译c语言项目,如有疑问,请看以下链接,今日根据昨天的配置来进一步完成项目的构建。

c语言- 如何构建CMake项目(Linux/VSCode)-CSDN博客

2. 动态静态lib的区别

1. 静态库与动态库对比表

特性静态库(.a / .lib)动态库(.so / .dll)
文件扩展名Linux: .a
Windows: .lib
Linux: .so
Windows: .dll
链接时机编译时完整链接到可执行文件运行时动态加载
可执行文件体积较大(库代码被复制到可执行文件中)较小(仅记录库的引用)
运行时依赖无需依赖库文件必须存在对应的动态库文件
内存占用每个程序独立占用库的内存多个程序共享同一份库的内存
更新维护需重新编译程序替换库文件即可生效
兼容性与编译时的库版本完全绑定需保证接口兼容性(版本管理重要)
性能略快(无运行时加载开销)略慢(首次加载需额外时间)
跨平台支持依赖编译平台需为不同平台编译对应的动态库
典型应用场景小型项目、嵌入式系统(无动态加载环境)大型项目、插件系统、多程序共享库

2. 核心区别详解

1. 链接方式与内存管理
  • 静态库

    • 在编译时,库的代码会被完整地复制(copy)到最终的可执行文件中。

    • 优点:程序独立运行,无需外部依赖。

    • 缺点:可执行文件体积大,多进程运行时内存占用高(库代码被多次加载)。

  • 动态库

    • 编译时仅记录库的符号(函数名、变量名等),运行时由操作系统动态加载。

    • 优点:节省磁盘和内存空间,支持热更新(替换库文件无需重新编译程序)。

    • 缺点:部署时需确保目标系统存在正确的库版本。

2. 更新与维护
  • 静态库
    修改库代码后,必须重新编译链接程序才能生效。

    # 重新编译静态库和程序

  • gcc -c Exampile.c -o Exampile.o
    ar rcs libExampile.a Exampile.o
    gcc main.c -L. -lExampile -o main

    动态库

  • 更新库文件后,只需替换旧库文件,所有依赖该库的程序会自动使用新版本(需接口兼容)。

  • # 编译动态库
    gcc -shared -fPIC Exampile.c -o libExampile.so
  • # 编译程序时链接动态库
    
    gcc main.c -L. -lExampile -o main

    3. 跨平台与兼容性

  • 静态库
    不同操作系统(如 Linux 和 Windows)需分别编译静态库,且格式不兼容。

  • 动态库
    需为每个平台编译对应的动态库(如 Linux 的 .so 和 Windows 的 .dll),且需注意符号版本控制(如使用 soname)。

1

1

1

3. 在linux环境下设置库与编译文件

主要是更改CMakeLists.txt文件,分五部分

1. 更改source,指定路径下的文件

# 2.需要的依赖库 现在没有
set(SOURCESsrc/foo.csrc/bar.csrc/you.c
)

2. 用获取到的路径变量,创建动/静库

# 创建静态库 source获取路径
add_library(mylib_static STATIC ${SOURCES})# 创建动态库,source获取路径
add_library(mylib_shared SHARED ${SOURCES})

3. 对动态库设置rpath

set_target_properties(mylib_shared PROPERTIES# 插入路径为INSTALL_RPATH "\$ORIGIN"BUILD_WITH_INSTALL_RPATH TRUE
)

4.  连接动/静库(此时为动态库)

# 链接共享库
target_link_libraries(main mylib_shared)

5. 把之前扫描src下的c文件注释掉

# 扫描src目录下的所有C文件
# aux_source_directory(src SRC_FILES)
# add_executable(main ${SRC_FILES})

CMakeLists.txt文件

cmake_minimum_required(VERSION 3.10.0) # CMake版本
project(t1 VERSION 0.1.0 LANGUAGES C) # 项目版本# debug模式
SET(CMAKE_BUILD_TYPE Debug) # debug模式# SET(CMAKE_BUILD_TYPE Release) #Release严格测试模式# 暂时不管,测试
include(CTest)
enable_testing()# 2.需要的依赖库 现在没有
set(SOURCESsrc/foo.csrc/bar.csrc/you.c
)# 3.设置可执行文件与链接库保存的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)# 4.设置头文件目录使得系统可以找到对应的头文件
include_directories(${PROJECT_SOURCE_DIR}/inc/inner # 自己目录的头文件${EIGEN3_INCLUDE_DIR} # 其他系统目录的头文件 也可以直接写路径/usr/include/eigen3${Pangolin_INCLUDE_DIRS}
)# 5.编译动态库并链接库文件
# 创建静态库 source获取路径
add_library(mylib_static STATIC ${SOURCES})# 创建动态库,source获取路径
add_library(mylib_shared SHARED ${SOURCES})# 设置rpath仅对共享库生效
set_target_properties(mylib_shared PROPERTIES# 插入路径为INSTALL_RPATH "\$ORIGIN"BUILD_WITH_INSTALL_RPATH TRUE
)# 6.生成可执行文件
# 选择需要编译的源文件,有几个文件写几个
add_executable(main src/main.c)# add_executable(my src/main.c src/test.c)
# 扫描src目录下的所有C文件
# aux_source_directory(src SRC_FILES)
# add_executable(main ${SRC_FILES})# 链接共享库
target_link_libraries(main mylib_shared)# 链接静态库
# target_link_libraries(main mylib_static)# 配置cmake项目名称
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})# 配置cmake项目c语言的版本 11
set(CMAKE_C_STANDARD 11)# 设置交叉编译器的位置
set(CMAKE_C_COMPILER gcc)
include(CPack)

点击ctrl+shift+b编译后,执行bin下的mian二进制文件

相关文章:

  • 前端面经-WebGL/threeJS
  • 【Java高阶面经:微服务篇】9.微服务高可用全攻略:从架构设计到自动容灾
  • Java 实现四种单例(都是线程安全)
  • 工程优化大纲
  • 高并发架构设计之限流
  • Linux查 ssh端口号和服务状态
  • 通过 curl 精准定位问题
  • 什么是实时流数据?核心概念与应用场景解析
  • 如果教材这样讲--单片机IO口Additional Functions和 Alternate Functions的区别
  • PaddleOCR的Pytorch推理模块
  • PostgreSQL使用
  • SQL 查询来查看 PostgreSQL的各连接数
  • 海康NVR录像回放SDK原始流转FLV视频流:基于Java的流媒体转码(无需安装第三方插件ffmpeg)
  • upload-labs通关笔记-第16关 文件上传之exif_imagetype绕过(图片马)
  • 软件设计师考试需背诵知识点
  • HarmonyOS NEXT应用开发实战:玩鸿蒙App客户端开发
  • 【图像大模型】Hunyuan-DiT:腾讯多模态扩散Transformer的架构创新与工程实践
  • 【iOS(swift)笔记-10】利用类的继承来实现不同地区语言的显示
  • Mcu_Bsdiff_Upgrade
  • 监督学习与无监督学习区别
  • 深圳做微信商城网站建设/关键词林俊杰mp3
  • 网站排名软件优化/正规seo一般多少钱