3.3 Linux头文件和库的搜索路径

1、FAQ

1.1、glibc安装时.so库文件和.h头文件都安装到什么文件夹,gcc怎么能正确的找到相应的文件夹?

当我们在build gcc时设定–prefix=/path/,则gcc安装到/path/,gcc默认会在/path/lib/路径下搜寻库,在/path/include/路径下搜寻头文件。
例如,一般linux系统把gcc和glibc都安装到/usr/目录,所以gcc可执行文件在/usr/bin目录下,而glibc的库文件在/usr/lib目录下,glibc的头文件在/usr/include目录下。
当然上述的关系并不是一定的,在安装gcc和glibc的时候可以手工指定。可以使用命令“gcc -print-search-dirs”来查看gcc库的搜索路径:

3.3 Linux头文件和库的搜索路径_第1张图片

可以使用以下几种方法来更改gcc默认搜寻的库路径和头文件路径:

  • (1)使用 “gcc –nostdlib –Lusrlibpath”来改变gcc的默认库搜索路径,使用 “gcc –nostdinc –Iusrincpath”来改变gcc的默认头文件搜索路径。
  • (2)使用“gcc –Wl, –sysroot=” 来改变gcc的默认库搜索路径。
  • (3)更改gcc的specs文件来自定义gcc的任何选项。

Specs是gcc的配置文件。这种修改方法功能最强大,但是难度和风险也最大,因为gcc的spec文件比较晦涩难懂,我也暂时不会修改,只是先给大家介绍有这种方法的存在。
使用“gcc –v“命令查看gcc specs的路径:

2

也有些安装的gcc使用的是内置的spec,而没有外置的spec文件:

3.3 Linux头文件和库的搜索路径_第2张图片

对于内置的spec,可以使用命令“gcc -dumpspecs “查看具体的spec内容:

3.3 Linux头文件和库的搜索路径_第3张图片

也可以使用“gcc -specs= “来指定gcc的spec文件。

  • (4) gcc默认的配置是否在build时由configure命令传入的?

使用“gcc –v“命令可以查看gcc的configure值,关于configure选项的说明在gcc-4.1.0\gcc\doc\install.texi文件中有详细描述。

3.3 Linux头文件和库的搜索路径_第4张图片

1.2、程序链接时,链接库的搜寻路径有哪些?

链接时,库的搜寻路径的配置有以下方法:(具体使用可参见实例一章的描述)

  • (1) 使用 “gcc –Llibpath –llibname”指定链接库搜寻路径。
  • (2)使用环境变量“LIBRARY_PATH” 指定链接库搜寻路径。
  • (3)使用ld连接脚本中的 “SEARCH_DIR” 指定链接库搜寻路径。

1.3、程序运行时,动态链接库的搜寻路径有哪些?

链接时,库的搜寻路径的配置有以下方法:(具体使用可参见实例一章的描述)

  • (1) 编译时使用 “gcc –Wl,-rpath”指定运行时动态链接库的搜寻路径,硬编码进ELF文件 “RPATH”选项。
  • (2) 编译时使用环境变量 “LD_RUN_PATH”指定运行时动态链接库的搜寻路径,硬编码进ELF文件 “RPATH”选项。
  • (3)使用环境变量 “LD_LIBRARY_PATH”指定运行时动态链接库的搜寻路径。
  • (4)使用配置文件“/etc/ld.so.conf”指定运行时动态链接库的搜寻路径。
  • (5)使用运行时动态链接库的默认搜寻路径“/lib、/usr/lib”。

1.4、程序编译时,头文件的搜寻路径有哪些?

编译时,头文件的搜寻路径的配置有以下方法:(具体使用可参见实例一章的描述)

  • (1) 编译时使用“gcc –I incpath”指定头文件搜寻路径。
  • (2) 编译时使用环境变量 “C_INCLUDE_PATH”指定头文件搜寻路径。
  • (3) 编译时使用gcc的默认头文件搜寻路径。

常用头文件目录的说明:

  • (1)、/usr/src/linux/include:

/usr/src/linux/是内核源码路径,/usr/src/linux/include包含的是内核头文件,一般在编译模块时使用。

  • (2)、/usr/include

/usr/include路径主要是glibc的头文件,是用来编译用户态文件的。但是/usr/include其中也包含内核头文件所需的linux/、asm/文件夹,但是这两个文件夹主要是用来做一些兼容性用的,真正用到内核头文件还是要用/usr/src/linux/include。

1.5、制作交叉编译器时,各项搜寻路径的配置?

制作交叉编译器时,需要关注相关四种路径的配置:编译时链接的库文件路径、编译时用到的头文件路径、编译时用到的二进制工具路径、编译时指定的动态加载器的名称路径。

  • (1)、编译时链接的库文件路径:

如果不指定,应该是和安装路径相关的默认路径。如果要指定,可以在编译binutils中ld的时候,使用“LIB_PATH”选项指定:

3.3 Linux头文件和库的搜索路径_第5张图片

  • (2)、编译时用到的头文件路径:
  • (3)、编译时用到的二进制工具路径:

默认二进制工具的路径,可以使用以下命令查看:

7

使用指定的二进制工具,可以使用“gcc -B”选项:

  • (4)、编译时指定的动态加载器的路径和名称:

硬编码进elf的动态加载器路径和名称,由gcc spec文件指定:

3.3 Linux头文件和库的搜索路径_第6张图片

2、实例操作

生成两个.c文件:

cat >say.c<<eof
#include "stdio.h"
void say()
{
printf("Say!");
}
Eof

cat >test.c <<eof
#include "stdio.h"
void say();
main(){
say();
}
eof

2.1、链接时库的搜寻路径

将say.c编译成libsay.so,再在编译test.c时来链接libsay.so,用以测试gcc链接时库的搜寻路径。

9

  • (1)使用 “gcc –Llibpath –llibname”指定链接库搜寻路径:

3.3 Linux头文件和库的搜索路径_第7张图片

  • (2)使用环境变量“LIBRARY_PATH” 指定链接库搜寻路径:

    3.3 Linux头文件和库的搜索路径_第8张图片

  • (3)使用ld连接脚本中的 “SEARCH_DIR” 指定链接库搜寻路径:

使用“ld –verbose”命令查看gcc的默认链接脚本中SEARCH_DIR参数,当然你也可以使用 “ld –Txxx.lds”来指定链接脚本。

3.3 Linux头文件和库的搜索路径_第9张图片

拷贝libsay.so到SEARCH_DIR指定路径,并链接测试:

3.3 Linux头文件和库的搜索路径_第10张图片

2.2、运行时动态加载库的搜寻位置

  • (1) 编译时使用 “gcc –Wl,-rpath”指定运行时动态链接库的搜寻路径,硬编码进ELF文件 “RPATH”选项:

3.3 Linux头文件和库的搜索路径_第11张图片

使用readelf文件查看elf文件中的硬编码运行时库搜寻路径:

3.3 Linux头文件和库的搜索路径_第12张图片

  • (2) 编译时使用环境变量 “LD_RUN_PATH”指定运行时动态链接库的搜寻路径,硬编码进ELF文件 “RPATH”选项:

3.3 Linux头文件和库的搜索路径_第13张图片

  • (3)使用环境变量 “LD_LIBRARY_PATH”指定运行时动态链接库的搜寻路径:

3.3 Linux头文件和库的搜索路径_第14张图片

  • (4)使用配置文件“/etc/ld.so.conf”指定运行时动态链接库的搜寻路径:

    3.3 Linux头文件和库的搜索路径_第15张图片

  • (5)使用运行时动态链接库的默认搜寻路径“/lib、/usr/lib”:

3.3 Linux头文件和库的搜索路径_第16张图片

生成一个.c文件和一个.h文件:

cat >test1.c <<eof
> #include "test1.h"
> void main()
> {
> printf("Test .h include!\n");
> }
> eof

cat >test1.h <<eof
> #include "stdio.h"
> eof

2.3、程序编译时,头文件的搜寻路径有哪些?

  • (1) 编译时使用“gcc –I incpath”指定头文件搜寻路径:

    3.3 Linux头文件和库的搜索路径_第17张图片

  • (2) 编译时使用环境变量 “C_INCLUDE_PATH”指定头文件搜寻路径:

3.3 Linux头文件和库的搜索路径_第18张图片

  • (3) 编译时使用gcc的默认头文件搜寻路径:

gcc的默认头文件搜寻路径设置方法还没弄明白。但是可以使用以下命令查看:

3.3 Linux头文件和库的搜索路径_第19张图片

使用默认路径来编译:

3.3 Linux头文件和库的搜索路径_第20张图片

3、参考资料

你可能感兴趣的:(Linux,驱动三板斧(旧文,2.6内核))