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. 更新与维护
  • 静态库

    修改库代码后,必须重新编译链接程序才能生效。

    重新编译静态库和程序

bash 复制代码
gcc -c Exampile.c -o Exampile.o
ar rcs libExampile.a Exampile.o
gcc main.c -L. -lExampile -o main

动态库

  • 更新库文件后,只需替换旧库文件,所有依赖该库的程序会自动使用新版本(需接口兼容)。
复制代码
# 编译动态库
bash 复制代码
gcc -shared -fPIC Exampile.c -o libExampile.so
复制代码
# 编译程序时链接动态库
bash 复制代码
gcc main.c -L. -lExampile -o main
  1. 跨平台与兼容性
  • 静态库

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

  • 动态库

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

1

1

1

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

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

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

cpp 复制代码
# 2.需要的依赖库 现在没有
set(SOURCES
    src/foo.c
    src/bar.c
    src/you.c
)

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

cpp 复制代码
# 创建静态库 source获取路径
add_library(mylib_static STATIC ${SOURCES})

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

3. 对动态库设置rpath

cpp 复制代码
set_target_properties(mylib_shared PROPERTIES

    # 插入路径为
    INSTALL_RPATH "\$ORIGIN"
    BUILD_WITH_INSTALL_RPATH TRUE
)

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

cpp 复制代码
# 链接共享库
target_link_libraries(main mylib_shared)

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

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

CMakeLists.txt文件

cpp 复制代码
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(SOURCES
    src/foo.c
    src/bar.c
    src/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二进制文件

相关推荐
_下雨天.1 小时前
LVS负载均衡
服务器·负载均衡·lvs
小成202303202654 小时前
Linux高级02
linux·开发语言
mounter6254 小时前
【硬核前沿】CXL 深度解析:重塑数据中心架构的“高速公路”,Linux 内核如何应对挑战?-- CXL 协议详解与 LSF/MM 最新动态
linux·服务器·网络·架构·kernel
钢琴上的汽车软件4 小时前
C 语言中const与指针:三种常见写法辨析
c语言·指针和const
知行合一。。。4 小时前
Python--04--数据容器(总结)
开发语言·python
++==4 小时前
Linux 进程间通信与线程同步技术详解:IPC 机制、线程 API、同步工具与经典同步问题
linux
咸鱼2.04 小时前
【java入门到放弃】需要背诵
java·开发语言
ZK_H4 小时前
嵌入式c语言——关键字其6
c语言·开发语言·计算机网络·面试·职场和发展
特长腿特长4 小时前
centos、ubantu系列机的用户和用户组的结构是什么?具体怎么配置?用户组权限怎么使用?这篇文章持续更新,帮助你复习linux的基础知识
linux·运维·centos
澈2074 小时前
深入浅出C++滑动窗口算法:原理、实现与实战应用详解
数据结构·c++·算法