最近开始看《深入理解Java虚拟机》,出来混果然还是要还的,就从最基础的债开始还起吧。第一部分主要是编译JDK,由于个人是M1芯片,导致编译过程中出现诸多问题,网上又少有相关报错,导致花费了不少时间
System Environment
Workspace Specs | |
---|---|
OS | |
Chip | |
Xcode | |
Xcode Comand Line Tools | If you have installed homebrew before, then homebrew will automatically install it for you, and if not, please refer to this article. |
Homebrew |
Get JDK source code
First, we need to download the source code of openJDK12 from the openJDK’s official website
If the JDK’s version that we want to compile is N , then we need to prepare another JDK whose version has to be N-1 at least. That’s because part of JDK is written by Java, so we need another available JDK in compile time when we compile it, and such another JDK is officially called ‘Bootstrap JDK‘. So we need to install openJDK 11 with instruction
brew install cask adoptopenjdk11
had we install homebrew before.The directory structure is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14openjdk
├── ADDITIONAL_LICENSE_INFO
├── ASSEMBLY_EXCEPTION
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── bin
├── build
├── configure
├── doc
├── make
├── src
└── test
Configure
Execute
bash configure
in the root directory of the JDK you just get, you will get the error message like this If all goes well:1
configure: The tested number of bits in the target (64) differs from the number of bits expected to be found in the target (32) configure: error: Cannot continue.
The reason is clearly clarifed in this question:
Apple Silicon chips M1, M2 are all 64-bits architectures. Do not compiler for 32-bit
So we have to get openJDK 17, which is a relatively new version and available for M1. We also need to prepare a new Bootstrap JDK which should be Java 16. Use the same instruction
brew install cask adoptopenjdk16
Rerun
bash configure
, then you will get a new error like this:1
X 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.
As you can see from the message, sprintf is considered insecurity, but we can miss it by adding a parameter
--disable warnings as errors
, so rerunbash configure --disable warnings as errors
If you are fortunate enough, you will see success message:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21Configuration summary:
* Name: macosx-aarch64-server-release
* Debug level: release
* HS debug level: product
* JVM variants: server
* JVM features: server: 'cds compiler1 compiler2 dtrace epsilongc g1gc jfr jni-check jvmci jvmti management nmt parallelgc serialgc services shenandoahgc vm-structs zgc'
* OpenJDK target: OS: macosx, CPU architecture: aarch64, address length: 64
* Version string: 17-internal+0-adhoc.effy.openjdkbackup (17-internal)
Tools summary:
* Boot JDK: openjdk version "16.0.2" 2021-07-20 OpenJDK Runtime Environment Zulu16.32+15-CA (build 16.0.2+7) OpenJDK 64-Bit Server VM Zulu16.32+15-CA (build 16.0.2+7, mixed mode) (at /Users/effy/Library/Java/JavaVirtualMachines/azul-16.0.2/Contents/Home)
* Toolchain: clang (clang/LLVM from Xcode 14.3)
* C Compiler: Version 14.0.3 (at /usr/bin/clang)
* C++ Compiler: Version 14.0.3 (at /usr/bin/clang++)
Build performance summary:
* Cores to use: 8
* Memory limit: 16384 MB
Make images
Excute
make images
, then you’ll get an error like this: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=== Output from failing command(s) repeated here ===
* For target support_interim-jmods_support__create_java.base.jmod_exec:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (assembler_aarch64.hpp:248), pid=56946, tid=9987
# guarantee(val < (1ULL << nbits)) failed: Field too big for insn
#
# JRE version: (17.0.3) (build )
# Java VM: OpenJDK 64-Bit Server VM (17.0.3+0-jvmci-22.1-b05, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, serial gc, bsd-aarch64)
# 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:
# /opt/labs-openjdk-17/make/hs_err_pid56946.log
#
#
* For target support_interim-jmods_support__create_java.logging.jmod_exec:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (assembler_aarch64.hpp:248), pid=56929, tid=10243
# guarantee(val < (1ULL << nbits)) failed: Field too big for insn
#
# JRE version: (17.0.3) (build )
# Java VM: OpenJDK 64-Bit Server VM (17.0.3+0-jvmci-22.1-b05, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, serial gc, bsd-aarch64)
# 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:
# /opt/labs-openjdk-17/make/hs_err_pid56929.log
#
#
* All command lines available in /opt/labs-openjdk-17/build/labsjdk/make-support/failure-logs.
=== End of repeated output ===
No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.
gmake[3]: Leaving directory '/opt/labs-openjdk-17'
make[2]: *** [/opt/labs-openjdk-17/make/Init.gmk:315: main] Error 2
make[2]: Leaving directory '/opt/labs-openjdk-17'
make[1]: *** [/opt/labs-openjdk-17/make/Init.gmk:186: graal-builder-image] Error 2
make[1]: Leaving directory '/opt/labs-openjdk-17'
make: *** [labs17.makefile:27: /opt/labs-17/bin/java] Error 2You need to do like this issue does, and add some codes in
src/hotspot/cpu/aarch64/immediate_aarch64.cpp
.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17uint64_t replicate(uint64_t bits, int nbits, int count)
{
+ assert(count > 0, "must be");
+ assert(nbits > 0, "must be");
+ assert(count * nbits <= 64, "must be");
+
+ // Special case nbits == 64 since the shift below with that nbits value
+ // would result in undefined behavior.
+ if (nbits == 64) {
+ return bits;
+ }
uint64_t result = 0;
// nbits may be 64 in which case we want mask to be -1
uint64_t mask = ones(nbits);
for (int i = 0; i < count ; i++) {
result <<= nbits;Rerun
make images
, you will get the last error:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22Compiling 56 files for java.sql.rowset
Compiling 82 files for jdk.jlink
Compiling 95 files for jdk.jshell
error: invalid integral value '16-DMAC_OS_X_VERSION_MIN_REQUIRED=10120' in '-mstack-alignment=16-DMAC_OS_X_VERSION_MIN_REQUIRED=10120'
make[3]: *** [/Users/jdk/build/macosx-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/bsd_x86_64.o] Error 1
make[3]: *** Waiting for unfinished jobs....
Compiling 229 files for jdk.javadoc
make[2]: *** [hotspot-server-libs] Error 2
make[2]: *** Waiting for unfinished jobs....
Compiling 2736 files for java.desktop
ERROR: Build failed for target 'images' in configuration 'macosx-x86_64-server-fastdebug' (exit code 2)
Stopping sjavac server
make[1]: *** [main] Error 2
=== Output from failing command(s) repeated here ===
make: *** [images] Error 2
* For target hotspot_variant-server_libjvm_objs_bsd_x86_64.o:
error: invalid integral value '16-DMAC_OS_X_VERSION_MIN_REQUIRED=10120' in '-mstack-alignment=16-DMAC_OS_X_VERSION_MIN_REQUIRED=10120'
* All command lines available in /Users/jdk/build/macosx-x86_64-server-fastdebug/make-support/failure-logs.
=== End of repeated output ===Fortunatelly, you just need to do like this issue, add two ‘spaces’ in
make/autoconf/flags-other.m4
, it’s quite weird right?1
2
3
4
5
6
7
8
9
10
11# Fix linker warning.
# Code taken from make/autoconf/flags-cflags.m4 and adapted.
- JVM_BASIC_ASFLAGS+="-DMAC_OS_X_VERSION_MIN_REQUIRED=$MACOSX_VERSION_MIN_NODOTS \
+ JVM_BASIC_ASFLAGS+=" -DMAC_OS_X_VERSION_MIN_REQUIRED=$MACOSX_VERSION_MIN_NODOTS \
-mmacosx-version-min=$MACOSX_VERSION_MIN"
if test -n "$MACOSX_VERSION_MAX"; then
- JVM_BASIC_ASFLAGS+="$OS_CFLAGS \
+ JVM_BASIC_ASFLAGS+=" $OS_CFLAGS \
-DMAC_OS_X_VERSION_MAX_ALLOWED=$MACOSX_VERSION_MAX_NODOTS"
fi
fi
Reference
1: how-to-compile-openjdk-11-on-an-m1-macbook
2: hotspot arm64 bug exposed by latest clang
3: Build failure with Xcode 13.0 after JDK-8264848
4: 深入理解Java虚拟机(第三版),周志明