事先说明:本教程不适用于Windows,只适用于macOS、Ubuntu等类Unix系统。
1.下载JDK源码
需要注意的是,编译JDK源码需要一个Boot JDK作为引导,比如JDK12,就要以JDK11或JDK12的环境作为基础,再去编译JDK源码,而且不是每个版本都能成功编译的!推荐使用新一点的版本,比如JDK1.8就有点难,要求的环境版本太低了。也就是我要编译JDK11源码,还需要我主机上有JDK11/JDK10的环境。
先下载JDK源码,我这里使用的是JDK11的源码进行编译(推荐使用,其他版本有可能不能编译成功)
http://jdk.java.net
使用wget或者直接下载的方式,下载并解压,会得到一个openjdk的文件夹。
2.安装环境和进行项目构建
2.1 XCode--macOS必备神器
Xcode9.1+
,并且低于XCode12.2
,我这里使用的是XCode11.5
。
需要注意的是:高于12.2的XCode会缺依赖,不能使用,必须使用XCode12.2以下的版本,太高版本自带的XCode版本可能比较高。
XCode
官方下载路径:https://developer.apple.com/download/all/
2.2 antoconf和freetype
正常来说都可以用home brew进行安装,但是我只安装成功了freetype,autoconf报404,于是我采用源码直接安装的方式。
必须安装的哟,下面给出链接,需要安装的依赖有下面这两个
https://download.savannah.gnu.org/releases/freetype/
http://ftp.gnu.org/gnu/autoconf/
下载完之后,手动使用它们的源码进行安装,两个依赖都采用这种方式安装。
cd xxxx #进入对应的项目根目录
./configure
sudo make
sudo make install
安装之后,当然是配置环境变量咯~这个大家应该都会吧。
2.3 进入jdk根目录,依次执行下面命令
sh configure
make all
make images #打成镜像,成为和我们真实的JDK一样,有bin文件。
这个过程会比较漫长。。。。应该起码得十几分钟吧。
关于执行过程中可能遇到的报错:
- 1.error: C++11 was disabled in PCH file but is currently enabled
这个百度上没有解决方案,但是解决方案其实在官方文档中有写(jdk根目录/doc目录下有文档),但是靠自己解决太难了。我搞了七八个小时,最后全局搜索英文的doc文档才找到了解决方法。
最终解决方法如下:
sh configure --disable-warnings-as-errors --disable-precompiled-headers --with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked"
需要说明的是:--disable-warnings-as-errors
的作用是关闭将警告当成错误的检查,--disable-precompiled-headers
的作用是关闭预编译头文件,--with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked"
的作用的话是设置JVM运行时参数为忽略相关的过时/类型强转的警告。
如果需要对HotSpotVM源码进行debug,使用如下命令
sh configure --disable-warnings-as-errors --disable-precompiled-headers --with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked" --enable-debug
执行成功之后...会在jdk源码根路径/build/xxx-release/images/jdk/
或者/build/xxx-fastdebug/images/jdk/
目录下生成我们安装版的jdk,接着要做的就是导入IDEA。这个会根据你之前配置的来决定,如果有使用debug的话就是第二个。
- 2.
No xcodebuild tool and no system framework headers
,解决方法:安装XCode
并执行命令sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
在SDK这里增加一项自己的源码的jdk,选择主路径。
应用,并更改项目结构/模块中的JDK为你配置的JDK。
测试,写一个HelloWorld,发现使用的JDK是我们编译好的JDK,并且执行成功!
编译源码肯定会想在源码中写注释,或者改源码,那么应该怎么做?上面配置之后,源码还只是只读文档而已。
我们下面来进行修改:
将源路径中的全部内容删掉,替换为我们下载的源码环境,也就是jdk源码根路径/src/
下的全部,然后点击应用、确认,等待IDEA重新编制索引即可。
编制索引成功再次进行测试,尝试直接动源码,如果能改了,说明配置成功了!
但是配置成功之后我们对源码并不能生效,那么要怎么样生效呢?重新使用make images
编译一遍,这里是增量改变,会比之前快很多。
还有可能出现写了中文注释,出现乱码的,应该怎么解决?
通过VSCode,全局搜索encoding ascii
,并指定文件路径为./make
将源码中的ascii
改为utf-8
,重新进行编译(改了任何源码都得重新构建!),成功!完成!
3. 在IDE中进行HotSpotVM的调试
事先说明:需要使用debug模式构建,也就是在构建时使用了基于debug模式进行构建
3.1 使用Clion导入HotSpotVM项目并进行调试
需要注意的是:应该导入的项目是openjdk/src/
,而不是openjdk的整个代码。
3.1.1 Clion IDE会自动弹出生成cMakefileList.txt
3.1.2 创建运行配置
- 1.需要指定执行文件为
openjdk/build/macosx-x86_64-normal-server-fastdebug/jdk/bin/java
。 - 2.指定环境变量为要运行的类的类路径(生成的目标文件的路径,应该为
classes
目录下)。 - 3.程序参数用于指定主类的全类名,比如
CLASSPATH=com.wanna.TestMain
。
3.1.3 打断点和调试
给hotspot/share/runtime/thread.cpp
的create_vm
函数打上断点,并进行调试。
3.2 使用VSCode导入HotspotVM项目并进行调试
在当前目录下的.vscode/launch.json
中配置如下内容,需要自行修改参数主要有
- 1.
program
,指定生成的jdk镜像下的java可执行文件路径; - 2.
environment
中的value
改为之前的环境变量,也就是对应Clion中配置的CLASSPATH=xxx
; - 3.
args
中指定类名(含包名,如com.wanna.TestMain
)
{
"version": "0.2.0",
"configurations": [
{
"name": "jdk11s-src",
"type": "cppdbg",
"request": "launch",
"program": "/Users/wanna/Desktop/Code/java/jdksrc/openjdk11s/build/macosx-x86_64-normal-server-fastdebug/jdk/bin/java", //要运行的目标程序
"args": [
"com.wanna.TestMain" //要运行的.class文件的包名
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [ //配置环境变量
{
"name": "CLASSPATH",
"value": "/Users/wanna/Desktop/Code/java/jdksrc/jdk_debug/target/classes"
},
],
"externalConsole": false,
"MIMode": "lldb",
// "preLaunchTask": "jdk11s-build" //运行编译任务
}
]
}
同样,给hotspot/share/runtime/thread.cpp
的create_vm
函数打上断点,并进行调试。
个人博客:http://wanna1314y.top:8090/