gcc编译器创建和使用静态库、动态库
http://www.cnblogs.com/dyllove98/archive/2013/06/25/3155599.html
目录树结构:

test/include/hello.h
#ifdef _HELLO_H_
#define _HELLO_H_
void hello();
#endif
test/src/hello.c
#include "hello.h"
#include <stdio.h>
void hello()
{
printf("hello world!\n");
}
test/bin/main.c
#include "hello.h"
int main()
{
hello();
}
静态库过程如下:
第一步:生成目标文件
进入到test/src/目录下:
#gcc -c -I../include hello.c
生成目标文件hello.o,(注意:大写的i,表示搜索头文件,本实例中为搜索hello.h)
第二步:生成静态库文件
#ar rc libhello.a hello.o
该命令将hello.o添加到静态库文件libhello.a,ar命令就是用来创建、修改库的,也可以从库中提出单个模块,参数r表示在库中插入或者替换模块,c表示创建一个库,关于ar命令的详细使用规则可以参考文章http://blog.csdn.net/xuhongning/article/details/6365200。
第三步:生成可执行文件
该命令将编译main.c并链接静态库文件libhello.a生成可执行文件main,注意:参数-L添加库文件搜索目录,因为libhello.a在libtest/lib目录中,这里需要指定该目录通知gcc,参数-l指定链接的库文件名称,比如 -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
这一步将在libtest/src目录中生成可执行文件main。
#gcc main.c -o main -I../include -L../src -lhello
$ ldd test
执行test,可以看到它是如何调用动态库中的函数的。
动态库过程如下:
前提知识:
编译参数解析
最主要的是GCC命令行的一个选项:
-shared该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
(1) 生成动态库文件
进入test/src目录,执行命令:
gcc hello.c -o libhello.so -I../include -fPIC -shared
这一步将在当前目录生成动态库文件libhello.so,
(2) 生成可执行文件
进入test/bin目录,执行命令:
gcc main.c -o main -I../include -L../src -lhello
此时在当前目录中已经生成了可执行文件main,执行./main时却提示错误:
./main: error while loading shared libraries: libhello.so: cannotopen shared object file: No such file or directory
也就是找不到动态库文件libhello.so,
有两种方法:
一、可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行)。
二、把当前路径加入环境变量LD_LIBRARY_PATH中
当然,如果你觉得不会引起混乱的话,可以直接把该库拷入/lib,/usr/lib/等位置(无可避免,这样做也要有权限),这样链接器和加载器就都可以准确的找到该库了。
我们采用第二种方法:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
如下:
export LD_LIBRARY_PATH=”../lib”
gcc main.c -I../include -L../lib -lhello -o main
然后再执行./main就没有错误了。
【补充】
环境变量LD_LIBRARY_PATH指示动态连接器可以装载动态库的路径,在链接动态库文件前设置该变量为库文件所在路径,注意:用export LD_LIBRARY_PATH=”…”方式只是临时生效的,如果要永久有效可以写入~/.bashrc文件中(当前用户有效),跟修改PATH类似,exportLD_LIBRARY_PATH=$LD_LIBRARY_PATH:”…”。
当然如果有root权限的话,也可以修改/etc/ld.so.conf文件,将要添加的动态库搜索路径写入该文件中,然后调用/sbin/ldconfig来达到同样的目的。
附录:
1. 编译链接库:-lz -lrt -lm -lc都是什么库?
libz 压缩库(Z)
librt 实时库(real time):shm_open系列
libm 数学库(math)
libc 标准C库(C lib)
可以进入/lib,/usr/lib,可以看到你机器上大多数的libXXXX
-----------------2019-06-29 16:22:51----------------
Linux gcc编译和程序运行时头文件及库搜索顺序
gcc 在编译时如何去寻找所需要的头文件:
※搜寻会从-I开始
※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
※再找内定目录
/usr/include
/usr/local/include
编译的时候:
※gcc会去找-L
※再找gcc的环境变量LIBRARY_PATH
※再找内定目录
/lib和/lib64
/usr/lib 和/usr/lib64
/usr/local/lib和/usr/local/lib64
这是当初compile gcc时写在程序内的
运行时动态库的搜索路径
动态库的搜索路径搜索的先后顺序是:
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib
gcc编译器创建和使用静态库、动态库的更多相关文章
- Linux中创建和使用静态库&动态库
库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 Linux下库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在 ...
- linux静态与动态库创建及使用实例
一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...
- windows库的创建和使用:静态库+动态库
windows库的创建和使用:静态库+动态库 一.静态库的创建和使用 1. 静态库创建 (1)首先创建projecttest,測试代码例如以下: 1) test.h void test_print ...
- C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项
目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...
- Linux 静态库&动态库调用
1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不 ...
- 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释
#1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...
- C++开发新版本vs使用旧版本vs编译的静态库动态库
关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成 ...
- 生成lua的静态库.动态库.lua.exe和luac.exe
前些日子准备学习下关于lua coroutine更为强大的功能,然而发现根据lua 5.1.4版本来运行一段代码的话也会导致 "lua: attempt to yield across me ...
- linux下 GCC编译链接静态库&动态库
静态库 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库, 我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量(例如以后 ...
随机推荐
- IO模型(epoll)--详解-02
写在前面 从事服务端开发,少不了要接触网络编程.epoll作为linux下高性能网络服务器的必备技术至关重要,大部分游戏服务器都使用到这一多路复用技术.文章核心思想是:要让读者清晰明白EPOLL为什么 ...
- lightinthebox程序bug zencart
1.清空旧产品分类,新增分类与产品,前台首页不显示中间栏,提示无产品:布局设置 -(Main Page - Opens with Category)首页显示某分类,把新增的某分类ID填上或者设为0即可 ...
- uestc summer training #3 线段树优化建边
线段树建边 struct E { int value, modvalue; } a[MAXN << ]; pair<int, int> b[MAXN]; ], r[MAXN & ...
- k8s master节点添加kubectl的使用
- SpringBoot 出现内置的Tomcat没有启动的情况
Tomcat未启动,也未报错 pom.xml文件中增加 <dependency> <groupId>org.springframework.cloud</groupId& ...
- 2017 CVTE Windows开发二面 3.8 (offer)
中午1点左右,广州的号码打过来了,是CVTE的hr,然后问我下午4点半有没有时间,帮我约视频的二面. 当然有时间了啦,然后hr给我邮箱发了个链接,让我4点半登陆进去. 因为1面没问任何网络和操作系统的 ...
- Python CGI编程Ⅷ
通过CGI程序传递checkbox数据 checkbox用于提交一个或者多个选项数据,HTML代码如下: 以下为 checkbox.py 文件的代码: 修改 checkbox.py 权限: 通过CGI ...
- Spring MVC 面试题
什么是springMVC?作用? springMVC是一种web层mvc框架,用于替代servlet(处理|响应请求,获取表单参数,表单校验等). 为什么要用springMVC? 基本上,框架的作用就 ...
- css,scss解决样式:表格的重叠边框
初始效果: 解决方法: 给带有边框的元素设置如下样式margin:0 0 -borderwidth -borderwidth 这里的borderwidth即为边框的宽度,按照上图所示,则添加样式 ma ...
- Mybatis-Plus的BaseMapper的用法
1.如何使用BaseMapper进行数据库的操作. 2.使用BaseMapper进行插入实体时如何让UUID的主键自动生成. Student实体类,其中id属性主键为UUID package com. ...