LFS 学习日记(第六章之再次调整工具链)

2010年07月13日 星期二

http://www.linuxfromscratch.org/lfs/view/6.6/chapter06/readjusting.html
6.10. Re-adjusting the Toolchain

question:
The toolchain will be adjusted so that it will link any newly compiled program against these new libraries.
链接到这些新的库文件是指动态链接还是指静态链接?
在第6章,在 glibc 之前安装的两个包 Linux API Hearders 和 Man Pages 都没有二进制编译的过程,所以它们不会链接到任何库文件。第5章之所以还要先安装第一遍 Binutils 和 Gcc 主要是为了编译这个第5章的 glibc 吗?

question:
第五章的 glibc 为什么不能直接用宿主系统里的工具编译? 在第5章里,能不能省略 Binutils 和 Gcc 的第一遍编译?为什么? 为什么第6章不需要对这两个工具链工具包进行两次编译?

question:
First, backup the /tools linker, and replace it with the adjusted linker we made in chapter 5.
与第5章:5.9. Binutils-2.20 - Pass 2 The value of this variable specifies the linker's default library search path.
第5章准备的那个 ld-new 与第5章后来使用的那个 ld 的区别是什么?
5.9中 CC="$LFS_TGT-gcc -B/tools/lib/" 的 -B 后的 /tools/lib/ 指的是编译器使用的相关库的搜索路径;--with-lib-path=/tools/lib 指的是编译 Binutils 时搜索的库文件路径。-C ld LIB_PATH=/usr/lib:/lib 中的 LIB_PATH 指的是使用 ld 程序时它的库文件搜索路径(使用第5章里后面使用的那个ld的默认库文件搜索路径是 /tools/lib )。问题:这3个参数的描述正确吗?第5章后来使用的那个 ld 的默认库文件搜索路径为什么会是 /tools/lib ,是在哪里指定的呢?
另,在vim 中查看第5章的 ld-new 和 ld (即第6章的 ld 和 ld-old),搜索“SEARCH_DIR”可以看见前者(第6章的 ld )有下面这段(第二次出现的位置):
^@/* Script for -N: mix text and data on same page; don't align data */
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
              "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("/tools/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/lib");

而后者(第6章的 ld-old )则有下面这段(第二次出现的位置):

^@/* Script for -N: mix text and data on same page; don't align data */
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
              "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("/tools/i686-pc-linux-gnu/lib"); SEARCH_DIR("/tools/lib");

这样的搜索贯穿全部内容都是一样的,即前者为:SEARCH_DIR("/tools/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/lib"); 后者为:SEARCH_DIR("/tools/i686-pc-linux-gnu/lib"); SEARCH_DIR("/tools/lib"); 另外,这是否说明LFS 在第6章目前位置的 ld 程序并不纯净,因为它里面还在首先搜索 /tools/i686-pc-linux-gnu/lib 目录。

gcc -dumpspecs | sed -e 's@/tools@@g' \
    -e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \ #
question:
在 info sed * Regular Expressions::中,'.'代表任意字符,包括新行(`.'     Matches any character, including newline.);'*'代表零或更多前面的正则表达式(`*'     Matches a sequence of zero or more instances of matches for the preceding regular expression,),那么这里是否可以说多个新行并包括新行里的任意字符,那岂不是从此替换到文件末尾吗?但实际却只替换了一行。是否可以这样理解一行由开头的新行(\r)、中间的字符、末尾的结束符(\n)组成,那么,这里的'.'只替换了新行(\r),而没有替换结束符,所以才没有替换到文件尾部?

答:上面的理解是错的,经过在 lfs-support IRC 上的请教,sed 只能一行一行的进行处理,根本不能在被替换的正则表达式部分处理换行符(\n),但可以在替换部分加入换行符。perl 可以把个文件加上换行号转换成一个字符串,这样就可以处理换行符了。

    -e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' > \
    `dirname $(gcc --print-libgcc-file-name)`/specs

todo:
sed 语法中正则表达式".*"在各种情况下替换情况:定位替换,一般替换,连续替换(加g)sed 在线文档: http://www.gnu.org/software/sed/manual/
sed 的 s 替换命令中的 g 标志表示替换每行所有匹配的字符串。如果一行中有多个匹配的字符串,如果不加 g 标志就只会替换这行的第一个匹配的字符串,加了 g 标志就会替换所有匹配的字符串。

question:
sed 怎样替换换行符?
参考答案:
1), sed 'H;$ !D;g;s/\n//g' http://tonykorn97.itpub.net/post/6414/493837
但是具体命令有待学习。
2),http://www.ixpub.net/thread-1495704-1-1.html
因为sed先取一行,然后把\n去掉,再执行命令,最后打印的时候把\n加上去(只是从grep类推,但相信sed也是如此)。而:“有些命令可以改变"流程(flow)",比如命令N,它在不移除当前行的情况下读入下一行到模式空间中。这样就能对多行进行模式测试。”

2010年07月14日 星期三

grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log
这里的 .* 正则表达式与上面的是同样的意思,即为同一行中的零到多个任意字符
又如: "info sed" 里 * Usage:: 菜单里的例子如下:
     grep -i 'hello.*world' menu.h main.c

This lists all lines in the files `menu.h' and `main.c' that contain
the string `hello' followed by the string `world'; this is because `.*'
matches zero or more characters within a line.  *Note Regular
Expressions::.  The `-i' option causes `grep' to ignore case, causing
it to match the line `Hello, world!', which it would not otherwise
match.

grep -B1 '^ /usr/include' dummy.log #
除了打印匹配行还打印此的上面1行,也可以是: --before-context=1