root@desktop:~# gcc --help
Usage: gcc [options] file...
Options:
-pass-exit-codes Exit with highest error code from a phase
--help Display this information
--target-help Display target specific command line options
--help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]
Display specific types of command line options
(Use '-v --help' to display command line options of sub-processes)
--version Display compiler version information
-dumpspecs Display all of the built in spec strings
-dumpversion Display the version of the compiler
-dumpmachine Display the compiler's target processor
-print-search-dirs Display the directories in the compiler's search path
-print-libgcc-file-name Display the name of the compiler's companion library
-print-file-name=<lib> Display the full path to library <lib>
-print-prog-name=<prog> Display the full path to compiler component <prog>
-print-multi-directory Display the root directory for versions of libgcc
-print-multi-lib Display the mapping between command line options and
multiple library search directories
-print-multi-os-directory Display the relative path to OS libraries
-print-sysroot Display the target libraries directory
-print-sysroot-headers-suffix Display the sysroot suffix used to find headers
-Wa,<options> Pass comma-separated <options> on to the assembler
-Wp,<options> Pass comma-separated <options> on to the preprocessor
-Wl,<options> Pass comma-separated <options> on to the linker
-Xassembler <arg> Pass <arg> on to the assembler
-Xpreprocessor <arg> Pass <arg> on to the preprocessor
-Xlinker <arg> Pass <arg> on to the linker
-combine Pass multiple source files to compiler at once
-save-temps Do not delete intermediate files
-pipe Use pipes rather than intermediate files
-time Time the execution of each subprocess
-specs=<file> Override built-in specs with the contents of <file>
-std=<standard> Assume that the input sources are for <standard>
--sysroot=<directory> Use <directory> as the root directory for headers
and libraries
-B <directory> Add <directory> to the compiler's search paths
-b <machine> Run gcc for target <machine>, if installed
-V <version> Run gcc version number <version>, if installed
-v Display the programs invoked by the compiler
-### Like -v but options quoted and commands not executed
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o <file> Place the output into <file>
-x <language> Specify the language of the following input files
Permissible languages include: c c++ assembler none
'none' means revert to the default behavior of
guessing the language based on the file's extension
打印信息
--version 显示编译器版本信息
-dumpspecs 显示所有内建 spec 字符串
-dumpversion 显示编译器的版本号
-dumpmachine 显示编译器的目标处理器
-print-search-dirs 显示编译器的搜索路径
-print-libgcc-file-name 显示编译器伴随库的名称
-print-file-name=<库> 显示 <库> 的完整路径
-print-prog-name=<程序> 显示编译器组件 <程序> 的完整路径
-print-multiarch 显示目标的标准化 GNU 三元组(被用于库路径的一部分)
-print-multi-directory 显示不同版本 libgcc 的根目录
-print-multi-lib 显示命令行选项和多个版本库搜索路径间的映射
-print-multi-os-directory 显示操作系统库的相对路径
-print-sysroot 显示目标库目录
-print-sysroot-headers-suffix 显示用于寻找头文件的 sysroot 后缀
摘自 gcc查找头文件的规则
见:http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
libdir是{prefix}/lib,target是arch=vendor-os,version就是GCC的版本,在Fedora上做实验:
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.4.6/include-fixed" ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../x86_64-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include /usr/include End of search list.
这里prefix=/usr。第一个include-fixed文档没有提到。第二是/usr/target/include,第三个是/usr/local/include,第四个是libdir/gcc/target/version/include/,第五个是/usr/include.
看GCC编译帮助文档,用--with-local-prefix能覆盖/usr/local/include。这个目录其实没什么重要的头文件。我更关心的是交叉编译时,如果不指定--with-local-prefix,交叉编译器会搜索主机上的/usr/local/include吗?实验结果是不会。这应该是理所当然的。
--with-native-system-header-dir能覆盖/usr/include,文档上说当它和--with-sysroot一起用时,用在with-sysroot的参数目录下搜索前者指定的目录。根据我对文档的理解,单独使用--with-native-system-header-dir,把参数设为绝对路径(与with-sysroot一起用时一定要用相对路径?),即可覆盖/usr/include。我仍然只关心交叉编译器的行为。交叉编译器搜索主机的/usr/include显然不合理。实验证明,即使什么参数也不加,编出来的交叉编译器不会去找/usr/include。郁闷的是,交叉编译器居然不会去找{prefix}/include。/usr/include看起来就像当prefix=/usr的情况。不知道编译本机编译器而prefix不为/usr时,编出来的编译器是否会还会找/usr/include,即/usr/include是否是硬编码的路径。
文档中说的四个路径,/usr/local/include与/usr/include不会被查找。/usr/target/include会被查找,但这个目录不存在。 prefix/lib/gcc/target/version/{include,include-fixed,sys-include}会被查找。其中sys-include不存在,include-fixed里包含limit相关的两个头文件,include则包含由编译器提供的底层头文件,如stdarg.h, cpuid.h(编译某个C库时曾遇到因找不到编译器提供的cpuid.c而报错)。所以,文件档中所提的,只有/usr/target/include与prefix/lib/gcc/target/version/include被查找了,而且仅后者起(有限的)实际作用。
这里最大的缺失就是/usr/include的替代物。原生编译器可以在这里找到原生系统glibc的头文件,但编译glibc并与gcc共享prefix,glibc的头文件其实上安装在prefix/include。看来/usr/include是个硬编码的值而不能作prefix/include解。所以,编译交叉编译器时要用--with-native-system-header-dir来指定/usr/include的替代值,也就是为目标机器准备的glibc的头文件所在地,如果用相同的prefix,那就应该是prefix/include。
结果令人失望,单独指定--with-native-system-header-dir不起任何作用。指定--with-sysroot=${prefix}的话,会抱怨应该包含系统头文件的目录不存在--它恐怕想找${prefix}/usr/include。我建了这个目录果然就编译通过了。其实文档里说过了,指定--with-sysroot相应于把--sysroot作为一个输入gcc的默认选项,注意是交叉编译器的选项,man gcc可以看到详细解释。这对LFS来说是个好选项。所以,查找规则跟原生gcc无异,只是根目录不作原解。
原来还以为要用--with-sysroot与--with-native-system-header-dir来指定头文件目录。现在看起来,应该把glibc的prefix设为gcc_prefix/usr,再指定--with-sysroot,就不需要做其它事了。但是交叉编译的ld要加上--with-sysroot,这个选项居然在configure的帮助里没有出现(只有一个指定build sysroot的选项),但是man文档里有说明。
最后,编译glibc时居然碰到__waitpid_nocancel未定义的引用。起初还以为nptl不支持ppc64,因为看了一下相应目录,没有找到nocancel的文件。最后发现不知为何,ppc64下的这个文件被删了!!原始解压出来是有的。可能之前用同一个源码树做了不同的配置,虽然在源码树外编译,还是会改变源码树的文件。