简介


这是个相当基础的话题,平时也觉得知道一点。如头文件会先在当前目录查找,如果未找到会查找系统目录。

但当问题出现时,还是有点不知所措,对所谓的“系统目录”一知半解,很难把它们的清楚完整地梳理出来。

借此时机,梳理一下。

头文件


一般有两种形式的写法:双引号和尖括号,如下:

#include <iostream>
#include "demo.h"

当然也可以直接写绝对路径,那就不会有查找路径的问题了。

它们查找路径的顺序是有区别的,双引号形式会查找当前目录,而尖括号形式不会,具体查找顺序为:

  1. 当前目录(仅双引号形式)
  2. 编译时指定的头文件目录(由gcc -I参数指定)
  3. 系统环境变量 CPLUS_INCLUDE_PATH(c++头文件)或 C_INCLUDE_PATH(c头文件)指定的目录
  4. gcc默认目录:/usr/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/5/include(注:最后一个路径是gcc程序的库文件地址,各个用户的系统上可能不一样)

如果各目录下存在相同的文件,则先找到哪个就使用哪个,这时顺序很重要。特别注意,尖括号形式不查找当前目录。

gcc的默认目录与安装gcc时指定的–prefix有关,该值可通过 gcc -v查看,具体的目录可通过 echo | g++ -v -x c++ -E -查看,如下:

#include "..." search starts here:
#include <...> search starts here:/usr/include/c++/5/usr/include/x86_64-linux-gnu/c++/5/usr/include/c++/5/backward/usr/lib/gcc/x86_64-linux-gnu/5/include/usr/local/include/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/usr/include/x86_64-linux-gnu/usr/include

知道了头文件的查找规则,查找问题也就得心应手了。

添加路径到头文件默认搜索路径

注意,除非必要,一般不建议这样做。比较好的方式是写入到CMakeLists或者Makefile中。

  • 一次性生效,命令行输入即可,只对当前shell生效,重新登录消失:

c++: export CPLUS_INCLUDE_PATH=xxx:$CPLUS_INCLUDE_PATH
c: export C_INCLUDE_PATH=XXXX:$C_INCLUDE_PATH

  • 用户级生效:

修改用户的 ~/.bashrc,在文件最后添加上述命令。执行source ~/.bashrc 或者重新登录生效。

  • 全局级生效:

修改/etc/profile 文件,在文件最后添加上述命令,运行 source /etc/profile 后生效。对所有用户生效。

库文件


头文件用于编译,库文件用于链接,编译通过了,还要链接通过。链接时库文件的查找顺序如下:

  1. 编译时指定的库文件目录(由gcc -L参数指定)
  2. 环境变量LIBRARY_PATH指定的目录
  3. 系统默认目录:/lib; /usr/lib; /usr/local/lib

一般用户安装的库会安装在/usr/local/lib,系统自带的库位于/lib; /usr/lib,用户自己编译的库可能就要使用-L参数指定了。

编译时通过了,还会有一个问题,就是运行动态库的使用。因为动态库是运行时加载的,所以还会有一个查找的顺序:

  1. 编译时指定的动态库搜索路径(通过gcc 的参数"-Wl,-rpath,"指定。当指定多个动态库搜索路径时,路径之间用冒号:分隔)
  2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径(路径之间用冒号:分隔)
  3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径
  4. 默认的动态库搜索路径/lib:/usr/lib

特别注意,库文件的查找默认是不查找当前目录的,也就是说,即使使用的库位于同一个目录内,也需要指定才能指定。

所以,当下次遇到下面这个错误时,就容易找到原因了:

./a.out: error while loading shared libraries: demo.so: cannot open shared object file: No such file or directory

添加路径到库文件默认搜索路径

注意,除非必要,一般不建议这样做。比较好的方式是写入到CMakeLists或者Makefile中。

与头文件默认路径的添加方法类似,添加的命令如下:

#动态链接库搜索路径:
export LD_LIBRARY_PATH=XXX:$LD_LIBRARY_PATH
#静态链接库搜索路径:
export LIBRARY_PATH=XXX:$LIBRARY_PATH

三个维度的生效范围同头文件。

总结


一知半解能应付照猫画虎式写代码,但是一旦写错,出现问题,就无所适从。

解决问题的根本还是要彻底弄明白事情的来龙去脉,这样才能抽丝剥茧,处理问题游刃有余。

一个再简单不过的问题依然如此,对于复杂的问题,更需要静下心来,琢磨透彻了。

Linux下c/c++头文件和库文件的查找路径相关推荐

  1. linux+C环境下动态管理头文件和库文件

    本文共分三个部分:首先给出了一个简单的Makefile的例子,然后分别详细阐述了头文件和库文件的相关知识 1.一个Makefile的例: -L是指定链接时搜索路径,比如-L./等: -l是指定具体的库 ...

  2. Linux下gcc编译中关于头文件与库文件搜索路径相关问题

    如何指定GCC的默认头文件路径 网上偶搜得之,以之为宝:) 原地址:http://blog.chinaunix.net/u/28781/showart.php?id=401631 ========== ...

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

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

  4. linux应用开发:头文件和库文件的路径及使用

    1. 头文件 1)系统标准头文件位置: /usr/include下,以及安装库的头文件位置:/usr/local/include/ 如 #include<linux/can.h> 对应 / ...

  5. 嵌入式linux头文件,飞凌嵌入式知识汇092期:C工程的组织方式(头文件的功能)以及Linux下常用的头文件的作用...

    1.1每个C++/C程序通常分为两个文件.一个文件用于保存程序的声明(declaration),称为头文件.另一个文件用于保存程序的实现(implementation),称为定义(definition ...

  6. Linux找头文件规则,linux 头文件、库文件查找顺序

    linux 头文件.库文件查找顺序 默认分类 2009-11-14 01:24:28 阅读126 评论0 字号:大中小 linux 头文件.库文件查找顺序 2009-11-03 12:36 Inclu ...

  7. C语言的头文件和库文件(函数库)

    C语言的头文件和库文件(函数库) 分类: Unix环境高级编程 2011-04-17 14:37 2576人阅读 评论(1) 收藏 举报 语言cgcclinuxunix 在C语言中,头文件提供对常量的 ...

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

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

  9. Linux下构建自己的C++共享库并配合pkg-config生成链接选项

    Linux下构建自己的C++共享库并配合pkg-config生成链接选项 本文将以C++链表的新建.打印操作为例构建自己的共享库,并在实际调试代码时尝试使用.我们在做数据结构题时经常需要将链表打印出来 ...

  10. Linux下GCC生成和使用静态库和动态库详解(二)

    2.1准备好测试代码hello.h.hello.c和main.c: hello.h(见程序1)为该函数库的头文件. hello.c(见程序2)是函数库的源程序,其中包含公用函数hello,该函数将在屏 ...

最新文章

  1. 第二章:3、BP神经网络
  2. linux perl telnet安装,linux @ Net :: Telnet和vt-100终端的Perl问题
  3. 六、前端开发-JavaScript DOM
  4. Migration Necessary
  5. java十年技术栈[总结复习用]
  6. ASP.NET获取客户端、服务器端基础信息
  7. decode和case的用法
  8. js 浅拷贝(浅复制、浅克隆)、深拷贝(深复制、深克隆)
  9. python的前端和后端_python是前端还是后端
  10. vscode c++ code runner 配置 opencv
  11. 【MOOC】建筑智能化系统工程(南工职)(1)基础知识
  12. python之爬虫(十一) 实例爬取上海高级人民法院网开庭公告数据
  13. open drain和push pull
  14. Python自做的一个zabbix_sender程序
  15. oracle资产负债表重分类吗,资产负债表必须重分类的吗
  16. Leetcode——唯唯诺诺对并查集的初次相见
  17. 孰能浊以止,静之徐清
  18. 北洋 BTP-R380 打印机驱动
  19. fidder配合夜神模拟器进行抓包
  20. 利用勾子监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理

热门文章

  1. FLUENT-UDF日记-14-DEFINE_HEAT_FLUX
  2. 杰理之ANC 方案开发流程-篇
  3. 基于QT的网络音乐播放器(四)
  4. SpringBoot实现定时重启项目
  5. 国内外微服务技术架构演进背景
  6. 跳蚱蜢,青蛙跳杯子(python)
  7. 因果推断:断点回归应用于业务数据分析的思路
  8. linux USB驱动入门之发送SCSI指令INQUERY给U盘获取U盘信息
  9. 龙族幻想导入数据id_App Annie 7月报告:跑跑卡丁车、龙族幻想首次上榜,全球iOS收入前3均被腾讯包揽...
  10. 用户体验 | 如何度量用户体验?