mac编译jdk12并用Clion调试踩坑笔记

前言

才开始看《深入理解Java虚拟机》�这本书,里面第一章就让我们编译jdk,记录一下踩坑的过程。

环境如下

Mac OS 11.1

xcode-select version 2384.

Apple clang version 12.0.0 (clang-1200.0.32.28)

CLion 20202.4

照着书上编译完后,说需要修改CMakeList.txt,否则用Clion进行调试的时候一些头文件会标红。

发现还是JetBrain官方推荐了另一种方法,Tips & Tricks: Develop OpenJDK in CLion with Pleasure
可以先看我的错误记录,修改了源码之后再直接看官方的然后跳到调试部分。

但是只看源码的话vscode 或许也是个很不错的选择,它最起码不会显示include的文件not found

编译jdk12

从http://hg.openjdk.java.net/jdk/jdk12/file/06222165c35f下载jdk12

安装如下依赖

brew install mercurial
brew install autoconf
brew install freetype
brew install ccache

下载jdk11,我原来就下载好了jdk,可以用brew安装jdk11

修改vim ~/.bash_profile,这一步不是必须

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/
export JAVA_11_HOME=/Library/Java/JavaVirtualMachines/jdk-11.0.8.jdk/Contents/Home/

#alias命令动态切换jdk版本
alias jdk8="export JAVA_HOME=$JAVA_8_HOME"
alias jdk11="export JAVA_HOME=$JAVA_11_HOME"

之后在终端输入jdk8或jdk11可以自动切换。

执行configure命令

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

之后可以看到一些配置信息,其中boot jdk是jdk11,而我系统中当前jdk是jdk8,所以它会��自动找到N-1版本的JDK,

之后可在build目录下生成一个配置目录,之后如果进行多次编译,或者目录产生后又修改了配置,记得先使用make cleanmake dist-clean

进入这个配置目录,查看生成文件,发现和书上的不太一样

$ tree
.
├── Makefile
├── bootcycle-spec.gmk
├── buildjdk-spec.gmk
├── compare.sh
├── configure-support
│   ├── classes.jsa
│   ├── config.log
│   └── config.status
├── configure.log
└── spec.gmk

编译

输入命令,加入compile-commands参数生成的是compilation database,如果不加这个参数,导入clion头文件一直都是红的,找不到路径。

$ sudo make compile-commands

错误记录

错误一

make images时候出现

错误二

打开该文件将这一行注释了,重新执行sudo make clean&&sudo make dist-clean,再执行出现以下错误

参考https://codingnote.cc/p/234919/进行修改,其中在sharedRuntime.cpp上有两处

image

错误三:

src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m:134:9: error: converting the result of '?:' with integer constants to a boolean always evaluates to 'true' [-Werror,-Wtautological-constant-compare]
 if (colorIndex < (useAppleColor) ? sun_lwawt_macosx_LWCToolkit_NUM_APPLE_COLORS : java_awt_SystemColor_NUM_COLORS) {
     ^
   1 error generated.

参考https://github.com/openjdk/jdk/commit/4622a18a

最后出现下面的信息,就相当于编译成功了

Creating jdk image
Creating CDS archive for jdk image
Stopping sjavac server
Finished building target 'images' in configuration 'macosx-x86_64-server-fastdebug'

执行

make CONF=macosx-x86_64-server-fastdebug

进入jdk12/build/macosx-x86_64-server-fastdebug/jdk/bin目录查看编译的java版本

$ ./java -version
openjdk version "12-internal" 2019-03-19
OpenJDK Runtime Environment (fastdebug build 12-internal+0-adhoc.root.jdk12)
OpenJDK 64-Bit Server VM (fastdebug build 12-internal+0-adhoc.root.jdk12, mixed mode)

至此,证明我们已经编译完成了 JDK12

compile-commands配置方式解释

在构建一个slowdebug

bash configure --with-debug-level=slowdebug --with-jvm-variants=server
make CONF=macosx-x86_64-server-slowdebug compile-commands
make CONF=macosx-x86_64-server-slowdebug

我debug级别为slowdebug,JetBrain推荐是fastdebug,我为了将两个编译的jdk项目区分

第一个make时候使用了CONF参数,指定了要编译某个具体的配置,如果只有一个配置,可以省略,但我是编译了fastdebugslowdebug两个级别的JDK,所以使用了这个参数,执行完该命令,就会在${source_root}/build/macosx-x86_64-server-slowdebug下生成compile_commands.json文件。

第二个make是在导入CLion之前,要编译一下,因为某些模块使用了预编译头,如果不编译,CLion会在索引过程中提示找不到各种各样的文件。执行以下命令进行编译:

CLion 调试

因为正常情况下直接导入项目文件,会生成CmakeList.txt,书上说我们需要修改这个CmakeList.txt,而我不知道怎么修改,JetBrain官方给我们回答了这个问题。Tips & Tricks: Develop OpenJDK in CLion with Pleasure

生成Compilation Database,然后导入的时候选择compile_commands.json这个文件就好了

所以我用JetBrain官方的方法和通过 compile-commands参数编译之后的jdk和不通过compile-commands参数编译的jdk�也是和下面一样的配置。所以可以一起使用。

配置Toolchains

点击configurations,通过preference进入设置

image

选择Open or Import选择compile-commands.json最后一定选上Open as Project,然后会等待一段时间的索引

再点最上方的Tools->CMake->Change Project Root,将根目录修改为jdk12所在的目录,就是包含build的目录

配置 Build Targets

配置make,Arguments要加CONF=

配置clean,注意Arguments除了要在前面加CONF= 最后还要加上clean

配置Run/Debug configurations

这里的java是编译之后的那个路径下的java二进制文件,即jdk12/macosx-x86_64-server-fastdebug/jdk/bin/java

${source_root}/src/java.base/share/native/libjli/java.c的JavaMain函数打断点,点击Debug,效果如下:

以下内容复制自参考博客

SIGSEGV代表指针所对应的地址是无效地址,没有物理内存对应该地址。其实还有一个,是SIGBUS,代表指针所对应的地址是有效地址,但总线不能正常使用该指针,通常是未对齐的数据访问所致。

MacOSCLion默认使用LLDB进行Debug,所以要避免这种情况,可以通过在进入第一个断点时,执行以下命令避免后面出现此类问题:

# LLDB使用如下命令,GDB暂不讨论,原理基本一致,可以自行搜索
pro hand -p true -s false SIGSEGV SIGBUS

这样虽然可以解决问题,但如果每次Debug都手动修改,会很繁琐。在JetBrains的文章Develop OpenJDK in CLion with Pleasure中,文末也提到了解决这种问题,但我试了一下,却总是不生效,也没找到是什么原因。

不过最后在这个博客中找到了一个解决方案,博主提到,LLDB只支持Session级别的忽略设置(GDB貌似支持全局,感兴趣的同学可以尝试),就是需要先启动Debug,打断点,然后执行忽略命令,才可以生效。然后博主提出了一种解决方案,在~/.lldbinit文件中,使用如下命令,实现每次Debug时自动打个断点,然后输入pro hand -p true -s false SIGSEGV SIGBUS,最后继续执行后续流程,文件内容如下(其中main.c文件的路径自行替换):

breakpoint set --file /Users/XXX/XXX/XXX/jdk12/src/java.base/share/native/launcher/main.c --line 98 -C "pro hand -p true -s false SIGSEGV SIGBUS" --auto-continue true

最后,在控制台查看输出。

修改CMakeList.txt的一点思路

思路一

因为slowdebug和fastdebug是在jdk12下的build目录下,导入的时候都将jdk12设置为project的根目录了,前者是compile-commands命令生成的,使用diffmerge查看两者有什么不一样的地方

逐渐往下翻,发现它们的不同在于除了一些命名,fastdebug多了些slowdebug没有的一点点东西,其余的slowdebug有的fastdebug的都有,那是不是可以合理猜测我根本就不用修这个CMakeList.txt了?

为了验证,我又将fastdebug重新编译了一遍作为对比,如下图,左边是新的参数为compile-commands,右边是旧的

他们的区别和前面的图其实是一样的。只不过之前是使用了make images命令,多了点东西。

建议还是用创建compilation database的方法。

思路二

打开https://github.com/ojdkbuild/ojdkbuild/tree/master/src,看到只有jdk8,11,13,15,没有12怎么办,我去历史记录里找到了12的CMakeList.txt,就是如下链接,下一步就是复制粘贴大法了

https://github.com/ojdkbuild/ojdkbuild/blob/599bc0f760b53e1ecf12777e0443ca991129c3a6/src/java-12-openjdk/CMakeLists.txt

但是这条路还是走不通

你可能感兴趣的:(mac编译jdk12并用Clion调试踩坑笔记)