用arm-linux交叉编译器使用动态库时搜索标准路径是什么?

1. 链接和运行时库文件搜索路径到设置        库文件在链接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的。通常 Linux 系统把 /lib 和 /usr/lib 两个目录做为默认的库搜索路径,因此使用这两个目录中的库时不须要进行设置搜索路径便可直接使用。对于处于默认库搜索路径以外的库,须要将库的位置添加到 库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:

            须要注意的是:这种搜索路径的设置方式对于程序链接时的库(包括共享库和静态库)的定位已经足够了,可是对于使用了共享库的程序的执行仍是不够的。这是因 为为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,因此是直接读取库列表文件

,简单的说,它的做用就是将/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache 以供使用。所以当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增长新的库路径后,须要运行一下 /sbin/ldconfig使全部的库文件都被缓存到ld.so.cache中,若是没作,即便库文件明明就在/usr/lib下的,也是不会被使用 的,结果编译过程当中抱错,缺乏xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。

            在程序链接时,对于库文件(静态库和共享库)的搜索路径,除了上面的设置方式以外,还能够经过 -L 参数显式指定。由于用 -L 设置的路径将被优先搜索,因此在链接的时候一般都会以这种方式直接指定要链接的库的路径。

版本的改变,这有时会给应用程序带来兼容性的问题,形成某些程序运行不正常。为了不出现上面的这些状况,在 GTK+ 及其依赖库的安装过程当中对于库的搜索路径的设置将采用另外一种方式进行。这种设置方式不须要 root 权限,设置也简单。

2.交叉编译时候如何配置链接库的搜索路径

        交叉编译的时候不能使用本地(i686机器,即PC机器,研发机器)机器上的库,可是在作编译连接的时候默认的是使用本地库,即/usr/lib, /lib两个目录。所以,在交叉编译的时候,要采起一些方法使得在编译连接的时候找到须要的库。

        首先,要知道:编译的时候只须要头文档,真正实际的库文档在连接的时候用到。 (这是个人理解,假若有不对的地方,敬请网上各位大侠指教) 而后,讲讲如何在交叉编译连接的时候找到须要的库。

    (1)交叉编译时候直接使用-L和-I参数指定搜索非标准的库文档和头文档的路径。例如:

)。一般状况下推荐仍是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,而且该库的路径信息保存在可执行文件中,运行时它会直接到该路 径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。

Linux下动态库使用小结

1. 静态库和动态库的基本概念
        静态库,是在可执行程序链接时就已经加入到执行码中,在物理上成为执行程序的一部分;使用静态库编译的程序运行时无需该库文件支持,哪里均可以用,可是生 成的可执行文件较大。动态库,是在可执行程序启动时加载到执行程序中,能够被多个可执行程序共享使用。使用动态库编译生成的程序相对较小,但运行时须要库 文件支持,若是机器里没有这些库文件就不能运行。

bad》)。一般状况下推荐仍是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,而且该库的路径信息保存在可执行文件中,运行时它会直 接到该路径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。

}

本文记录了根文件系统的一些知识点,Busybox 工具的使用和 最小根文件系统的制作。

根文件系统是特殊用途的文件系统,必须属于某种文件系统格式。那么文件系统是用来干嘛的?

  • 首先,存储设备(块设备,像硬盘、 flash 等) 是分块(扇区)的,物理上底层去访问存储设备时是按照块号(扇区号)来访问的。这就很麻烦。

  • 其次,文件系统是一些代码,是一套软件,这套软件的功能就是对存储设备的扇区进行管理,将这些扇区的访问变成了对目录和文件名的访问。我们在上层按照特定的目录和文件名去访问一个文件时,文件系统会将这个目录 + 文件名转换成对扇区号的访问。

  • 最后,不同的文件系统的差异在于对这些扇区的管理策略和方法不同,如坏块管理、 碎片管理。

  • dev 目录下的设备文件。在 linux 中一切皆是文件,硬件设备被虚拟化成一个设备文件。

  • sys 和 proc 目录。可以为空但是必须有,和驱动有关。 属于 linux 中的虚拟文件系统。

  • etc 目录。存放运行时配置文件。 /etc 目录下的所有配置文件会直接或者间接的被 /linuxrc 所调用执行,完成操作系统的运行时配置。 etc 目录是制作 rootfs 的关键。

  • lib 目录下放的是当前操作系统中的动态和静态链接库文件。

    • 使用专用工具软件制作的可供烧录的镜像文件

    • 镜像中包含了根文件系统中的所有文件

    • 烧录此镜像类似于对相应分区格式化。

    • 镜像文件系统具有一定的格式,格式是内化的,跟文件名后缀是无关的。

    • 根文件系统其实就是一个包含特定内容的文件夹而已

    • 根文件系统可由任何一个空文件夹添加必要文件构成而成

    • 根文件系统的雏形就是在开发主机中构造的文件夹形成的

    • 镜像文件形式的根文件系统主要目的是用来烧录到块设备上,设备上的内核启动后去挂载它。镜像文件形式的根文件系统是由文件夹形式的根文件系统使用专用的镜像制作工具制作而成的。

    • 最初在开发主机中随便 mkdir 创建了一个空文件夹,然后向其中添加一些必要的文件(包括etc 目录下的运行时配置文件、/bin 等目录下的可执行程序、 /lib 目录下的库文件等···)后就形成了一个文件夹形式的 rootfs。 然后这个文件夹形式的 rootfs 可以被 kernel 通过 nfs 方式来远程挂载使用,但是不能用来烧录块设备。我们为了将这个 rootfs 烧录到块设备中,于是用一些专用的软件工具,将其制作成可供烧录的一定格式的根文件系统镜像。

    • 文件夹形式的 rootfs 是没有格式的,制作成镜像后就有了一定的 rootfs 格式了, 格式是由我们的镜像制作过程和制作工具来决定的。 每一种格式的镜像制作工具的用法都不同。

  1. busybox是一个C语言写出来的项目,里面包含了很多.c文件和.h文件。

  2. busybox 这个程序开发出来就是为了在嵌入式环境下构建根文件系统(以下简称 rootfs)使用的,也就是说他就是专门开发的 init 进程应用程序。

  3. busybox 为当前系统提供了一整套的 shell 命令程序集。譬如 vi、cd、mkdir、ls 等。在桌面版的 linux 发行版(譬如 ubuntu、redhat等)中 vi、cd、ls 等都是一个一个的单独的应用程序。但是在嵌入式 linux 中,为了省事我们把 vi、cd 等所有常用的 shell 命令集合到一起构成了一个 shell 命令包,起名叫 busybox。

  4. Busybox 在编写过程中对文件大小进行了优化,并考虑了系统资源有限(比如内存等)的情况。与一般的 GNU 工具集动辄几 M 的体积相比,动态链接的 Busybox 只有几百 K,即使是采用静态链接也只有1 M 左右。Busybox 按模块设计,可以很容易地加入、去除某些命令,或增减命令的某些选项。

  • linuxrc 是一个可执行的应用程序。 是应用层的,和内核源码一点关系都没有。

  • linuxrc 如果是静态编译连接的那么直接可以运行;如果是动态编译连接的那么我们还必须给他提供必要的库文件才能运行。但是因为我们 linuxrc 这个程序是由内核直接调用执行的, 因此用户没有机会去导出库文件的路径,因此实际上 linuxrc 没法动态连接,一般都是静态连接的。

  • linuxrc 执行时引出用户界面。操作系统启动后在一系列的自检运行配置之后,最终会给用户一个操作界面(cmdline 或 GUI),这个用户操作界面就是由 /linuxrc 带出来的。用户界面等很多事并不是在 /linuxrc 程序中负责的,用户界面有自己专门的应用程序,但是用户界面的应用程序是直接或者间接的被 linuxrc 调用执行的。用户界面程序和其他的应用程序就是进程 2、3、4 ···,这就是我们说的进程 1(init 进程,也就是 /linuxrc)是其他所有应用程序进程的祖宗进程。

  • linuxrc 负责系统启动后的配置。操作系统启动起来后也不能直接用,要配置下。操作系统启动后的应用层的配置(一般叫运行时配置,英文简写 etc),是为了让我们的操作系统用起来更方便,更适合个人的爱好或者实用性。

  • VFS 是借鉴了文件系统的设计理念(通过文件系统将底层难以管理的物理磁盘扇区式访问,转换成目录 + 文件名的方式来访问),将硬件设备的访问也虚拟化成了对目录 + 文件的访问。所以有了 VFS 后我们可以通过设备文件(如/dev/mmcblk0p2) 的方式来访问系统中的硬件设备。

  • VFS 将对硬件设备的访问和对普通文件的访问给接口统一化了(linux 中一切皆是文件)。VFS 成了一个隔离层,隔离了下层的不同文件系统的差异性,对上层应用提供一个统一的接口。

  • VFS 将不同文件系统和下层硬件设备(块设备)驱动之间的细节也给屏蔽了。不同类型的文件系统在本身设计时是 不用考虑各种不同的硬件设备的具体操作差异的,这里有一个类似于 VFS 的设计理念。

  • VFS 机制和 rootfs 挂载与其他文件系统的挂载都是有关联的。内核中有一些 sys proc 这种虚拟文件系统,也是和 VFS 机制有关。 /dev/目录下的设备文件都和 VFS 有关。


主要是实现applets框架的文件
与压缩有关的命令源文件,例如:bzip2、gzip等
自带的一些默认配置文件
与控制台相关的一些命令,例如:setconsole
常用的核心命令,例如:cat、rm等
常用的编辑命令,例如:vi、diff等
用于查找的命令,例如:find、grep等
init进程的实现源文件
与网络相关的命令,例如:telnetl、arp等
与shell相关的实现,例如:ash、msh等
Linux下常用的命令,主要是与文件系统相关的,例如:mkfs_ext2等
  1. 解压 Busybox 源码后,进入 Busybox 目录,打开图像界面配置菜单:

  2. 进入配置菜单后,进行相关配置。我们可以静态或者动态编译Busybox,选择动态编译,使得Busybox可执行文件更小,选项开关如下:

  3. 经过上诉步骤之后,这个时候选择配置界面的 Exit 退出,保存刚刚的配置,之后就可以看到在源代码目录下多了一个 .config 文件。.config 配置文件里面的内容记录了我们刚刚选中的功能。如下所示:

    每一个都是名值对的形式,名称是一个环境变量,后面的值如果为 Y 代表选中,注释行代表裁减掉的功能。

  4. 生成的文件将默认安装到目录 _install。

BusyBox 编译成功后,在 目录 _install 下可以看到生成的 文件,我们可以继续添加文件,做成一个最小根文件系统。或是直接操作 Busybox 这个可执行文件,用法如下:

其中 命令 是编译 BusyBox 时选中的命令,用法同 Linux 下的命令,只是加上 ./BusyBox 。比如我们在编译时选中的 flashcp 命令,编译成功后,我们把 BusyBox 放到开发板中,就可以直接使用新加入的 flashcp 命令了,而不用重新编译和烧录根文件系统到开发板中:

}

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

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

  • (3)更改gcc的specs文件来自定义gcc的任何选项。

Specs是gcc的配置文件。这种修改方法功能最强大,但是难度和风险也最大,因为gcc的spec文件比较晦涩难懂,我也暂时不会修改,只是先给大家介绍有这种方法的存在。

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

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

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

  • (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的默认头文件搜寻路径。

常用头文件目录的说明:

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

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

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

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

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

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

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

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

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

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

2.1、链接时库的搜寻路径

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

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

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

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

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

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

  • (2) 编译时使用环境变量 “LD_RUN_PATH”指定运行时动态链接库的搜寻路径,硬编码进ELF文件 “RPATH”选项:
  • (3)使用环境变量 “LD_LIBRARY_PATH”指定运行时动态链接库的搜寻路径:
  • (4)使用配置文件“/etc/ld.so.conf”指定运行时动态链接库的搜寻路径:

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

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

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

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

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

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

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

}

我要回帖

更多关于 arm编译 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信