接上篇,当openjdk6的代码库已经用mercurial clone/fclone完毕之后,就可以构建openjdk6了。当然构建与阅读源代码没有太大关系,只是如果日后还要做hack的话,总要通过构建和测试来检查、调试自己的hack不是,所以了解openjdk6的构建方法还是有点必要的。
基本上,代码库根目录下的README-builds.html中的讲解已经很到位了,我这里再简要地啰嗦一下整个步骤,权当个中文翻译好了。

  1. 必需的应用程序:gcc 4,g++ 4,GNU make (>3.80),m4 (>1.4.4)。以及README-builds.html中指定的很多个开发包(dev)。我的操作系统是Ubuntu 8.10,内核版本为2.6.27-14,按照README-builds.html的包依赖关系,一下子:

    sudo apt-build install binutils cpp libfreetype6-dev g++ cpp-4.1 g++-4.1 gcc-4.1 gcc-4.1-base libstdc++6-4.1-dev gawk gcc libasound2-dev libc6 libc6-dev libc6-i686 libcupsys2-dev libgcrypt11-dev libgnutls-dev libgnutls26 libgpg-error-dev libice-dev liblockfile1 libopencdk10 libpopt-dev libsm-dev libtasn1-3-dev libx11-dev libxau-dev libxaw7-dev libxdmcp-dev libxext-dev libxi-dev libxmu-dev libxmu-headers libxmuu-dev libxp-dev libxpm-dev libxrandr-dev libxt-dev libxtrap-dev libxtst-dev libxv-dev m4 make ssl-cert x-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev x11proto-randr-dev x11proto-record-dev x11proto-trap-dev x11proto-video-dev x11proto-xext-dev zlib1g-dev

    就好了。我的机器里其实已经装了libstdc++6-4.3-dev以及g++-4.3,不过保险起见还是把g++ 4.1以及libstdc++6 4.1的东西搞进来了,尊重一下README-builds.html,也顺便给自己少找些麻烦——后来测试的时候还真发现用libstdc++6 4.3或者g++ 4.3的话会编译失败,大概看了看错误信息,结论是以我现在的c++水平如果要把它port到4.3的话还是暴有难度的…嗯,那就4.1吧,听话的孩子有糖吃。

  2. 参照README-builds.html,有2个环境变量是必需的,当然这俩环境变量的值指向的目录也不是乱来的:
    • Bootstrap JDK:README-builds.html自己都说了,编译openjdk6的时候还需要一个已有的jdk6是很那啥的。没办法,估计语言发展起来之后需要自己来编译自己的某一部分也不是很罕见的事情吧。我的系统里已经装了SUN的jdk6,所以,ALT_BOOTDIR=/usr/lib/jvm/java-6-sun。
    • JDK binary plugins:这东西还是个新鲜玩意儿,以前是没听说过。照着README-builds.html里的指示,按图索骥到最新发布的jdk 6 binary plugins:http://download.java.net/openjdk/jdk6/promoted/b14/jdk-6-ea-plug-b14-linux-i586-25_nov_2008.jar。这是个可执行jar文件,java -jar一下,accept一下条款之类的东西,指定个目录就可以安装了。安装完成后,在安装目录里会看到一个openjdk-binary-plugs的子目录,结构和普通jdk一致,内容只有两个文件:LICENSE和jre/lib/rt-closed.jar。rt-closed.jar的内容没什么惊喜,一堆SUN自己的SNMP功能的支持类,光看这文件名就知道肯定是不方便开源的东西。不管它的内容:ALT_BINARY_PLUGS_PATH=~/projects/openjdk/jdk6-bin-plugins/openjdk-binary-plugs/ 。
    • 其他的几个环境变量我是没有再手动设置,估计debian系的系统里,那些dev包安装妥当之后也不用再自己设了。

然后,终于可以开始make了,先来make sanity一下,确认当前配置没问题,没问题的话就可以直接跑make了。所有c/c++的代码无疑都是gcc、g++来编译的,其他诸如corba、jaxp、jaxws是单独用javac以及ant编译的,我用的机器上已经装好了ant 1.6.5,编译jaxp和jaxws时也没出什么问题。整个make过程在我这台P4 2.4G MHz 2G RAM的机器里花费掉了…差点儿一个小时…中间看到”linking vm…”的时候我几乎要哭出来了…
make成功后,build/目录下包括所有编译、链接出来的可执行文件以及jar包,还有javadoc。里面的j2re-image和j2sdk-image分别是…jre以及jdk,嗯,废话,是吧。进到bin目录下./java -version一下:

iusr@wisdom:~/projects/openjdk/jdk6/build/linux-i586/bin$ ./java -version
openjdk version “1.6.0-internal”
OpenJDK Runtime Environment (build 1.6.0-internal-iusr_18_mar_2009_16_32-b00)
OpenJDK Client VM (build 11.0-b17, mixed mode)

Yay!


Update: 到一台默认语言设成中文的ubuntu 8.10上重make一次,结果出错了…有3个注意事项要更新一下:

  1. g++、libstdc++6 dev包的版本问题。如果几个版本共存的话,确保g++-4.1在PATH的最前面能被最先找到。这个比较好解决,而且一旦g++版本正确的话也会确保include路径是对应的libstdc++6的头文件库。小问题。
  2. make之前要unset JAVA_HOME。这个环境变量如果存在的话make sanity会报错,错误信息也很明显,所以,同样是小问题。
  3. LANG=C。无论export出去还是运行make,一定确保LANG兼容英语,否则会出现很奇异的错误…
  4. apt-build install libmotif-dev 。这个忘记了很不应该,因为我用awesome,所以还特别地在.profile里export AWT_TOOLKIT=MToolkit了的。

其他的诸如gawk、m4之类居家旅行必备的东西,如果落下没说的话还请自己装好。