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);
1 int add(int a, int b)
2 {
3 return a+b;
4 }
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$ ls
add.c add.h hello.c
apple@ubuntu:~/LearnLinux$ gcc -o add.o -c add.c
apple@ubuntu:~/LearnLinux$ gcc -o hello.o -c hello.c
apple@ubuntu:~/LearnLinux$ ls
add.c add.h add.o hello.c hello.o
但是链接时如果不链接相关的库的话就会出现错误
apple@ubuntu:~/LearnLinux$ gcc -o hello hello.o
hello.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.o
apple@ubuntu:~/LearnLinux$ ls
add.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$ make
gcc -o hello hello.c
apple@ubuntu:~/LearnLinux$ ls
hello hello.c makefile
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$ ls
hello.c makefile
apple@ubuntu:~/LearnLinux$ make
gcc -o hello.o -c hello.c
gcc -o hello hello.o
------Succeed!------------
apple@ubuntu:~/LearnLinux$ make all
显示调用语句
apple@ubuntu:~/LearnLinux$ make clean
rm hello.o
rm hello
apple@ubuntu:~/LearnLinux$ ls
hello.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 makefile
apple@ubuntu:~/LearnLinux$ make
gcc -o hello.o -c hello.c
gcc -o hello hello.o
------Succeed!------------
apple@ubuntu:~/LearnLinux$ ls
hello 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$ ls
hello.cpp makefile
apple@ubuntu:~/LearnLinux$ make
g++ -c -o hello.o hello.cpp
g++ -o hello hello.o
apple@ubuntu:~/LearnLinux$ ls
hello hello.cpp hello.o makefile
apple@ubuntu:~/LearnLinux$ ./hello 4 6
4+6 = 10
同时编译多个源文件只需在SRCS = hello.cpp\ add.cpp即可