1.2. 自己编译JDK

1.2.1. 获取源码

获取OpenJDK源码有两种方式:

  1. 通过mercurial代码版本管理工具从repository中直接取得源码(repository地址:http://hg.openjdk.java.net/jdk/jdk12),获取过程如下命名所示:

    1. hg clone http://hg.openjdk.java.net/jdk/jdk12
  2. 直接访问准备下载的JDK版本的仓库页面(譬如本例中的OpenJDK12的页面为:http://hg.openjdk.java.net/jdk/jdk12/),然后点击左边菜单中的“Browse”,将显示如下的源码根目录页面。

自己编译JDK - 图1
此时点击左边的“zip”链接即可现在当前版本打包好的源码,到本地直接解压即可。

1.2.2. 系统需求

为了尽量少出错误,我选择了比较新的OpenJDK版本(OpenJDK12),编译系统采用的是MacOS,而且要求本地要有至少为N-1的、编译好的JDK(也就是说我这里会选择至少为OpenJDK11的版本)。
为了减少系统中安装的JDK版本过多,本人使用sdkman作为我的软件开发套件的并行版本工具,具体如何使用请去浏览sdkman的官网(https://sdkman.io/)。
在控制台使用sdk list java命令可以查看本机的JDK版本,由下图可以发现我使用的就是OpenJDK11版本,后续我们会将自己编译好的jdk也交于sdkman去管理,这样就省去了配置JAVA_HOME的麻烦。
自己编译JDK - 图2

1.2.3. 构建编译环境

对于MacOS,需要MacOSX10.13版本以上,并安装好最新版本的XCodeCommand Line Tools for XCode,这两个SDK提供了OpenJDK所需要的CLang编译器以及Makefile中用到的其他外部命令。
在编译的过程中需要依赖若干的第三方库,这里不需要列出OpenJDK编译依赖库,不列出的原因在后续步骤就会知晓。

1.2.4. 进行编译

进入到刚才解压的jdk目录下:

  1. cd WorkSpaces/OpenSourceProject/jdk12

自己编译JDK - 图3
编译OpenJDK不仅仅是为了叨叨在自己机器中诞生的编译成品,而是带着调试,定制化等需求,这样就必须了解OpenJDK提供的编译参数才行,这些参数可以使用“bash configure --help”命令查询到,编译参数有很多,我们可以选择使用,下面是其中一部分的参数展示:
自己编译JDK - 图4
以上是configure命令的部分参数,所有参数均可通过以下形式使用:

  1. bash configure [options]

譬如,编译FastDebug版、仅含Server模式的HostSpot虚拟机,命令应为:

  1. bash configure --enable-debug --with-jvm-variants=server

configure命令承担了依赖项检查、参数配置和构建输出目录结构等多项职责,如果编译过程中需要的工具链或者依赖项有所缺失,命令执行后将会得到明确的提示,并且该出该依赖的安装命令。
如果一切顺利的话,就会收到配置成功的提示,并且输出调试级别,Java虚拟机的模式、特性、使用的编译器版本
等配置摘要信息,如下所示:
自己编译JDK - 图5
configure命令之后需要执行make命令,即在使用bash configure命令完成依赖检查之后便可以输入“make images”执行整个OpenJDK编译了。编译很少会一帆风顺的,我在编译的时候就出现错误,这个时候就要求具备一些解决debug的能力,我出现的错误如下所示:
image-20191220213950345.png
由以上可以看出,导致编译中断是因为测试程序中有错误,而我出现的这个错误很简单,给的提示也很明显,通过观察指定代码的上线文之后,发现出错的代码在后续程序中没有被引用到,所以我就采取最简单的方式,注释掉即可,具体如下所示:
自己编译JDK - 图7
在编译出错解决完问题之后,一定要先运行“make clean”和“make dist-clean”命令,接着运行“bash configure”命令,最后再运行”make images“,如果一切顺利你就会看到如下提示信息:
自己编译JDK - 图8
编译完成之后,进入到OpenJDK源码的“build/配置名称/jdk”目录下就可以看到OpenJDK的完整编译结果了,具体如下所示:
自己编译JDK - 图9
然后使用sdk install命令,安装jdksdkman

  1. sdk install java myself-open-12 /Users/gnehcgnaw/WorkSpaces/OpenSourceProject/jdk12/build/macosx-x86_64-server-fastdebug/jdk

自己编译JDK - 图10
这时候使用在终端再次使用sdk list java,就发现了自己编译的jdk版本了,具体如下所示:
自己编译JDK - 图11
然后使用使用sdk default命令切换jdk版本,具体如下所示:

  1. sdk default java myself-open-12

自己编译JDK - 图12

1.2.5. 在IDE工具中进行源码调试

使用CLion新建一个项目,选择“New CMake Project from Sources”,在源码文件夹中填入OpenJDK源码根目录,此时,CLion已经自动选择好了需要导入的源码,具体如下图所示,点击OK按钮就会导入源码并自动创建好CMakeLists.txt文件。
自己编译JDK - 图13自己编译JDK - 图14
自己编译JDK - 图15
这份自动生成的CMakeLists.txt并不能直接使用,OpenJDK本身也没有为任何IDE提供支持,但是如果只是为了能够在CLion中跟踪、阅读源码,而不需要修改重新编译的话,那直接在Run/Debug Configurations中添加一个CMake Application,然后Executable选择我们刚才编译出来的FastDebug版的java命令,运行参数加上-version或着某个class文件的路径,再把Before launch里面的Build去掉,就可以开始运行调试了,具体如下图所示:
自己编译JDK - 图16
点击“Run”,看到如下图所示,就说明可以调试程序了。
自己编译JDK - 图17
下面进行Java程序与JDK源码联合调试,调试代码如下所示:
自己编译JDK - 图18
思路:先用javacXx.java编译成Xx.class,然后用java Xx命令运行得到程序结果。
所以,配置如下:
自己编译JDK - 图19
自己编译JDK - 图20
点击CLoin中的debug,显示如下:
自己编译JDK - 图21
最后运行结果是:
自己编译JDK - 图22
说明可以进行联合调试了。