背景
由于最近想分析几个native
方法,所以需要手头有一个可以debug
的JDK
,因此,这两天折腾了折腾,踩了10+个坑,看了10+篇文章,尝试了10+次,最后总算把JDK
给编出来了,当在自己编译出来的JDK
上运行javac -version
输出了那熟悉的文字后,感觉已是老泪纵横还是很有成就感的。
前期准备
了解一下OpenJDK的相关知识 : 我们要编译的是Open JDK 9u
安装Homebrew
(可选)
番羽土啬: 因为假如编译出错需要查询错误的解决方案时需要通过一个不存在的网站来进行
准备一个好用的源码编辑器: 因为运气好的话[滑稽]我们可能需要修改JDK
源码中的八阿哥(我用的 mscode)
安装一个Boot JDK
: 因为JDK
中有不少代码是Java
写的,所以想要编译JDK
就需要用到另一个JDK
来辅助(鸡生蛋、蛋生鸡/自己拽自己的头发把自己拽起来),我安装的是Oracle官方的JDK
安装freetype
:这是个依赖项brew install freetype
安装Xcode
环境描述
操作系统: macOS High Sierra Version: 10.13.3 (17D47)
Boot JDK
: 1.8.0_161
freetype
: 2.9
Xcode
: Version 9.2 (9C40b)
Open JDK
源码: jdk9u-2e265b4b8622
corba-2ef36e70f490
hotspot-bb73b31e70e3
jaxp-95a71f690b44
jaxws-f4f878b5f01c
jdk-a779673ab57d
langtools-e2bf77b3f002
nashorn-fb3f7ae74bf6
前人蹚过的坑/我蹚过的坑
不要编译JDK 8
: 因为编译8需要Xcode 4
现在Xcode
版本已远高于4了(这个坑是前人蹚出来的,当然我不信邪,然后自己蹚了一遍,然后发现确实是个坑)
尽量不要使用Mercurial
来下Open JDK
的源码,而用浏览器直接下载打包好的源码: 因为你要用Mercurial
下载了Open JDK
的顶层工程后,还需要执行其中的get_source.sh
来下载其子工程的源码,这个过程漫长而且失败率高(关键还没有执行百分比提示,干等),用浏览器自己下载所有子工程的压缩包要快很多,而且成功率100%
(我自己蹚出来的,前人的几篇文章中全告诉我用Mercurial
,结果坑了)
编译JDK 9u
而不是JDK 9
因为我当时编译9
的时候出了一堆error,所以我想带个u
的是不是会好些,当然这个有很大程度是我臆测的,我后期就都拿9u
搞了,没试9
,如果各位有兴趣可以自己蹚蹚这个
configure
的时候一定要带上--disable-warnings-as-errors
这个参数,否则编译过程中的warning
也会中断编译的进程,实际上这些warning
并不影响编译后的目标JDK
的运行
走流程
如果前面几点 该准备的你都准备了 ,该注意的你也注意了 ,那么开始走流程编译吧,如果报错(有很大几率会)不要摔键盘,用前面我们提到的不可描述存在的网站来找答案,我自己摸着石头过河,反复试了2天才搞定,鲁迅先生说的好:“只要功夫深,铁杵磨成针” ,祝你好运!!
step0
所有前文提到的准备工作
step1
下载源码压缩包
并将下载好的源码压缩包解压后按官方源码库的层级码放好
step2
在源码顶层目录上执行sh configure --with-debug-level=slowdebug --disable-warnings-as-errors --with-freetype-include=/usr/local/Cellar/freetype/2.9/include/freetype2 --with-freetype-lib=/usr/local/Cellar/freetype/2.9/lib
(带版本号的地方自己注意根据实际情况换)如果这一步没问题的话应当看到这样的输出:
step3
如果你的编译环境以及源码版本跟我的完全一样,那么先别make all
,先来修一个bug :(patch在此 )
这个bug会导致make
报这个:error: ordered comparison between pointer and zero ('char *' and 'int') 。。。此处省略
打开hotspot
目录中的
src/share/vm/memory/virtualspace.cpp
搜索其中if (base() > 0) {
改为if (base() != NULL) {
src/share/vm/opto/lcm.cpp
搜索其中if (Universe::narrow_oop_base() > 0) {
改为 if (Universe::narrow_oop_base() != NULL) {
src/share/vm/opto/loopPredicate.cpp
搜索其中assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be");
改为 assert(rng->Opcode() == Op_LoadRange || iff->is_RangeCheck() || _igvn.type(rng)->is_int()->_lo >= 0, "must be");
step4
make all
编译时间略长,我的机子是2017款的 MacBook Pro大概用了20分钟+(没仔细计),而且编译过程中风扇狂转,笔记本的话注意剩余电量以及散热,编译若成功,指定javac
全路径运行一下javac -version
看看
如果报了error,具体error具体分析,因为编译环境不同,可能error也不同,去不存在的网站找找解决方案,耐心+运气你就一定能成功的。
总结
原以为编一个JDK
能有多难,事实证明:是不难,但是坑多,麻烦,前前后后试了10多次,一共花了两天时间,从尝试编译JDK 8
再到9
中间出了各样问题,之中一度想放弃,但是由于想用它来实现更远的目标,所以还是坚持弄下来了,最终在搜索引擎和前人的帮助下成功了,所以还是那句话:“只要功夫深铁杵磨成针”,按正确的方向,反复尝试,终能成功。
参考资料
Building OpenJDK 8 on Mac OS X Mavericks
Building and Packaging OpenJDK9 for OSX
Compilation errors with clang-4.0
OpenJDK / jdk10 / jdk10 / hotspot
changeset 13502:316854ef2fa2
Ordered comparison between pointer and zero ('char *' and 'int') error #5
MAC编译OpenJDK8
Compile&Debug openjdk
openjdk code compilation/ IDE setup
使用Clion(GDB)调试小型JVM源码
解决GDB在Mac下不能调试的问题
xcode-select active developer directory error
Mac OsX Sierra - Stuck on binaryTreeDictionary.hpp compilation