Back
Featured image of post [实战]自己动手编译JDK实录

[实战]自己动手编译JDK实录

前言

最近在看周志明老师的经典《深入理解Java虚拟机》,第1章最后是一个自己编译JDK的实战,想到羊哥之前也出过这样一期视频,觉得做一做也蛮有成就感的,还可以加深下对Java的理解,所以边做边写下此篇博文。

环境准备

系统环境

我的环境是macOS10.14.6(黑苹果),问题相对Windows应该会少很多,推荐大家也是用Linux或者macOS来进行编译。

Xcode下载

一些C/C++相关的工具链一般是用Xcode带的,所以去官网下载就行。但是如果像我一样是黑苹果,系统不是最新的,官网的版本很可能不适配(目前最新Xcode 13要求macOS 11以上),所以只能翻到以前百度云里存的Xcode11.xip下载解压并安装就可以了。

xip文件在解压时需要用系统自带的解压工具,不要用第三方的,不然解压出来不是一个.app文件。

还有就是解压时可能会遇到系统验证问题,通过以下两步解决:

  1. 运行以下命令行
# 最后是xip文件的位置
xattr -d com.apple.quarantine Xcode_11.xip
  1. 在系统设置中修改系统的时间约为2018年7月,然后允许任何来源的软件安装。

所有软件环境基础

以下都是编译中需要用到的软件环境,确保都已经安装

# 有一个已经可用的jdk,版本至少是要编译的版本-1
java -version
# 输出
openjdk version "11.0.9" 2020-10-20
OpenJDK Runtime Environment (build 11.0.9+11)
OpenJDK 64-Bit Server VM (build 11.0.9+11, mixed mode)

# C的编译器
clang --version
# 输出
Apple clang version 11.0.0 (clang-1100.0.33.8)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

# C++的编译器
clang++ --version
# 输出
Apple clang version 11.0.0 (clang-1100.0.33.8)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

# 自动配置工具autoconf
# 下载方式:brew install autoconf
autoconf --version
# 输出
autoconf (GNU Autoconf) 2.69

# 编译构建工具
make --version
# 输出
GNU Make 3.81

# 渲染库freetype
freetype-config --ftversion
# 输出
2.10.4

源码下载

这次要编译的目标版本是jdk11,所以下载jdk11的源码

方式一:通过Mercurial

JDK是通过这个叫Mercurial的版本管理工具来进行代码管理的,这个和git是一类工具,只不过过于小众。而且这种方式慢,不推荐。

  • 安装Mercurial
brew install mercurial
hg clone https://hg.openjdk.java.net/jdk/jdk11/

方式二:官网下载压缩包

这种方式速度快,推荐这种方式

前往地址:

Java Platform, Standard Edition 11 Reference Implementations

点击下载zip压缩包即可

新建一个专门的文件夹存放源码包,解压后就可以看到目录结构

src就是源码部分,看到里面基本都是C和C++的代码,说明Java就是用C和C++写的。

自动配置工作

这一步进行编译前的自动编译工作

# 首先cd进源码目录,也就是上图的openjdk11
cd openjdk11

# 运行脚本
sh configure

这个过程较快,最后会输出一些概览信息。

正式编译工作

第一次编译直接进行全量编译,执行:

make all

这个过程比较久,耐心等待,会生成可执行文件,JDK成品镜像等很多东西

过程中的警告可以忽略,只要不出现错误导致整个过程停止即可

可以看到这个过程中我的mac的活动监视器,CPU快要炸了

直到控制台最后几行输出一下信息就证明成功了

Creating support/demos/image/jfc/SampleTree/SampleTree.jar
Creating support/demos/image/jfc/TableExample/TableExample.jar
Creating support/demos/image/jfc/TransparentRuler/TransparentRuler.jar
Creating jdk image
Finished building target 'all' in configuration 'macosx-x86_64-normal-server-release'

成品验收

完成上一步后就可以发现目录下多了一个build目录,进入build/macosx-x86_64-normal-server-release/目录可以看到如下文件

命令行验证下

# 进入编译后的jdk的bin目录
cd build/macosx-x86_64-normal-server-release/jdk/bin

# 执行java命令查看版本
./java -version

# 输出
openjdk version "11-internal" 2018-09-25
OpenJDK Runtime Environment (build 11-internal+0-adhoc.ccqstark.openjdk11)
OpenJDK 64-Bit Server VM (build 11-internal+0-adhoc.ccqstark.openjdk11, mixed mode)

最终的JDK成品就在images/jdk目录下,这个就和我们平时在官网上下载的JDK基本是一样的

IDEA中使用新JDK

新建一个Hello World项目

添加自己编译的JDK的路径

切换项目所用的JDK为刚刚新增的

运行之后可以看到我们使用的JDK已经换成自己编译得到的了

定制JDK

当我们需要自己定制一套属于自己的JDK的时候就需要我们去修改源码中的一些实现,修改之后要生效的话必须重新编译一次,这次的编译就可以用增量编译了。

修改Sourcepath

删除原来全部路径

重新添加我们一开始下载的压缩包中解压出来的src目录下的源码,并让IDEA重新索引

修改源码

我们Ctrl加鼠标点击进入println源码,并做点修改意思意思

增量编译

再次cd到解压出来的大目录下,执行

make images

进行增量编译,速度会比全量编译快

再次运行代码发现之前对源码的修改已经生效

参考资料

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
一辈子热爱技术
Built with Hugo
Theme Stack designed by Jimmy
gopher