LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: vanhu

LFS工具链构建的几个问题

[复制链接]
发表于 2006-3-5 08:22:27 | 显示全部楼层
Post by good02xaut
怎么就这么难呢,俺发现俺的表达越来越成问题了:confused:
ld也好,ld.so也好,我只想说,谈到ld的时候就说ld,不要和ld.so然到一起。

ld的搜索路径,还是搜索方法,就单个的说,答案我给过了。
ld.so的搜索路径,还是搜索方法,就单个的说,答案我也给过了。

静态链接器就是静态链接器,有自己的功能,何必动辄就和人家动态链接器沾亲带故的呢?:)
动态链接器一样:)

如果开3个帖子或许更好:
[color="Red"]1.静态链接器ld的搜索路径如何设定?搜索规则是什么?
[color="red"]2.动态链接器ld.so的搜索路径如何设定?搜索规则是什么?
[color="red"]3.静态链接器ld和动态链接器ld.so有什么联系?

其中1我曾经开过帖子了:)
这么描述,应该清楚我的意思了吧?汗。。。


lz不是猜测这二者是否有同样的这和那吗?我觉得没有必要分析的时候一起来。本来没有关系的东西(其实有联系),联系起来更不好寻找答案。仅此而已:)


我比较笨,你就多说一点吧。。。。

1. 静态的链接器 ld 的搜索路径如何设定?搜索规则是什么?
ld 这个不管是否静态的,设置是从LIB_PATH设置。搜索规则是从 LIB_PATH 搜索。

2. ld.so 搜索路径如何设定?搜索规则是什么?
设置和搜索都是按照 $GLIBC_PREFIX/etc/ld.so.conf 进行。

3. 有啥联系。
对于一个程序,比如 tar。ld 是编译的时候用的,ld.so 是运行的时候用的。
静态编译的程序的话,就不需要 ld.so 了,因为不用找库。

不知道我有没有说错。不过我最近已经说错了很多了。。。呵呵。
回复 支持 反对

使用道具 举报

发表于 2006-3-5 12:05:54 | 显示全部楼层
同意 终极幻想 , ld 和 ld.so 就是两个东西, 混在一起就糊涂了.
回复 支持 反对

使用道具 举报

发表于 2006-3-5 12:12:58 | 显示全部楼层
归功于 good02xaut 兄弟,没有他的话,我也不会明白这些东西的。:thank
回复 支持 反对

使用道具 举报

发表于 2006-3-5 19:31:24 | 显示全部楼层
呵呵。
版主终于明白俺的意思了:)

这就好比鸡蛋,然进去怎么就不好出来。
如果是公鸡和鸡蛋就好些,大家就比较分清鸡是鸡,蛋是蛋。
当然公鸡和鸡蛋也是有联系的,ld和ld.so也是有联系的。
等单个的都清楚了,联系也就知道了;)
回复 支持 反对

使用道具 举报

发表于 2006-3-5 19:38:16 | 显示全部楼层
是啊,,不是你的这堆说教,我还真没明白你说什么,当然,我也就不会研究的这么透彻了。:)。。再次感谢兄弟的好意:thank
回复 支持 反对

使用道具 举报

发表于 2006-3-5 19:41:38 | 显示全部楼层
大家明白了就好。呵呵

toolchain是LFS的精华。
ld(gcc),ld.so是toolchain的精华:)
回复 支持 反对

使用道具 举报

发表于 2006-7-28 20:43:19 | 显示全部楼层
ld 是编译的时候用的


这个不对吧~~
编译只是生成object

根据《深入理解计算机系统》里面的讲解,

源程序==》预处理器(cpp)==》编译器(ccl)==》汇编器(as)==》链接器(ld)==》可执行文件

也就是说ld将object文件链接到一块。


  1. wangyao@fisherman:~$ gcc -v hello.c
  2. 使用内建 specs。
  3. 目标:i486-linux-gnu
  4. 配置为:../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.0 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-awt=gtk-default --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --with-tune=i686 --enable-checking=release i486-linux-gnu
  5. 线程模型:posix
  6. gcc 版本 4.0.4 20060507 (prerelease) (Debian 4.0.3-3)
  7. /usr/lib/gcc/i486-linux-gnu/4.0.4/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -mtune=i686 -auxbase hello -version -o /tmp/ccA0iJ3e.s
  8. 忽略不存在的目录“/usr/local/include/i486-linux-gnu”
  9. 忽略不存在的目录“/usr/include/i486-linux-gnu”
  10. #include "..." 搜索从这里开始:
  11. #include <...> 搜索从这里开始:
  12. /usr/local/include
  13. /usr/lib/gcc/i486-linux-gnu/4.0.4/include
  14. /usr/include
  15. 搜索列表结束。
  16. GNU C version 4.0.4 20060507 (prerelease) (Debian 4.0.3-3) (i486-linux-gnu)
  17.         compiled by GNU C version 4.0.4 20060507 (prerelease) (Debian 4.0.3-3).
  18. GGC 准则:--param ggc-min-expand=63 --param ggc-min-heapsize=63428
  19. as -V -Qy --32 -o /tmp/ccoNhv8l.o /tmp/ccA0iJ3e.s
  20. GNU assembler version 2.16.91 (i486-linux-gnu) using BFD version 2.16.91 20060413 Debian GNU/Linux
  21. /usr/lib/gcc/i486-linux-gnu/4.0.4/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.0.4/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.0.4 -L/usr/lib/gcc/i486-linux-gnu/4.0.4 -L/usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib -L/usr/lib/gcc/i486-linux-gnu/4.0.4/../../.. -L/lib/../lib -L/usr/lib/../lib /tmp/ccoNhv8l.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i486-linux-gnu/4.0.4/crtend.o /usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crtn.o

复制代码


在最后,实际上是调用了/lib/ld-linux.so.2进行链接


  1. wangyao@fisherman:~$ gcc -v -static hello.c
  2. 使用内建 specs。
  3. 目标:i486-linux-gnu
  4. 配置为:../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without -included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.0 --en able-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-aw t=gtk-default --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4. 0-1.4.2.0/jre --enable-mpfr --disable-werror --with-tune=i686 --enable-checking= release i486-linux-gnu
  5. 线程模型:posix
  6. gcc 版本 4.0.4 20060507 (prerelease) (Debian 4.0.3-3)
  7. /usr/lib/gcc/i486-linux-gnu/4.0.4/cc1 -quiet -v hello.c -quiet -dumpbase hello. c -mtune=i686 -auxbase hello -version -o /tmp/ccxgWSit.s
  8. 忽略不存在的目录“/usr/local/include/i486-linux-gnu”
  9. 忽略不存在的目录“/usr/include/i486-linux-gnu”
  10. #include "..." 搜索从这里开始:
  11. #include <...> 搜索从这里开始:
  12. /usr/local/include
  13. /usr/lib/gcc/i486-linux-gnu/4.0.4/include
  14. /usr/include
  15. 搜索列表结束。
  16. GNU C version 4.0.4 20060507 (prerelease) (Debian 4.0.3-3) (i486-linux-gnu)
  17.         compiled by GNU C version 4.0.4 20060507 (prerelease) (Debian 4.0.3-3).
  18. GGC 准则:--param ggc-min-expand=63 --param ggc-min-heapsize=63428
  19. as -V -Qy --32 -o /tmp/ccWN5yLO.o /tmp/ccxgWSit.s
  20. GNU assembler version 2.16.91 (i486-linux-gnu) using BFD version 2.16.91 2006041 3 Debian GNU/Linux
  21. /usr/lib/gcc/i486-linux-gnu/4.0.4/collect2 -m elf_i386 -static /usr/lib/gcc/i48 6-linux-gnu/4.0.4/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.0.4/../.. /../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.0.4/crtbeginT.o -L/usr/lib/gcc/i 486-linux-gnu/4.0.4 -L/usr/lib/gcc/i486-linux-gnu/4.0.4 -L/usr/lib/gcc/i486-linu x-gnu/4.0.4/../../../../lib -L/usr/lib/gcc/i486-linux-gnu/4.0.4/../../.. -L/lib/ ../lib -L/usr/lib/../lib /tmp/ccWN5yLO.o --start-group -lgcc -lgcc_eh -lc --end- group /usr/lib/gcc/i486-linux-gnu/4.0.4/crtend.o /usr/lib/gcc/i486-linux-gnu/4.0 .4/../../../../lib/crtn.o

复制代码


最后没有调用ld-linux.so.2进行链接。


我想问一下,既然ld是编译程序时链接目标文件的,ld-linux.so.2是加载运行时动态链接库的。为什么我们在用gcc进行编译的时候时调用ld-linux.so.2来进行链接目标文件呢???
难道是动态编译的问题吗?动态编译时采用ld-linux.so.2,静态编译时采用ld??
回复 支持 反对

使用道具 举报

发表于 2006-7-28 21:14:44 | 显示全部楼层
ipconfigme 说的没错,
1.ld 是链接的时候用的
但一般提到"编译"时, 指的是你说的完整过程, 一般一个 make 命令.
gcc 调用时可以把所有的步骤分开, 但一般都几步合在一起.
源程序==》预处理器(cpp)==》编译器(ccl)==》汇编器(as)==》链接器(ld)==》可执行文件

gcc main.c 如果不要其他文件, 直接就会生成 可执行文件 a.out

文件多时一般分两步, 编译链接
gcc main.c -o main.o
gcc needed.c -o needed.o
gcc main.o needed.o -o a.out 这是用 gcc 间接调用 ld 等链接器

2. 动态链接时采用ld-linux.so.2,静态链接时采用ld
基本上可以这么说.
动态链接应该只是把运行时动态链接库的入口表写入, 方便运行时调用.
静态链接则是把 *.a *.o 的需要的函数(包括入口和实现)写入, 不需要 runtime 支持.

gcc main.o needed.o -o a.out
但这样写, 应该会用 ld 链接 main.o needed.o ,然后默认会 ld.so 链接 libc.so, 就是两个都用.
回复 支持 反对

使用道具 举报

发表于 2006-7-28 22:37:53 | 显示全部楼层
动态链接时采用ld-linux.so.2,静态链接时采用ld
但是,我感觉这么说有点牵强。

ld也可以动态的进行链接。

我的意思是,ld-linux.so.2不应该去链接objects;链接是ld的工作(ld可以动态也可以静态的链接)。

ld-linux.so.2只是负责程序运行时,搜索并加载需要的链接库。

这样,ld与ld-linux.so.2的只能就有些混乱了~~
回复 支持 反对

使用道具 举报

发表于 2006-7-28 23:38:21 | 显示全部楼层
/usr/lib/gcc/i486-linux-gnu/4.0.4/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.0.4/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.0.4 -L/usr/lib/gcc/i486-linux-gnu/4.0.4 -L/usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib -L/usr/lib/gcc/i486-linux-gnu/4.0.4/../../.. -L/lib/../lib -L/usr/lib/../lib /tmp/ccoNhv8l.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i486-linux-gnu/4.0.4/crtend.o /usr/lib/gcc/i486-linux-gnu/4.0.4/../../../../lib/crtn.o

红字部分也许并不是调用 ld.so , 只是将路径写入.
但也有可能必须调用 ld.so 做生成函数表, 甚至只是检查一下.
没有读过 gcc 链接系统的源码, 不能确定 ld.so 这时的用处.

你这么有实践精神, 可以按 gcc -v 给出的详细步骤, 自己一步步做下去
最后一步使用一个不存在的 ld.so , 但存在时又要可以运行,
-dynamic-linker /tools/lib/ld-linux.so.2
要确保 /tools/lib/ld-linux.so.2 存在时, 是可以编译运行通过的.
然后把/tools/lib/ld-linux.so.2 改名, 用同一命令链接, 看看情况.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表