库文件可以理解为别人写好的现成的代码,但是看不见源码,只提供程序入口。库又分为动态库和静态库,静态库是在编译的时候将库编译进可执行程序中,运行时不再依赖库文件,而动态库是在运行时加载,运行时需要依赖库文件。静态库以libxxx.a命名,动态库以libxxx.so命名。

  比如编写两个文件,hello.c和main.c,源码如下:

hello.c

1 #include <stdio.h>
2
3 void hello(void)
4 {
5 printf("Hello World\n");
6 }

main.c

1 extern void hello(void);
2
3 int main(int argc, const char *argv[])
4 {
5 hello();
6
7 return 0;
8 }

  可以用gcc hello.c main.c 命令将两个文件编译成一个可执行文件,但是如果我不希望hello.c中的源代码被人看到,我就会将hello.c制作成库文件。

生成静态库

  执行命令:gcc -c hello.c -o hello.o  得到hello.o文件

  执行命令:ar crs libhello.a hello.o   得到libhello.a文件,ar命令的具体解释可以参照这篇博客:https://blog.csdn.net/hxg130435477/article/details/8217247

这时就可以使用libhello.a文件了,执行命令:gcc main.c -L. -lhello -o hello

  得到可执行文件hello。

  需要注意的几个地方:

  1、使用ar命令生成的静态库需要由.o文件生成,如果使用命令ar crs libhello.a hello.c 也能生成名为libhello.a的文件,但生成的libhello.a不能用,编译时会报错:

    “could not read symbols: Archive has no index; run ranlib to add one collect2: ld returned 1 exit status”

  2、生成的.a文件一定要以lib开头,比如libhello.a,而在指定库名时却不能加上最前面的“lib”,否则编译时会都提示找不到库。

ar crs libhello.a hello.o     //正确
ar crs hello.a hello.o //错误
gcc main.c -L. -lhello        //正确
gcc main.c -L. -llibhello //错误

  3、-L用于指定库的路径,与路径之间可以用空格隔开,也可以不用空格。-l用于指定库名,与库名之间可以用空格隔开,也可以不用

gcc main.c -L. -lhello        //正确
gcc main.c -L . -l hello //正确

  4、如果使用-L指定的路径中没有-l指定的库,或者编译时不加-L参数,那么编译器会去系统默认的库路径中寻找,默认路径为/lib。测试的时候将libhello.a拷贝到/usr/lib或者/lib目录下,测试完之后删除该文件需要使用:sudo rm -f

同时编译多个文件

  假设存在3个文件,hello.c,how.c和main.c,在当前路径下生成了hello.o,libhello.a,how.o,libhow.a,只编译c文件可以用:

gcc main.c hello.c how.c

  how.c 和libhello.a

gcc main.c how.c -L . -lhello

  libhow.a和libhello.a

gcc main.c -L . -lhello -lhow

  上面这种情况由于libhello.a和libhow.a在同一路径,所以只需要使用-L指定一次路径,而如果这两个文件不在同一个路径,那么就需要分别用-L指定路径,比如libhello.a在./dir目录下时:

gcc main.c -L . -lhow -L ./dir -lhello

多个文件合并

  1、将多个.o文合并为一个.a文件:

ar crs libnew.a hello.o how.o
gcc main.c -L . -lnew

  2、将.o文件加入.a文件:

ar crs libhello.a how.o

  3、将多个.a文件合并为一个新的.a文件

ar crs libhello.a hello.o
ar crs libhow.a how.o
ar crsT libnew.a libhello.a libhow.a
gcc main.c -L. -lnew

  注意执行前要先删掉所有的.a文件,第三步中要加参数"T",否则生成的libnew.a不能使用,编译不过,如果说第3步没有加“T”参数,在不删除.a的情况下重复执行123步,得到的libnew.a也不能使用。原因需要看ar命令和它的参数,在这里不作具体分析。

linux静态库的更多相关文章

  1. linux静态库的生成与使用(转)

    linux静态库的生成与使用(转) 库是一种软件组件技术,库里面封装了数据和函数. 库的使用可以使程序模块化. Windows系统包括静态链接库(.lib文件)和动态链接库(.dll文件). Linu ...

  2. Linux静态库生成指南

    Linux静态库生成指南   Linux上的静态库,其实是目标文件的归档文件.在Linux上创建静态库的步骤如下: 写源文件,通过 gcc -c xxx.c 生成目标文件. 用 ar 归档目标文件,生 ...

  3. Linux 静态库(.a)转换为动态库(.so)

    Linux 静态库转换为动态库 参考 http://blog.csdn.net/moxuansheng/article/details/5812410 首先将.a文件转为.so文件是可以实现的 原因是 ...

  4. 关于Linux静态库和动态库的分析

    关于Linux静态库和动态库的分析 关于Linux静态库和动态库的分析 1.什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可运行代码的二进制形式.能够被操作系统加 ...

  5. Linux静态库和共享库

    1.什么是静态库静态库类似windows中的静态lib 关于windows中的静态lib,可参考 Windows动态链接库DLL 特点:包含函数代码声明和实现,链接后所有代码都嵌入到宿主程序中. 只在 ...

  6. Linux静态库和动态库

    Linux 工具 ❑ GCC: The GNU Compiler Collection, containing the GNU C compiler❑ G++: A C++ compiler, inc ...

  7. Linux 静态库与动态库搜索路径设置详解【转】

    原文地址:http://blog.chinaunix.net/uid-29025972-id-3855495.html 1. 连接和运行时库文件搜索路径的设置 库文件在连接(静态库和共享库)和运行(仅 ...

  8. Linux 静态库和动态库 使用说明

        Linux下程序运行中,有两种库,静态库和动态库.     静态库:名字一般为libxxx.a,编译时会整合到可执行程序中,优点是运行时不需要外部函数库支持,缺点是编译后程序较大,一旦静态库改 ...

  9. 详细讲解 关于Linux静态库和动态库的分析

    基本概念 库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀. 例如:libhello.so libhello.a 为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: ...

  10. Linux 静态库与共享库的使用

    申明: 正如题如示,本篇讲的是Linux下是静态库与共享库,而Window下的动态链接库详细情况可见这篇文章:windows动态链接库 DLL 浅析.虽然原理,思想差不多,但是细节却各有不同. 一.静 ...

随机推荐

  1. 基于SpringBoot+Mybatis+MySQL5.7的轻语音乐网

    一个基于SpringBoot+Mybatis+MySQL5.7的轻语音乐网站项目 1.主要用到的技术: 使用maven进行项目构建 使用Springboot+Mybatis搭建整个系统 使用ajax连 ...

  2. Nebula Graph 在微众银行数据治理业务的实践

    本文为微众银行大数据平台:周可在 nMeetup 深圳场的演讲这里文字稿,演讲视频参见:B站 自我介绍下,我是微众银行大数据平台的工程师:周可,今天给大家分享一下 Nebula Graph 在微众银行 ...

  3. 最速下降法--MATLAB程序

    function x = fxsteep(f,e,a,b)x1 = a;x2 = b;Q = fxhesson(f,x1,x2);x0 = [x1,x2]';temp = [x0];fx1 = dif ...

  4. NET 5 MemoryCache与Redis使用以及StackExchange.Redis和CSRedisCore

    简介以及区别 ASP.NET Core 缓存Caching,.NET Core 中为我们提供了Caching 的组件. 目前Caching 组件提供了三种存储方式. Memory Redis SqlS ...

  5. spring的事物传递

    Propagation.REQUIRED:默认也是常用的事物级别,在当前事物中执行,不存在事物,则创建新事物执行. Propagation.SUPPORTS:支持使用当前事物,当前事物不存爱,则不使用 ...

  6. Python强大的日志模块logging

    前言 日志是对于软件执行所发生的事件的一种追踪记录方式.日常使用过程中对代码执行的错误和问题会进行查看日志来分析定位问题所在.平常编写代码以及调试也经常用到.通常的新手的做法是直接print打印,但是 ...

  7. eclipse的相关操作和使用快捷键

    修改字体Window->preferences->General->Appearance->ColorsandFonts ->Basic->text Font 在e ...

  8. Elasticsearch java api操作(一)(Java Low Level Rest Client)

    一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...

  9. 三、hadoop、yarn安装配置

    本文hadoop的安装版本为hadoop-2.6.5 关闭防火墙 systemctl stop firewalld 一.安装JDK 1.下载java jdk1.8版本,放在/mnt/sata1目录下, ...

  10. spark-streaming-连接kafka的两种方式

    推荐系统的在线部分往往使用spark-streaming实现,这是一个很重要的环节. 在线流程的实时数据一般是从kafka获取消息到spark streaming spark连接kafka两种方式在面 ...