2019-12-14 更新

  1. 更新了下载源码的方式
  2. 更新了参数
  3. 更新了 CLion 的配置

最近准备花点时间看看 JVM 的源码,所以要在本地编译调试一下。我有一台 Linux 台式机, 一台 Macbook Pro (macOS Catalina)。在 Linux 上还是比较方便的,照着文档一遍就编译成功了。但是在 Mac 上就踩了几个坑。这里来记录一下,希望遇到相似问题的朋友们有缘可以读到这篇文章。

编译 @ Mac

我最开始是借鉴了这篇文章。简单来说包含这几步:

  1. 下载源码
  2. 安装依赖
  3. 执行 configure
  4. 编译

先列出我最后执行的指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 下载源码, 这里就不赘述了
cd openjdk10

# 安装依赖
## ccache 是用于编译缓存
brew install freetype ccache

# 执行 configure.
## 之所以设置 with-boot-jdk 是因为我安装了多个 JDK 版本。
## 另外,虽然文档说可以用 openjdk 9 或者 10 来编译,但是 openjdk 10 之后移除了 javah,所以建议还是用 openjdk 9。
bash configure \
--with-debug-level=slowdebug --enable-dtrace \
--with-jvm-variants=server --with-target-bits=64 \
--enable-ccache --with-num-cores=6 --with-memory-size=8000 \
--disable-warnings-as-errors \
--with-freetype=/usr/local \
--with-extra-cflags=-stdlib=libc++ --with-extra-cxxflags=-stdlib=libc++ --with-extra-ldflags=-stdlib=libc++ \
--with-boot-jdk=/Library/Java/JavaVirtualMachines/adoptopenjdk-9.jdk/Contents/Home

# 编译
make images

下面是我在编译过程中遇到的几个问题:

源码下载

实际上不算是一个问题。如果你用 hg 来下载,因为需要下载所有编辑历史,会比较慢。如果你不需要历史的话,可以去下载压缩包

找不到 FreeType

我使用了 homebrew 来安装 freetype,只需要一条简单的命令:

1
brew install freetype

但是在执行 configure 的时候,还是报找不到 freetype 头文件的问题。报错信息很有用,直接告诉我可以配置 --with-freetype-include 来手动指定路径。在 Mac 下头文件被放在了 /usr/local/include 这个路径中,在 configure 的时候加上 --with-freetype=/usr/local 即可 (之所以用 --with-freetype 是因为只设定头文件不够,还需要指定 dylib 的路径)。

找不到 new 头文件

在运行完 configure 之后执行 make images 时,遇到了报错信息 'new' cannot be found,大意就是找不到 new 这个头文件。报错信息也提示我要加上 -stdlib=libc++ 这个编译参数,但是没说要怎么加。最开始,我很快在文档里找到了 --with-extra-cxxflags 这个 configure 参数,加上了之后发现还是报一样的错。我以为打开方式不对,就去 google 了一下。网上众说纷纭,还有说要把老版本 macOS 的头文件拷贝下来的。。。最后开始通过错误日志发现编译使用了 clang,而不是 clang++(我看文件名是 .hpp 就以为指定 cxx 就可以了),加上 --with-extra-cflags=-stdlib=libc++ 就可以编译成功了。

调试 @ Mac

对我个人来说,只是编译通过,肯定是没法满足代码阅读的需求的。最少最少也得有 go to definition 的功能吧。JVM 是用 C++ 实现的,如果能用一个支持 C++ 的 IDE 肯定能让你事半功倍。之前 C++ 项目一直用 CLion,所以这次也选择了它。

作为 JetBrain 旗下的产品,CLion 的质量肯定不用多说。但是 CLion 只支持自动导入和索引使用 CMake 构建的项目。如果直接导入 openjdk 的源码,就处处飘红。这篇文章里也只是将 CLion attach 到 jvm 进程,然后可以断点而已。

之前的版本使用了 compiledb, 但我发现只在 Linux 上有效,好像是因为 gnumake 版本的问题。这里用一个笨办法,手写 CMakeList。这是我现在用的 CMakeLists.txt,欢迎使用。