源代码、目标文件、可执行文件、静态库文件、动态库文件

2021-12-02  本文已影响0人  张科_Zack

源代码、目标文件、可执行文件、静态库文件、动态库文件

名词介绍都以 C++ 源代码为例, 使用的编译系统为 clang++。

1.名词介绍

2. clang++ 使用

2.1源代码

创建两个 cpp 文件:add.cpp 和 main.cpp

// add.cpp , 该文件实现 add 函数来对两整数求和
#include <iostream>
using namespace std;
int add(int a, int b) {
    return a + b;
}

声明 add 函数方便下文使用静态库和动态库链接并生成可执行文件。

#include <iostream>

using namespace std;
int add(int a, int b);
int main(int argc, const char * argv[]) {
    cout << add(2, 4) << endl;
    return 0;
}

2.2 使用源码生成目标文件

  1. C++ 中目标文件以 .o为扩展名,使用如下命令编译 add.cpp 并生成目标文件 add.o
clang++ -c add.cpp

使用 file add.o 命令输出目标文件类型, 可以看到 add.o 也是 Mach-O 文件的一种

add.o: Mach-O 64-bit object x86_64
  1. 为 main.cpp 生成目标文件
    使用如下命令生成 main.o 目标文件,我们并没有对 add 函数提供实现只是为其声明,可见编译生成目标文件并不需要对某个函数提供具体实现只要找到其申明过程就行。
clang++ -c main.cpp
file add.o 
结果:
add.o: Mach-O 64-bit object x86_64
file main.o  
结果:
main.o: Mach-O 64-bit object x86_64

通过以上两个步骤我们分别生成了 add.o 以及 main.o 两个目标文件, 并且可见目标文件是 Mach-O 文件。

2.3 使用目标文件生成静态库

这里我们有两个目标文件 add.omain.o,其关系是 main.o 是主程序目标文件而 add.o 是依赖目标文件,我们最终目标是生成 main 可执行文件去满足对 add 加和函数的结果输出,因此生成静态库文件则是对 add.o 文件作处理,使用如下命令生成 libadd.a 静态库。

ar -r libadd.a add.o
结果如下:
ar: creating archive libadd.a
file libadd.o
结果如下:
libadd.a: current ar archive random library

可见 .a 静态库文件并不是 Mach-O 文件
以上 ar 命令是 archive 的缩写,也就是其实是对 目标文件的压缩,据了解静态库是 一系列目标文件的组合。

2.4 使用目标文件生成动态库文件

使用 目标文件 add.o 生成动态库 libadd.so

clang++ add.o -shared -fPIC -o libadd.so
file libadd.so
输出结果:
libadd.so: Mach-O 64-bit dynamically linked shared library x86_64

可见 .so 可见是 Mach-O 文件

2.5 可执行文件生成

2.5.1 不使用依赖库生成可执行文件

# app.cpp
#include <iostream>

using namespace std;
int main(int argc, const char * argv[]) {
    cout << "Hello World!" << endl;
    return 0;
}

clang++ -c app.cpp
clang++ app.o -o app
file app
结果:
app: Mach-O 64-bit executable x86_64

  ./app
 结果:
 Hello World!

2.5.2 使用静态库生成可执行文件

使用静态库生成可执行的文件时需要链接对应的静态依赖库, 这里需要链接 libadd.a, 以下命令可以理解为, 通过链接静态库libadd.a为目标文件 main.o 生成可执行文件 main, 由于我们通过上述几个步骤即生成了静态库也生成了动态库,则链接是优先使用动态库链接,但这里我们需要使用静态库因此先把动态库 libadd.so 删除。

rm -rf libadd.so
clang++ main.o -L. -ladd -o main
file main
结果:
main: Mach-O 64-bit executable x86_64

2.5.3 使用动态库生成可执行文件

动态库生成可执行文件与静态库命令一致,链接时优先使用动态库链接,但我们之前把动态库删除了需要先生成动态库。

clang++ add.o -shared -fPIC -o libadd.so
clang++ main.o -L. -ladd -o main

可执行文件也是 Mach-O 文件

3. 动态库与静态库区别

由于其生成可执行文件时是拷贝到其中的而动态库则是动态链接的。每个使用静态库生成的可执行文件都会包含对应静态库而动态库生成的则只会链接对应的同一份动态库。

上一篇 下一篇

猜你喜欢

热点阅读