首先梳理一下源文件到可执行文件的整个过程,下面是两个源文件的组成main.c和sum.c
// main.c
int sum(int *a, int n);
int array[2] = { 1, 2 };
int main() {
int val = sum(array, 2);
return val;
}
// sum.c
int sum(int *a, int n) {
int i, s = 0;
for (i = 0; i < n; i++) {
s += a[i];
}
return s;
}
使用命令:gcc -Og -o prog main.c sum.c调用GCC的驱动程序。下图是静态链接,链接器将可重定位的目标文件组合起来,形成一个可执行目标文件prog。这个链接的过程可以分为三个步骤:
- 它首先运行C预处理器cpp,将C源程序main.c翻译成一个ASCII码的中间文件main.i
- 接下来,C编译器cc1将main.i翻译成一个ASCII汇编语言文件main.s
- 最后,汇编器as将main.s翻译成一个可重定位目标文件main.o,此时的目标文件还不能执行,需要通过链接器将其与所依赖的函数(如sum.o)链接到一块才可以生成可执行文件
在运行可执行文件prog时,shell调用操作系统中一个叫做加载器的函数,他将可执行文件prog中的代码和数据复制到内存,然后将控制转移到这个程序的开头。
GCC不会保留预处理文件(.i文件),但可以通过-E选项在预处理阶段完毕后停止编译,将预处理信息保存到一个文件。
gcc -E main.c -o main.i gcc -E main.c > main.i2.2 -o 选项
指定生成目标的名称,gcc main.c sum.c -o main。
三、编译 3.1 -S 选项只激活预处理和编译,把源文件编译成为汇编文件后停止,源文件可以是.c文件,也可以是.i文件。
gcc main.c -o main.s -S gcc main.i -o main.s -S四、汇编 4.1 -c 选项
只激活预处理,编译,和汇编,把源文件编译成可重定位目标文件,源文件可以是.c、.i、.s文件。
gcc main.c -o main.o -c gcc main.i -o main.o -c gcc main.s -o main.o -c4.2 objdump 命令
objdump命令是Linux下的反汇编目标文件或者可执行文件的命令,它以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。
- 反汇编应用程序,objdump -d main.o
- 显示文件头信息,objdump -f main.o
- 显示制定section段信息(comment段),objdump -s -j .comment main.o
如果程序需要使用某个动态库中的函数,则在程序的编译阶段和之后的运行阶段都需要链接这个动态库, 即编译时链接和运行时链接。
5.1 编译时链接 1)-L 指定编译时库的路径指定编译时,搜索使用到的库的路径,可以是静态库,也可以是动态库,-L.表示当前路径。
2)-l 指定编译时引用库的名字指定编译时使用到的库名称,可以是静态库,也可以是动态库,静态库libmine.a和动态库libmine.so均可使用-lmine。
loongson@loongson-pc:~/workspace/cpptest$ ls main.c sum.c loongson@loongson-pc:~/workspace/cpptest$ gcc main.c -o main /usr/bin/ld: /tmp/ccYPPudv.o: in function `main': main.c:(.text+0x28): undefined reference to `sum' /usr/bin/ld: main.c:(.text+0x30): undefined reference to `sum' collect2: error: ld returned 1 exit status loongson@loongson-pc:~/workspace/cpptest$ gcc sum.c -o sum.o -c loongson@loongson-pc:~/workspace/cpptest$ ls main.c sum.c sum.o loongson@loongson-pc:~/workspace/cpptest$ ar -cr libmine.a sum.o loongson@loongson-pc:~/workspace/cpptest$ ls libmine.a main.c sum.c sum.o loongson@loongson-pc:~/workspace/cpptest$ gcc main.c -o main -lmine -L. loongson@loongson-pc:~/workspace/cpptest$ ls libmine.a main main.c sum.c sum.o5.2 运行时链接 1)-Wl,-rpath 指定运行时动态库路径
用于指定程序运行时查找动态链接库的路径,多个路径是使用冒号隔开,这样就不用添加路径到 /etc/ld.so.conf 文件中或者环境变量LD_LIBRARY_PATH了,在需要多个so版本共存时很有用。
六、其他 6.1 -c 选项参考链接:
https://blog.csdn.net/qq_35865125/article/details/87868653
https://blog.csdn.net/gangyanliang/article/details/73162231
https://blog.csdn.net/hktkfly6/article/details/61922685
https://blog.csdn.net/tsxw24/article/details/10220735



