ZhiBing's blog(码上看世界) ZhiBing's blog(码上看世界)
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

ZhiBing Zheng

时间会回答成长
首页
  • Linux工具链

    • shell命令
  • 构建

    • CMake
    • Makefile
  • 版本管理

    • Git
    • Github
  • IDE及工具

    • vscode
    • CLion
  • 设计模式

    • 设计原则
  • 编程语言

    • C++
    • Go
    • Python
    • Shell
  • 调试

    • gdb
  • 开发者测试

    • gtest
  • 系统支撑

    • 操作系统
  • 性能优化

    • 编译优化选项
    • perf
    • valgrind
  • 容器

    • Docker
  • 微服务

    • Rancher
  • 其他
  • 随笔
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • Linux工具链

  • 构建

    • CMake

      • CMake Day 1 —— 初识 CMake
      • CMake Day 2 —— 指定 C/C++的标准
      • CMake Day 3 —— 编译二进制或库
      • CMake Day 4 —— 设置头文件路径和链接库
      • CMake Day 5 —— 从 CMakeLists.txt 传递变量到源文件
      • CMake Day 6 —— 安装规则(install rules)
      • CMake Day 7 —— option
      • CMake Day 8 —— 编译成一个库(利用OBJECT)
    • Makefile

  • 版本管理

  • IDE及工具

  • 基础领域
  • 构建
  • CMake
zhengzhibing
2022-11-19

CMake Day 8 —— 编译成一个库(利用OBJECT)

# CMake Day 8 —— 编译成一个库(利用OBJECT)

对外发布库时,通常考虑发布少量的库,此时可以收集所有源码编译成一个库,但是不够简洁,可以先编译成OBJECT库,然后再编译成目标文件。

须知:

静态库可以视作编译过程的中间文件,因为单独的静态库没有任何作用。动态库则不然,动态库可以视作最终的二进制文件,所以不存在合并动态库。通俗的讲,合并路径有如下几种:

  • 静态库+静态库=静态库
  • 静态库+静态库=可执行文件
  • 静态库+动态库=动态库

例如有这样一个项目(https://github.com/AZMDDY/cmake-demo/tree/main/cmake-day-8/demo1):

.
├── CMakeLists.txt
├── dir1
│   ├── CMakeLists.txt
│   ├── dir3
│   │   ├── CMakeLists.txt
│   │   └── test3.cpp
│   └── test1.cpp
└── dir2
    ├── CMakeLists.txt
    └── test2.cpp
1
2
3
4
5
6
7
8
9
10
11

如果想将这些源码编译成一个库,有三个办法:

  1. 直接获取这些源码路径,一次性编译成库。

    add_library(demo1 STATIC ../dir2/test2.cpp ../dir1/test1.cpp ../dir1/dir3/test3.cpp)
    
    1

    如上,这仅仅是个demo,在实际项目中不可能采用这样的方法,实际项目也会划分了很多模块,都这样编译放在一起,维护成本太高。

  2. 在编译好每个模块后,利用ar命令将多个静态库合并。

    ar crsT libdemo1.a libdemo1_test1.a libdemo1_test2.a libdemo1_test3.a
    
    1

​ 顺带提一下,静态库合并成动态库的方式如下:

g++ -shared -o libdemo1.so -Wl,--whole-archive dir1/libdemo1_test1.a dir1/dir3/libdemo1_test3.a dir2/libdemo1_test2.a -Wl,--no-whole-archive
1
  1. 利用OBJECT将每个模块都编译成OBJECT库,然后再将OBJECT编译成静态库或动态库。

    add_library(demo1_test1_obj OBJECT test1.cpp)
    add_library(demo1_test2_obj OBJECT test2.cpp)
    add_library(demo1_test3_obj OBJECT test3.cpp)
    
    add_library(obj_demo1 SHARED $<TARGET_OBJECTS:demo1_test1_obj> $<TARGET_OBJECTS:demo1_test2_obj> $<TARGET_OBJECTS:demo1_test3_obj>)
    
    1
    2
    3
    4
    5
上次更新: 2022/11/19, 16:52:47
CMake Day 7 —— option
makefile-day-1

← CMake Day 7 —— option makefile-day-1→

最近更新
01
HPE gen10 plus 安装ESXI 7
06-12
02
ESXI 7安装黑群晖
06-12
03
ESXI 7安装win10
06-12
更多文章>
Theme by Vdoing | Copyright © 2022-2024 ZhBing Zheng | 粤ICP备2022062743号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式