昨天在自己的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的区别的更多相关文章

  1. Linux gcc编译(动态库,静态库)

    1. linux 库路径: /lib , /usr/lib , /usr/local/lib 2.linux 编译静态库 a.编写源文件vi pr1.c void print1(){    print ...

  2. Linux程序编译链接动态库版本号的问题

    不同版本号的动态库可能会不兼容,假设程序在编译时指定动态库是某个低版本号.执行是用的一个高版本号,可能会导致无法执行. Linux上对动态库的命名採用libxxx.so.a.b.c的格式.当中a代表大 ...

  3. Linux中的动态库和静态库(.a/.la/.so/.o)

    Linux中的动态库和静态库(.a/.la/.so/.o) Linux中的动态库和静态库(.a/.la/.so/.o) C/C++程序编译的过程 .o文件(目标文件) 创建atoi.o 使用atoi. ...

  4. Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名

    Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf  动态库的后缀为*.so  静态库的后缀为 libxxx.a   ldconfig   目录名 转载自:http://b ...

  5. 【转】分析Linux和windows动态库

    原文地址:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Lin ...

  6. Linux和windows动态库

    转载:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中 ...

  7. linux中制作动态库

    制作一个动态库我们可以使用gcc工具来制作一个动态库示例:自己制作一个动态库,库函数的功能是传递一个字符串并输出.第一步:需要准备3个文件:hello.h.hello.c.test.c.其中hello ...

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

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

  9. Linux环境编译动态库和静态库总结

    对Linux环境动态库和静态库的一些基础知识做一些总结, 首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文 ...

随机推荐

  1. UML之类之间的关系

    UML 简介 统一建模语言(Unified Modeling Language,UML) 作用:对软件系统进行说明 如果说软件系统是一本小说的话,那么 UML 就是将小说动漫化. 也许你看过这本小说, ...

  2. Linux普通用户如何获取root权限 sudo -i

    从下图中可以知道,xiaolai这个用户连接到服务器后它没有权限,更新代码都更新不了 那么我们作为一个普通用户要获取管理员权限,怎么办呢? 输入 sudo -i 然后再输入普通用户的这个密码 获取成功 ...

  3. 在浏览器窗口内移动的div

    ------------今天研究了一个最简单的屏保效果----------- 效果图如下:效果很神奇,就是这个div在浏览器窗口不断的灵活移动 代码却很简单 <!DOCTYPE html> ...

  4. STM32串口遇到的一个问题

    做HLW8032电能表项目中关于USART使用DMA接收定长数据的问题 1:由于HLW8032芯片一上电,芯片就会通过串口每隔50ms向STM32发送24字节的数据,且我不能通过STM32控制HLW8 ...

  5. Kafka日志压缩剖析

    1.概述 最近有些同学在学习Kafka时,问到Kafka的日志压缩(Log Compaction)问题,对于Kafka的日志压缩有些疑惑,今天笔者就为大家来剖析一下Kafka的日志压缩的相关内容. 2 ...

  6. 测试工具Fiddler(二)—— 入门使用

    Fiddler设置与安装证书 一.Fiddler常见设置 Options位置:Tools->Options 二.移动端连上Fiddler作为代理 注意:因为Charles也是默认8888端口,小 ...

  7. 利用Springmvc的AbstractXlsxView下载Excel文件

    设计一个模型,在针对多中数据类型进行拓展 public abstract class ExcelView extends AbstractXlsxView { public CellStyle cel ...

  8. [题解][Codeforces]Codeforces Round #602 (Div. 1) 简要题解

    orz djq_cpp lgm A 题意 给定一个分别含有 \(\frac n2\) 个左括号和右括号的括号序列 每次可以将序列的一个区间翻转 求一个不超过 \(n\) 次的操作方案,使得操作完之后的 ...

  9. 12、python文件的操作

    前言:本文主要介绍python中文件的操作,包括打开文件.读取文件.写入文件.关闭文件以及上下文管理器. 一.打开文件 Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处 ...

  10. python练习题-9-6

    本代码是<Python核心编程(第二版)>第九章的9-6练习题,完成的功能为:文件比较:比较两个文本文件是否相同,如果不同,给出第一个不同处的行号和列号. #!/usr/bin/env p ...