Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1555918
  • 博文数量: 290
  • 博客积分: 3468
  • 博客等级: 中校
  • 技术积分: 3461
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-28 22:21
文章分类

全部博文(290)

文章存档

2016年(13)

2015年(3)

2014年(42)

2013年(67)

2012年(90)

2011年(75)

分类: LINUX

2011-05-03 09:49:19

~thinker/GinGin_CGI.py/show_id_doc/405

Open source 常见的toolchain,就非gcc 和binutils 系列莫属。
然而,商业公司提供的toolchain,往往必需安装在特定目录,这总是惹恼有洁癖者,如我。然而,若将toolchain 任意搬动位置,则会曝露gcc 的一个缺陷,gcc 找不到其它幅程式或library 。这是因为gcc 假设library 和toolchain 会安装在固定位置,于是在build toolchain 时,就将这些路径设定死。于是,对于不想重新build toolchain,或只拿到binary 的user 而言,就必需使用-nostdlib 这个参数,然后加上一堆-I 和-L 参数,使gcc 能正确的找到library 。

另外,一些toolchain ,因为平台的因素,无法使用gcc 预设好的参数内容。于是要强迫使用者必需下一堆固定的参数,例如: Android 就在其build system 里,为gcc 设定一堆和平台相关的参数,像是-mthumb。于是,若使用该toolchain 自行开发软体,就誓必要找出这些参数,并正确的设定为gcc 的参数。这完全是一堆苦工。其实,只要作toolchain 的人多用点心,使用toolchain 其实可以不用这么累。

sysroot

一般而言,gcc 会到/usr/lib 和/usr/include 下找library 、 header files 和其它一些start files 、 end files。当我们在build gcc 设定--prefix=/path/to/xxx ,则gcc 安装到/path/to/xxx ,也在该目录下的lib/ 和include/ 找library 和header 。旦,若装gcc 移到其它目录时, gcc 会找不到这些library 。这时,我们可以在呼叫gcc 时,给予--sysrooot=/new/path/to/xxx 参数。如此,gcc 就会改以/new/path/to/xxx 为参考目录,去搜寻所需的幅程式和library 等。

然而,要注意的是, ld 必需要能support --sysroot。这必需在configure binutils 时,给予--sysroot=xxx 参数。 xxx 可以是任意目录,不一定是实际安装的位置。这个参数的主要目的是使ld 启动--sysroot 的功能。

Spec File

--sysroot 解决了一部分问题,但​​有更大部分的问题是toolchain 往往要你设定一些固定参数。例如,你会需要设定一些header file 的目录,并且设定一些平台有关的参数。这些设定往往又臭又长,很容易出错。其实,这些参数可以写在spec file 里,使用者就不用一再的重复指定这些参数。例如,以下是我为Android 设定的spec file 的内容

%rename cc1_android old_cc1_android
%rename cc1plus_android old_cc1plus_android

*android_root:
%R/../../../../../

*android_product:
generic

*ccflags:
%{!march=:-march=armv5te} %{!mt​​une=:-mtune=xscale} -mthumb \
-fno-strict-aliasing -finline-limit=64 -mthumb-interwork \
-fno-short-enums \
-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5TE__ \
-isystem %(android_root)bionic/libc/arch-arm/include/ \
-isystem %(android_root)bionic/libc/include \
-isystem %(android_root)bionic/libstdc++/include \
-isystem %(android_root)bionic/libc/kernel/common \
-isystem %(android_root)bionic/libc/kernel/arch-arm \
-isystem %(android_root)bionic/libm/include \
-isystem %(android_root)bionic/libm/include/arch/arm \
-isystem %(android_root)bionic/libthread_db/include \
-include %(android_root)system/core/include/arch/linux-arm/AndroidConfig.h \
-isystem %(android_root)system/core/include/arch/linux-arm/

*cc1_android:
%(old_cc1_android) %(ccflags)

*cc1plus_android:
%(old_cc1plus_android) %(ccflags)

像Android 的header files 就散置在一堆目录,于是build system 就指定了一堆参数。如果你自己写个小程式,又不使用Android 的build system 时,就必需自己指定这些参数。于是,有人写了一个perl 的小程式,作为gcc 的wrapper ,帮你指定一些参数。其实不用这么麻烦,只需像上例一样,设定一个spec file ,在执行gcc 时加上一个参数就能自动套用这些参数

    
gcc -specs myandroid.specs

spec file 设计的很有弹性,可以对参数列的内容进行修改,也可以加入条件性的参数。像上例{!march=:...} 就是指定,当参数列没有指定-march= 的参数时,就在cc1 的参数例加入-march=armv5te。另外我还指定了一些巨集和-system 指定一些header file 的路径。而这些路径是相对于%R ,也就是--sysroot 所指定的路。例如--sysroot=/my/path/to/the/kkk/ ,则%(android_root)bionic/libm/include/arch/arm 就会对应到/my/path/to/th/kkk/../. ./../../../bionic/libm/include/arch/arm 。

更进一步

--sysroot 的预设内容,其实是可以设定成相对于gcc 本身的位置。在 configure 时,若

configure --with-sysroot='${exec_prefix}/xxx'

则编译出来的gcc ,其sysroot 就会相对于其执行路径。如此user 甚至不必再手动指定--sysroot 。

结论

有了spec files ,我们只需设定-specs 和--sysroot 两个参数就能解决所有的问题。其实在建toolchain 时,应该再多花一点时间,帮user 作好spec files 。这样的 toolchain 才方便使用。关于spec file 更详细的内容,请参考
阅读(1816) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~