关于C或C++的#include搜索路径,lib库搜索路径

1. 环境变量

  • 系统环境变量

我们知道,我们经常要设置一些环境变量,系统环境变量我们非常容易理解。其实我们在windows中经常容易接触。其实环境变量是一个非常广泛的一个概念,它与web应用程序中的web.config所处的角色很像。什么意思呢?就是说,程序(系统或应用)要运行的时候,它的基本业务逻辑可能是一定的,但是实现业务逻辑的时候有些设置性的东西却可以改变程序很多。如web应用程序,编译之后他的业务逻辑基本不会发生改变,但是如果你更改一些web.config中的参数,程序的运行就会发生相应的改变。这些设置。就像电视机上面调制一样。改变了设置会得到某些不同。
那么环境变量可以理解成设置的一种,为什么有不直接称为设置呢?因为它处于一种被动的境地。越多说越糊涂。
最常见的环境变量莫过于PATH,和ClassPATH,这个在设置jdk的时候就需要设置,这里的PATH变量指的是,当系统的接口接收到一个程序启动命令的时候,除了默认在当前目录下寻找那个可执行文件意外,还需要到那些地方寻找。有了这个设置,你就不需要一定要进入那个目录才能执行那个程序了。ClassPATH变量也差不多,它设置的是那些类似于动态库的路径,也就是说,程序在执行的时候,发现要引入动态库,那样就要在这个变量指定的地方去找。
在linux中,系统也有一个PATH变量。其实系统有一个文件是专门记录那些环境变量的。
1)/etc/profile,系统登录会执行这个文件在当前环境中引入那些变量。
2)还有 /home/ali/.bashrc 这个文件,简单的来说,/etc/profile是对全局有效的,而./bashrc是对当前用户有效.
3)还有一种设置方法,就是通过终端命令直接修改,我们知道前面两个文件其作用的方式就是当程序进入状态的时候,他们会被执行引入到当前空间,那么在当前状态下就会有这些变量,程序也就是可以使用它们。那么如果我们直接在内存中修改该他们,就可以起到暂时的作用。

  • 程序环境变量

根据前面我们说过环境变量的作用和意义,就很容易推出,普通的程序也可以有环境变量。按照前面系统的环境变量起作用的模式。应用程序,也可以有一些配置文件来持久保存这些环境变量,在程序执行的时候,这些变量会通过某种方式进入程序执行的空间,这样程序执行的时候就可以使用这些变量了。而同样,我们可以改变这些变量来“适量”的改变我们的程序。

GCC就是这样一个程序。很多时候,应用程序需不需要环境变量机制,关键看他是否有很多的选择性,GCC就是一个这样的程序。最常用GCC程序环境变量就是include搜索路径,以及库搜索路径。它们分别在编译和连接时使用。

2. include搜索路径

通常,使用C/C++开发程序时,会使用头文件,并且有头文件的实现。这时有三类文件,使用头文件的源文件,头文件,实现头文件的源文件。编译时,头文件和源文件一起就可以了。通常,他们是在同一目录下的,所以不会有什么问题。

但是,当你使用到了系统自身的一些头文件的时候,你需要引入一些头文件,而这些文件不在当前目录下,使用绝对地址是一个办法,但是是一个极差的办法。所以GCC就有一个搜索机制。就是在规定的那些文件夹下,搜索你所引入的那个头文件。这样解决了问题。这个环境变量叫着CPLUS_INCLUDE_PATH。属于GCC,与系统无关。我们看看GCC头文件搜索路径。

#include “headfile.h”引用头文件的搜索顺序为:

  • 先搜索当前目录
  • 然后搜索-I指定的目录
  • 再搜索gcc的环境变量CPLUS_INCLUDE_PATH(C程序使用的是C_INCLUDE_PATH)
  • 最后搜索gcc的内定目录:/usr/include,/usr/local/include,/usr/lib/gcc/x86_64-redhat-linux/4.1.1/include
    各目录存在相同文件时,先找到哪个使用哪个。

#include <headfile.h>引用头文件的搜索顺序为:
1.先搜索-I指定的目录
2.然后搜索gcc的环境变量CPLUS_INCLUDE_PATH
3.最后搜索gcc的内定目录:/usr/include,/usr/local/include,/usr/lib/gcc/x86_64-redhat-linux/4.1.1/include
各目录存在相同文件时,先找到哪个使用哪个。

注:#include <>方式不会搜索当前目录!

这里要说下include的内定目录,它不是由$PATH环境变量指定的,而是由g++的配置prefix指定的(知道它在安装g++时可以指定,不知安装后如何修改的,可能是修改配置文件,需要时再研究下):

# g++ -v

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 

在安装g++时,指定了prefix,那么内定搜索目录就是:Prefix/include,Prefix/local/include,Prefix/lib/gcc/–host/–version/include。编译时可以通过-nostdinc++选项屏蔽对内定目录搜索头文件。

3. 库搜索路径

在编译之后,程序要进行链接操作。前面指出,链接不管是动态还是静态,GCC必须确认“真的有”那些头文件的实现。于是就需要定位找到那些文件。与include的情景差不多,使用绝对目录是可以的,但不适于管理。于是就出现了lib搜索路径环境变量LIBRARY_PATH。

编译时,库文件搜索路径:

  • gcc会去找-L
  • 再找gcc的环境变量LIBRARY_PATH
  • 再找内定目录 /lib /usr/lib /usr/local/lib,这是当初compile gcc时写在程序内的(不可配置的?)

运行时,动态库搜索路径:

  • 编译目标代码时指定的动态库搜索路径(这是通过gcc 的参数"-Wl,-rpath,“指定。当指定多个动态库搜索路径时,路径之间用冒号”:"分隔)
  • 环境变量LD_LIBRARY_PATH指定的动态库搜索路径(当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔)
  • 配置文件/etc/ld.so.conf中指定的动态库搜索路径;
  • 默认的动态库搜索路径/lib;
  • 默认的动态库搜索路径/usr/lib。

注:不要把这个与库文件搜索路径混淆了,程序执行时有linux系统/usr/bin/ld程序控制的过程,这里只是顺带介绍,以完整程序的整个生命周期:编译、链接、启动,装载(包括动态装载)、执行。

我们在对GCC这个命令总结一下。编译的时候,使用-I命令,装入include搜索路径;连接的时候,使用-l、-L命令,可以装入连接搜索路径或文件;
执行的时候,在当初编译连接时候,使用-Wl可以装入动态库的搜索路径。

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值