Gcc的编译流程
预处理阶段: gcc –E hello.c –o hello.i
编译阶段: gcc –S hello.i –o hello.s
汇编阶段:gcc –c hello.s –o hello.o
链接阶段:gcc hello.o –o hello
执行:./hello
GCC的选项
GCC 有超过100个的编译选项可用. 主要包括编译处理选项、警告选项、出错选项、优化选项、体系结构选项。
-c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
-o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。
-S 编译选项告诉 GCC 在为 C 代码产生了汇编语言文件后停止编译. GCC 产生的汇编语言文件的缺省扩展名是 .s .
-g,产生符号调试工具(GNU的gdb)所必要的符号信息,要想对源代码进行调试,我们就必须加入这个选项。
-O,对程序进行优化编译、连接,产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。
-O2,比-O更好的优化编译、连接,当然整个编译、连接过程会更慢。
简单的makefile文件如下
start: hello.o //标号:依赖项
[tab键] gcc -o hello hello.o //只会执行这一句除非需要依赖关系才会执行依赖标号的
@echo "------------------ok----------------" //@的意思是输出的时候不会输出echo
hello.o:
[tab键] gcc -o hello.o -c hello.c
clean:
[tab键] rm -rf hello.o
makefile中也可以有变量一般变量都用大写如:VARNAME=some_text
引用变量$(VARNAME)
如:
AA=gcc
start: hello.o //标号:依赖项
[tab键] $(AA)-o hello hello.o //只会执行这一句除非需要依赖关系才会执行依赖标号的
@echo "------------------ok----------------" //@的意思是输出的时候不会输出echo
hello.o:
[tab键] $(AA)-o hello.o -c hello.c
clean:
[tab键] rm -rf hello.o
以后换编译器就只需要改变AA的值就可以啦。。
再次简化
AA=gcc
SRCS=hello.c
OBJS=hello.o #还可以这样写:OBJS=$(SRCS:.c=.o)
EXEC=hello
start: $(OBJS) //标号:依赖项
$(AA)-o $(EXEC) $(OBJS) //只会执行这一句除非需要依赖关系才会执行依赖标号的
@echo "------------------ok----------------" //@的意思是输出的时候不会输出echo
$(OBJS) :
$(AA)-o $(OBJS) -c $(SRCS)
clean:
rm -rf $(OBJS)
////////////////
还有如下:
.SUFFIXES: .c .o #这是一种规则表示x.c文件与x.o文件关联
SRCS=hello.c
OBJS=$(SRCS:.c=.o)
EXES=hello
CC=gcc
start: $(OBJS)
$(CC) -o $(EXES) $(OBJS)
@echo "------------------ok----------------"
.c.o: #关联项
$(CC) -o $@ -c $< # $@ 表示规则对应的目标文件 hello.o $< 表示规则关联的文件hello.c
clean:
rm -rf $(OBJS)
、、、、、、、、、、、、、、、、、、、、、、、、、、、、
/////////////////makefile同时编译多个文件
.SUFFIXES: .c .o #这是一种规则表示x.c文件与x.o文件关联
SRCS=hello.c\add.c #在这里同时编译2个文件
OBJS=$(SRCS:.c=.o)
EXES=hello
CC=gcc
start: $(OBJS)
$(CC) -o $(EXES) $(OBJS)
@echo "------------------ok----------------"
.c.o: #关联项
$(CC) -o $@ -c $< #自动根据$(OBJS)中.o的数量循环编译,直到编译完所有的.c文件
clean:
rm -rf $(OBJS)
