ubuntu:gcc编译器使用


gcc 编译流程

  • 预处理
  • 编译
  • 汇编
  • 链接

1、预处理阶段

该阶段对包含的头文件、宏定义进行处理。
hello.c如下

#include <stdio.h>
int main()
{
	printf("Hello World");
}

输入以下命令对hello.c进行预处理

sudo gcc -E hello.c -o hello.i

.i为后缀的文件为经过预处理的C原始程序,上述命令的-E选项是对c文件只进行预处理不编译,-o选项指目标文件。
hello.i文件内容如下所示,可见gcc已经对hello.c进行了预处理,把“stdio.h”的内容插入到了hello.i文件中

在这里插入图片描述


2、编译阶段

此阶段gcc检查代码是否有错误,检查无误后将代码翻译成汇编代码
输入以下命令对预处理得到的.i文件进行编译,生成.s文件

sudo gcc -S hello.i -o hello.s

-S选项是只编译,不进行汇编,生成的汇编代码如下图所示
在这里插入图片描述


3、汇编阶段

该阶段把编译阶段生成的.s文件转成目标文件。
输入以下命令将.s文件转化为.o结尾的二进制目标代码

sudo gcc -c hello.s -o hello.o

-c为只汇编不链接
在这里插入图片描述


4、链接阶段

此阶段将hello.c 需要使用的printf函数链接到函数库中(/lib/x86_64-linux-gnu/libc.so.6),因为函数库实现了printf函数,而“stdio.h”中只有函数声明,只有链接到函数库libc.so.6中才能调用printf函数。

函数库分为:静态库和动态库。
静态库(后缀通常为.a)是指在编译链接时,将库文件代码全部加入可执行文件中,因此生成的文件大,但是运行时不需要库文件了。
动态库(后缀通常为.so)是在程序执行时加载,可以节省系统开销。
输入以下命令完成对hello.o文件的链接,并生成可执行文件

sudo gcc hello.o -o hello

在这里插入图片描述
输入./hello运行该可执行文件,结果如下

代码里面忘记加回车了
代码里面忘记加回车了,影响不大 😂


gcc常用选项

  • -o file
    输出文件名为file的文件
  • -v
    打印编译过程等信息
  • -I dir
    头文件搜索目录添加dir目录

制作函数库

先准备两个c文件:usgn_pow.c、pow_test.c如下所示

/*usgn_pow.c:库程序*/
unsigned long long unsgn_pow(unsigned int x, unsigned int y)
{
	unsigned long long res = 1;
	if (y == 0)
	{
		res = 1;
	} 
	else if (y == 1)
	{
		res = x;
	}
	else
	{
		res = x * unsgn_pow(x, y - 1);
	}
	return res;
}

/*pow_test.c*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
	unsigned int x, y;
	unsigned long long res;
	if ((argc < 3)||(sscanf(argv[1],"%u", &x) != 1)||(sscanf(argv[2], "%u", &y)) != 1)
	{
		printf("Usage: pow base exponent\n");
		exit(1);
	}
	res = unsgn_pow(x,y);
	printf("%u ^ %u = %u\n", x, y, res);
	exit(0);
}

1、静态库的创建和使用

输入以下命令,使用ar归档工具将目标文件集成在一起。

sudo gcc -c unsgn_pow.c
ar rcsv libpow.a unsgn_pow.o

输出如下:
在这里插入图片描述
在目录下生成了一个libpow.a静态库文件:
在这里插入图片描述
完成上述步骤后,使用下面的命令编译主程序,并链接到刚刚生成的静态库libpow.a

sudo gcc pow_test.c -o pow_test -L . -lpow

其中 选项 “-L dir”是在库文件搜索路径中添加dir目录,“-lname”选项指示编译时链接到库文件libpow.alibpow.so
输入./pow_test 2 2命令后运行结果如下所示:
在这里插入图片描述


2、动态库的创建和使用

首先使用gcc的-fPIC选项为动态库构造一个目标文件(.o后缀)

sudo gcc -fPIC -Wall -c unsgn_pow.c

在这里插入图片描述
再使用-shared选项生成一个动态库libpow.so

sudo gcc -shared -o libpow.so unsgn_pow.o

在这里插入图片描述
最后编译程序并链接动态库libpow.so
注意这时候目录下同时存在静态库和动态库,如图:
在这里插入图片描述
输入以下命令:

sudo gcc -o pow_test pow_test.c -L . -lpow

这个命令和之前链接静态库是一样的,那么这次链接的是动态库还是静态库呢?答案是:动态库。
链接动态库还是链接静态库可以用 -static选项和-shared选项指定,-static选项是链接静态库,禁止使用动态库;-shared选项是默认选项,尽可能的链接动态库,当没有动态库时才链接静态库。
执行可执行程序之前需要注册动态库路径名这里 直接将libpow.so文件复制到/lib或者/usr/lib目录下,这是系统的默认库路径:

 sudo cp libpow.so /lib
  sudo cp libpow.so /lib

在这里插入图片描述


  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值