gcc & makefile

来源:互联网 发布:全球人工智能产业规模 编辑:程序博客网 时间:2024/04/30 13:13

gcc


使用gcc,程序员可以对编译过程有更多的控制,编译过程可分为3个阶段

  • 预处理
  • 汇编
  • 链接
程序员可以在编译的任何阶段结束后停止整个编译过程以检查编译器在该阶段输出的信息。




预处理将源代码和头文件结合在一起,也就是将头文件中的内容拷贝一份到原文中中;编译就是讲预编译的文件编译成二进制文件;将库中的文件链接进来,实现链接生成可执行文件。

ldd hello(可执行文件)可以查看该可执行文件连接到哪些库

nm hello 可以查看可执行文件被编译成那些名字

hello.c源文件

  1 #include<stdio.h>                                                                                  2 #include<stdlib.h>  4 int main(int argc, char *argv[])  5 {  6         if(argc < 3)  7                 printf("请输入两个参数\n");  8         else  9         { 10                 int a = atoi(argv[1]); 11                 int b = atoi(argv[2]); 12                 printf("%d + %d = %d\n", a, b, a+b); 13         } 14  15         return 0; 16 }  

预编译:

gcc -o hello1.c -E hello.c

预编译说白了就是将头文件拷贝到源文件中

编译:

gcc -o hello.o -c hello1.c
告诉gcc对源程序hello.c进行编译,但不链接,编译输出hello.o文件中.


链接:

gcc -o hello hello.o
告诉gcc对源程序hello.c进行链接,生成可执行hello


gcc常用选项

为了提高代码的质量,在编译的时候最好加上-Wall

编译多个文件:

源文件add.h
int add(int a, int b);   

源文件add.c
 1 int add(int a, int b)                                                                              2 {  3         return a+b;  4 }

源文件hello.c
  1 #include<stdio.h>                                                                                  2 #include<stdlib.h>  3 #include"add.h"  4 int main(int argc, char *argv[])  5 {  6         if(argc < 3)  7                 printf("请输入两个参数\n");  8         else  9         { 10                 int a = atoi(argv[1]); 11                 int b = atoi(argv[2]); 12                 printf("%d + %d = %d\n", a, b, add(a, b)); 13         } 14  15         return 0; 16 }

单独编译时因为不会链接库,所以不会出现错误

apple@ubuntu:~/LearnLinux$ lsadd.c  add.h  hello.capple@ubuntu:~/LearnLinux$ gcc -o add.o -c add.capple@ubuntu:~/LearnLinux$ gcc -o hello.o -c hello.capple@ubuntu:~/LearnLinux$ lsadd.c  add.h  add.o  hello.c  hello.o

但是链接时如果不链接相关的库的话就会出现错误
apple@ubuntu:~/LearnLinux$ gcc -o hello hello.ohello.o:在函数‘main’中:hello.c:(.text+0x63):对‘add’未定义的引用collect2: error: ld returned 1 exit status

这时候需要将add.o库链接进来
apple@ubuntu:~/LearnLinux$ gcc -o hello hello.c add.oapple@ubuntu:~/LearnLinux$ lsadd.c  add.h  add.o  hello  hello.c  hello.o  makefile



make




源文件hello.c
 1 #include<stdio.h>                                                                                  2 #include<stdlib.h>  3 int main(int argc, char *argv[])  4 {  5         if(argc < 3)  6                 printf("请输入两个参数\n");  7         else  8         {  9                 int a = atoi(argv[1]); 10                 int b = atoi(argv[2]); 11                 printf("%d + %d = %d\n", a, b, a+b); 12         } 13  14         return 0; 15 }

创建makefile
  1 start:                                                                                             2         gcc -o hello hello.c                             

执行make语句
  tabstop=8apple@ubuntu:~/LearnLinux$ makegcc -o hello hello.capple@ubuntu:~/LearnLinux$ lshello  hello.c  makefile

由此可见,make语句能帮助我们编译连接文件。

make文件
1 start:hello.o                                                                                      2         gcc -o hello hello.o  3         @echo '------Succeed!------------'  4   5 hello.o:  6         gcc -o hello.o -c hello.c  7   8 all:  9         @echo '显示调用语句' 10  11 clean: 12         rm hello.o 13         rm hello

调用make语句
  tabstop=8apple@ubuntu:~/LearnLinux$ lshello.c  makefileapple@ubuntu:~/LearnLinux$ makegcc -o hello.o -c hello.cgcc -o hello hello.o------Succeed!------------apple@ubuntu:~/LearnLinux$ make all显示调用语句apple@ubuntu:~/LearnLinux$ make cleanrm hello.orm helloapple@ubuntu:~/LearnLinux$ lshello.c  makefile

第一次执行make命令时,执行两句话,再次make时只执行其中的一句,因为start后边是依赖项,如果没有该依赖项则先调用依赖项,如果有的话直接执行该依赖项后边的语句。


@echo “-------------OK------------”输出字符串,@表示只输出结果不输出命令本身




此时的makefile文件
  1 CC=gcc                                                                                             2 SRCS=hello.c  3 OBJS=$(SRCS:.c=.o)  4 EXEC=hello  5   6 start:$(OBJS)  7         $(CC) -o $(EXEC) $(OBJS)  8         @echo '------Succeed!------------'  9  10 $(OBJS): 11         $(CC) -o $(OBJS) -c $(SRCS) 12  13 all: 14         @echo '显示调用语句' 15  16 clean: 17         rm $(OBJS) 18         rm $(EXEC)

hello.c  makefileapple@ubuntu:~/LearnLinux$ makegcc -o hello.o -c hello.cgcc -o hello hello.o------Succeed!------------apple@ubuntu:~/LearnLinux$ lshello  hello.c  hello.o  makefile



  1 .suffixes:.c .o                                                                                    2   3 CC=gcc  4 SRCS=hello.c  5 OBJS=$(SRCS:.c=.o)  6 EXEC=hello  7   8 start:$(OBJS)  9         $(CC) -o $(EXEC) $(OBJS) 10         @echo '------Succeed!------------' 11  12 .c.o: 13         $(CC) -o $@ -c $< 14  15 all: 16         @echo '显示调用语句' 17  18 clean: 19         rm $(OBJS) 20         rm $(EXEC)~                       

再次编译时只编译更变的源文件,源文件没有更改的不再编译,根据源文件的修改时间,如果源文件的修改时间在.o文件之后则会发生编译,之前就不会重新编译。


编译调试C++程序
源文件hello.cpp
1 #include<iostream>                                                                                 2 #include<stdlib.h>  3   4 using std::cout;  5 using std::endl;  6   7 int main(int argc, char *argv[])  8 {  9         if(argc < 3) 10                 cout<<"请输入两个参数"<<endl; 11         else 12         { 13                 int a = atoi(argv[1]); 14                 int b = atoi(argv[2]); 15                 cout<<a<<"+"<<b<< " = "<<a+b<<endl; 16         } 17  18         return 0; 19 }

makefile文件
  1 .suffixes:.cpp .o                                                                                  2   3 CC=g++  4 SRCS=hello.cpp  5 OBJS=$(SRCS:.cpp=.o)  6 EXEC=hello  7   8 start:$(OBJS)  9         $(CC) -o $(EXEC) $(OBJS) 10  11 .cpp.0: 12         $(CC) -o $@ $< 13  14 clean: 15         rm $(OBJS) 16         rm $(EXEC)~                         

执行命令:
apple@ubuntu:~/LearnLinux$ lshello.cpp  makefileapple@ubuntu:~/LearnLinux$ makeg++    -c -o hello.o hello.cppg++ -o hello hello.oapple@ubuntu:~/LearnLinux$ lshello  hello.cpp  hello.o  makefileapple@ubuntu:~/LearnLinux$ ./hello 4 64+6 = 10



同时编译多个源文件只需在SRCS = hello.cpp\ add.cpp即可

0 0
原创粉丝点击