MacOS编译OpenJDK9

code

环境准备

macOS High Sierra,版本 10.13.6

安装brew

如果没有安装,参考这里,命令:

1
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装mercurial

openjdk代码由hg管理,命令:

1
$ brew install mercurial

安装ccache

ccache可以提高编译速度,命令:

1
$ brew install ccache

安装freetype

freetype编译需要,命令:

1
$ brew install freetype

编译

源码下载

1
2
3
4
5
6
7
8
# clone到指定目录
$ hg clone http://hg.openjdk.java.net/jdk9/jdk9 YourOpenJDK

# 进入下载目录
$ cd YourOpenJDK

# 执行下载命令
$ bash ./get_source.sh

编译配置

1
$ bash configure --with-target-bits=64 --with-freetype=/usr/local/Cellar/freetype/2.9.1 --enable-ccache --with-jvm-variants=server,client --with-boot-jdk-jvmargs="-Xlint:deprecation -Xlint:unchecked" --disable-warnings-as-errors --with-debug-level=slowdebug 2>&1 | tee configure_mac_x64.log

注意需要修改命令中的freetype版本号

编译参数简介:

1
2
3
4
5
6
7
8
9
--with-target-bits:设置32位/64位编译
--with-freetype:设置freetype路径
--enable-ccache:设置启用ccache
--with-jvm-variants=client,server:为了保证兼容性,编译时JVM的Client和Server都会被编译
--with-boot-jdk-jvmargs:提供运行Bootstrap JDK所需要的JVM参数
--disable-zip-debug-info:禁用zip调试信息
--disable-warnings-as-errors:禁用将警告当做错误,避免因为警告而中断编译
--with-debug-level:设置调试等级
2>&1 | tee configure_mac_x64.log:将错误信息重定向至标准输出,并输出到configure_mac_x64.log

编译配置创建完成后控制台输出:

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
A new configuration has been successfully created in
/Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug
using configure arguments '--with-target-bits=64 --with-freetype=/usr/local/Cellar/freetype/2.9.1 --enable-ccache --with-jvm-variants=server,client --with-boot-jdk-jvmargs='-Xlint:deprecation -Xlint:unchecked' --disable-warnings-as-errors --with-debug-level=slowdebug'.

Configuration summary:
* Debug level: slowdebug
* HS debug level: debug
* JDK variant: normal
* JVM variants: server client
* OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64
* Version string: 9-internal+0-adhoc.yier.jdk9 (9-internal)

Tools summary:
* Boot JDK: java version "1.8.0_181" Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode) (at /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home)
* Toolchain: clang (clang/LLVM)
* C Compiler: Version 10.0.0 (at /usr/bin/clang)
* C++ Compiler: Version 10.0.0 (at /usr/bin/clang++)

Build performance summary:
* Cores to use: 4
* Memory limit: 8192 MB
* ccache status: Active (3.6)

NOTE: You have requested to build more than one version of the JVM, which
will result in longer build times.

编译

1
2
3
4
5
# 设定语言选项
$ export LANG=C

# 编译命令并输出日志到文件
$ make all LOG=debug 2>&1 | tee make_mac_x64.log

编译完成后控制台输出:

1
Finished building target 'all' in configuration 'macosx-x86_64-normal-serverANDclient-slowdebug'

编译错误

问题一

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
29
30
31
=== Output from failing command(s) repeated here ===
/usr/bin/printf "* For target hotspot_variant-client_libjvm_objs_virtualspace.o:\n"
* For target hotspot_variant-client_libjvm_objs_virtualspace.o:
(/usr/bin/grep -v -e "^Note: including file:" < /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs/hotspot_variant-client_libjvm_objs_virtualspace.o.log || true) | /usr/bin/head -n 12
../src/share/vm/memory/virtualspace.cpp:584:14: error: ordered comparison between pointer and zero ('char *' and 'int')
if (base() > 0) {
~~~~~~ ^ ~
1 error generated.
if test `/usr/bin/wc -l < /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs/hotspot_variant-client_libjvm_objs_virtualspace.o.log` -gt 12; then /bin/echo " ... (rest of output omitted)" ; fi
/usr/bin/printf "* For target hotspot_variant-server_libjvm_objs_lcm.o:\n"
* For target hotspot_variant-server_libjvm_objs_lcm.o:
(/usr/bin/grep -v -e "^Note: including file:" < /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs/hotspot_variant-server_libjvm_objs_lcm.o.log || true) | /usr/bin/head -n 12
../src/share/vm/opto/lcm.cpp:42:35: error: ordered comparison between pointer and zero ('address' (aka 'unsigned char *') and 'int')
if (Universe::narrow_oop_base() > 0) { // Implies UseCompressedOops.
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~
1 error generated.
if test `/usr/bin/wc -l < /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs/hotspot_variant-server_libjvm_objs_lcm.o.log` -gt 12; then /bin/echo " ... (rest of output omitted)" ; fi
/usr/bin/printf "\n* All command lines available in /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs.\n"

* All command lines available in /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs.
/usr/bin/printf "=== End of repeated output ===\n"
=== End of repeated output ===
if /usr/bin/grep -q "recipe for target .* failed" /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log 2> /dev/null; then /usr/bin/printf "\n=== Make failed targets repeated here ===\n" ; /usr/bin/grep "recipe for target .* failed" /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log ; /usr/bin/printf "=== End of repeated output ===\n" ; /usr/bin/printf "\nHint: Try searching the build log for the name of the first failed target.\n" ; else /usr/bin/printf "\nNo indication of failed target found.\n" ; /usr/bin/printf "Hint: Try searching the build log for '] Error'.\n" ; fi

No indication of failed target found.
Hint: Try searching the build log for '] Error'.
/usr/bin/printf "Hint: See common/doc/building.html#troubleshooting for assistance.\n\n"
Hint: See common/doc/building.html#troubleshooting for assistance.

make[1]: *** [main] Error 2
make: *** [all] Error 2

错误1指向文件../src/share/vm/memory/virtualspace.cpp第584行,调整为:

1
2
// if (base() > 0) {
if (base() != NULL) {

错误2指向文件../src/share/vm/opto/lcm.cpp第42行,调整为:

1
2
// if (Universe::narrow_oop_base() > 0) { // Implies UseCompressedOops.
if (Universe::narrow_oop_base() != NULL) { // Implies UseCompressedOops.

解决方案:https://bugs.openjdk.java.net/browse/JDK-8187787

问题二

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
29
=== Output from failing command(s) repeated here ===
/usr/bin/printf "* For target hotspot_variant-server_libjvm_objs_loopPredicate.o:\n"
* For target hotspot_variant-server_libjvm_objs_loopPredicate.o:
(/usr/bin/grep -v -e "^Note: including file:" < /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs/hotspot_variant-server_libjvm_objs_loopPredicate.o.log || true) | /usr/bin/head -n 12
../src/share/vm/opto/loopPredicate.cpp:903:73: error: ordered comparison between pointer and zero ('const TypeInt *' and 'int')
assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be");
~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~
../src/share/vm/utilities/debug.hpp:141:33: note: expanded from macro 'assert'
#define assert(p, ...) vmassert(p, __VA_ARGS__)
^
../src/share/vm/utilities/debug.hpp:130:9: note: expanded from macro 'vmassert'
if (!(p)) { \
^
1 error generated.
if test `/usr/bin/wc -l < /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs/hotspot_variant-server_libjvm_objs_loopPredicate.o.log` -gt 12; then /bin/echo " ... (rest of output omitted)" ; fi
/usr/bin/printf "\n* All command lines available in /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs.\n"

* All command lines available in /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/failure-logs.
/usr/bin/printf "=== End of repeated output ===\n"
=== End of repeated output ===
if /usr/bin/grep -q "recipe for target .* failed" /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log 2> /dev/null; then /usr/bin/printf "\n=== Make failed targets repeated here ===\n" ; /usr/bin/grep "recipe for target .* failed" /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log ; /usr/bin/printf "=== End of repeated output ===\n" ; /usr/bin/printf "\nHint: Try searching the build log for the name of the first failed target.\n" ; else /usr/bin/printf "\nNo indication of failed target found.\n" ; /usr/bin/printf "Hint: Try searching the build log for '] Error'.\n" ; fi

No indication of failed target found.
Hint: Try searching the build log for '] Error'.
/usr/bin/printf "Hint: See common/doc/building.html#troubleshooting for assistance.\n\n"
Hint: See common/doc/building.html#troubleshooting for assistance.

make[1]: *** [main] Error 2
make: *** [all] Error 2

错误指向../src/share/vm/opto/loopPredicate.cpp第903行,调整为:

1
2
//assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be");
assert(rng->Opcode() == Op_LoadRange || iff->is_RangeCheck() || _igvn.type(rng)->is_int()->_lo >= 0, "must be");

解决方案:https://bugs.openjdk.java.net/browse/JDK-8187787

问题三

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGILL (0x4) at pc=0x0000000102b4cc58, pid=50033, tid=6403
#
# JRE version: OpenJDK Runtime Environment (9.0) (slowdebug build 9-internal+0-adhoc.yier.jdk9)
# Java VM: OpenJDK 64-Bit Server VM (slowdebug 9-internal+0-adhoc.yier.jdk9, mixed mode, tiered, compressed oops, serial gc, bsd-amd64)
# Problematic frame:
# V [libjvm.dylib+0xd4cc58] PerfData::~PerfData()+0x8
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/yier/Documents/openjdk/jdk9/make/hs_err_pid50033.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#

[error occurred during error reporting (), id 0x4]

make[3]: *** [/Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/jdk/_packages_attribute.done] Abort trap: 6
make[2]: *** [exploded-image-optimize] Error 2

ERROR: Build failed for target 'all' in configuration 'macosx-x86_64-normal-serverANDclient-slowdebug' (exit code 2)
[ -f /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/javacservers/server.port ] && /bin/echo Stopping sjavac server && /usr/bin/touch /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/javacservers/server.port.stop; true
/bin/date '+%Y %m %d %H %M %S' | /usr/bin/awk '{ print $1,$2,$3,$4,$5,$6,($4*3600+$5*60+$6) }' > /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_end_TOTAL
/bin/date '+%Y-%m-%d %H:%M:%S' > /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_end_TOTAL_human_readable
/bin/echo `/bin/cat /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_start_TOTAL` `/bin/cat /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_end_TOTAL` TOTAL | /usr/bin/awk '{ F=$7; T=$14; if (F > T) { T+=3600*24 }; D=T-F; H=int(D/3600); M=int((D-H*3600)/60); S=D-H*3600-M*60; printf("%02d:%02d:%02d %s\n",H,M,S,$15); }' > /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_diff_TOTAL
/usr/bin/printf -- "----- Build times -------\nStart %s\nEnd %s\n%s\n%s\n-------------------------\n" "`/bin/cat /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_start_TOTAL_human_readable`" "`/bin/cat /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_end_TOTAL_human_readable`" "`/bin/ls /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_diff_* | /usr/bin/grep -v _TOTAL | /usr/bin/xargs /bin/cat | /usr/bin/sort -k 2`" "`/bin/cat /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/make-support/build-times/build_time_diff_TOTAL`" > >(/usr/bin/tee -a /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log) 2> >(/usr/bin/tee -a /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log >&2) && wait
if /usr/bin/grep -q "recipe for target .* failed" /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log 2> /dev/null; then /usr/bin/printf "\n=== Make failed targets repeated here ===\n" ; /usr/bin/grep "recipe for target .* failed" /Users/yier/Documents/openjdk/jdk9/build/macosx-x86_64-normal-serverANDclient-slowdebug/build.log ; /usr/bin/printf "=== End of repeated output ===\n" ; /usr/bin/printf "\nHint: Try searching the build log for the name of the first failed target.\n" ; else /usr/bin/printf "\nNo indication of failed target found.\n" ; /usr/bin/printf "Hint: Try searching the build log for '] Error'.\n" ; fi
----- Build times -------
Start 2019-10-16 20:52:13
End 2019-10-16 20:52:28

00:00:15 TOTAL
-------------------------

No indication of failed target found.
Hint: Try searching the build log for '] Error'.
/usr/bin/printf "Hint: See common/doc/building.html#troubleshooting for assistance.\n\n"
Hint: See common/doc/building.html#troubleshooting for assistance.

make[1]: *** [main] Error 2
make: *** [all] Error 2

注释文件hotspot/src/share/vm/runtime/perfMemory.cpp第75~77行:

1
2
3
// if (SafepointSynchronize::is_at_safepoint() && !StatSampler::is_active()) {
// PerfDataManager::destroy();
// }

解决方案:https://stackoverflow.com/questions/50678467/building-openjdk-9-on-mac-os/54954805

但是这样处理后,使用jstat监控JVM时可能会导致 内存泄露

测试验证

1
2
$ cd build/macosx-x86_64-normal-serverANDclient-slowdebug/jdk/bin/
$ ./java -version

控制台输出:

1
2
3
openjdk version "9-internal"
OpenJDK Runtime Environment (slowdebug build 9-internal+0-adhoc.yier.jdk9)
OpenJDK 64-Bit Server VM (slowdebug build 9-internal+0-adhoc.yier.jdk9, mixed mode)

参考

Mac OSX 10.12.1 编译 Openjdk 9
macOS 编译 OpenJDK 10
在 macOS 上编译 OpenJDK 8