Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别
昨天在自己的CentOs7.1上写makefile的时候,发现在一个C程序在编译并链接一个已生成好的lib动态库的时候出错。链接命令大概是这样的:
[root@typecodes tcpmsg]# gcc -o hello main.c -lmyhello
/usr/bin/ld: cannot find -lmyhello
collect2: error: ld returned 1 exit status

1 gcc链接动态库时的搜索路径
自以为在当前工程中设置好了环境变量 LD_LIBRARY_PATH 包含了工程中的lib库路径,并且还在 /etc/ld.so.conf/apphome.conf 中配置了lib库的路径。那么在调用动态库的时候,gcc就应该能自动去搜索该目录。

很遗憾ld链接器报了如上的错误,但是如果在上面的gcc命令中添加上 -L /root/gcc_test/tcp_msg/lib/ 参数,即明确动态库的绝对路径,是能够链接成功的。
2 Google上查找 /usr/bin/ld: cannot find -l* 的出错原因
gg了很久gcc ld链接动态库出错的原因,结果还是没找到理想的答案。后来猜想是不是在CentOs7中LD_LIBRARY_PATH不起作用的缘故,但是也不应该,因为自己用的GCC(version 4.8.3)跟操作系统没关系。于是重新搜索了gcc LD_LIBRARY_PATH的作用,竟然发现gcc在编译链接时链接的动态库跟 LIBRARY_PATH 有关而跟 LD_LIBRARY_PATH 没关系!
3 关于Linux gcc中的 LIBRARY_PATH 和 LD_LIBRARY_PATH 参数说明
下面摘取了两篇较权威的说明资料:
1、 GNU 上关于LIBRARY_PATH的说明:
LIBRARY_PATH
The value of LIBRARY_PATH is a colon-separated list of directories, much like PATH.
When configured as a native compiler, GCC tries the directories thus specified when searching for special linker files, if it can't find them using GCC_EXEC_PREFIX.
Linking using GCC also uses these directories when searching for ordinary libraries for the -l option (but directories specified with -L come first).
2、 man7 上关于LD_LIBRARY_PATH的说明:
LD_LIBRARY_PATH
A colon-separated list of directories in which to search for
ELF libraries at execution-time. Similar to the PATH
environment variable. Ignored in set-user-ID and set-group-ID
programs.
后面发现 StackOverflow 上关于 LIBRARY_PATH 和 LD_LIBRARY_PATH 的解释更直白:
LIBRARY_PATH is used by gcc before compilation to search for directories containing libraries that need to be linked to your program.
LD_LIBRARY_PATH is used by your program to search for directories containing the libraries after it has been successfully compiled and linked.
EDIT: As pointed below, your libraries can be static or shared.
If it is static then the code is copied over into your program and you don't need to search for the library after your program is compiled and linked.
If your library is shared then it needs to be dynamically linked to your program and that's when LD_LIBRARY_PATH comes into play.
通过这三篇资料的说明,很快明白了 LIBRARY_PATH 和 LD_LIBRARY_PATH 的作用。于是,自己在项目配置文件中添加 export LIBRARY_PATH=${LIBRARY_PATH}:${APPHOME}/lib 。接着将这个配置文件加载到CentOs的环境变量中,这样就在gcc编译不用加 -L 参数生成目标文件CommuTcp了。
4 总结
关于 LIBRARY_PATH 和 LD_LIBRARY_PATH 的关系,这里自己再总结一下。
4.1 Linux gcc编译链接时的动态库搜索路径
GCC编译、链接生成可执行文件时,动态库的搜索路径顺序如下(注意不会递归性地在其子目录下搜索):
1、gcc编译、链接命令中的-L选项;
2、gcc的环境变量的LIBRARY_PATH(多个路径用冒号分割);
3、gcc默认动态库目录:/lib:/usr/lib:usr/lib64:/usr/local/lib。
4.2 执行二进制文件时的动态库搜索路径
链接生成二进制可执行文件后,在运行程序加载动态库文件时,搜索的路径顺序如下:
1、编译目标代码时指定的动态库搜索路径:用选项-Wl,rpath和include指定的动态库的搜索路径,比如gcc -Wl,-rpath,include -L. -ldltest hello.c,在执行文件时会搜索路径`./include`;
2、环境变量LD_LIBRARY_PATH(多个路径用冒号分割);
3、在 /etc/ld.so.conf.d/ 目录下的配置文件指定的动态库绝对路径(通过ldconfig生效,一般是非root用户时使用);
4、gcc默认动态库目录:/lib:/usr/lib:usr/lib64:/usr/local/lib等。
其中,Linux GCC默认的动态库搜索路径可以通过 ld --verbose 命令查看:
[root@typecodes tcpmsg]# ld --verbose
............
SEARCH_DIR("/usr/x86_64-redhat-linux/lib64");
SEARCH_DIR("/usr/local/lib64");
SEARCH_DIR("/lib64");
SEARCH_DIR("/usr/lib64"); ##### 64位系统
SEARCH_DIR("/usr/x86_64-redhat-linux/lib");
SEARCH_DIR("/usr/local/lib");
SEARCH_DIR("/lib");
SEARCH_DIR("/usr/lib");

转自:http://typecodes.com/cseries/gcclderrlibrarypath.html
Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别的更多相关文章
- Linux gcc编译(动态库,静态库)
1. linux 库路径: /lib , /usr/lib , /usr/local/lib 2.linux 编译静态库 a.编写源文件vi pr1.c void print1(){ print ...
- Linux程序编译链接动态库版本号的问题
不同版本号的动态库可能会不兼容,假设程序在编译时指定动态库是某个低版本号.执行是用的一个高版本号,可能会导致无法执行. Linux上对动态库的命名採用libxxx.so.a.b.c的格式.当中a代表大 ...
- Linux中的动态库和静态库(.a/.la/.so/.o)
Linux中的动态库和静态库(.a/.la/.so/.o) Linux中的动态库和静态库(.a/.la/.so/.o) C/C++程序编译的过程 .o文件(目标文件) 创建atoi.o 使用atoi. ...
- Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名
Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名 转载自:http://b ...
- 【转】分析Linux和windows动态库
原文地址:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Lin ...
- Linux和windows动态库
转载:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中 ...
- linux中制作动态库
制作一个动态库我们可以使用gcc工具来制作一个动态库示例:自己制作一个动态库,库函数的功能是传递一个字符串并输出.第一步:需要准备3个文件:hello.h.hello.c.test.c.其中hello ...
- linux静态与动态库创建及使用实例
一,gcc基础语法: 基本语法结构:(由以下四部分组成) gcc -o 可执行文件名 依赖文件集(*.c/*.o) 依赖库文件及其头文件集(由-I或-L与-l指明) gcc 依赖文件集(*.c/*.o ...
- Linux环境编译动态库和静态库总结
对Linux环境动态库和静态库的一些基础知识做一些总结, 首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文 ...
随机推荐
- Redis系列(一):Redis简介及环境安装
提到Redis,大家肯定都听过,并且应该都在项目中或多或少的使用过,也许你觉得Redis用起来挺简单的呀,但如果有人问你下面的几个问题(比如同事或者面试官),你能回答的上来吗? 什么是Redis? R ...
- echarts设置柱状图颜色渐变及柱状图粗细大小
series: [ { name: '值', type: 'bar', stack: '总量', //设置柱状图大小 barWidth : 20, //设置柱状图渐变颜色 itemStyle: { n ...
- docker学习1--dockerfile
记录docker学习过程 实践启动一个redis server 命令之前 要弄懂 dockfile 镜像 容器 三者概念以及三者之间的关系 dockerfile格式 # Comment 注释 INST ...
- python列表的方法(改变原列表)
xxx.append() 末尾添加一个元素效果图: 代码: # append() 末尾添加一个元素 my_list = ['] print('原列表:',my_list) my_list.a ...
- spring注入相关注解
本次主要整理四个注解 @ComponentScan.@Scope.@Conditional.@Import 1. @ComponentScan(value = "com.xiaoguo&qu ...
- mysql的查询优化
参考网站:http://www.liyblog.top/p/6 这里总结了52条对sql的查询优化,下面详细来看看,希望能帮助到你 1, 对查询进行优化,应尽量避免全表扫描,首先应考虑在 wh ...
- web网页设计五种布局
1.大框套小框布局 2.通栏布局 3.导航栏在主视觉下方的布局 4.左中右布局 5.环绕式布局
- DataFrame数据合并
一.join 作用:默认情况下,他是把行索引相同的数据合并到一起注意:以左为准,没有的部分用NaN补全 例子 import pandas as pd import numpy as np df1 = ...
- 机器学习-MNIST数据集使用二分类
一.二分类训练MNIST数据集练习 %matplotlib inlineimport matplotlibimport numpy as npimport matplotlib.pyplot as p ...
- 定时任务莫名停止,Spring 定时任务存在 Bug??
Hello~各位读者新年好!这里楼下小黑哥给大家拜个年,祝大家蒸蒸日上烫烫烫,年年有余屯屯屯. 那年那 Bug 春节放假,小黑哥坐上高铁回家,突然想到一次生产问题.那是小黑哥参加工作第一年,那一年国庆 ...