GCC编译过程分析
1.1 编译过程
1.1.1 常用的编译命令
$ gcc -o hello hello.c //这句命令包含预处理 编译 汇编 链接
$ ./hello // 运行可执行文件
hello.c
#include <stdio.h>
#define DEBUG
int main(int argv, char **argc)
{
printf("hello world!!\n");
#ifdef DEBUG
printf("debug info\n");
#endif
return 0;
}
运行结果:
1.1.2 打印详细的编译过程
$ gcc -o hello hello.c -v
$ ./hello
我们分析一下详细编译过程:
1.1.3 手工体验一下详细的编译过程
$ gcc -E -o hello.i hello.c //预处理
$ gcc -S -o hello.S hello.i //编译
$ gcc -c -o hello.o hello.S //汇编
$ gcc -o hello hello.o 其他.o //链接
分析:直观看到每个阶段生成的文件,可以vi打开各文件看看其内容。
1.2 常用的编译选项
1.2.0 源码
main.c
#include <stdio.h>
#include "add.h"
int main(int argv, char **argc)
{
int a, b;
printf("请输入两个被加数:");
scanf("%d%d",&a, &b);
printf("和为:%d\n",add(a,b));
return 0;
}
add.c
int add(int num1, int num2)
{
return num1+num2;
}
add.h
#ifndef __ADD_H
#define __ADD_H
int add(int num1, int num2);
#endif
1.2.1 常用选项
- -E 预处理
- -c 预处理、编译、汇编、不链接
- -o 指定输出的文件
- -I (大写)指定头文件目录
- -L 指定链接库时文件目录
- -l (小写)指定链接哪个库文件
1.2.2 编译多个文件
-
一起编译、链接
$ gcc -o add main.c add.c
-
分开编译、统一链接
$ gcc -c -o main.o mian.c $ gcc -c -o add.o add.c $ gcc -o add main.o add.o
1.2.3 制作、使用动态库
//命令
$ gcc -c -o main.o main.c
$ gcc -c -o add.o add.c
$ gcc -shared -o libadd.so add.o file1.o file2.o(可以使用多个.o 生成动态库)
$ gcc -o add main.o -ladd -L /libadd.so所在目录
//实践
feng@ubuntu:~/work$ gcc -c -o add.o add.c
feng@ubuntu:~/work$ gcc -c -o main.o main.c
feng@ubuntu:~/work$ gcc -shared -o libadd.so add.o //制作动态库成功
feng@ubuntu:~/work$ ls
add.c add.h add.o hello.c libadd.so main.c main.o
feng@ubuntu:~/work$ gcc -o add main.o -ladd -L ./ //链接成功
feng@ubuntu:~/work$ ls
add add.c add.h add.o hello.c libadd.so main.c main.o
feng@ubuntu:~/work$ ./add //第一种方式: //报错:找不到库
./add: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
feng@ubuntu:~/work$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/feng/work //导入路径
feng@ubuntu:~/work$ ./add
请输入两个被加数:12 23
和为:35
feng@ubuntu:~/work$ sudo cp libadd.so /lib //第二种方式:放在 /lib 目录下
[sudo] password for feng:
feng@ubuntu:~/work$ cd /lib
feng@ubuntu:/lib$ ls
file libadd.so
firefox libmbim python2.7 X11
firefox-addons libqmi python3
feng@ubuntu:/lib$ cd - //返回上一次的目录
feng@ubuntu:~/work$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home //已经不用这步了(故意搞错)
feng@ubuntu:~/work$ ./add //防止上面影响
请输入两个被加数:23
43
和为:66 //正常执行
1.2.4 制作、使用静态库
//命令
$ gcc -c -o main.o main.c
$ gcc -c -o add.o add.c
$ ar crs libadd.a add.o file1.o file2.o(可以使用多个.o 生成静态库)
$ gcc -o add main.o libadd.a (如果.a 不在当前目录下,需要指定它的绝对或相对路径)
运行:
不需要把静态库 libadd.a 放到板子上。
注意:执行 arm-linux-gnueabihf-gcc -c -o add.o add.c 交叉编译需要在最后面加上 -fPIC 参数。
1.2.5 很有用的选项
$ gcc -E main.c // 查看预处理结果,比如头文件是哪个
$ gcc -E -dM main.c > 1.txt // 把所有的宏展开,存在 1.txt 里
$ gcc -Wp,-MD,abc.dep -c -o main.o main.c // 生成依赖文件 abc.dep,后面 Makefile 会用