GCC 编译过程
扩展名 | 说明 |
---|---|
.c | C语言源代码文件 |
.h | 头文件 |
.i | 已经预处理过的C源代码文件 |
.s | 汇编语言源代码文件 |
.o | 编译后的目标文件 |
hello.c
#include <stdio.h>
int main() {
int a = 1;
printf("%d", a);
}
生成预处理文件
gcc -E hello.c -o hello.i
生成汇编文件(汇编源代码)
gcc –S hello.c –o hello.s
生成对应的目标文件
gcc -c hello.c -o hello.o
生成二进制程序
gcc hello.o -o hello
多文件编译
单一文件夹
say_hello.h
#ifndef _SAY_HELLO_H
#define _SAY_HELLO_H
void say_hello(char *str);
#endif
say_hello.c
#include <stdio.h>
#include "say_hello.h"
void say_hello(char *str)
{
printf("%s",str);
}
hello.c
#include <stdio.h>
#include "say_hello.h"
int main()
{
say_hello("hello world!\n");
}
一步编译
gcc hello.c say_hello.c -o hello
多文件夹
GCC 默认头文件搜索路径为当前目录和 /usr/include
,若头文件不存在于这两个文件夹中则需要额外指定头文件搜索路径,使用 -I
指定。
gcc hello.c functions/say_hello.c -o hello –I functions
makefile
多文件编译直接通过指令编译过于繁琐,可以使用 make 工具。make 工具根据 makefile 文件中的规则完成对特定文件的编译,最后生成对应的可执行文件。
makefile 基本格式:
目标: 依赖列表
命令
命令缩进必须使用 tab 缩进。
使用 make
指令会自动寻找当前目录下的 makefile
文件。
# 目标文件 -> 二进制程序
hello: hello.o say_hello.o
gcc hello.o say_hello.o -o hello
# 源文件 -> 目标文件
say_hello.o: say_hello.c
gcc -c say_hello.c -o say_hello.o
# 源文件 -> 目标文件
hello.o: hello.c
gcc -c hello.c -o hello.o
# make clean 时执行的指令,清除上次 make 产生的所有文件
clean:
rm -f *.o
rm -f hello
makefile 层次图
makefile 宏定义
CC=gcc
CFLAGS=-Wall-c
OBJS=hello.o say_hello.o
INCLUDE=function
hello: ${OBJS}
${CC} ${OBJS} -I INCLUDE -o hello
say_hello.o: say_hello.c say_hello.h
${CC} ${CFLAGS} say_hello.c -o say_hello.o
hello.o: hello.c say_hello.h
${CC} ${CFLAGS} hello.c -o hello.o
函数库
libxxx.a
的文件一般为静态函数库,libxxx.so
一般为动态函数库,动态函数库在编译的时候没有被编译到目标代码中,程序执行到相关函数的时候才调用函数库里的相应的函数,因此动态函数库产生的可执行文件比较小。
创建静态函数库
ar -rvs libpr.a pr1.o pr2.o
加载库进行编译(-L 添加当前目录为库搜索目录,-l 添加库 libxx.a)
gcc -o main main.c -L. -lpr
生成动态函数库
gcc -fpic -shared -o libpr.so pr1.c pr2.c
加载动态函数库
gcc -o main main.c ./libpr.so