首页 /  技术专区  /  C 屏幕太窄?试试伸展一下吧 >

ubuntu linux下的GCC编译器集合

1.1 ubuntu(Linux)下的GCC编译器集合

ubuntu的GCC编译器集合,在安装ubuntu时就自带了,实际上和codeblocks安装目录MingW目录下的GCC编译器集合一样,都是GNU组织开发的,只不过codeblocks这边是面向windows的,而ubuntu这边的GCC是面向Linux的。

注意区分大写的GCC和小写的gcc。

    GCC:指编译器集合

    gcc:指集合中的gcc程序

正是由于都是由GNU开发的,所以集合中的程序名字是一样的,有了前面codeblocks GCC的基础,ubuntu的GCC非常容易。

(1)编译时,必须用到的基本程序

cpp、cc1、as、collect2/ld、gcc

2)cpp(/usr/bin/):预编译

通过which可以查看cpp的安装目录。

(a)man手册查看

(b)演示

cpp helloword.c -o helloword.i

不指定目标文件,会直接将预处理后的结果输出到控制台(命令行)。

3)cc1(/usr/lib/gcc/x86_64-linux-gnu/5/cc1):编译

无法通过which查看cc1的安装目录,因为cc1的安装目录没有加入环境变量。

(a)man手册查看

查看不了,因为安装没有cc1的手册

(b)演示

/usr/lib/gcc/x86_64-linux-gnu/5/cc1 helloword.i -o helloword.s

为什么要加路径?

因为cc1所在的路径,没有加入Linux的环境变量。

4)as(/usr/bin/as):汇编编译

(a)man  as

(b)演示

as helloword.s -o helloword.o

不指定目标文件,会自动保存到同名的目标文件。

5)collect2/ld:链接

· ld:/usr/bin/ld

· collect2:/usr/lib/gcc/x86_64-linux-gnu/5/collect2

同样的,如果直接使用collect2/ld来链接的话,我们需要自己指定很多的选项和参数,所以我们一般不自己调用collect2/ld来链接,而是使用gcc来链接(gcc自动调用collect2/ld)。

gcc helloword.o -o helloword

不指定可执行文件的名字,就默认为a.out。

不要以为默认的名字时a.out,就认为Linux可执行文件的尾缀是.out,Linux下的可执行文件并没有尾缀要求。

我们后面会介绍默认的a.out这个名字是怎么来的。

6)gcc

使用gcc这个总的调度程序,gcc会自动调用cpp、cc1、as、collect2/ld等程序。

可以避免直接使用cpp、cc1、as、collect2/ld等程序所带来的麻烦。

(a)E

+ 只得到.i扩展c源文件

gcc -E helloworld.c -o helloworld.i

+ 如果不写目标文件,就直接输出到控制台。

+ file查看.i文件类型

(b)S

+ 只编译到.s文件

+ 演示

gcc -S helloworld.i -o helloworld.s
gcc -S helloworld.c -o helloworld.s

同样的,如果不写目标文件,会自动保存为同名的.s文件

+ file查看.s文件类型

(c)c

+ 只编译得到.o文件

+ 演示

1)gcc -c helloworld.s -o helloworld.o
2)gcc -c helloworld.i -o helloworld.o
3)gcc -c helloworld.c -o helloworld.o

如果不写目标文件,会自动的保存为同名的.o文件

+ file查看.o文件类型

(d)直接得到可执行文件

+ 演示

gcc helloworld.c -o helloworld
gcc helloworld.i -o helloworld
gcc helloworld.s -o helloworld
gcc helloworld.o -o helloworld

+ 如果不写可执行文件,会自动保存为a.out文件。

+ file查看可执行文件类型

(e)其它选项:O1/O2/Os/O3、Wall、g等选项与前面介绍的是一样的。

(2)编译器集合中的其它程序:nm、strip、objdump、ar、readelf、debug这程序都在/usr/bin/目录下,可以使用witch命令查看所在的目录。

1)nm:查看.o、可执行文件中的各种符号

演示:

nm helloworld.o
nm helloworld

2)strip:对可执行文件进行瘦身

给gcc指定-s选项时,gcc就是调用strip来瘦身的。

我们也可以gcc时先不指定-s,然后自己主动使用strip来瘦身。

3)objdump:反汇编,将机器指令反翻译为可以被人识别的汇编指令,这就反汇编

· 演示

- 对.o文件进行反汇编

objdump -D hellowolrd.o >  hw1.s

>:将反汇编结果保存到dmphelloworld1.s中。

- 对可执行文件进行反汇编

objdump -D hellowolrd > dmphelloworld2.s

· 反汇编的意义

其实对于做应用程序开发的我们来说,反汇编的意义不大,但是对于做逆向开发的人来说,这就很有意义,因为做逆向开发的人,需要分析二进制的机器指令,但是纯二进制的机器指令很难阅读,所以必须将二进制机器指令反翻译为ascii的汇编指令,才能阅读。

不知道什么是逆向开发的同学,请看《计算机体系结构——行业篇》的内容。

· 介绍objdump的目的。

    - 有必要了解

    - 本章后面可能会用到

    - 后续可能会出逆向的课,到时候就会用到反汇编命令

3)ar:用来制作静态库文件,讲c函数库时再介绍。

4)readelf:读取elf格式信息

后面用到时在介绍。

5)debug

调试程序用的,后面课程介绍。




0/200
图片验证码