目录
一. 什么是gcc和g++
二. gcc的基本使用方法
三. 库和链接
3.1 动态库和静态库
3.2 动态链接和静态链接
四. Debug和Release
五. makefile和make
六. 总结
由于C++兼容C语言,因此g++既可以编译C++也可以编译C语言。但是,一般建议使用gcc编译C语言,使用g++编译C++。
gcc和g++的使用方法完全一致,因此,本文以gcc为例讲解gcc/g++的使用方法。
以mycode.c代码为例,生成可执行文件的一般指令为:
生成可执行文件的默认文件名为a.out,程序运行的指令为:./a.out
如果我们希望自定义可执行文件的文件名,就需要用到-o选项:
假设我们希望生成的可执行文件文件名为mytest,那么指令应为:gcc mycode.c -o mytest.txt -std=c99,通过ll指令,可以看到生mytest文件生成成功。
我们知道,源文件(.c/.cpp)到可执行程序,需要经过四个步骤(预编译、编译、汇编、链接),每一步完成的工作为:
由可执行文件生成的四个步骤,引出gcc/g++的三个选项:
通过指令gcc -E mycode.c -o mycode.i -std=c99,生成预处理后的文件mycode.i,用vim打开两份文件,可以看出所有的条件编译、注释、宏和头文件,均按规则进行了处理(见图2.3)
通过gcc -S mycode.i -o mycode.s -std=c99,生成编译后的文件mycode.s,使用vim打开mycode.s文件,可以看到程序对应的汇编代码。
通过指令gcc -c mycode.s -o mycode.o -std=c99,生成二进制的目标文件mycode.o,这里由于vim是文本编辑器,查看二进制文件mycode.o看到的会是乱码,可以使用od来查看二进制文件内容,od查看二进制文件指令为:od 二进制文件名。
如果不使用-o、-i、-s选项中的任意一个,那么直接默认完成到链接工作,生成可执行文件。
可执行程序形成的时候,不是无序的二进制构造,而是遵循自己的格式 -- ELF格式。通过指令:readelf -S 可执行文件名,可以查看可执行文件的二进制构成。
链接,就是将汇编之后生成的二进制目标文件,与标准库进行链接。
库,本质上就是源文件(.c/.cpp)经过一定的翻译后进行打包后的文件,库有自己的路径。使用库可以达到隐藏源文件的目的, 库中提供函数方法的具体实现。
可以这样认为:头文件提供方法声明 + 库提供方法实现 + 用户代码 = 软件。
库,可分为动态库和静态库,在Window和Linux系统中,根据后缀名不同来区分动静态库:
库有自己的命名规则:libname.so.XXX,libname.a.XXX,其中库的实际名称只有中间name那一小部分,lib为前缀,.so.XXX/.a.XXX为后缀。
在Liunx系统中,库文件默认存储在路径/lib64/下,使用指令ls /lib64/libc.so*和ls /lib64/libc.s*,可以分别查看C语言的动态库和静态库。
Linux系统中,默认只有C/C++的动态库,没有静态库,静态库需要自行安装,安装方法为:
如果动态库缺失,那么涉及到动态库的所有程序,都不能正常运行。如果静态库缺失,方法的实现已经被提取到了可执行文件中,程序依旧能正常运行。
动态链接和静态链接各有其优缺点:
在默认情况下,gcc采用动态链接的方式编译源文件,如果希望采用静态链接的方式编译代码,首先要保证静态库存在,然后显示声明选项-static, 即可执行静态链接。
如图3.2所示,分别采用动态链接和静态链接的方式,编译mycode.c源文件,生成可执行文件mytest和mytest-static,通过ll查看文件属性,看到采用静态链接的可执行文件占用空间明显大于采用动态链接的。
关于查看可执行程序的动静态链接情况,有以下两条指令:
关于动静态库是否存在与动静态链接是否能够完成的关系,有下面三条规律:
Debug为调试版本,以Debug版本发布的可执行程序,会带有调试信息。Release为发布版本,以Release版本发布的可执行程序,不会带有调试信息。Release相比于Debug,运行效率高,运行内存消耗低,占用空间少,整体的性能较优,但是Release版本不能调试。
gcc默认情况采用Release版本发布可执行文件,如果要采用Debug版本发布,那么需要-g选项。
图4.1对比了采用Release版本可Debug版本发布的可执行文件mytest和mytest-debug的占用空间大小,可以看出Debug发布的可执行程序相比于Release占用更多空间。
如果源文件过多,那么手动输入文件名就会十分麻烦,并且如果要删除可执行程序,采用rm批量删除容易误删。通过makefile和make配合使用,可以避免上述问题。
我们需要在源文件的路径下面,通过touch makefile,创建名为makefile的文件。vim makefile打开文件,在首行输入依赖关系,另起一行输入依赖方法(见图5.1),保存并退出makefile文件。我们只需要在命令行中输入指令make,即可生成可执行文件,输入make clean,即可清除可执行文件。
通过指令 read -S mytest-static | grep -i debug,可以筛选出可执行文件中的调试信息。