Linux下gcc编译中关于头文件与库文件搜索路径相关问题
如何指定GCC的默认头文件路径
网上偶搜得之,以之为宝:)
原地址:http://blog.chinaunix.net/u/28781/showart.php?id=401631
===============================================================================
在交叉编译的时候我们需要用到其他的库,在config时候可以通过“-I”来指定头文件目录,但是每次都需要设置的话难免有些麻烦,找到一个简单的方法。看下文的红色部分。
有大量的环境变量可供设置以影响 GCC 编译程序的方式。利用这些变量的控制也可使用合适的命令行选项。一些环境变量设置在目录名列表中。这些名字和 PATH 环境变量使用的格式相同。特殊字符 PATH_SEPARATOR (安装编译程序的时候定义)用在目录名之间。在 UNIX 系统中,分隔符是冒号,而 Windows 系统中为分号。
C_INCLUDE_PATH
编译 C 程序时使用该环境变量。该环境变量指定一个或多个目录名列表,查找头文件,就好像在命令行中指定 -isystem 选项一样。会首先查找 -isystem 指定的所有目录。
==>也见 CPATH 、 CPLUS_INCLUDE_PATH 和 OBJC_INCLUDE_PATH 。
COMPILER_PATH
该环境变量指定一个或多个目录名列表,如果没有指定 GCC_EXEC_PREFIX 定位子程序,编译程序会在此查找它的子程序。
==>也见 LIBRARY_PATH 、 GCC_EXEC_PREFIX 和 -B 命令行选项。
CPATH
编译 C 、 C++ 和 Objective-C 程序时使用该环境变量。该环境变量指定一个或多个目录名列表,查找头文件,就好像在命令行中指定 -l 选项一样。会首先查找 -l 指定的所有目录。
==>也见 C_INCLUDE_PATH 、 CPLUS_INCLUDE_PATH 和 OBJC_INCLUDE_PATH 。
CPLUS_INCLUDE_PATH
编译 C++ 程序时使用该环境变量。该环境变量指定一个或多个目录名列表,查找头文件,就好像在命令行中指定 -isystem 选项一样。会首先查找 -isystem 指定的所有目录。
==>也见 CPATH 、 C_INCLUDE_PATH 和 OBJC_INCLUDE_PATH 。
DEPENDENCIES_OUTPUT
为文件名设置该环境变量会让预处理程序将基于依赖关系的 makefile 规则写入文件。不会包括系统头文件名字。
如果环境变量设置为单名,被看作是文件名字,而依赖关系规则的名字来自源文件名字。如果定义中有两个名字,则第二个名字是用作依赖关系规则的目标名。 设置该环境变量的结果和使用命令行选项 -MM 、 -MF 和 -MT 的组合是一样的。
==>也见 SUNPRO_DEPENDENCIES 。
GCC_EXEC_PREFIX
如果定义了该环境变量,它会作为编译程序执行的所有子程序名字的前缀。例如,如果将变量设置为 testver 而不是查找 as ,汇编器首先会在名字testveras 下查找。如果在此没有找到,编译程序会继续根据它的普通名进行查找。可在前缀名中使用斜线指出路径名。
GCC_EXEC_PREFIX 的默认设置为 prefix /lib/gcc-lib/ ,这里的 prefix 是安装编译程序时 configure 脚本指定的名字。该前缀也用于定位标准连接程序文件,包含进来作为可执行程序的一部分。
如果使用 -B 命令行选项,会重写该设置。
==>也见 COMPILER_PATH 。
LANG 该环境变量用于指出编译程序使用的字符集,可创建宽字符文字、串文字和注释。
定义 LANG 为 C-JIS ,指出预处理程序将多字节字符按照 JIS (日语工业标准)字符进行解释。 C-SJIS 可用来指出 Shift -JIS 字符而 C-EUCJP 指出日文 EUC 。
如果没有定义 LANG ,或定义为不可识别,函数 mblen() 被用来确定字符宽度,而 mbtowc() 用来将多字节序列转换为宽字符。
LC_ALL 如果设置,该环境变量的值重写 LC_MESSAGES 和 LC_CTYPE 的所有设置。
LC_CTYPE 该环境变量指出引用串中定义的多字节字符的字符分类。主要用于确定字符串的字符边界,字符编码需要用引号或转义符,可被错误地解释为字符串的结尾或特殊字 符串。对 Australian English ,可将它设置为 en_AU ; 对 Mexican Spanish ,可将它设置为 es_MX。如果没有设置该变量,默认为 LANG 变量的值,或如果没有设置 LANG ,那就使用 C 英语行为。也见 LC_ALL 。
LC_MESSAGES 该环境变量指出编译程序使用何种语言发出诊断消息。对 Australian English ,可设置为 en_AU ; 对 MexicanSpanish ,可设置为 es_MX 。如果变量没有设置,使用 LANG 变量的默认值,或如果没有设置 LANG ,那就使用 C英语行为。也见 LC_ALL 。
LD_LIBRARY_PATH 该环境变量不会影响编译程序,但程序运行的时候会有影响。变量指定一个目录列表,程序会查找该列表定位共享库。只有当未在编译程序的目录中找到共享库的时候,执行程序必须设置该变量。
LD_RUN_PATH 该环境变量不会影响编译程序,但程序运行的时候会有影响。该变量在运行时指出文件的名字,运行的程序可由此得到它的符号名字和地址。地址不会重新载入,因而可能符号引用其他文件中的绝对地址。这和 ld 工具使用 -R 选项完全一样。
LIBRARY_PATH
该环境变量可设置为一个或多个目录名字列表,连接程序会搜寻该目录,以查找特殊连接程序文件,和由 -l (字母 l )命令行选项指定名字的库。 由 -L 命令行选项指定的目录在环境变量的前面,首先被查找。
==>也见 COMPILER_PATH 。
OBJC_INCLUDE_PATH
在编译 Objective-C 程序的时候使用该环境变量。一个或多个目录名的列表由环境变量指定,用来查找头文件,就好像在命令行中指定 -isystem 选项一样。所有由 -isystem 选项指定的目录会首先被查找。
==>也见 CPATH 、 CPLUS_INCLUDE_PATH 和 C_INCLUDE_PATH 。
SUNPRO_OUTPUT
为文件名设置该环境变量会令预处理程序将基于依赖关系的 makefile 规则写入文件。会包含系统头文件名。 如果环境变量被设置为单个名字,它将会被当作文件名,依赖关系规则中的名字将由源文件的名字中获得。如果定义中有两个名字,第二个名字就是依赖关系规则中的目标名。 设置该环境变量的结果与在命令行中使用参数 -M 、 -MF 和 -MT 的效果一样。
==>参见 DEPENDENCIES_OUTPUT 。
TMPDIR
这个变量包含了供编译程序存放临时工作文件的目录的路径名。这些文件通常在编译过程结束时被删除。这种文件的一个例子就是由预处理程序输出并输入给编译程序的文件。
linux 默认的include在哪?
#include <linux/module.h> 中的module.h默认是在哪个目录下呢?我在/usr/include/linux下并没有找到这个文件。
另外想问一下,不同内核版本的linux头文件是不是一样的。比如:我在2.6.20内核的系统上,用2.6.10的头文件会不会有问题。
网友回复:
1
我的 module.h是在 内核编译好了的目录下的,不是在/usr/include/linux下,
2
在2.6.20内核的系统上,用2.6.10的头文件应该会有问题,内核的头文件和 当前系统运行的内核不一致。
网友回复:你引用的是内核下的头文件.
不在/usr/include下.
在: /usr/src/kernels/2.6.18-8.el5-x86_64/include/linux/module.h 下面... 中间的版本号是不一样的...你选你的就行了..
网友回复:请问楼上为什么是在/usr/src/kernels/2.6.18-8.el5-x86_64/include/linux/module.h呢?我查了一下环境变量,没有看到关于头文件的环境变量。gcc是如何知道头文件的位置的?
网友回复:这个问题很好,
你需要看看linux kernel的Makefile文件了。在什么地方找头文件,它说了算。:)
网友回复:你的程序是驱动之类的内核层的吧?
它调用的头文件就应该是内核源码里面的include了。一般的系统都把内核源码放在/usr/src下面,假如是自己编译的内核的话,也可以放在别处的。 至于gcc到哪里去找头文件,就看makefile了,或者直接用gcc命令的话,要加上-I来指定目录。
网友回复:楼上,可是我的makefile里没有指定include呀,gcc是怎么找到头文件的?
网友回复:gcc是怎么找到头文件的?
================================
回答了这个问题,LZ就明白了一切了,GCC找头文件有三种策略:
1.会在默认情况下指定到/usr/include文件夹(更深层次的是一个相对路径,GCC可执行程序的路径是/usr/bin,那么它在实际工作时指定头文件头径是一种相对路径方法,换算成绝对路径就是/usr/include)
2.GCC还使用了-I指定路径的方式,这一点大家都知道
3.还可以使用一个参数来指示GCC不搜索系统默认路径,这个参数我忘了,你搜一下就知道了
在编译驱动模块时,由于非凡的需求必须强制GCC不搜索系统默认路径,也就是不搜索/usr/include,要自己用-I参数来指定内核头文件路径,这个时候必须在Makefile中指定两个参数,一个是内核头文件路径,一个是强制GCC不搜索系统默认路径。在编译内核时,必须使用一个参数(强制GCC不搜索系统默认路径),否则就会引起混乱。
明白了上面的原理,LZ自己应该可以找到答案了吧????
来自:http://www.itzhe.cn/news/20071216/31985.html
Linux指定动态库路径
众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib。动态库被创建后,一般都复制到这两个目录中。当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函 数,以及该动态库的其它资源了。在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定。
方法一:在配置文件/etc/ld.so.conf中指定动态库搜索路径。
可以通过编辑配置文件/etc/ld.so.conf来指定动态库的搜索路径,该文件中每行为一个动态库搜索路径。每次编辑完该文件后,都必须运行命令ldconfig使修改后的配置生效。我们通过例1来说明该方法。 例1: 我们通过以下命令用源程序pos_conf.c(见程序1)来创建动态库 libpos.so,详细创建过程请参考文[1]。 # gcc -c pos_conf.c
#include <stdio.h>
接着通过以下命令编译main.c(见程序2)生成目标程序pos。 # gcc -o pos main.c -L. -lpos void pos(); 然后把库文件移动到目录/root/test/conf/lib中。 # mkdir -p /root/test/conf/lib 最后编辑配置文件/etc/ld.so.conf,在该文件中追加一行"/root/test/conf/lib"。 运行程序pos试试。 # ./pos 出错了,系统未找到动态库libpos.so。找找原因,原来在编辑完配置文件/etc/ld.so.conf后,没有运行命令ldconfig,所以刚才的修改还未生效。我们运行ldconfig后再试试。 # ldconfig 程序pos运行成功,并且打印出正确结果。
方法二:通过环境变量LD_LIBRARY_PATH指定动态库搜索路径。
通过设定环境变量LD_LIBRARY_PATH也可以指定动态库搜索路径。当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔。下面通过例2来说明本方法。 例2: 我们通过以下命令用源程序pos_env.c(见程序3)来创建动态库libpos.so。 # gcc -c pos_env.c #include <stdio.h> 测试用的可执行文件pos可以使用例1中的得到的目标程序pos,不需要再次编译。因为pos_conf.c中的函数pos和pos_env.c中的函数pos 函数原型一致,且动态库名相同,这就好比修改动态库pos后重新创建该库一样。这也是使用动态库的优点之一。 然后把动态库libpos.so移动到目录/root/test/conf/lib中。 # mkdir -p /root/test/env/lib 我们可以使用export来设置该环境变量,在设置该环境变量后所有的命令中,该环境变量都有效。 例如: # export LD_LIBRARY_PATH=/root/test/env/lib 但本文为了举例方便,使用另一种设置环境变量的方法,既在命令前加环境变量设置,该环境变量只对该命令有效,当该命令执行完成后,该环境变量就无效了。如下述命令: # LD_LIBRARY_PATH=/root/test/env/lib ./pos 程序pos运行成功,并且打印的结果是"/root/test/env/lib",正是程序pos_env.c中的函数pos的运行结果。因此程序pos搜索到的动态库是/root/test/env/lib/libpos |
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。