1.系统需求

本文使用Windows11 + [WSL2](什么是适用于 Linux 的 Windows 子系统 | Microsoft Learn),在WSL2中运行Ubuntu18.04作为系统构建OpenJDK,因为使用Linux或MacOS上构建工具链和依赖项上比在Windows上更容易。

mac上好用的java反编译工具_优先级

本次编译中采用得是64位操作系统,默认参数下编译出来的也是64位的OpenJDK,如果需要编译32位的版本,同样推荐在64位的机器上进行,因为编译过程中可以使用更大的内存(32位系统受4G内存限制),通过编译参数(--with-target-bits=32)来指定需要生成32位编译结果即可。在官方文档上要求编译OpenJDK需要至少2-4GB的内存空间,6-8GB的磁盘空间。虽然OpenJDK的源码只有不到600MB,但是编译过程会产生大量的中间文件,并且编译出不同优化级别(Product、FastDebug、SlowDebug)的HotSpot虚拟机可能要重复生成这些中间文件。

2.获取源码

源码链接:https://hg.openjdk.org/jdk/jdk12

点击左侧菜单中的zip,可以下载当前版本打包好的源代码。

mac上好用的java反编译工具_优先级_02

点击左侧菜单中的browse,可以看到源码的根目录页面。

mac上好用的java反编译工具_mac上好用的java反编译工具_03

3.构建编译环境

3.1 安装GCC

首先查看Ubuntu系统中的GCC版本,确保GCC版本不低于4.8,官方推荐使用GCC 7.8,但是也不建议GCC版本太高。

# 查看gcc/g++版本
gcc -v
# 查看系统已有的版本
ls /usr/bin/gcc*


Ubuntu18.04中的GCC版本为7.5,我们就使用这个。如果你的系统上没有GCC,可以使用以下命令安装GCC:

# 安装 "build-essential" 软件包,
# 会自动安装 GNU 编译器 (GCC)、GNU make、libc-dev 和其他必要的开发工具和库,
# 确保你能够编译和构建源代码程序
sudo apt-get install build-essential

如果你只想单独安装GCC编译器,可以使用以下命令:

sudo apt-get install gcc
# 如果想指定安装版本,例如指定GCC版本为7
# sudo apt-get install gcc-7

如果有多个版本的GCC,想要在多版本之间切换

  1. 先将需要的版本添加到update-alternatives中。例如,在命令 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 50 中,数字 50 表示正在安装的备选项的优先级。
    update-alternatives 命令用于管理指向提供类似功能的不同程序的符号链接。在这种情况下,它用于管理 gcc 编译器的符号链接。优先级值用于确定默认情况下应使用哪个备选项,当有多个备选项可用时。更大的值表示更高的优先级。在这种情况下,gcc-5 的优先级为 50,gcc-7 的优先级为 70这意味着在Auto mode下将优先选择gcc-7
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 50
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70
  1. 手动配置update-alternatives
sudo update-alternatives --config gcc

mac上好用的java反编译工具_优先级_04

mac上好用的java反编译工具_ubuntu_05

3.2 安装依赖库

工具

库名称

安装命令

FreeType

The FreeType Project

sudo apt-get install libfreetype6-dev

CUPS

Common UNIX Printing System

sudo apt-get install libcups2-dev

X11

X Window System

sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev

ALSA

Advanced Linux Sound Architecture

sudo apt-get install libasound2-dev

libffi

Protable Foreign Function Interface Library

sudo apt-get install libffi-dev

Autoconf

Extensible Package of M4 Macros

sudo apt-get install autoconf

3.3 安装Bootstrap JDK

假设要编译大版本号为mac上好用的java反编译工具_mac上好用的java反编译工具_06的JDK,我们要另外准备一个大版本号为mac上好用的java反编译工具_mac上好用的java反编译工具_07的、已经编译好的JDK,这是因为OpenJDK由多个部分(HotSpot、JDK类库、JAXWS…)组成,其中一部分(HotSpot)代码使用C、C++编写,而更多的代码则是使用Java来实现,因此编译这些Java代码就要用到JDK,官方称这个JDK为“Bootstrap JDK”。例如,编译OpenJDK 12时,Bootstrap JDK必须使用JDK11及之后的版本。

在Ubuntu中安装OpenJDK 11的命令如下:

sudo apt-get install openjdk-11-jdk

4.编译

需要下载的编译环境和依赖项目都齐备后,我们就可以按照默认配置来开始编译了。但通常我们编译OpenJDK的目的都不仅仅是为了得到在自己机器中诞生的编译成品,而是带着调试、定制化等需求,这样就必须了解OpenJDK提供的编译参数才行。

一些编译参数:

编译参数

说明

–with-debug-level=<level>

设置编译级别,可选值为release、fastdebug、slowdebug,越往后进行的优化措施就越少,带的调试信息就越多。默认模式为release。

–enable-debug

等效于–with-debug-level=fastdebug。

–with-native-debug-symbols=<method>

确定调试符号信息的编译方式,可选值为none、internal、external、zipped。

–with-version-string=<string>

设置编译JDK的版本号,例如java -version的输出就会显示该信息。

–with-jvm-variants=<variant>[,<variant>…]

编译特定模式的HotSpot虚拟机,可以多个模式并存,可选值为server、client、minimal、core、zero、custom。

–with-target-bits=<bits>

指明要编译32位还是64位的Java虚拟机。

–with-conf-name=<name>

指定编译配置名称,默认根据编译的操作系统、指令集架构、调试级别自动生成一个配置名称。例如,linux-x86_64-server-release。

以上是configure命令的部分参数,其他参数可以使用bash configure --help命令查询到。

所有参数通过以下形式使用:

bash configure [options]

例如,编译FastDebug版、仅含Server模式的HotSpot虚拟机,命令如下:

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

如果在检查配置中缺少依赖,直接按照提示安装即可,可能出现的问题:

  1. configure: error: Cloud not find fontconfig! You might be able to fix this by running ‘sudo apt-get install libfontconfig1-dev’.

配置成功的信息如下:

mac上好用的java反编译工具_优先级_08

最后,通过make命令编译。编译完成如下:

mac上好用的java反编译工具_ubuntu_09

进入OpenJDK源码的“build/配置名称/jdk”目录下,就可以看到完整的编译结果了。目录结构如下:

mac上好用的java反编译工具_java_10

如果多次编译,或者目录结构成功产生后又再次修改了配置,必须先使用make cleanmake dist-clean命令清理目录,才能确保配置生效。

在当前目录下,使用./bin/java -version进行验证,可以看到是我们编译的OpenJDK 12版本。

mac上好用的java反编译工具_java_11