OpenJDK 10编译
概述
标题说是OpenJDK10,实际上把OpenJDK8、9、10、12都试了一个遍。环境如下,注意需要一个安装好的JDK作为"Boot JDK"。
- MacOS 10.14.5
- Xcode 10.3(10G8),Apple LLVM version 10.0.1 (clang-1001.0.46.4)
- Oracle JDK8(build 1.8.0_192-b12)
这个环境下编译OpenJDK8就不用试了毕竟太老了。编译OpenJDK9、OpenJDK10需要把libstdc++放到Xcode里面,但编译OpenJDK9时到最后的编译阶段JVM启动时Crash了,但编译OpenJDK10是成功的,因此本人目前在这个环境下编译成功的OpenJDK最低版本是OpenJDK10。
至于OpenJDK12,什么都不用做直接编译基本就OK了。
编译OpenJDK10
还原libstdc++
因为Xcode10里面把libstdc++干掉了,所以编译OpenJDK10之前先要把libstdc++弄回来。 这也是我写这篇文章的主要目的,因为网上虽然有些朋友指出了这个方法,也提供了lib库下载,但要么只提供了iOS相关的文件,要么只提供了MacOS下的lib文件没有提供头文件...
最后我去苹果官网下载了Xcode9的安装包,解压提取了MacOS下libstdc++的lib文件和头文件,这里给需要的朋友提供下载地址:https://cdn.spirithy.com/code/xcode/XCode9 Dump.zip
下载解压后,把"MacOSX"下对应的文件复制到/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++和/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/ 目录下即可。
下载源码
安装Mercurial后,直接hg下载源码。可能比较慢,也可以到官网手动下载源码压缩包。
hg clone http://hg.openjdk.java.net/jdk10/jdk10/ jdk10
安装依赖和编译
依赖主要是openssl、freetype之类的,用brew安装即可,ccache可有可无。源码下载好后,先执行configure,注意下freetype路径:
./configure --with-debug-level=slowdebug --disable-warnings-as-errors --with-freetype-include=/usr/local/Cellar/freetype/2.10.1/include/freetype2 --with-freetype=/usr/local/Cellar/freetype/2.10.1
然后执行"make all"基本就可以了,编译好后的文件在build目录下。
make all
Docker下编译OpenJDK8
如果还不死心,想编译一把OpenJDK8,基本上比较靠谱的方法就是用Docker了。
Docker容器准备
Docker镜像最好是用CentOS,因为里面的各种工具链都比较老... 注意Docker run时加了"--cap-add=SYS_PTRACE --security-opt"这些安全相关的参数,这样后面才能在Docker容器中愉快地debug。
这里用的CentOS 7,除了安装基本的依赖外,还安装了一个OpenJDK 7作为Boot JDK。
docker run --cap-add=SYS_PTRACE --security-opt --name builder -v /Users/spirit/Projects/openjdk/:/var/spirit/openjdk -i -t centos:centos7 /bin/bash
yum -y update
yum -y groupinstall "Development Tools"
yum -y install unzip libXtst-devel libXt-devel libXrender-devel cups-devel freetype-devel alsa-lib-devel which wget vim
yum -y install java-1.7.0-openjdk-devel
下载源码
下载源码跟前面下载OpenJDK10一样。这里提一下,因为OpenJDK源码是分模块的,需要想切换到某个tag,除了根目录要用"hg up"切之外,几个子目录也不要忘记了。
hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8
编译前的准备
如果直接编译是会报错的,因为Makefile里面支持的linux内核只写到了3.X,估计当时4.X内核还没出。去把 /hotspot/make/linux/Makefile文件中声明的SUPPORTED_OS_VERSION,在最后加上"4%" 即可。
编译
configure阶段比较简单:
./configure --with-debug-level=slowdebug
编译阶段直接"make all"可能会遇到报错"cc1: all warnings being treated as errors",网上的其它方法都不管用,其实用make SCTP_WERROR="" all就行了,详见:http://openjdk.5641.n7.nabble.com/Re-Build-error-with-GCC4-8-on-Fedora19-td143112i20.html
make SCTP_WERROR="" all
关于调试
调试暂时没有结合CLion、VS Code之类的IDE来做,而是直接直接用的lldb、gdb(cgdb)来调试的。 稍微记录下注意事项和常用命令。
lldb(MacOS下OpenJDK10)
# 带参数启动
lldb -- /Users/spirit/Projects/openjdk/jdk10/build/macosx-x86_64-server-slowdebug/jdk/bin/java -version
# attach到指定进程
pro att -p 9939
# 下条件断点
br set --file verifier.cpp --line 171 -c '(int)strcmp("Serializer_1", klassName)==0'
# 禁用断点
br disable 1
# 启动断点
br enable 1
gdb(CentOS7下OpenJDK8)
首先,调试的时候如果报找不到调试信息"Missing separate debuginfo for/var/spirit/openjdk/jdk8/build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64/server/libjvm.so",是因为在编译时因为编译配置项不正确而没有生成调试的符号信息,或生成后被压缩为”libjvm.diz”了,所以无法找到。如果是因为没有编译时没有生成调试信息,需要修改编译配置并重新编译。对于被压缩的情况,可以去到"libjvm.so"所在目录解压:unzip libjvm.diz。
# 带参数启动
cgdb --args /var/spirit/openjdk/jdk8/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java "-cp" "/root/fastjson-test-1.0.0-SNAPSHOT-jar-with-dependencies.jar" "com.spirit.vdefineb.DefineTest"
# 下条件断点
b verifier.cpp:121 if (int)strcmp("Serializer_1", klassName)==0
# 禁用断点
disable 1
# 启动断点
enable 1