Linux gcc常用命令

本文详细介绍了使用GCC编译器进行C程序编译的全流程,包括预处理、编译、汇编和链接,以及处理多个源文件、库文件链接和错误检查的方法。通过实例演示了如何设置编译选项和连接路径,适合深入理解编译器工作原理。
摘要由CSDN通过智能技术生成

一.简单编译

1.程序代码

test.c

#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}

程序一步编译指令:

gcc test.c -o test

 实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译 (Compilation)、汇编 (Assembly)和连接(Linking)。

2.1预处理

gcc -E test.c -o test.i 或 gcc -E test.c

 可以输出 test.i 文件中存放着 test.c 经预处理之后的代码。打开 test.i 文件,看一看,就明白了。后 面那条指令,是直接在命令行窗口中输出预处理后的代码. gcc 的-E 选项,可以让编译器在预处理后停止,并输出预处理结果。在本例中,预处理结果就是将 stdio.h 文件中的内容插入到 test.c 中了。

2.2编译为汇编代码

gcc -S test.i -o test.s

2.3汇编

对于上一小节中生成的汇编代码文件 test.s,gas 汇编器负责将其编译为目标文件,如下:

gcc -c test.s -o test.o

2.4连接 

gcc 连接器是 gas 提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生 成可执行文件。附加的目标文件包括静态连接库和动态连接库。 对于上一小节中生成的 test.o,将其与C标准输入输出库进行连接,最终生成程序 然后./test ,然后出结果

test gcc test.o -o test

3.多个程序文件的编辑

通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用 GCC 能够很好地管理 这些编译单元。假设有一个由 test1.c 和 test2.c 两个源文件组成的程序,为了对它们进行编译,并 最终生成可执行程序 test,可以使用下面这条命令:

gcc test1.c test2.c -o test

操作步骤和上一个博客gcc生成动态和静态库里面实例类似可以参考

CSDN

如果同时处理的文件不止一个,GCC 仍然会按照预处理、编译和链接的过程依次进行。如果深究起 来,上面这条命令大致相当于依次执行如下三条命令:

gcc -c test1.c -o test1.o

gcc -c test2.c -o test2.o

gcc test1.o test2.o -o test

4.检错

gcc -pedantic illcode.c -o

-pedantic 编译选项并不能保证被编译程序与 ANSI/ISO C 标准的完全兼容,它仅仅只能用来帮助 Linux 程序员离这个目标越来越近。或者换句话说,-pedantic 选项能够帮助程序员发现一些不符合 ANSI/ISO C 标准的代码,但不是全部,事实上只有 ANSI/ISO C 语言标准中要求进行编译器诊断的 那些情况,才有可能被 GCC 发现并提出警告。 除了-pedantic 之外,GCC 还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W 开头,其中最有价值的当数-Wall 了,使用它能够使 GCC 产生尽可能多的警告信息。

gcc -Wall illcode.c -o illcode

GCC 给出的警告信息虽然从严格意义上说不能算作错误,但却很可能成为错误的栖身之所。一个优 秀的 Linux 程序员应该尽量避免产生警告信息,使自己的代码始终保持标准、健壮的特性。所以将 警告信息当成编码错误来对待,是一种值得赞扬的行为!所以,在编译程序时带上-Werror 选项,那 么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下: gcc -Werror test.c -o test

5 库文件连接

开发软件时,完全不使用第三方函数库的情况是比较少见的,通常来讲都需要借助许多函数库的支 持才能够完成相应的功能。从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(so、 或 lib、dll)的集合。。虽然 Linux 下的大多数函数都默认将头文件放到/usr/include/目录下,而库文 件则放到/usr/lib/目录下;Windows 所使用的库文件主要放在 Visual Stido 的目录下的 include 和 lib, 以及系统文件夹下。但也有的时候,我们要用的库不再这些目录下,所以 GCC 在编译时必须用自己 的办法来查找所需要的头文件和库文件。 例如我们的程序 test.c 是在 linux 上使用 c 连接 mysql,这个时候我们需要去 mysql 官网下载 MySQL Connectors 的 C 库,下载下来解压之后,有一个 include 文件夹,里面包含 mysql connectors 的头 文件,还有一个 lib 文件夹,里面包含二进制 so 文件 libmysqlclient.so 其中 inclulde 文件夹的路径是/usr/dev/mysql/include,lib 文件夹是/usr/dev/mysql/lib

5.1 编译成可执行文件 首先我们要进行编译 test.c 为目标文件,这个时候需要执行

gcc –c –I /usr/dev/mysql/include test.c –o test.o

5.2 链接 最后我们把所有目标文件链接成可执行文件:

gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test Linux 下的库文件分为两大类分别是动态链接库(通常以.so 结尾)和静态链接库(通常以.a 结尾), 二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。

5.3 强制链接时使用静态链接库 默认情况下, GCC 在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链 接库,如果需要的话可以在编译时加上-static 选项,强制使用静态链接库。 在/usr/dev/mysql/lib 目录下有链接时所需要的库文件 libmysqlclient.so 和 libmysqlclient.a,为了让 GCC 在链接时只用到静态链接库,可以使用下面的命令:

gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test

静态库链接时搜索路径顺序:

1. ld 会去找 GCC 命令中的参数-L

2. 再找 gcc 的环境变量 LIBRARY_PATH

3. 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初 compile gcc 时写在程序内的 动态链接时、执行时搜索路径顺序:

1. 编译目标代码时指定的动态库搜索路径

2. 环境变量 LD_LIBRARY_PATH 指定的动态库搜索路径

3. 配置文件/etc/ld.so.conf 中指定的动态库搜索路径

4. 默认的动态库搜索路径/lib

5. 默认的动态库搜索路径/usr/lib

有关环境变量:

LIBRARY_PATH 环境变量:指定程序静态链接库文件搜索路径 LD_LIBRARY_PATH 环境变量:指定程序动态链接库文件搜索路

六.总结

gcc常用命令的学习能够帮我我深入的去了解gcc背后的故事,学习常用的命令后,能够熟练的使用命令代码,也对它有了一定的了解,虽然在本次gcc背后的故事中没有完全的了解背后的故事,但对于我来说也是收益很大。

参考文献

GCC编译器背后的故事.pdf

Linux GCC常用命令.pdf

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值