GCC和程序编译过程
GCC是linux下面的编译器,最初名称是GNU C Compiler (GCC) ,后面逐渐可以编译各种语言,因此GNU Compiler Collection (GCC)。
他是自由软件大神Richard Stallman发起的。目前GCC系列在win和unix环境都可以使用,win中可以使用mingw或者cygwin
使用GCC,就要知道它的各种编译选项,而在这之前我们首先要知道程序的编译过程:
预处理,一般是包含头文件,展开宏定义等,生成.i格式输出文件
编译,将预处理后的文件编译生成汇编代码
汇编,将汇编代码生成机器码
链接,将多个不同的目标文件以及动态库和静态库路径链接生成最终的可执行文件
对于一个简单的文件,上面的流程gcc命令如下:
程序的运行过程:
预处理->编译->汇编->链接预处理 gcc -E hello.c -o hello.i编译,生成汇编代码 gcc -S hello.i -o hello.s汇编,生成.o汇编文件 gcc -c hello.s -o hello.o链接生成可执行文件 gcc hello.o -o helloGCC的其他常用选项包括如下:
gcc选项:
-o 输出可执行文件-c 编译生成目标文件-g 输出调试信息-O2 编译器优化级别 1-3-Wall 警告选项 输出警告信息-l 紧接着链接库 lpthread-L 指定链接库的路径-I 头文件路径-shared 编译成动态链接库注意-c只是生成目标文件,而-o直接回生成可执行文件
头文件与链接库文件
在编译程序的时候,我们通常需要关注的是头文件以及链接库文件
头文件.h开头,一般会有各种函数和结构的声明,库文件包括动态链接库与静态链接库,linux下分别是.so 和 .a
Makefile的作用和介绍
其实GCC编译器完全可以满足编译C以及CPP程序的需求,那么为什么还需要makefile呢。
Makefile的作用是将GCC编译的过程规则化,包括编译顺序,依赖关系,第二次进行增量编译,编译后的一些相关操作等。
Makefile会定义一对规则和依赖关系,规则定义如下:
名称: 依赖项1 依赖项2 .....
[tab] 一系列命令
一些选项和宏定义:
# 注释
\ 换行macro宏定义
CC 表示编译器的名称 CFLAGS表示编译器选项 LDLIBS表示链接库选项 $@ 代指目标文件 $<第一个依赖文件 $^所有依赖文件 $?所有的比目标文件更新的依赖文件$+和$^类似,但是可以包含重复
VPATH = src include 从src 和 include中寻找依赖项
vpath %.c src 从src找.c文件 vpath %.h include 从include找.h文件%.o:%.c #%表示文件匹配
相关examples:
#(1)
.c.o: # .c.o:表示所有的.o都与其对应的.c依赖
gcc -c $< # 表示编译所有的.c依赖项#(2)
#main依赖于 mytool1 和 mytools2
main:main.o mytools1.o mytools2.o
gcc -o $@ $^ .c.o: gcc -c $< -l.;#(3)
LINK_TARGET = test_me.exe
OBJS = \
Test1.o \ Test2.o \ Main.oREBUILDABLES = $(OBJS) $(LINK_TARGET)
clean :
rm -f $(REBUILDABLES) echo Clean doneall : $(LINK_TARGET)
echo All done$(LINK_TARGET) : $(OBJS)
g++ -g -o $@ $^%.o : %.cpp
g++ -g -o $@ -c $<Main.o : Main.h Test1.h Test2.h
Test1.o : Test1.h Test2.h Test2.o : Test2.h# %.dep : %.cpp
# g++ -M $(FLAGS) $< > $@# include $(OBJS:.o=.dep)