Compile&Link
编译和链接
起因
最近使用到一个简易RPC库,依赖项只有消息队列ZeroMQ,对应库名字是zmq。
目录结构如下
├── buttonrpc.hpp
├── CMakeLists.txt
├── example
│ ├── main_client.cpp
│ └── main_server.cpp
├── README.md
└── Serializer.hpp在自定义的头文件中buttonrpc.hpp中用到了zmq库,我使用apt下载下来。
其中CMakeLists.txt文件内容如下
cmake_minimum_required(VERSION 3.23)
project(buttonrpc_cpp14)
set(CMAKE_CXX_STANDARD 14)
include_directories(.) //添加头文件的查找路径,这样example目录下的cpp可以直接引入头文件而非完整路径。
add_executable(buttonrpc_cpp14 example/main_client.cpp)CMakeLists.txt的配置是没问题的,但使用CLionIDE编译运行时出现如下链接错误。
/usr/bin/ld: CMakeFiles/buttonrpc_cpp14.dir/example/main_client.cpp.o: in function `zmq::error_t::error_t()':
/usr/include/zmq.hpp:292: undefined reference to `zmq_errno'在次这前,我一直以为是只要引入头文件即可使用其内容。
然而事实是,需要链接。
知识梳理
编译链接生成可执行文件实际需要四个步骤,以及他们对应的g++命令
- 预处理(pre-process)
g++ -EPreprocess only; do not compile, assemble or link. - 编译 (Compile)
g++ -SCompile only; do not assemble or link. - 汇编(assemble)
g++ -cCompile and assemble, but do not link. - 链接 (link)
g++ -lPlace the output into file.
他们处理之后的文件后缀分别为
g++ -E main.cpp > main.i预处理后的文件 linux下以.i为后缀名,这个过程只激活预处理,不生成文件,因此你需要把它重定向到一个输出文件里 。g++ -S main.cpp生成main.s汇编文件。g++ -c main.cpp生成main.o含机器指令的目标文件。g++ main.o链接相关文件并生成a.out(可使用-o指定文件名字)可执行文件。
一般,直接使用g++ -c编译所有文件,然后使用g++ -o进行链接。
如果需要链接一些第三方库,需要g++ -o -l -l后面接库名。
实际上,C++标准库也是需要链接的,g++会默认链接它们,无须显式链接。
静态库和动态库
静态库
命名规则:
- Linux:libxxx.a
- window: libxxx.lib
制作:
gcc -c file1.c file2.car rcs libxxx.a file1.o file2.o
动态库
命名规则:
- Linux:libxxx.so
- windows: libxxx.dll
制作
gcc -c -fpic file1.c file2.cgcc -shared file1.o file2.o -o - libxxx.so编译后需要修改文件或环境变量。
工作原理
- 静态库工作gcc链接时会把静态库中的代码打包到可执行文件中。
- 动态库gcc链接时,动态库的代码不会被打包到可执行文件中。
- 当程序启动后,动态库会被动态加载到内存中,通过
ldd file命令检查动态库依赖关系 - 系统的动态载入器获取依赖库的绝对路径。对于elf格式的可执行程序,是由
ld_linux.so来完成。 - 先后检查文件的
DT_RPATHH- >LD_LIBRARY_PATH->etc/ld.so.cache文件列表->lib->/usr/lib目录后载入内存
- 当程序启动后,动态库会被动态加载到内存中,通过
对比
| 静态 | 动态 | |
|---|---|---|
| 优点 | 打包、加载速度快、打包无需提供静态库、移植方便 | 可以实现进程中资源共享、更新、部署、发布简单 |
| 缺点 | 消耗系统资源,浪费内存。更新、部署、发布麻烦 | 加载速度慢、发布程序时需要提供依赖的动态库 |
Compile&Link
https://messenger1th.github.io/2024/07/24/Articles/Compile&Link/