gcc的介绍以及静态库和动态库的生成和使用

一、gcc的使用

(一)gcc中的命令

	1) ld:主要用于链接

(2) ar:主要用于创建静态库。
(3) ldd:可以用于查看一个可执行程序依赖的共享库。
(4)objcopy:将一种对象文件翻译成另一种格式,譬如将.bin 转换成.elf、或
者将.elf 转换成.bin 等。
(5) objdump:主要的作用是反汇编。有关反汇编的详细介绍,请参见后文。
(6) readelf:显示有关 ELF 文件的信息,请参见后文了解更多信息。
(7) size:列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段、总大小等,请参见后文了解使用 size

(二)使用gcc的编译过程

1.预处理

预处理的过程主要包括以下过程:
(1) 将所有的#define 删除,并且展开所有的宏定义,并且处理所有的条件预编
译指令,比如#if #ifdef #elif #else #endif 等。
(2) 处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。
(3) 删除所有注释“//”和“/* */”。
(4) 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
(5) 保留所有的#pragma 编译器指令,后续编译过程需要使用它们。

2.编译

编译过程就是对预处理完的文件进行一系列的词法分析,语法分析,语义分析及
优化后生成相应的汇编代码。

3.汇编

汇编过程调用对汇编代码进行处理,生成处理器能识别的指令,保存在后缀为.o的目标文件中。由于每一个汇编语句几乎都对应一条处理器指令,因此,汇编相对于编译过程比较简单,通过调用 Binutils 中的汇编器 as 根据汇编指令和处理器指令的对照表一一翻译即可。
当程序由多个源代码文件构成时,每个文件都要先完成汇编工作,生成.o 目标
文件后,才能进入下一步的链接工作。注意:目标文件已经是最终程序的某一部分了,但是在链接之前还不能执行。

4.链接

链接也分为静态链接和动态链接,其要点如下:
(1) 静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大。链接器将函数的代码从其所在地(不同的目标文件或静态链接库中)拷贝到最终的可执行程序中。为创建可执行文件,链接器必须要完成的主要任务是:符号解析(把目标文件中符号的定义和引用联系起来)和重定位(把符号定义和内存地址对应起来然后修改所有对符号的引用)。
(2) 动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去。
① 在 Linux 系 统中,gcc 编译链接时的动态库搜索路径的顺序 通常为:首先从 gcc 命令的参数-L 指定的路径寻找 ;再从环境变量LIBRARY_PATH 指 定的路径寻址;再从默认路径 /lib、/usr/lib、/usr/local/lib 寻找 。
② 在 Linux 系 统中,执行二 进制 文件时的动态库搜索路径的顺序通常为:首 先搜 索编译目标代码时指定的动态库搜索路径;再从环境变量 LD_LIBRARY_PATH 指定的路径寻址;再从配置 文件/etc/ld.so.conf 中指定 的动态库搜索路径 ;再从默 认路径/lib、/usr/lib寻找 。
③ 在 Linux 系统 中,可以 用 ldd 命令查看 一个可执行程序依赖的共享库。由于链接动态库和静态库的路径可能有重合,所以如果在路径中有同名的静态库文件和动态库文件,比如 libtest.a 和 libtest.so,gcc 链接时默认优先选择动态库,会链接libtest.so,如果要让 gcc 选择链接 libtest.a 则可以指定 gcc 选项-static,该选项会强制使用静态库进行链接。

二、使用gcc生成静态库与动态库

(一)静态库

1.使用vim新建hello.h、hello.c以及main.文件

①hello.h

 #ifndef HELLO_H
#define HELLO_H
void hello(const char*name);
#endif         //HELLO_H

②hello.c

#include<stdio.h>
void hello(const char*name)
{
	printf("Hello%s\n",name);
}


③main.c

#include "hello.h"
int main()
{
	hello("everyone");
	return 0;
}


2.使用gcc编译hello.c文件

在这里插入图片描述

3.根据编译后的.o文件创建静态库

静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将创建的静态库名为 myhello,则静态库文件名就是libmyhello.a。在创建和使用静态库时,需要注意这点。创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件

4. 静态库的使用

在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明静态库名,gcc 将会从静态库中将公用函数连接到目标文件中。注意,gcc 会在静态库名前加上前缀 lib,然后追加扩展名.a 得到的静态库文件名来查找静态库文件.

(二)动态库

1. 由.o文件生成动态库

动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其文件扩展名为.so。例如:我们将创建的动态库名为 myhello,则动态库文件名就是libmyhello.so用 gcc 来创建动态库。在系统提示符下键入以下命令得到动态库文件 libmyhello.so
在这里插入图片描述

2. 动态库的使用

在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含
这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明动态库名进行编译。我
们先运行 gcc 命令生成目标文件,再运行它看看结果。程序在运行时,会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将终止程序运行。我们需要将文件 libmyhello.so 复制到目录/usr/lib 中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态库静态库是在程序编译期间链接的库文件,用于提供可重用的代码和函数,从而节省编写代码的时间和减少代码重复。下面是它们的使用生成方法: 1. 静态库 静态库是一种编译时链接的库文件,它会将库文件的代码和函数复制到可执行程序中。在使用静态库时,需要将静态库的文件路径和名称添加到编译器的链接器参数中,例如: ``` $ gcc main.c -L./lib -lfoo -o main ``` 其中,`-L./lib` 表示将库文件所在的目录添加到链接库的搜索路径中,`-lfoo` 表示链接名为 `libfoo.a` 的库文件,`-o main` 表示将编译生成的可执行文件命名为 `main`。 生成静态库方法如下: ``` $ gcc -c foo.c -o foo.o $ ar rcs libfoo.a foo.o ``` 其中,`-c foo.c -o foo.o` 表示将 `foo.c` 编译成目标文件 `foo.o`,`ar rcs libfoo.a foo.o` 表示将目标文件 `foo.o` 打包成静态库 `libfoo.a`。 2. 动态库 动态库是一种在运行时链接的库文件,它不会将代码和函数复制到可执行程序中,而是在程序运行时动态加载。在使用动态库时,需要将动态库的路径和名称添加到程序运行环境的搜索路径中,例如: ``` $ export LD_LIBRARY_PATH=./lib $ gcc main.c -lfoo -o main ``` 其中,`export LD_LIBRARY_PATH=./lib` 表示将库文件所在的目录添加到动态库的搜索路径中,`-lfoo` 表示链接名为 `libfoo.so` 的动态库,`-o main` 表示将编译生成的可执行文件命名为 `main`。 生成动态库方法如下: ``` $ gcc -fPIC -c foo.c -o foo.o $ gcc -shared -o libfoo.so foo.o ``` 其中,`-fPIC` 表示生成位置无关的代码,`-c foo.c -o foo.o` 表示将 `foo.c` 编译成目标文件 `foo.o`,`-shared -o libfoo.so foo.o` 表示将目标文件 `foo.o` 打包成动态库 `libfoo.so`。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值