Mac M1 编译OpenJDK
参考文献
- OpenJDK-编译 (mac)
- OpenJDK-调试 (CLion)
- 优雅地在Mac OS Catalina下 编译 Open JDK 13
- 编译及调试OpenJDK18|Understanding the JVM
- win10上构建并调试openjdk 11
MBP M1
编译OpenJDK
- 环境说明:
macOs: Sonoma 14.1.2 (23B92)
- 编译
OpenJDK
版本: jdk-23+4 - 使用的
boot jdk
版本: jdk-21.0.1+12
环境准备
1 | brew install FreeType |
安装XCode
-
安装完成后
1
xcode-select -s /Applications/Xcode.app/Contents/Developer
下载OpenJDK
源码
下载Boot JDK
- https://adoptium.net/zh-CN/temurin/releases/?version=21&os=mac&arch=aarch64&package=jdk
- 此处选择的是:
JDK21-LTS
编译
-
解压
OpenJDK
包,进入解压后的文件夹1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18╭─ ~/CLionProjects/jdk23
╰ cd jdk-jdk-23-4
╭─ ~/CLionProjects/jdk23/jdk-jdk-23-4
╰ ll
total 88
-rw-rw-r--@ 1 holelin staff 2.1K 1 4 09:36 ADDITIONAL_LICENSE_INFO
-rw-rw-r--@ 1 holelin staff 1.5K 1 4 09:36 ASSEMBLY_EXCEPTION
-rw-rw-r--@ 1 holelin staff 101B 1 4 09:36 CONTRIBUTING.md
-rw-rw-r--@ 1 holelin staff 19K 1 4 09:36 LICENSE
-rw-rw-r--@ 1 holelin staff 2.7K 1 4 09:36 Makefile
-rw-rw-r--@ 1 holelin staff 424B 1 4 09:36 README.md
drwxrwxr-x@ 7 holelin staff 224B 1 4 09:36 bin
drwxr-xr-x 5 holelin staff 160B 1 11 00:09 build
-rw-rw-r--@ 1 holelin staff 1.7K 1 4 09:36 configure
drwxrwxr-x@ 12 holelin staff 384B 1 4 09:36 doc
drwxrwxr-x@ 60 holelin staff 1.9K 1 4 09:36 make
drwxrwxr-x@ 75 holelin staff 2.3K 1 4 09:36 src
drwxrwxr-x@ 13 holelin staff 416B 1 4 09:36 test -
编译
1
# bash configure --with-boot-jdk=/Users/holelin/JavaEnv/jdk_compiler/jdk-21.0.1+12/Contents/Home --with-debug-level=slowdebug --enable-dtrace --with-jvm-variants=server --with-target-bits=64 --disable-ccache --with-num-cores=8 --with-memory-size=8000 --disable-warnings-as-errors
--with-boot-jdk=/Users/holelin/JavaEnv/jdk_compiler/jdk-21.0.1+12/Contents/Home
:- 指定用于引导(bootstrap)构建过程的 JDK 的路径.在这里,你正在指定一个 JDK 的路径,用于构建 OpenJDK.
--with-debug-level=slowdebug
:- 指定构建的调试级别.
slowdebug
是一种调试级别,它提供更多的调试信息,但相对于其他级别构建速度较慢.
- 指定构建的调试级别.
--enable-dtrace
:- 启用 DTrace 支持.DTrace 是一种动态跟踪框架,用于在运行时监测和分析系统和应用程序的性能.
--with-jvm-variants=server
:- 指定 JVM 变体.在这里,选择了
server
变体,它通常用于生产环境,提供了更好的性能.
- 指定 JVM 变体.在这里,选择了
--with-target-bits=64
:- 指定目标系统的位数.在这里,指定了 64 位目标系统.
--disable-ccache
:- 禁用 ccache,这是一个用于缓存编译结果的工具.在一些构建过程中,ccache 可能会导致问题,禁用它可能是一个解决方案.
--with-num-cores=8
:- 指定构建过程中并行编译的线程数.在这里,指定了 8 个线程.
--with-memory-size=8000
:- 指定 JVM 内存大小,单位为兆字节.在这里,指定了 8000MB(8GB)的内存大小.
--disable-warnings-as-errors
:- 禁用将编译警告视为错误的选项.通常,编译器会将警告当作错误来处理,但这里禁用了这个行为.
-
configure
执行成功后如下所示 -
编译
1
make images
- 编译会耗时一段时间
-
编译后会生成如下文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28╭─ ~/CLionProjects/jdk23/jdk-jdk-23-4
╰ cd build
╭─ ~/CLionProjects/jdk23/jdk-jdk-23-4/build
╰ ll
total 0
drwxr-xr-x 21 holelin staff 672B 1 11 10:09 macosx-aarch64-server-slowdebug
╭─ ~/CLionProjects/jdk23/jdk-jdk-23-4/build
╰ cd macosx-aarch64-server-slowdebug
╭─ ~/CLionProjects/jdk23/jdk-jdk-23-4/build/macosx-aarch64-server-slowdebug
╰ ll
total 14352
-rw-r--r-- 1 holelin staff 1.3K 1 11 10:09 Makefile
-rw-r--r-- 1 holelin staff 2.3K 1 11 10:09 bootcycle-spec.gmk
-rw-r--r-- 1 holelin staff 37K 1 11 00:42 build.log
-rw-r--r-- 1 holelin staff 241B 1 11 00:40 build.log.old
-rw-r--r-- 1 holelin staff 9.3K 1 11 10:09 buildjdk-spec.gmk
drwxr-xr-x 16 holelin staff 512B 1 10 23:57 buildtools
-rwxr-xr-x 1 holelin staff 3.9K 1 11 10:09 compare.sh
-rw-r--r-- 1 holelin staff 6.9M 1 11 00:10 compile_commands.json
drwxr-xr-x 5 holelin staff 160B 1 11 10:09 configure-support
-rw-r--r-- 1 holelin staff 19K 1 11 10:09 configure.log
-rw-r--r-- 1 holelin staff 19K 1 11 00:09 configure.log.old
drwxr-xr-x 3 holelin staff 96B 1 10 23:50 hotspot
drwxr-xr-x 8 holelin staff 256B 1 10 23:58 images
drwxr-xr-x 12 holelin staff 384B 1 10 23:56 jdk
drwxr-xr-x 11 holelin staff 352B 1 11 00:40 make-support
-rw-r--r-- 1 holelin staff 38K 1 11 10:09 spec.gmk
drwxr-xr-x 30 holelin staff 960B 1 10 23:57 support -
验证
- 进入
${openjdk源码目录}/build/macosx-aarch64-server-slowdebug/jdk/bin
下
1
2
3
4
5╭─ ~/CLionProjects/jdk23/jdk-jdk-23-4/build/macosx-aarch64-server-slowdebug/jdk/bin
╰ ./java -version
openjdk version "23-internal" 2024-09-17
OpenJDK Runtime Environment (slowdebug build 23-internal-adhoc.holelin.jdk-jdk-23-4)
OpenJDK 64-Bit Server VM (slowdebug build 23-internal-adhoc.holelin.jdk-jdk-23-4, mixed mode)- 出现上述信息,则表示编译成功
- 进入
编译过程中遇到的问题
1 | configure: error: No xcodebuild tool and no system framework headers found, use --with-sysroot or --with-sdk-name to provide a path to a valid SDK |
- 解决办法:安装
XCode
,可在App Store
中直接安装
使用Clion
打开编译好的项目
-
需要先试用命令生成
compile_commands.json
文件1
2
3
4
5
6╭─ ~/CLionProjects/jdk23/jdk-jdk-23-4
╰ make compile-commands
Building target 'compile-commands' in configuration 'macosx-aarch64-server-slowdebug'
Cleaning compile-commands make support artifacts ... done
Updating compile_commands.json
Finished building target 'compile-commands' in configuration 'macosx-aarch64-server-slowdebug'- 该文件会生成在
macosx-aarch64-server-slowdebug
目录下
- 该文件会生成在
-
打开
CLion
,操作路径:File > Open > compile_commands.json
文件,选择Open as Project
-
之后
CLion
会做扫描和index
,但是这时候还看不到源码相关的文件和目录,因为此时根目录是${openjdk源码目录}/build/macosx-x86_64-server-slowdebug
, 需要更改项目根目录. -
操作路径:
Tools -> Compilation Database -> Change Project Root
,选中OpenJDK
的源码根目录,CLion
再次扫描文件和建立index
,结束后就可以看到源码了,且不会提示无法找到头文件
调试
-
需要配置构建目标,操作路径:
Preferences > Build, Exceution, Deployment > Custom Build Targets
-
最终打开
Edit Tool
编辑小面板,其中Tool Settings
几个参数内容分别是:Field Content Program
make
Arguments
CONF=macosx-aarch64-server-slowdebug
Working directory
${openjdk源码目录}
Field Content Program
make
Arguments
CONF=macosx-aarch64-server-slowdebug clean
Working directory
${openjdk源码目录}
验证调试
调试java -version
- 在
CLion
右上方打开 **Edit Configurations
**面板
- 在
src/java.base/share/native/libjli/java.c
文件的JavaMain()
方法上打上断点,点击右上角的debug
,然后代码运行会停在断点处.
调试技巧
上述实现了JDK的增量编译和运行,如果要调试,还需要一些额外的设置.
调试过程中会出现
SIGSEGV
信号而导致调试不能继续进行,这是因为调试器默认会捕获这些信号,调试器以为程序运行出错,于是退出了.但实际上,SIGSEGV
的出现是 Hotspot 运行的正常逻辑,Hotspot 自己会捕获该信号然后做处理,所以我们要配置调试器忽略这些信号.在进入第一个断点的时候在LLDB下执行以下命令
pro hand -p true -s false SIGSEGV SIGBUS
可以避免此类问题.不过每次debug的时候都要输入这么一句就很麻烦,所以我们可以在**
~/.lldbinit
**文件中,使用如下命令,实现每次Debug时自动打个断点,然后输入pro hand -p true -s false SIGSEGV SIGBUS
,最后继续执行后续流程,文件内容如下(其中main.c文件的路径自行替换)breakpoint set --file /Users/naver/jvm/jdk12-06222165c35f/src/java.base/share/native/launcher/main.c --line 98 -C "pro hand -p true -s false SIGSEGV SIGBUS" --auto-continue true
上述引用中提到的信号,在本文环境中调试,捕捉到的信号是
SIGILL
,因此需要配置的SIGSEGV
和SIGBUS
替换为SIGILL,LLDB
调试器将忽略这类信号.
~/.lldbinit
为~/路径下的.lldbinit文件
,也即LLDB的初始配置文件(如果不存在的话可以自行创建).JetBrains官方文档提到了两个个更优的方案:
- 在
~/.lldbinit
中输入settings set target.load-cwd-lldbinit true
并保存,将允许LLDB
在初始化时读取项目根目录路径下的.lldbinit
文件;- 在项目根目录路径下创建
.lldbinit
文件,并输入br set -n main -o true -G true -C "pro hand -p true -s false SIGILL"
,将忽略SIGILL
信号并不需要添加断点.至此我们可以正常调试JDK源码