GCC编译器基础

GCC编译器的使用

​ 源文件需要经过编译才能生成可执行文件。在Windows下进行开发时,只需要点几个按钮即可编译,集成开发环境(比如Visual studio)已经将各种编译工具的使用封装好了。Linux下也有很多优秀的集成开发工具,但是更多的时候是直接使用编译工具;即使使用集成开发工具,也需要掌握一些编译选项。

​ PC机上的编译工具链为 gcc、ld、objcopy、objdump 等,它们编译出来的程序在x86平台上运行。要编译出能在ARM平台上运行的程序,必须使用交叉编译工具 xxx-gcc、xxx-ld 等(不同版本的编译器前缀不一样,比如 arm-linux-gcc),下面分别介绍。

GCC编译过程

引入

​ 一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)和链接(linking)等4步才能变成可执行文件。
GCC编译过程
GCC过程

​ 例如,现在我们创建一个hello.c文件:

$ sudo vi hello.c

​ 然后随意编写一个打印helloworld的程序,确保能编译通过并用来进行测试:

#include<stdio.h>
int main(int argc, char *argv[])
{
    printf("helloworld");
    return 0;
}

​ 通过不同的 gcc 选项可以控制这些过程:

不同的gcc选项控制

​ 在日常交流中通常使用“编译”统称这4个步骤

​ gcc使用示例:

gcc hello.c						//输出一个名为a.out的可执行程序,然后可以执行./a.out
gcc -o hello hello.c			//输出名为hello的可执行程序,然后可以执行./hello
gcc -o hello hello.c -static	//静态链接

gcc -c -o hello.o hello.c		//先编译(不链接)
gcc -o hello hello.o			//再链接

​ 如果代码写入了错误,通常都是在编译的过程中报错,所以只经过预处理是不会报错的。

​ 执行“gcc -o hello hello.c -v”时,可以查看到这些步骤:

cc1 main.c -o /tmp/ccXCx1YG.s
as		   -o /tmp/ccZfdaDo.o /tmp/ccXCx1YG.s
    
cc1 sub.c -o /tmp/ccXCx1YG.s
as		   -o /tmp/ccZfdaDo.o /tmp/ccXCx1YG.s
    
collect2 -o test /tmp/ccZfdaDo.o /tmp/ccn8Cjq6.o....

​ 可以手工执行以下命令体验以下:

gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o

​ 完成编译后,使用 ./hello 命令就能执行程序。

GCC常用选项

常用编译选项

在学习时,我们暂时只需要了解下表中的选项:

常用选项描述
-E预处理,开发过程中想快速确定某个宏可以使用“-E -dM”
-c把预处理、编译、汇编都做了,但是不链接
-o指定输出文件
-I指定头文件目录
-L指定链接时库文件目录
-l指定链接哪一个库文件

怎么编译多个文件

①一起编译、链接:

gcc -o test main.c sub.c

每次修改都需要重新编译全部文件,当编译多个文件时,比较浪费编译的时间。

②分开编译,统一链接

gcc -c -o main.o main.c
gcc -c -o sub.c sub.c
gcc -o test main.o sub.o

当编译多个文件时,分开编译统一链接就显得比较高效。

制作、使用静态库

gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
ar crs libsub.a sub.o (sub2.o sub3.o可以使用多个.o生成静态库)
gcc -o test main.o libsub.a (如果.a不在当前目录下,需要指定它的绝对或相对路径)

​ 运行:

​ 不需要把静态库libsub.a放到板子上。

​ 注意:执行 arm-linux-gnueabihf-gcc -c -o sub.o sub.c 交叉编译需要在最后加上 -fPIC 参数。

制作、使用动态库

​ 制作、编译:

gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -shared -o libsub.so sub.o (sub2.o sub3.o可以使用多个.o生成动态库)
gcc -o test main.o -lsub -L /libsub.so/所在目录/

​ 运行:

​ ①先把libsub.so放到PC或板子上的/lib目录,然后就可以运行test程序。

​ ② 如果不想把libsub.so放到/lib,也可以放在某个目录比如/a,然后如下执行:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/a
./test

很有用的选项

gcc -E main.c	//查看预处理结果,比如头文件是哪个
gcc -E -dM main.c >1.txt	//把所有的宏展开,存在1.txt里
gcc -Wp,-MD,adc.dep -c -o main.o main.c	//生成依赖文件abc.dep,后面Makefile会用
    
echo 'main(){}'| gcc -E -v -	//它会列出头文件目录、库目录(LIBRARY_PATH)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FantasyQin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值