0. 回顾一下 gcc 选项

==============================================

-E : 仅做预处理,例如去注释,宏展开,include 展开等

-S : 将源程序编译为汇编代码 *.s

-c :  预处理,汇编,生成目标文件 *.o

-o :  预处理,汇编,链接,生成可执行 ELF 文件

==============================================

-g :  编译时加入调试信息

-Wall : 编译时显示所有告警

-std=c99 : 编译时支持 c99 语法

-I directory : (i) 加入头文件搜索目录

-lxxx : (L) 链接静态库或动态库

==============================================

1. 创建和使用静态库

- 库文件 arithmetic.c

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b; }

- 头文件 arithmetic.h

#ifndef ARITHMETIC_H_
#define ARITHMETIC_H_ extern int add(int, int);
extern int sub(int, int);
extern int mul(int, int);
extern int div(int, int); #endif

- 主测试文件 use_arithmetic_lib.c

#include "arithmetic.h"
#include <stdio.h> int main(void)
{
int x, y;
printf("Enter two integers: ");
scanf("%d%d", &x, &y); printf("add is: %d\n", add(x, y));
printf("sub is: %d\n", sub(x, y));
printf("mul is: %d\n", mul(x, y));
printf("div is: %d\n", div(x, y)); return ;
}

生成静态库步骤:

1)编译 arithmetic.c 为目标文件,生成 arithmetic.o

$ gcc -c arithmetic.c

2)将 arithmetic.o 转换为静态库文件(注意,库文件命名规则,libxxx.a)

$ ar rcs libarithmetic.a arithmetic.o

使用静态库:

方法1:$ gcc use_arithmetic_lib.c -static ./libarithmetic.a -o use_arithmetic_lib

方法2:$ gcc use_arithmetic_lib.c -L. -larithmetic -o use_arithmetic_lib               # -L 指定静态库文件路径

正规使用静态库到方式: $ gcc use_arithmetic_lib.c  -static  -L.  -larithmetic  -o  use_arithmetic_lib

对于静态库,编译完成后,可执行文件可以脱离静态库运行。但是设想一下,如果一个静态库被调用很多次,则在内存中有这个库很多重复的加载,这是引入动态库的原因之一。以下介绍动态库。

2. 创建和使用动态库

(使用和上述静态库同样的c代码)

生成动态库步骤:

1)编译 arithmetic.c 为目标文件,生成 arithmetic.o

$ gcc -c arithmetic.c

2)将目标文件转换成动态库文件 (注意动态库文件的命名规则 libxxx.so.major.minor)

$ gcc -fPIC -shared -o libarithmetic.so.0.1 arithmetic.o

以上两步可以合在一起,

$ gcc -fPIC -shared -o libarithmetic.so.0.1 arithmetic.c

使用动态库文件:

$ gcc use_arithmetic_lib.c  -L.  -larithmetic  -o  use_arithmetic_lib

要使编译后的可执行文件能找到动态库文件,则,

1) 将动态库文件拷贝到 /usr/local/lib(建议自己生成的动态库文件放在此目录。默认动态库文件搜索路径是 /usr/lib, /lib, /usr/local/lib)

$ sudo cp libarithmetic.so.0.1 /usr/local/lib

2)创建一个软链接

$ sudo ln -sf libarithmetic.so.0.1 libarithmetic.so

3) 更新 ld 缓存

$ sudo ldconfig

使用可执行文件时,不能脱离动态库环境(例如,可执行文件不能放到其它机器上跑), run 结果如下,

=====================================================================================

有时编译完成后,执行时报错: cannot open shared object file: No such file or directory 解决方法有以下两种:

第一种: 在 .bashrc 中添加 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib  (假定动态链接文件.so 安装在 /usr/local/lib 下)

第二种: $ sudo vim /etc/ld.so.conf  添加 /usr/local/lib 然后执行 $ sudo ldconfig

=====================================================================================

动态库文件的好处是,可以动态更新库文件,不用重复编译可执行文件。如下,

更改 arithmetic.c 为 arithmetic_modify.c 为,

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b + ; }

编译生成目标文件:

$ gcc -c arithmetic_modify.c

生成动态库文件:

$ gcc -fPIC -shared -o libarithmetic.so.0. arithmetic.o

拷贝动态库文件到 /usr/local/lib

$ sudo cp libarithmetic.so.0.2 /usr/local/lib

更新软连接

$ sudo ln -sf libarithmetic.so.0.2 libarithmetic.so

再执行一下 use_arithmetic_lib,

最后,使用命令 ldd 可以查看可执行文件的动态库依赖关系,如下,

$ ldd use_arithmetic_lib

完。

Linux 创建静态库(.a)和动态库(.so)的更多相关文章

  1. 在Linux中创建静态库.a和动态库.so

    转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...

  2. 自己在linux上编译、链接、动态库和静态库的学习笔记

    在平常的项目中,我们都是使用公司要求的makefile.makedebug一类的文件,因此,在编译.链接.生成和链接动态库与静态库的时候,我们只是简单的使用一些已经设置的变量,只是简单的修改.添加一些 ...

  3. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库 ...

  4. Linux高级编程--02.gcc和动态库

    在Linux环境下,我们通常用gcc将C代码编译成可执行文件,如下就是一个简单的例子: 小实验:hello.c #include <stdlib.h> #include <stdio ...

  5. 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件

    <CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...

  6. linux c编程调用系统的动态库时,要使用dlopen等函数吗?

    同问 linux c编程调用系统的动态库时,要使用dlopen等函数吗? 2012-11-27 21:55 提问者: hnwlxyzhl 我来帮他解答 满意回答 2012-12-07 09:08 li ...

  7. 静态库(.a)与动态库(.so)的简明介绍

    静态库(.a)与动态库(.so)的简明介绍 gcc有很多关于静态库,动态库的选项如-l,-L,-fPIC,-shared -Wl,-soname,看着很复杂容易混淆,其实静态库和动态库都是应需而生,只 ...

  8. linux下添加动态链接库路径、动态库加载等方法

    linux下添加动态链接库路径的方法 2017年01月20日 10:08:17 阅读数:5596   Linux共享库路径配置 Linux下找不到共享库文件的典型现象为明明已经安装某个软包(如libn ...

  9. Linux链接库一(动态库,静态库,库放在什么路径下)

    http://www.cppblog.com/wolf/articles/74928.html http://www.cppblog.com/wolf/articles/77828.html http ...

随机推荐

  1. C#导入Excel、Excel导入、导入.xls 、导入.xlsx、Excel2003版本、Excel2007版本

    C#导入Excel: 1.选择Excel 03版文件 2.选择需要读取数据的Excel工作表   3.选择工作表中需要读取的列 源码地址在图片下面,不要点击图片,点击下载地址跳转下载.

  2. linux学习笔记-wget相关知识

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! wget是非交互式的网络文件下载工具,这里参考帮助文档,记录下实用参数和使用方法. 一.wget的实用参数: wget: 用法: ...

  3. js 取数组中某个对象的集合

    var arr = [ {a:1,b:2,c:3}, {a:4,b:5,c:6}, {a:7,b:8,c:9} ]; arr1=[]; arr.forEach(function(v){ arr1.pu ...

  4. HTML元素被定义为块级元素或内联元素。那么什么是块级元素,什么是内联元素呢

    块级元素(block)特性: 块级元素在浏览器显示时,通常会以新行来开始(和结束). 宽度(width).高度(height).内边距(padding)和外边距(margin)都可控制;就像以前用到的 ...

  5. IDEA项目搭建十四——Web站点Controller基类及布局页静态资源设计

    一.简介 站点搭建完成后,编写页面时一般会有如下几个需求 1.嵌套静态页面时有很大一部分通用代码,如css.js这部分可以使用thymeleaf的局部片段代码块组成 2.这些静态资源默认放在程序中,但 ...

  6. 虚拟现实的头戴式设备的视野(FOV)原理

    本文原址https://www.cnblogs.com/zhangmiao14/p/5836664.html. 对于VR,它做得最好的就是它对生活的变化,有一些关键因素需要调整的恰如其分.如果做得正确 ...

  7. 我喜欢 Google Flutter

    在 Google I/O ’17 上,Google 向我们介绍了 Flutter —— 一款新的用于创建移动应用的开源库. 正如你所想的那样,Flutter 是能够帮助创建拥有漂亮 UI 界面的跨平台 ...

  8. 你不可不知的Java引用类型之——ReferenceQueue源码详解

    定义 ReferenceQueue是引用队列,用于存放待回收的引用对象. 说明 对于软引用.弱引用和虚引用,如果我们希望当一个对象被垃圾回收器回收时能得到通知,进行额外的处理,这时候就需要使用到引用队 ...

  9. java中的数据类型,运算符,字符串,输入输出,控制流,大数值,数组; 《java核心技术卷i》 第三章:java基本程序结构;

    <java核心技术卷i> 第三章:java基本程序结构: 每次看书,去总结的时候,总会发现一些新的东西,这次对于java的数组有了更深的了解: java中的数据类型,运算符,字符串,输入输 ...

  10. ros中自定义消息 报错 ImportError: No module named em

    大家好,欢迎来到我的博客,之前写的都是比较松散的,鉴于工作的原因,之后的随笔将持续更新ROS以及linux使用方面的随笔,欢迎大家留言,相互学习 ——————————————————————————— ...