xiaobaoqiu Blog

Think More, Code Less

Build Openjdk

前几天看了微博上build openJDK 的一篇文章, 决定也尝试一下自己 build 出来一个 JDK.下面是 build 的过程以及遇到的一些问题及解决办法. 本文基于 Ubutu 14.04 LTS 版本.

build 过程涉及 openJDK 部分源码的修改, 修改完的代码我上传到github了, 地址: https://github.com/xiaobaoqiu/ubuntu_build_openjdk7.git

1.准备工作

OpenJDK 官网: http://openjdk.java.net/

注意OpenJDK的版本控制使用 Mercurial 做的.

下面是 build 之前的一些准备工作, 主要包含几个:

1.安装 Mercurial

Mercurial 官网: https://www.mercurial-scm.org/

1
sudo apt-get install mercurial

2.下载 openJDK 源码

1
hg clone http://hg.openjdk.java.net/jdk7/jdk7

之后, 进入源码目录, 有个 get_source.sh 的脚本, 执行就可以了.

3.安装 build 需要的工具

就是 g++ 之类的 make 需要的工具.

1
sudo apt-get install gawk g++ libcups2-dev libasound2-dev libfreetype6-dev libx11-dev libxt-dev libxext-dev libxrender-dev libxtst-dev libfontconfig1-dev

4.准备一个BOOT JDK

需要注意, 如果 build openJDK7, 需要准备 JDK6(如果用JDK7, 会碰到一个错误, 后面会讲到).

2.Build

写了简单的小shell, 配置一些环境变量(如 BOOT JDK 位置).

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
cd ./jdk7

unset JAVA_HOME

export LANG=C
export ALT_BOOTDIR="/home/q/java/jdk1.6.0_45"

# 并行编译线程数,与CPU核数一致
export HOTSPOT_JOBS=8
export ALT_PARALLEL_COMPILE_JOBS=8

export ALLOW_DOWNLOADS=true

export SKIP_COMPARE_IMGAGES=true
export USE_PRECOMPILED_HEADER=true

# Compiling contents
export BUILD_LANGTOOLS=true
export BUILD_HOTSOPT=true
export BUILD_JDK=true

# Avoid javaws & applet build
BUILD_DEPLOY=false
# Avoid installation build
BUILD_INSTALL=false
export EXTRA_LIBS=/usr/lib/x86_64-linux-gnu/libasound.so
make sanity && time make

和源码在同级目录(自己调整):

1
2
3
4
xiaobaoqiu@xiaobaoqiu:~/Work/SourceCode/jdk/openjdk7$ ll
-rwxrwxr-x  1 xiaobaoqiu xiaobaoqiu  735  2月  4 11:48 build7.sh*
drwxrwxr-x  4 xiaobaoqiu xiaobaoqiu 4096  2月  3 17:30 hgforest-crew/
drwxrwxr-x 14 xiaobaoqiu xiaobaoqiu 4096  2月  4 14:01 jdk7/

之后, 执行 build7.sh 脚本就行了(需要chmod +x build7.sh). 幸运的话就没问题了(基本不可能没问题), 下面是我碰到的一些问题和解决办法.

3.问题

下面是 build 过程的一些问题总结.

1.This OS is not supported

错误信息大致如下:

1
"*** This OS is not supported:" `uname -a`; exit 1;

这是由于内核版本太高了, 需要简单修改 Makefile, 首先看一下当前的 Linux 系统版本:

1
2
xiaobaoqiu@xiaobaoqiu:~/Work/SourceCode/jdk/openjdk7$ uname -r
3.13.0-63-generic

在 jdk7/hotspot/make/linux/Makefile 文件中修改 SUPPORTED_OS_VERSION, 增加自己的内核版本支持

1
SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 2.7% 3.13%

2.error: “__LEAF” redefined

这是 openJDK 源码和 gcc 源码冲突, 一个bug, 参见: http://bugs.java.com/view_bug.do?bug_id=7103224

需要按照 http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/a6eef545f1a2 修改代码, 涉及的代码包括以下 6 个文件, 具体的完整代码可以从文章开头提供的 github 地址下载.

1
2
3
4
5
6
jdk7/hotspot/src/share/vm/opto/addnode.cpp
jdk7/hotspot/src/share/vm/prims/jniCheck.cpp
jdk7/hotspot/src/share/vm/prims/jvmtiEnter.xsl
jdk7/hotspot/src/share/vm/prims/jvmtiEnv.cpp
jdk7/hotspot/src/share/vm/prims/jvmtiExport.cpp
jdk7/hotspot/src/share/vm/runtime/interfaceSupport.hpp

3.error: converting ‘false’ to pointer type ‘methodOop’

错误信息:

1
2
3
4
/home/xiaobaoqiu/Work/SourceCode/jdk/openjdk7/jdk7/hotspot/src/share/vm/oops/constantPoolOop.cpp:272:39: error: converting 'false' to pointer type 'methodOop' [-Werror=conversion-null]
   if (cpool->cache() == NULL)  return false;  // nothing to load yet
                                       ^
cc1plus: all warnings being treated as errors

修改(具体的完整代码可以从文章开头提供的 github 地址下载.): /openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp 第272行 return false改为return (methodOop)false;

4.error: converting ‘false’ to pointer type ‘Node’*

错误信息

1
2
3
4
/home/xiaobaoqiu/Work/SourceCode/jdk/openjdk7/jdk7/hotspot/src/share/vm/opto/loopnode.cpp:896:49: error: converting 'false' to pointer type 'Node*' [-Werror=conversion-null]
   if (expr == NULL || expr->req() != 3)  return false;
                                                 ^
cc1plus: all warnings being treated as errors

修改(具体的完整代码可以从文章开头提供的 github 地址下载.): openjdk/hotspot/src/share/vm/opto/loopnode.cpp: 第896行 return false改为return (Node*)false;

5.Unable to load native library: /home/q/java/jdk1.7.0_80/jre/lib/amd64/libjava.so

错误信息:

1
Unable to load native library: /home/q/java/jdk1.7.0_80/jre/lib/amd64/libjava.so: symbol JVM_SetNativeThreadName, version SUNWprivate_1.1 not defined in file libjvm.so with link time reference

解决: 使用 JDK6 作为BOOT JDK

6.gcc: error: unrecognized command line option ‘-mimpure-text’

这个-mimpure-text是gcc给Solaris的编译选项,所以注释掉即可

修改/jdk/make/common/shared/Compiler-gcc.gmk, 去掉 -mimpure-text (具体的完整代码可以从文章开头提供的 github 地址下载.)

7. Error: time is more than 10 years from present: 1136059200000

错误信息

1
2
3
4
5
6
Error: time is more than 10 years from present: 1136059200000
java.lang.RuntimeException: time is more than 10 years from present: 1136059200000
  at build.tools.generatecurrencydata.GenerateCurrencyData.makeSpecialCaseEntry(GenerateCurrencyData.java:285)
  at build.tools.generatecurrencydata.GenerateCurrencyData.buildMainAndSpecialCaseTables(GenerateCurrencyData.java:225)
  at build.tools.generatecurrencydata.GenerateCurrencyData.main(GenerateCurrencyData.java:154)
make[4]: *** [/home/xiaobaoqiu/Work/SourceCode/jdk/openjdk7/jdk7/build/linux-amd64/lib/currency.data] Error 1

修正 jdk7/jdk/src/share/classes/java/util/CurrencyData.properties 文件, 保证时间在 10 年之内.(具体的完整代码可以从文章开头提供的 github 地址下载.):

1
2
3
4
5
AZ=AZM;2005-12-31-20-00-00;AZN
MZ=MZM;2006-06-30-22-00-00;MZN
RO=ROL;2005-06-30-21-00-00;RON
TR=TRL;2004-12-31-22-00-00;TRY
VE=VEB;2008-01-01-04-00-00;VEF

4.后续

经过一番折腾之后, build 成功:

1
2
3
4
5
6
7
8
9
10
11
12
-- Build times ----------
Target all_product_build
Start 2017-02-04 12:02:33
End   2017-02-04 12:14:00
00:00:07 corba
00:00:05 hotspot
00:00:07 jaxp
00:00:05 jaxws
00:10:59 jdk
00:00:04 langtools
00:11:27 TOTAL
-------------------------

默认 build 的结果在 jdk7/build/linux-amd64 下:

1
2
3
4
xiaobaoqiu@xiaobaoqiu:~/Work/SourceCode/jdk/openjdk7/jdk7/build/linux-amd64/bin$ ./java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-root_2017_02_04_11_48-b00)
OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)

需要 build openJDK8 也基本一样, 下载源码地址变一下, openJDK8 源码没有需要该的, 一路通畅:

脚本稍微变更(注意需要 configure , 参考其自带的 README-builds.html):

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
cd ./jdk8

unset JAVA_HOME

export LANG=C
export ALT_BOOTDIR="/home/q/java/default"

# 并行编译线程数,与CPU核数一致
export HOTSPOT_JOBS=8
export ALT_PARALLEL_COMPILE_JOBS=8

export ALLOW_DOWNLOADS=true

export SKIP_COMPARE_IMGAGES=true
export USE_PRECOMPILED_HEADER=true

# Compiling contents
export BUILD_LANGTOOLS=true
export BUILD_HOTSOPT=true
export BUILD_JDK=true

# Avoid javaws & applet build
BUILD_DEPLOY=false
# Avoid installation build
BUILD_INSTALL=false
export EXTRA_LIBS=/usr/lib/x86_64-linux-gnu/libasound.so
#export EXTRA_LIBS=/usr/lib/x86_64-linux-gnu/libasound.so.2
bash ./configure
time make all

build 成功:

1
2
3
4
xiaobaoqiu@xiaobaoqiu:~/Work/SourceCode/jdk/openjdk8/jdk8/build/linux-x86_64-normal-server-release/jdk/bin$ ./java -version
openjdk version "1.8.0-internal"
OpenJDK Runtime Environment (build 1.8.0-internal-root_2017_02_06_11_46-b00)
OpenJDK 64-Bit Server VM (build 25.0-b70, mixed mode)