在Windows系统下,我们已经能够很熟练的使用**VS、VSCode、VSC++**等编译器熟练地输出“Hello World”。可是在不同的Lunux操作系统下又该是怎样操作的呢? 这就不得不提到今天所提的gcc系列命令。
例如:在Linux下创建一个Goodbye.c用来输出“Goodbye”
#include
int main()
{
printf("Goodbye!!\n");
return 0;
}
gcc一个文件,系统会默认生成一个是a.out的一个可执行文件,再执行a.out方可输出。
[root@VM-16-17-centos Blog]# gcc Goodbye.c
[root@VM-16-17-centos Blog]# ./a.out
[root@VM-16-17-centos Blog]# Goodbye!!
注意:[./+可执行文件]是直接执行的命令,一般gcc后不具体添加命令选项会默认给a.out可执行文件。
可恶! 在这里我们意识到,Linux下并不会直接编译通过就输出,而是gcc后会生成一个可执行文件,再通过一个可执行文件来间接执行。那么为什么在Linux系统下会这样”多此一举“呢?接下来我们就要了解一下一段程序电脑是怎么翻译的。
首先,一段程序电脑会进行预处理、编译、汇编、链接的翻译:
由于Linux系统默认自带语言级别的头文件和库,经过此“四大才子”之手程序才会最终呈现出我们想要的方式。
作用: 展开所包含的头文件、宏的替换和满足条件的编译(如if、else语句满足即编译,不满足忽略)等。
文件格式:Goodbye.i
命令选项: -E
具体命令:gcc -E + 可执行文件 -o + 名称.i
该命令意为从现在开始进行程序翻译直到预处理完就停止。命令可以查看预处理完后的文件形态。
作用:将程序翻译成汇编语言。
文件格式:Goodbye.s
命令选项:-S
具体命令:gcc -S + 可执行文件 -o + 名称.s
该命令意为从现在开始进行程序翻译直到编译完就停止。命令可以查看编译完后的文件形态。
作用:汇编成可重定位的目标二进制文件,如:.bin .obj文件等,该状态下不可被执行。
文件格式:Goodbye.o
命令选项:-c
具体命令:gcc -c + 可执行文件 -o + 名称.o
该命令意为从现在开始进行程序翻译直到汇编完就停止。命令可以查看汇编完后的文件形态。
作用:将形成的.obj文件和库文件进行某种合并,形成可执行程序。
说明:链接分为静态链接和动态链接,而动静态又和Linux下的静态库和动态库有关,文件在执行最后一步连接时会选择和静态库链接形成静态链接或者和动态库链接形成动态链接。
注意:当前市面上90%都是动态链接。
格式:libXXXX.a (后缀为a)
说明:静态库在连接时会被找到,直接拷贝到自己的可执行文件中。因为自身的拷贝,会使目标文件体积过大,比较浪费资源。
格式:libXXXX.so(后缀为so)
说明: 动态连接成功后,程序会依赖动态库,一旦动态库缺失,便无法运行。
编译、汇编、过程等过程中的命令选项组合起来是-E -S -c,活像键盘左上角的Esc退出键,只不过其中S是大写而已,因此可以看键盘左上角Esc来记忆命令选项。
程序翻译过程中格式分别为**.i 、.s、 .o文件,而市面上也有一种镜像文件是拿.iso文件后缀结尾的。因此可以通过记忆镜像文件**后缀来记忆文件格式后缀。
一个可执行的.c文件只有经过上述的四步之后才会生成用户想要的文件,在Windows下大部分市面上的编译器都会替用户直接生成编译结果,而Linux下提供了更为细节的命令选项,支持用户更为细节的查看文件。喜欢的老铁麻烦点个赞支持下吧!