最近在看《深入理解Java虚拟机》,记一下编译OpenJDK12过程:在Ubuntu20.04 LTS系统编译OpenJDK12,调试工具 CLion 2019.1。
第一步:获取OpenJDK12源码
书中提供了两种获取OpenJDK源码的方式,我采用的是第二种:直接访问JDK版本的仓库页面https://hg.openjdk.java.net/jdk/jdk/jdk12/,然后点击左侧菜单中的 Browse(如图1)。点击后,将显示如图2的源码根目录页面。此时点击左边的 zip 即可下载当前版本的源码。
下载后,解压到单独的文件夹下。书中有这样一段描述:“所有的文件,包括源码和依赖项目,都不要放在包含中文的目录里面,这样做不是一定产生不可解决的问题,只是没有必要给自己找麻烦。”
我下载之后,放在了当前用户的主目录下,如图3。
![](https://i-blog.csdnimg.cn/blog_migrate/780cc78ab9009ca2e6ce3843b1fa1f61.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7c3667b4fa4ce0f9b575098a052fc8e0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/75443b2de2bc721250a49069555f4a35.png)
第二步:构建编译环境
构建编译环境,分为:
- 安装OpenJDK 11
- 安装编译器 GCC
- 安装编译OpenJDK的依赖库
2.1 安装OpenJDK11
因为OpenJDK由多个部分构成:HotSpot、JDK类库、JAXWS、JAXP等,其中HotSpot代码使用C、C++编写,而更多的代码是使用Java语言实现,因此编译这些Java代码就需要用到另一个编译期可用的JDK,官方成这个JDK为 Bootstrap JDK。编译OpenJDK 12时,Bootstrap JDK就必须使用JDK 11及之后的版本。安装命令:
sudo apt-get install openjdk-11-jdk
2.2 安装编译器 GCC
安装GCC来进行编译,必须确保最低的版本为GCC 4.8,官方推荐使用 GCC 7.8来完成编译。在Ubuntu上期纳湖区嗯GCC的命令为:
sudo apt-get install build-essential
2.3 安装编译OpenJDK的依赖库
工具 | 安装命令 |
FreeType | sudo apt-get install libfreetype6-dev |
CUPS | sudo apt-get install libcups2-dev |
X11 | sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev |
ALSA | sudo apt-get install libasound2-dev |
libffi | sudo apt-get install libffi-dev |
Autoconf | sudo apt-get install autoconf |
第三步:编译
进入下载的jdk文件目录下,依次执行:
bash configure
make images
如果多次编译,必须先执行 make clean 和 make dist-clean 命令清理目录。
可能出现的错误:
在执行 bash configure 的时候,可能会因为缺失某些依赖包导致失败,如图4,按照提示安装即可。
![](https://i-blog.csdnimg.cn/blog_migrate/b61e935b1edc27b54c8b6ddac3d70b61.png)
在执行 make images 的时候,一直提示 missing directory,如图5。根据报错信息,我去查看了下载的 jdk 目录下确实没有 jdk.compiler 目录。于是,执行 rm -rf 命令删除了下载的包,重新下载解压,执行上述命令:bash configure、make images。这次,成功了!
![](https://i-blog.csdnimg.cn/blog_migrate/5e6a9ba5bba90b569f29ea4f82a8baa6.png)
执行 bash configure 成功,如图6。执行 make images 成功,如图7。
![](https://i-blog.csdnimg.cn/blog_migrate/eac1766a46956a5232bb24c14ab8c063.png)
![](https://i-blog.csdnimg.cn/blog_migrate/731bab2fee000320ca11b8a9f2681ccf.png)
编译成功后,会在 jdk build/配置名称 目录下产生如下目录结构:
buildtools/:用于生成、存放编译过程中用到的工具
hotspot/:HotSpot虚拟机编译的中间文件
images/:使用 make *-image 产生的镜像存放在这里
jdk/:编译后产生的 jdk 就放在这里
support/:存放编译时产生的中间文件
test-results/:存放编译后的自动化测试结果
configure-support/:这三个目录是存放执行 configure、make 和 test 的临时文件
make-support/
test-support/
此时,进入 build/配置名称/jdk 目录下就可以看到OpenJDK的完整编译结果了,可以把它复制到JAVA_HOME目录,就可以作为一个完整的JDK来使用。如果没有人设置过JDK开发版本的话,这个JDK的开发版本号里默认为带上编译的机器名,如图8所示。
![](https://i-blog.csdnimg.cn/blog_migrate/189156898292a48a6514b9c338cada34.png)
编译过程总结:在编译过程中出现的错误,要一句一句看提示的错误信息,不要盲目地去百度,有的博客的错误可能和我们遇到的是一样的,但有时候你都找不到你遇到这种错误。比如我在 make images 遇到的 missing directory ,谁会想到下载下来的包会没有 jdk.compiler 呢?重新下载一遍就好了,所以还是以自己本地报错信息为切入点把。
第四步:调试
我用的IDE是CLion 2019.1。起初我也下载新版本的CLion,但是没有找到 New CMake Project from Sources,加上对IDE不熟悉,重新安装了CLion 2019.1版本。
按照书本描述,选择 New CMake Project from Sources,选择 OpenJDK 源码根目录,点击OK就会自动导入源码并自动创建 CMakeLists.txt 文件。但这个自动生成的 CMakeLists.txt 并不能直接使用。不过,如果只是想在 CLion 中跟踪、阅读源码,不需要修改重新编译的话,则不用修这个文件,如果需要在 CLion 中修改源码,并重新编译产生新的 JDK,又或者不想阅读源码时看见一堆头文件缺失提示的话,还是需要把 CMakeLists.txt 修好。在书中,笔者提供了 GitHub 上现有的参考,但是访问发现唯独没有 OpenJDK12 版本的 CMakeLists.txt,如图9所示。
![](https://i-blog.csdnimg.cn/blog_migrate/eb1454f5a9e0b695227cc15205579f2c.png)
暂时不修了,直接在 Run/Debug Configurations 中增加一个 CMake Applcation,然后在 Executable 选择刚才编译出来的 FastDebug目录下的 java 命令,运行参数加上 -version,再把 Before launch 里面的 Build 去掉,就完成配置了,如图10。
HotSpot 虚拟机启动器的执行入口是 java.c 的 JavaMain() 方法,可以打断点单步跟踪,如图11所示。