深入理解Java虚拟机(2)之一-macOS下编译openjdk10

==因为电脑系统版本和软件版本都比较高,在编译jdk7和jdk8的时候出现各种各样的问题,编译jdk10一次就ok了。==

编译openjdk10

编译环境

  • 系统环境 :macOS Mojave 10.14.3
  • 编译器 :clang
  • openJdk :openjdk10
  • boostrap JDK :oracle jdk1.8.0_202
  • xcode version :9.4.1(xcode 10libc++替换了stdlibc++)
  • ant version :1.10.5
  • freetype 2.10.0
  • ccache 3.7.1

获取源码

Mercurial代码管理工具从仓库下载

1
2
3
4
5
brew install mercurial
hg clone http://hg.openjdk.java.net/jdk10/jdk10/ jdk10
cd jdk10
chmod 755 get_source.sh
./get_source.sh

配置环境变量env.sh

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
# 设定语言选项,必须设置
export LANG=C
# Mac平台,C编译器不再是GCC,是clang
export CC=gcc
# 跳过clang的一些严格的语法检查,不然会将N多的警告作为Error
export COMPILER_WARNINGS_FATAL=false
# 链接时使用的参数
export LFLAGS='-Xlinker -lstdc++'
# 是否使用clang
export USE_CLANG=true
# 使用64位数据模型
export LP64=1
# 告诉编译平台是64位,不然会按32位来编译
export ARCH_DATA_MODEL=64
# 允许自动下载依赖
export ALLOW_DOWNLOADS=true
# 并行编译的线程数
export HOTSPOT_BUILD_JOBS=4
# 已过时
# export ALT_PARALLEL_COMPILE_JOBS=4
# 是否跳过与先前版本的比较
export SKIP_COMPARE_IMAGES=true
# 是否使用预编译头文件,加快编译速度
export USE_PRECOMPILED_HEADER=true
# 是否使用增量编译
export INCREMENTAL_BUILD=true
# 编译内容
export BUILD_LANGTOOLS=true
export BUILD_JAXP=false
export BUILD_JAXWS=false
export BUILD_CORBA=false
export BUILD_HOTSPOT=true
export BUILD_JDK=true
# 编译版本
export SKIP_DEBUG_BUILD=true
export SKIP_FASTDEBUG_BUILD=false
export DEBUG_NAME=debug
# 避开javaws和浏览器Java插件之类的部分的build
export BUILD_DEPLOY=false
export BUILD_INSTALL=false
# 加上产生调试信息时需要的 objcopy
export OBJCOPY=gobjcopy
1
2
3
4
5
6
7
8
9
source env.sh

# configure
bash ./configure \
--with-target-bits=64 \
--with-debug-level=slowdebug \
--disable-warnings-as-errors \
--with-freetype=/usr/local/Cellar/freetype/2.10.0/ \
--enable-ccache

完成后出现以下内容:

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
====================================================
The existing configuration has been successfully updated in
/Users/qliang/Documents/code/openjdk/jdk10/build/macosx-x86_64-normal-server-slowdebug
using configure arguments '--with-target-bits=64 --with-debug-level=slowdebug --disable-warnings-as-errors --with-freetype=/usr/local/Cellar/freetype/2.10.0/ --enable-ccache'.

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

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

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

WARNING: The result of this configuration has overridden an older
configuration. You *should* run 'make clean' to make sure you get a
proper build. Failure to do so might result in strange build problems.

开始编译

1
2
3
# 编译
make clean
make all

成功出现以下信息:

1
Finished building target 'default (exploded-image)' in configuration 'macosx-x86_64-normal-server-slowdebug'

验证

./build/macosx-x86_64-normal-server-slowdebug/jdk/bin/java -version

出现:

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

编译openjdk8

编译环境

  • 系统环境 :macOS Mojave 10.14.3
  • 编译器 :clang
  • openJdk :openjdk8
  • boostrap JDK :oracle jdk1.8.0_202
  • xcode version :10.1 (10B61)
  • ant version :1.10.5
  • XQuartz 2.7.11

获取源码

Mercurial代码管理工具从仓库下载

1
2
3
4
5
brew install mercurial
hg clone http://hg.openjdk.java.net/jdk8u/jdk8u-dev/ JDK8u
cd JDK8
chmod 755 get_source.sh
./get_source.sh

配置环境变量env.sh

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
# 设定语言选项,必须设置
export LANG=C
# Mac平台,C编译器不再是GCC,是clang
export CC=gcc
# 跳过clang的一些严格的语法检查,不然会将N多的警告作为Error
export COMPILER_WARNINGS_FATAL=false
# 链接时使用的参数
export LFLAGS='-Xlinker -lstdc++'
# 是否使用clang
export USE_CLANG=true
# 使用64位数据模型
export LP64=1
# 告诉编译平台是64位,不然会按32位来编译
export ARCH_DATA_MODEL=64
# 允许自动下载依赖
export ALLOW_DOWNLOADS=true
# 并行编译的线程数
export HOTSPOT_BUILD_JOBS=4
export ALT_PARALLEL_COMPILE_JOBS=4
# 是否跳过与先前版本的比较
export SKIP_COMPARE_IMAGES=true
# 是否使用预编译头文件,加快编译速度
export USE_PRECOMPILED_HEADER=true
# 是否使用增量编译
export INCREMENTAL_BUILD=true
# 编译内容
export BUILD_LANGTOOLS=true
export BUILD_JAXP=false
export BUILD_JAXWS=false
export BUILD_CORBA=false
export BUILD_HOTSPOT=true
export BUILD_JDK=true
# 编译版本
export SKIP_DEBUG_BUILD=true
export SKIP_FASTDEBUG_BUILD=false
export DEBUG_NAME=debug
# 避开javaws和浏览器Java插件之类的部分的build
export BUILD_DEPLOY=false
export BUILD_INSTALL=false
# 加上产生调试信息时需要的 objcopy
export OBJCOPY=gobjcopy
1
2
3
4
5
6
7
8
9
source env.sh

# configure
bash ./configure \
--with-target-bits=64 \
--with-debug-level=slowdebug \
--disable-warnings-as-errors \
--enable-debug-symbols \
ZIP_DEBUGINFO_FILES=0

执行成功出现以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Configuration summary:
* Debug level: slowdebug
* JDK variant: normal
* JVM variants: server
* OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64

Tools summary:
* Boot JDK: java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode) (at /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home)
* C Compiler: version (at /usr/bin/gcc)
* C++ Compiler: version (at /usr/bin/g++)

Build performance summary:
* Cores to use: 2
* Memory limit: 16384 MB
* ccache status: not installed (consider installing)

执行make


遇到的问题

  1. configure: error: GCC compiler is required. Try setting --with-tools-dir.

解决方案

修改 common/autoconf/generated-configure.sh

搜索 GCC compiler is required

对应内容注释掉。

  1. error: Xcode 4 is required to build JDK 8

解决方案

修改 common/autoconf/generated-configure.sh

搜索 error: Xcode 4 is required to build JDK 8,注释对应5行

两行内容注释掉。

  1. error: invalid argument '-std=gnu++98' not allowed with 'C'

解决方案

修改 common/autoconf/generated-configure.sh

搜索 -std=gnu++98,注释

两行内容注释掉

2.

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
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:367:27: error: friend declaration specifying a default argument must be a definition
inline friend relocInfo prefix_relocInfo(int datalen = 0);
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:462:18: error: friend declaration specifying a default argument must be the only declaration
inline relocInfo prefix_relocInfo(int datalen) {
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:367:27: note: previous declaration is here
inline friend relocInfo prefix_relocInfo(int datalen = 0);
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:463:21: error: 'fits_into_immediate' is a protected member of 'relocInfo'
assert(relocInfo::fits_into_immediate(datalen), "datalen in limits");
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:375:15: note: declared protected here
static bool fits_into_immediate(int data0) {
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:464:59: error: 'RAW_BITS' is a protected member of 'relocInfo'
return relocInfo(relocInfo::data_prefix_tag, relocInfo::RAW_BITS, relocInfo::datalen_tag | datalen);
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:272:23: note: declared protected here
enum RawBitsToken { RAW_BITS };
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:464:10: error: calling a protected constructor of class 'relocInfo'
return relocInfo(relocInfo::data_prefix_tag, relocInfo::RAW_BITS, relocInfo::datalen_tag | datalen);
^
/Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/code/relocInfo.hpp:273:3: note: declared protected here
relocInfo(relocType type, RawBitsToken ignore, int bits)
^

解决方案

修改 hotspot/src/share/vm/code/relocInfo.hpp

367行 int datalen = 0 改为 int datalen

462行 int datalen 改为 int datalen = 0

  1. 1
    2
    3
    /Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/opto/loopPredicate.cpp:775: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");
    ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~

解决方案

_igvn.type(rng)->is_int() >= 0 改为 _igvn.type(rng)->is_int()->_lo >= 0

  1. 1
    2
    3
    /Users/qliang/Documents/code/JDK8/hotspot/src/share/vm/runtime/virtualspace.cpp:331:14: error: ordered comparison between pointer and zero ('char *' and 'int')
    if (base() > 0) {
    ~~~~~~ ^ ~

解决方案

base() > 0 改为 base() != 0

  • 一定要出现编码错误再修改文件,不然会报错误
1
2
3
4
5
6
7
8
9
10
/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home//bin/javac  -J-XX:ThreadStackSize=1536 -J-XX:-PrintVMOptions -J-XX:+UnlockDiagnosticVMOptions -J-XX:-LogVMOutput -J-Xmx512m -J-Xms512m -J-XX:PermSize=32m -J-XX:MaxPermSize=160m -encoding -source 6 -target 6 -d /Users/qliang/Documents/code/jvm/openjdk_7u/corba/btclasses \
-sourcepath ../../tools/src ../../tools/src/build/tools/stripproperties/StripProperties.java
javac: 无效的标记: 6
用法: javac <options> <source files>
-help 用于列出可能的选项
make[4]: *** [/Users/qliang/Documents/code/jvm/openjdk_7u/corba/btjars/stripproperties.jar] Error 2
make[3]: *** [build] Error 1
make[2]: *** [build] Error 1
make[1]: *** [corba-build] Error 2
make: *** [build_product_image] Error 2
1
2
hotspot/src/share/vm/adlc/archDesc.cpp:335:35: error: '&&' within '||'
[-Werror,-Wlogical-op-parentheses]
1
export COMPILER_WARNINGS_FATAL=false

5.

1
clang: error: unknown argument: '-fpch-deps'

解决方案

修改 hotspot/make/bsd/makefiles/gcc.make

1
2
3
4
5
# 注释217-219行
# Flags for generating make dependency flags.
# ifneq ("${CC_VER_MAJOR}", "2")
# DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
# endif

6.高版本的gcc不再支持编译选项stabs

1
2
3
4
5
6
7
8
9
10
487 warnings and 4 errors generated.
make[8]: *** [precompiled.hpp.gch] Error 1
make[7]: *** [the_vm] Error 2
make[6]: *** [product] Error 2
make[5]: *** [generic_build2] Error 2
make[4]: *** [product] Error 2
make[3]: *** [all_product_universal] Error 2
make[2]: *** [universal_product] Error 2
make[1]: *** [hotspot-build] Error 2
make: *** [build_product_image] Error 2

完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## Finished jdk (build time 00:03:28)

----- Build times -------
Start 2019-03-18 20:53:08
End 2019-03-18 21:00:51
00:00:23 corba
00:02:48 hotspot
00:00:13 jaxp
00:00:20 jaxws
00:03:28 jdk
00:00:31 langtools
00:07:43 TOTAL
-------------------------
Finished building OpenJDK for target 'default'

==以下为编译openjdk7出现的各种问题,最终没有编译成功。==

编译openjdk7

编译环境

  • 系统环境 :macOS Mojave 10.14.3
  • 编译器 :clang
  • openJdk :jdk7u-dev
  • boostrap JDK :oracle jdk1.7.0_80
  • xcode version :10.1 (10B61)
  • ant version :1.9.13

获取源码

Mercurial代码管理工具从仓库下载

1
2
3
4
5
brew install mercurial
hg clone http://hg.openjdk.java.net/jdk7u/jdk7u-dev
cd jdk7u-dev
chmod 755 get_source.sh
./get_source.sh

直接下载官方打包的源代码


配置环境变量env.sh

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
46
47
48
49
50
51
52
53
#语言选项,这个必须设置,否则编译好后会出现一个HashTable的NPE错
export LANG=C

#Bootstrap JDK的安装路径。必须设置。
export ALT_BOOTDIR=/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/

#允许自动下载依赖
export ALLOW_DOWNLOADS=true

#并行编译的线程数,设置为和CPU内核数量一致即可
export HOTSPOT_BUILD_JOBS=6
export ALT_PARALLEL_COMPILE_JOBS=6

#比较本次build出来的映像与先前版本的差异。这个对我们来说没有意义,必须设置为false,否则sanity检查会报缺少先前版本JDK的映像。如果有设置dev或者DEV_ONLY=true的话这个不显式设置也行。
export SKIP_COMPARE_IMAGES=true

#使用预编译头文件,不加这个编译会更慢一些
export USE_PRECOMPILED_HEADER=true

export COMPILER_WARNINGS_FATAL=false

#要编译的内容
export BUILD_LANGTOOLS=true
#export BUILD_JAXP=false
#export BUILD_JAXWS=false
#export BUILD_CORBA=false
export BUILD_HOTSPOT=true
export BUILD_JDK=true

#要编译的版本
#export SKIP_DEBUG_BUILD=false
#export SKIP_FASTDEBUG_BUILD=true
#export DEBUG_NAME=debug

#把它设置为false可以避开javaws和浏览器Java插件之类的部分的build。
BUILD_DEPLOY=false

#把它设置为false就不会build出安装包。因为安装包里有些奇怪的依赖,但即便不build出它也已经能得到完整的JDK映像,所以还是别build它好了。
BUILD_INSTALL=false

#编译结果所存放的路径
export ALT_OUTPUTDIR=/Users/qliang/Documents/code/jvm/openjdk_7u

#这两个环境变量必须去掉,不然会有很诡异的事情发生(我没有具体查过这些“”诡异的事情”,Makefile脚本检查到有这2个变量就会提示警告“)
unset JAVA_HOME
unset CLASSPATH

export ALT_FREETYPE_HEADERS_PATH=/usr/local/include/freetype2
export ALT_FREETYPE_LIB_PATH=/usr/local/Cellar/freetype/2.9.1/lib

# export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8

# make 2>&1 | tee $ALT_OUTPUTDIR/build.log
1
2
3
4
5
6
7
source env.sh

# 检查
make sanity

Sanity check passed.
即可进行编译

遇到的问题

  1. llvm-gcc找不到
    1
    /bin/sh: /Library/Developer/CommandLineTools/usr/bin/llvm-gcc: No such file or directory

解决方案

1
2
3
cd /Library/Developer/CommandLineTools/usr/bin/
# 软连接
sudo ln -s gcc llvm-gcc

2.FreeType版本过低

1
ERROR: FreeType version  2.3.0  or higher is required.

解决方案:环境变量添加如下

1
2
export ALT_FREETYPE_HEADERS_PATH=/usr/local/include/freetype2
export ALT_FREETYPE_LIB_PATH=/usr/local/Cellar/freetype/2.9.1/lib
  1. 1
    主版本 52 比 51 新, 此编译器支持最新的主版本。

解决方案

1
boostrap JDK版本太高,降低版本
  1. 编码问题
1
2
/Users/qliang/Documents/code/jvm/openjdk_7u/corba/gensrc/com/sun/corba/se/spi/activation/Locator.java:6: 错误: 编码ascii的不可映射字符
* ���IDL-to-Java ��������� (���������), ������ "3.2"������

解决方案

借鉴于 https://0x9e370001.iteye.com/blog/1729802 修改文件的方法

1
2
3
4
5
6
7
8
9
10
11
12
文件: /corba/make/common/shared/Defs-java.gmk

133行
JAVACFLAGS += -encoding ascii
改为
#JAVACFLAGS += -encoding ascii

194行
BOOT_JAVACFLAGS += -encoding ascii -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
改为

BOOT_JAVACFLAGS += -encoding -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
  • 一定要出现编码错误再修改文件,不然会报错误
1
2
3
4
5
6
7
8
9
10
/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home//bin/javac  -J-XX:ThreadStackSize=1536 -J-XX:-PrintVMOptions -J-XX:+UnlockDiagnosticVMOptions -J-XX:-LogVMOutput -J-Xmx512m -J-Xms512m -J-XX:PermSize=32m -J-XX:MaxPermSize=160m -encoding -source 6 -target 6 -d /Users/qliang/Documents/code/jvm/openjdk_7u/corba/btclasses \
-sourcepath ../../tools/src ../../tools/src/build/tools/stripproperties/StripProperties.java
javac: 无效的标记: 6
用法: javac <options> <source files>
-help 用于列出可能的选项
make[4]: *** [/Users/qliang/Documents/code/jvm/openjdk_7u/corba/btjars/stripproperties.jar] Error 2
make[3]: *** [build] Error 1
make[2]: *** [build] Error 1
make[1]: *** [corba-build] Error 2
make: *** [build_product_image] Error 2
1
2
hotspot/src/share/vm/adlc/archDesc.cpp:335:35: error: '&&' within '||'
[-Werror,-Wlogical-op-parentheses]
1
export COMPILER_WARNINGS_FATAL=false

5.

1
clang: error: unknown argument: '-fpch-deps'

解决方案

修改 hotspot/make/bsd/makefiles/gcc.make

1
2
3
4
5
# 注释217-219行
# Flags for generating make dependency flags.
# ifneq ("${CC_VER_MAJOR}", "2")
# DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
# endif

6.高版本的gcc不再支持编译选项stabs

1
2
3
4
5
6
7
8
9
10
487 warnings and 4 errors generated.
make[8]: *** [precompiled.hpp.gch] Error 1
make[7]: *** [the_vm] Error 2
make[6]: *** [product] Error 2
make[5]: *** [generic_build2] Error 2
make[4]: *** [product] Error 2
make[3]: *** [all_product_universal] Error 2
make[2]: *** [universal_product] Error 2
make[1]: *** [hotspot-build] Error 2
make: *** [build_product_image] Error 2

该文章来源《深入理解Java虚拟机》读后实践

以上

LeoQin wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
0%