700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Linux编译器-gcc/g++的使用

Linux编译器-gcc/g++的使用

时间:2023-03-10 21:08:43

相关推荐

Linux编译器-gcc/g++的使用

★★★★★ 是小夏啊!

我们知道,当我们用像VS等这样的编译器写完代码后,会通过快捷键操作或是编译器上相应的选项来编译运行,紧接着我们一般通过控制面板来观察程序运行的结果,从而判断自己写的程序代码是否满足要求,进而对其进行Debug,修改代码直至输出达到预期目标。

那么有这么几个值得我们思考的问题:VS等编译器是如何将程序代码转换成可执行程序的?在企业中广受喜爱的Linux操作系统下又是怎样的?对于Linux操作系统中gcc/g++是如何使用的?

目录

一、背景知识

1、预处理(头文件展开、去注释、条件编译、进行宏替换等)

2、编译(生成汇编,汇编语言也需要编译,也有汇编编译器)

3、汇编(生成机器可识别代码)

4、链接(生成可执行文件或库文件)

函数库 :(链接时涉及的重要概念)

函数库的分类 :

二、gcc实际操作中如何将.c文件转化成可执行程序

三、g++实际操作中如何将.cpp文件转化成可执行程序

四、Linux项目自动化构建工具-make/Makefile

★ 依赖关系

★ 依赖方法

★ 原理

★ 项目清理

★ 测试

一、背景知识

1、预处理(头文件展开、去注释、条件编译、进行宏替换等)

[xxp@VM-24-3-centos lesson1]$ gcc -E test.c -o test.i[xxp@VM-24-3-centos lesson1]$ lsinstall.sh test.c test.i

★ 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。

★ 实例: gcc –E test.c –o test.i。

★ 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。

★ 选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。

2、编译(生成汇编,汇编语言也需要编译,也有汇编编译器)

[xxp@VM-24-3-centos lesson1]$ gcc -S test.i -o test.s[xxp@VM-24-3-centos lesson1]$ lsinstall.sh test.c test.i test.s

★ 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作, 在检查无误后,gcc 把代码翻译成汇编语言。

★ 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

★ 实例: gcc –S test.i –o test.s。

3、汇编(生成机器可识别代码)

[xxp@VM-24-3-centos lesson1]$ gcc -c test.s -o test.o[xxp@VM-24-3-centos lesson1]$ lsinstall.sh test.c test.i test.o test.s

★ 汇编阶段是把编译阶段生成的“.s”文件转成目标文件。

★ 读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了。

★ 实例: gcc –c test.s –o test.o。

4、链接(生成可执行文件或库文件)

[xxp@VM-24-3-centos lesson1]$ gcc test.o -o test[xxp@VM-24-3-centos lesson1]$ lsinstall.sh test test.c test.i test.o test.s

★ 在成功编译之后,就进入了链接阶段。

★ 实例: gcc hello.o –o hello。

函数库 :(链接时涉及的重要概念)

我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。

函数库的分类 :

链接如何理解:自己写的C程序和第三方库提供的方法关联起来。

函数库一般分为静态库和动态库两种。这里我们通过一个形象的例子来讲解:

如图所示,一名学生学习过程中需要通过电脑来查找资料;一种方案是到学校外面的网吧的资料库(动态库)查找,这种方法叫做动态链接(需要链接第三方库);另一种方案是在学校建立起等同于校外网吧的机房,相当于将函数库的内容拷贝到我自己的可执行程序当中,叫做静态链接。(不需要任何库)。

如图所示:gcc默认采用动态链接的方式生成可执行程序。

二、gcc实际操作中如何将.c文件转化成可执行程序

在第一部分,细述了gcc将.c文件转化成可执行程序的整个过程,但在实际使用过程当中不必如此麻烦。只需要一条指令即可:

[xxp@VM-24-3-centos lesson1]$ gcc test.c -o test[xxp@VM-24-3-centos lesson1]$ lsinstall.sh test test.c[xxp@VM-24-3-centos lesson1]$ ./testhello world

三、g++实际操作中如何将.cpp文件转化成可执行程序

基本上和gcc使用一致,与vs的不同点是gcc和g++编译时的指令不同,而在vs中只需关注文件类型即可。g++也可当作gcc来编译.c文件。

[xxp@VM-24-3-centos lesson1]$ touch myfile.cpp[xxp@VM-24-3-centos lesson1]$ vim myfile.cpp[xxp@VM-24-3-centos lesson1]$ lsinstall.sh Makefile myfile.cpp test test.c[xxp@VM-24-3-centos lesson1]$ rm test[xxp@VM-24-3-centos lesson1]$ g++ test.c -o test[xxp@VM-24-3-centos lesson1]$ lsinstall.sh Makefile myfile.cpp test test.c[xxp@VM-24-3-centos lesson1]$ ./testhello world[xxp@VM-24-3-centos lesson1]$ g++ myfile.cpp -o myfile[xxp@VM-24-3-centos lesson1]$ ./myfilehello linux

四、Linux项目自动化构建工具-make/Makefile

首先,需要声明的一点是make是指令,Makefile是文件。在Makefile文件中存储的是相应的依赖关系和依赖方法。那么什么是依赖关系?什么是依赖方法?下面举个例子来说明:

一名学生来到月末后,需要家里边给生活费,他与父母之间就具有一种依赖关系;当他给家里边人打电话索要生活费的这种行为称作是依赖方法。但并不是所有的依赖方法都是成立的,例如:他和室友也具有某种依赖关系,但这种依赖关系并不足以其索要生活费这种依赖方法成立。

下面我们通过具体实例代码指令来实现:

[xxp@VM-24-3-centos lesson1]$ touch Makefile[xxp@VM-24-3-centos lesson1]$ vim Makefile

[xxp@VM-24-3-centos lesson1]$ makegcc test.c -o test -std=c99[xxp@VM-24-3-centos lesson1]$ lsinstall.sh Makefile test test.c[xxp@VM-24-3-centos lesson1]$ make cleanrm -f test[xxp@VM-24-3-centos lesson1]$ lsinstall.sh Makefile test.c

★ 依赖关系

例子在上面

上面的文件 test ,它依赖 test.o

test.o , 它依赖 test.s

test.s , 它依赖 test.i

test.i , 它依赖 test.c

★ 依赖方法

例子在上面

gcc hello.* -option hello.* ,就是与之对应的依赖关系

★ 原理

make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么

1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test” 这个文件,并把这个文件作为最终的目标文件。

3. 如果test文件不存在,或是hello所依赖的后面的hello.o文件的文件修改时间要比hello这个 文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成test这个件。

4. 如果test所依赖的test.o文件不存在,那么make会在当前文件中找目标为test.o文件的依赖 性,如果找到则再根据那一个规则生成test.o文件。(这有点像一个堆栈的过程)

5. 当然,你的C文件和H文件是存在的啦,于是make会生成 test.o 文件,然后再用 test.o 文 件声明make的终极任务,也就是执行文件test了。

6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出 第一个目标文件。

7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退 出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在, 那么对不起,我就不工作啦。

★ 项目清理

1、工程是需要被清理的

2、像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

3、但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。

4、可以将我们的 test 目标文件声明成伪目标,测试一下。

★ 测试

[xxp@VM-24-3-centos lesson1]$ lsinstall.sh Makefile test.c[xxp@VM-24-3-centos lesson1]$ makegcc test.c -o test -std=c99[xxp@VM-24-3-centos lesson1]$ lsinstall.sh Makefile test test.c[xxp@VM-24-3-centos lesson1]$ makemake: `test' is up to date.[xxp@VM-24-3-centos lesson1]$ make cleanrm -f test[xxp@VM-24-3-centos lesson1]$ lsinstall.sh Makefile test.c[xxp@VM-24-3-centos lesson1]$ make cleanrm -f test

如上述测试,当执行完make指令后未对项目进行清理时,无法再次执行make指令;但是对于make clean指令却总是被执行的。

★ makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率

★★★★★ 感谢阅读!!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。