gcc是Linux系统下一款专门针对于C语言的代码编译软件。g++则是Linux下针对于CPP语言的代码编译软件,实际上g++底层也大量用了gcc代码。
1.gcc基本认识与安装
gcc是一款Linux系统下的C语言编译软件。
sudo yum install -y gcc // 下载gcc
当我们下载好gcc之后,可以查看一下版本号来验证是否安装成功了。
gcc -v // 查看gcc版本号
有下面版本号的话一般问题就不大了。
这里说一下,gcc默认支持的语法是比较老的,像一些C99的语法可能有一些不支持,可以去网上搜一个gcc配置C99的教程去配置一下,当然也可以每次编译的时候带上语法提升命令也行。
gcc test.c -std=c99 -o test.exe // 编译test.c文件,用C99语法,且编译的可执行文件为test.exe
然后g++也是一个Linux下的编译器,跟gcc十分相似,我估计g++底层可能就是用到了gcc的一些功能也不奇怪。然后需要注意的是g++是编译c++代码的,CPP后缀可以是xxx.cc
或者是 xxx.cxx
。
2.gcc编译过程
对于C或者CPP这样的语言,编译需要执行两个大的过程,一是编译,二是链接。
2.1编译 和 链接
在编译环境下又可以分为预处理、编译、汇编三部分和最后的链接,可以参见下图:
● -E 完成预处理后停止编译,生成xxx.i文件
● -D 命令行式添加宏
● -S 完成编译后停止编译,编译后是一些汇编语言,生成xxx.s文件
● -c 完成汇编后停止编译,汇编后是一些二进制语言,生成xxx.o文件
2.2编译步骤形成的原因
之所以上面说的编译部分分为预处理、编译、汇编这么麻烦,是由于历史原因导致的。
是这样的,在计算机刚出现的时候,我们人类直接拿着二进制跟计算机交流,计算机也能听得明白。
后来科学家觉得用二进制跟计算机交流太麻烦了,十分逆反我们人类的语言习惯,就用二进制写了个语言,叫汇编语言。这时候汇编语言计算机就看不懂了,只能先把汇编语言翻译成二进制然后计算机才能看的明白。
随着计算机的发展,汇编也不好使了,人们还是觉得汇编不够贴近人类语言习惯,就用汇编发明了后来的C、CPP、Java等高级语言。计算机只认识二进制,所以这些高级语言也得翻译成二级制才行。这时候有两种方式,一是直接把高级语言翻译成二进制,二是先把高级语言翻译成汇编,再由汇编翻译成二进制。
显然,当时科学家或者说是程序员选择了第二种方式,因为只需要把高级语言翻译成汇编就行了,汇编到二进制这活前人已经把这活干了。
所以就出现了比较繁琐的编译过程…
2.3编译器的自举
先有编译器还是先有对应的语言的呢???
先有编译器。没编译器怎么转化为二进制的对不对。那这个编译器怎么来的?用先前的语言写的。
我们拿汇编举例,汇编刚开始的时候只有二进制这种语言…然后科学家就拿着二进制硬搓了个汇编的编译器,然后才可以用汇编写代码。既然现在汇编语言可以用了,那我用汇编语言写个编译器不过分吧。所以说汇编译器就成了用汇编写的编译器了。我们把这个过程称之为编译器的自举。
2.4链接
链接这个过程干的啥???
主要是把编好的各种文件组合在一起,包括一些函数库,自己写的一些源文件等等…
在链接库的时候(比如链接C语言标准库),有两种链接方式,即静态链接
和动态链接
。
库分为静态库和动态库两种,对应也有静态链接和动态链接两种。
静态链接:把所需要的库拷贝到自己文件中,在进行编译不需要依赖外界的库。
动态链接:十分依赖外界的库,再进行编译时会去访问外界的库。
● Linux下
○ 动态库:.so
○ 静态库:.a
● windows下
○ 动态库:.dll
○ 静态库:.lib
编译静态库指令:
gcc test.c -o static_test.exe // 编译动态文件,gcc默认就是动态链接 gcc test.c -o static_test.exe -static // 编译静态文件
静态链接与动态连接的优缺点:
Linux系统一般默认提供C动态库,但是对于静态库需要自己去下载和安装。
● 动态库(动态链接)
○ 优点:节约空间
○ 缺点:对函数库依赖性强,库一旦丢失,程序无法编译。
● 静态库(静态链接)
○ 优点:每个文件都需要单独的库内容拷贝,对函数库依赖性弱。
○ 缺点:浪费空间
gcc test.c -o dynamic_test.ext // 编译动态文件 gcc test.c -o static_test.exe -static // 编译静态文件 ls -d dynamic_test.exe static_test.exe -l // 输出两个文件详细信息
我们发现,静态链接生成的可执行文件大一点…
两种链接方式的应用:
两种库都有自己的应用场景,不过还是要以动态库为主流。
● 静态库适用于小型开发项目
● 动态库适用于大型开发项目团队之间的合作协调
原因:LINK
EOF