库文件可以理解为别人写好的现成的代码,但是看不见源码,只提供程序入口。库又分为动态库和静态库,静态库是在编译的时候将库编译进可执行程序中,运行时不再依赖库文件,而动态库是在运行时加载,运行时需要依赖库文件。静态库以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. Linux下安装ffmpeg,视频格式转换

    下载ffmpeg 从ffmpeg官网:http://ffmpeg.org/download.html 下载最新的ffmpeg安装包,然后通过如下命令解压: 解压 ffmpeg-*.tar.bz2 文件 ...

  2. Python批量创建word文档(1)- 纯文字

    Python创建word文档,任务要求:小杨在一家公司上班,每天都需要给不同的客户发送word文档,以告知客户每日黄金价格.最后贴上自己的联系方式.代码如下: 1 ''' 2 #python根据需求新 ...

  3. 浅析Python装饰器

    1.什么是装饰器 在介绍装饰器之前,我们先来思考一个问题:使用Python语言进行程序设计时,如果我们想扩展一个函数的功能,一般会怎么做呢? 比如,有一个名为print_info函数,当前该函数内只做 ...

  4. flowable中传入审批人是list

    package org.springblade.flow.engine.listener; import org.flowable.engine.delegate.DelegateExecution; ...

  5. 身份证前6位地址码+码表+MySQL

    insert into smd_address_code(add_code,address) values('110000','北京市'); insert into smd_address_code( ...

  6. python-OpenCV 使用GrabCut来实现图片的前景与后景的分割

    先上一个效果图: 使用Python3.7+OpenCV 3.x. 需要引入 numpy库. 在图上用鼠标左键和右键标记前景和后景即可.如果需要重新标记图像,关闭程序重新运行. 以下是具体实现代码. # ...

  7. jQuery的data()方法

    jQuery文档对.data()方法的描述: As of jQuery 1.4.3 HTML 5 data- attributes will be automatically pulled in to ...

  8. 使用sqlmap

    实验环境要求: 1.安装win7或win10的笔记本或PC电脑一台,硬盘100GB,内存8GB 2.安装VMware Workstation 14以上 总体目标:基于centos7搭建dvwa web ...

  9. 美团关于分布式ID实践方案

    在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识.如在美团点评的金融.支付.餐饮.酒店.猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的 ...

  10. maven版本仲裁原则

    这里有一个案例是项目里依赖了b组件,b组件依赖了a组件1.0.2版本,而用户也直接在pom依赖了a组件并声明的1.0.0版本,结果在仲裁时选择了1.0.0版本的a组件: +- com.xxx:a:ja ...