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编译器创建和使用静态库、动态库的更多相关文章

  1. Linux中创建和使用静态库&动态库

    库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 Linux下库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在 ...

  2. linux静态与动态库创建及使用实例

    一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...

  3. windows库的创建和使用:静态库+动态库

    windows库的创建和使用:静态库+动态库   一.静态库的创建和使用 1. 静态库创建 (1)首先创建projecttest,測试代码例如以下: 1) test.h void test_print ...

  4. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    目录 . 引言 . 交叉编译 . Cygwin简介 . 静态库编译及使用 . 动态库编译及使用 . MinGW简介 . CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件 ...

  5. Linux 静态库&动态库调用

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

  6. 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释

    #1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...

  7. C++开发新版本vs使用旧版本vs编译的静态库动态库

    关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成 ...

  8. 生成lua的静态库.动态库.lua.exe和luac.exe

    前些日子准备学习下关于lua coroutine更为强大的功能,然而发现根据lua 5.1.4版本来运行一段代码的话也会导致 "lua: attempt to yield across me ...

  9. linux下 GCC编译链接静态库&动态库

    静态库 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库, 我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量(例如以后 ...

随机推荐

  1. Jmeter Beanshell 编程简介

    简介 Jmeter除了提供丰富的组件以外,还提供脚本支持,可通过编写脚本来丰富Jmeter,实现普通组件无法完成的功能.Beanshell是一种轻量级的Java脚本语言,完全符合Java规范,并且内置 ...

  2. 第二章 Vue快速入门-- 28 自定义按键修饰符

    事件处理-按键修饰符 js 里面的键盘事件对应的键码 <!DOCTYPE html> <html lang="en"> <head> <m ...

  3. IDEA查看JDK源代码

    之前已经讲解过如何使用Eclipse查看源代码,IDEA作为一个集成开发环境越来越流行,今天学习以下如何使用Eclipse查看JDK的代码. File->Project Structure,选择 ...

  4. 【鸽】poj3311 Hie with the Pie[状压DP+Floyd]

    题解网上一搜一大坨的,不用复述了吧. 只是觉得网上dp方程没多大问题,但是状态的表示含义模糊.不同于正常哈密顿路径求解,状态表示应当改一下. 首先定义一次移动为从一个点经过若干个点到达另一个点,则$f ...

  5. CSS选择器的权重与优先规

    我们把特殊性分为4个等级,每个等级代表一类选择器,每个等级的值为其所代表的选择器的个数乘以这一等级的权值,最后把所有等级的值相加得出选择器的特殊值. 4个等级的定义如下: 第一等:代表内联样式,如: ...

  6. 手写一个类加载器demo

    1.什么是类加载器? 2.加载方式 ClassLoader类加载器,主要的作用是将class文件加载到jvm虚拟机中.jvm启动的时候,并不是一次性加载所有的类,而是根据需要动态去加载类,主要分为隐式 ...

  7. jquery getScript动态加载JS方法改进详解

    有许多朋友需要使用getScript方法动态加载JS,本文将详细介绍此功能的实现方法 $.getScript(url,callback) 这个方法是jquery自身提供的一个用于动态加载js的方法.当 ...

  8. BZOJ 3589: 动态树 树链剖分+线段树+树链的并

    利用树剖序的一些性质~ 这个题可以出到 $\sum k=10^5$ 左右. 做法很简单:每次暴力跳重链,并在线段树上查询链和. 查询之后打一个标记,把加过的链都置为 $0$.这样的话在同一次询问时即使 ...

  9. cogs1682. [HAOI2014]贴海报 x

    1682. [HAOI2014]贴海报 ★★☆   输入文件:ha14d.in   输出文件:ha14d.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] Bytetow ...

  10. sh_02_del关键字

    sh_02_del关键字 name_list = ["张三", "李四", "王五"] # (知道)使用 del 关键字(delete)删除 ...