在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库(*.a)与动态库(*.so)的生成与使用方式是不同的。刚开始可能会不适应,但是用多了应该会习惯这种使用,因为步骤上并没有VS下配置那么繁琐。下面就分别总结下linux下生成并使用静态库与动态库的方法:(由于是C++项目,所以编译器用的g++,但是与gcc的使用是相通的)

首先是准备工作,把我们需要封装成库文件的函数的头文件与源文件写好,如下:

//myAPI.h
int ADD(int a, int b);
int MINUS(int a, int b);

//myAPI.cpp
#include "myAPI.h"int ADD(int a, int b){return a + b;
}int MINUS(int a, int b){return a - b;
}

接下来准备一个测试用的主函数源文件:

//main.cpp
#include "myAPI.h"
#include <iostream>int main(){std::cout << "1 + 1 = " << ADD(1, 1) << std::endl;std::cout << "1 - 1 = " << MINUS(1, 1) << std::endl;return 0;
}

重要说明:

linux下用生成静态库的命令 ar 处理 myAPI.o 文件生成静态库文件,生成的库文件应遵循规范,及linux下库文件加“lib”前缀。

编译/链接生成时,也要注意,目标文件/库文件之间有依赖关系,则需要把被依赖文件放到后面(g++6.x),才能编译,

不然可能报错 找不到变量函数/ 未定义的引用 "undefined reference to". 

贴上Makefile,有注解:

all: main-1 main-2 main-a main-so main-so2main-1: myAPI.cpp main.cpp myAPI.hg++ -o main-1 myAPI.cpp main.cpp@echo "main-1 done.  直接编译省略显示编译.o文件"@echomain-2: main.cpp myAPI.og++ -o main-2 myAPI.o main.cpp@echo "main-2 done.  显示编译.o文件"@echomain-a: libmyAPI.ag++ -o main-a  main.cpp libmyAPI.a@echo "main-a done.  使用.a静态库文件 链接生成程序"@echomain-so: libmyAPI.sog++ -o main-so main.cpp ./libmyAPI.so@echo "main-so done.  直接使用.so动态库文件(需要带路径,运行时直接使用此路径) 链接生成程序"@echomain-so2: libmyAPI.sog++ -o main-so2 main.cpp -L. -lmyAPI@echo "main-so2 done.  让g++自动在当前目录("."表示当前目录,或"./")查找.so动态库文件 链接生成程序"@echo "    但运行时默认到/usr/lib目录查找,,或运行前设置环境变量 LD_LIBRARY_PATH 为动态库的路径"@echomyAPI.o: myAPI.cpp myAPI.hg++ -c myAPI.cpp@echo "myAPI.o done.  编译.o文件"@echolibmyAPI.a: myAPI.oar crv libmyAPI.a myAPI.o@echo "libmyAPI.a done.  编译.a静态库文件"@echolibmyAPI.so:g++ -fPIC -c myAPI.cppg++ -shared -o libmyAPI.so myAPI.o@echo "libmyAPI.so done.  编译.so动态库文件,需要 .o文件编译时加选项 -fPIC"@echo "    或者 直接编译动态库:"@echo "    g++ -shared -fPIC -o libmyAPI.so myAPI.cpp"@echo#或者 直接编译动态库:
#libmyAPI.so:
#    g++ -shared -fPIC -o libmyAPI.so myAPI.cpp
#clean:rm -f *.o *.a *.so main-*

最后运行程序:

[root@lzp test2]# ./main-1
1 + 1 = 2
1 - 1 = 0
[root@lzp test2]# ./main-2
1 + 1 = 2
1 - 1 = 0
[root@lzp test2]# ./main-a
1 + 1 = 2
1 - 1 = 0
[root@lzp test2]# ./main-so
1 + 1 = 2
1 - 1 = 0
[root@lzp test2]# ./main-so2
./main-so2: error while loading shared libraries: libmyAPI.so: cannot open shared object file: No such file or directory

可以看到 main-so直接运行了,但是 main-so2 运行出错了,找不到动态库,需要把动态库放到/usr/lib目录;  或者使用"LD_LIBRARY_PATH"环境变量后可以直接运行

[root@lzp test2]# LD_LIBRARY_PATH=./
[root@lzp test2]# ./main-so2
./main-so2: error while loading shared libraries: libmyAPI.so: cannot open shared object file: No such file or directory
[root@lzp test2]# LD_LIBRARY_PATH=./  ./main-so2
1 + 1 = 2
1 - 1 = 0

PS:但是在 G++ 6.x版本下直接运行main-so2不出错,,以上是G++4.X版本编译的

在项目开发过层中尽量让lib是垂直关系,避免循环依赖;越是底层的库,越是往后面写!

例如:

g++ ...  obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib)  -o $@

这样写可以避免很多问题,这个是在搭建项目的构建环境的过程中需要考虑 清楚地,在编译和链接上浪费太多的生命不值得!

  推荐一本书,写的很深刻:《程序员的自我修养——链接、装载与库》

[参考: http://www.tuicool.com/articles/m67z2u2;  http://blog.chinaunix.net/uid-24352482-id-3199452.html]

[参考: http://www.cnblogs.com/little-ant/p/3398885.html]

转载于:https://www.cnblogs.com/lzpong/p/5776728.html

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

  1. g++ 编译mysql动态库_Linux下g++编译以及使用静态库和动态库的方法详解

    下面小编就为大家带来一篇Linux下g++编译与使用静态库和动态库的方法.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 在windows环境下,我们通常在IDE如VS的 ...

  2. linux下g编译文件或目录,【转】在linux下使用gcc/g++编译多个.h文件

    博主写得很好 多个文件编译在linux下编译,下面有三个文件,分别是1.cpp 和 2.cpp 和myhead.h 文件. 1.cpp 2.cpp myhead.h 假如他们都在一个目录下面,那么编译 ...

  3. Linux下的vim编辑器与gcc编译器及静动态库的制作

    1.vim编辑器的使用: (1)vim的三种模式: 命令模式:打开文件默认进入命令模式 编辑模式:需要输入一些命令切换到编辑模式 末行模式:在末行模式可以输入一些命令 命令模式aios和AIOS都可以 ...

  4. C/C++编译总结 (Linux下g++、makefile、automake)

    C/C++编译总结 (Linux下g++.makefile.automake) !! 阅读前提示: 1)本文是自己的学习过程和经验的总结,和大多数人一样,不懂就搜度娘.csdn.博客园等等,内容难免有 ...

  5. linux编译l和l区别,linux 下 g++编译程序时-I(大写i) 与-L(大写l)-l(小写l) 的作用详解...

    作为一个linux入门级使用者,gcc/g++的简单操作已经用过多次, 但是有时稍微复杂一点的程序就会使用到库.在遇到问题的时候我查了挺多前辈总结的资料,也留个脚本希望对朋友们有个帮助.如果也能处理你 ...

  6. linux 中如何将文件粘贴到usr下的lib内,学会在Linux下GCC生成和使用静态库和动态库...

    一.基本概念1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同(主 ...

  7. Linux下Gcc生成和使用静态库和动态库详解

    参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...

  8. 从四个问题透析Linux下C++编译链接

    摘要:编译&链接对C&C++程序员既熟悉又陌生,熟悉在于每份代码都要经历编译&链接过程,陌生在于大部分人并不会刻意关注编译&链接的原理.本文通过开发过程中碰到的四个典型 ...

  9. Linux下的编译(环境是centos6.8 gcc 4.4.7)

    Linux下的编译(环境是centos6.8 gcc 4.4.7) 1. 运行命令:yum install gcc gcc-c++ bzip2 bzip2-devel bzip2-libs Pytho ...

最新文章

  1. OpenCV中积分图介绍与应用
  2. Shellcode开发辅助工具shellnoob
  3. python常用的工具函数
  4. STL常用对象,不会搞得C++跟没学一样
  5. JavaScript自动设置IFrame高度(兼容各主流浏览器)
  6. php 兼容unicode文字的字符串大小写转换,php实现兼容Unicode文字的字符串大小写转换strtolower()和strtoupper()...
  7. 计算机网络数据链路层之扩展以太网(含以太网交换机及虚拟局域网)
  8. 5G工业路由器 物联网终端应用
  9. 如何选型音视频即时通讯产品
  10. taskctl跨调度服务依赖实现
  11. 用CDR(coreldraw)怎么把图片转为矢量图
  12. 也致第一次安装Rime的你
  13. Flowers Sky Wallet First school/Primary school holiday Getting up early Reading Home c
  14. javax.validation.Validation使用方法
  15. FPGA工程师面试试题集锦11~20
  16. 在技术招聘中,HR 如何识别候选人的“味道”?
  17. 问题 Q:巧克力与小花梨
  18. 宽带技术大比拼(转)
  19. 网站接入第三方微博登录—PHP
  20. Java实战之管家婆记账系统(7)——备份、恢复和退出功能实现

热门文章

  1. poi设置列宽自适应_Sentinel 系统自适应限流原理剖析与实战指导
  2. php点击后增加html元素,如何动态生成html元素以及为元素追加属性的方法介绍(附代码)...
  3. LeetCode 20.有效括号
  4. linux内核编译如何选择cpu类型,Ubuntu内核编译和CPU Hot-Plug特性配置全过程及遇到问题记录...
  5. c得到当前时分秒 linux_Linuxc - Linux系统下的时间知识点
  6. idea springboot 发布webservice 发布服务_阿里云发布 Spring Boot 新脚手架,真香
  7. python3多线程协程_python3-----多进程、多线程、多协程
  8. 【渝粤教育】广东开放大学 网页设计与制作 形成性考核 (25)
  9. 通信原理速学02:随机过程
  10. EPS(Evolved Packet System,演进的分组系统)