参考文献

MBP M1编译OpenJDK

  • 环境说明: macOs: Sonoma 14.1.2 (23B92)
  • 编译OpenJDK版本: jdk-23+4
  • 使用的boot jdk版本: jdk-21.0.1+12

环境准备

1
2
3
brew install FreeType
brew install Autoconf
brew install gcc

安装XCode

  • 安装完成后

    1
    xcode-select -s /Applications/Xcode.app/Contents/Developer

下载OpenJDK源码

下载Boot JDK

img

编译

  • 解压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 变体,它通常用于生产环境,提供了更好的性能.
    • --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执行成功后如下所示

    img

  • 编译

    1
    make images
    • 编译会耗时一段时间
    img
  • 编译后会生成如下文件

    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,结束后就可以看到源码了,且不会提示无法找到头文件

    img

调试

  • 需要配置构建目标,操作路径: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源码目录}

img

img

img

img

img

验证调试

调试java -version

  • CLion右上方打开 **Edit Configurations**面板

img

  • src/java.base/share/native/libjli/java.c文件的JavaMain()方法上打上断点,点击右上角的debug,然后代码运行会停在断点处.

img

调试技巧

上述实现了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,因此需要配置的SIGSEGVSIGBUS替换为SIGILL,LLDB调试器将忽略这类信号.

~/.lldbinit~/路径下的.lldbinit文件,也即LLDB的初始配置文件(如果不存在的话可以自行创建).

JetBrains官方文档提到了两个个更优的方案:

  1. ~/.lldbinit中输入settings set target.load-cwd-lldbinit true并保存,将允许LLDB在初始化时读取项目根目录路径下的.lldbinit文件;
  2. 在项目根目录路径下创建.lldbinit文件,并输入br set -n main -o true -G true -C "pro hand -p true -s false SIGILL",将忽略SIGILL信号并不需要添加断点.

至此我们可以正常调试JDK源码