编译Openjdk

 从来没有想过要自己去编译jdk,更没有想过要交叉编译jdk。哈哈,我也真是个人才(主要是领导安排的活)。为了联手以及填坑,先编译x86平台下的openjdk,下面是编译过程其中包含很多错误,记录一下心路历程。

一、环境

软件

版本

操作系统

Redhat7.1

bootJdk

1.7.0_51

GNU Make

3.82

g++ (GCC)

4.8.2

Openjdk

1.8u

二、步骤

2.1 安装依赖文件(其实就是configure过程中报的错误)

yum install cups-devel
yum install libXtst-devel libXt-devel libXrender-devel
yum install freetype-devel
yum install alsa-lib-devel

如果不能上外网,可参考如何搭建本地yum

2.2 configure配置

Configure过程需要指定一个最重要的参数--with-boot-jdk,按照官网编译说明文档,这个参数必须是前一个大版本的jdk,例如我们需要编译jdk1.8,那么boot-jdk必须是jdk1.7。执行如下命令行:

sh configure --prefix=/root/openjdk/output --target=i686 --with-boot-jdk=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.51-2.4.5.5.el7.x86_64 --with-target-bits=64

configure过程其实就是各种依赖文件安装,一般把依赖文件搞定问题就不大。

2.3 进入build目录,执行编译

[root@localhost jdk8u]# cd build/linux-x86_64-normal-server-release/
[root@localhost linux-x86_64-normal-server-release]# ls
bootcycle-spec.gmk  build.log.old  config.h    config.status        corba  docstemp  hotspot-spec.gmk  jaxp   jdk        Makefile  source_tips  spec.sh
build.log           compare.sh     config.log  configure-arguments  docs   hotspot   images            jaxws  langtools  nashorn   spec.gmk     tmp
[root@localhost linux-x86_64-normal-server-release]# make
[root@localhost linux-x86_64-normal-server-release]# 

2.4 MAKE常用参数

参数

说明

JOBS=X

同时编译线程数目,默认是16

LOG=debugLOG=trace

编译日志级别不同,用于编译出错定位

clean-XXX

支持langtools, hotspot, jaxp, jaxws,jdk

还有一些其他参数,可执行make help

2.5 测试

[root@localhost test-demo-hello]# ../bin/javac Hello.java 
[root@localhost test-demo-hello]# ../bin/java Hello
Hello World!
[root@localhost test-demo-hello]# 
[root@localhost test-demo-hello]# 

三、问题

  本篇最核心内容就在于此,搜了很多文章,大部分都是没有问题,这种文章对于我来说一点意义没有。下面这些问题,基本上都是makefile的问题。然而为啥makefile有问题,猜测是代码版本有问题。

【问题1 找不到变量定义】

Generating exceptions classes
Compiling 163 files for BUILD_TOOLS
/bin/sh: -Xbootclasspath/p:/root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/langtools/dist/bootstrap/lib/javac.jar: 没有那个文件或目录
gmake[2]: *** [/root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/btclasses/_the.BUILD_TOOLS_batch] 错误 127
gmake[2]: *** 正在等待未完成的任务....
gmake[1]: *** [gensrc-only] 错误 2
make: *** [jdk-only] 错误 2
[root@localhost linux-x86_64-normal-server-release]# 

问题原因:主要是找不到变量JVM的定义

解决方法:修改两个配置文件

1)修改jdk/make/Tools.gmk,在第60行附近,增加JAVA_SMALL的定义

JAVA_SMALL ?= /root/openjdk/ppc64_openjdk/bootjdk7u79/jdk1.7.0_79/bin/java -Xms64M -Xmx1100M -XX:PermSize=32m -XX:MaxPermSize=160m -XX:ThreadStackSize=1536

2)修改make/common/JavaCompilation.gmk,在553行附近,有一个$$($1_JVM),将其设置为

/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.51-2.4.5.5.el7.x86_64/bin/java -Xms64M -Xmx1100M -XX:PermSize=32m -XX:MaxPermSize=160m -XX:ThreadStackSize=1536

【问题2 异常错误,无影响】

Verifying /home/jdk8u/build/linux-x86_64-normal-server-release//jdk/gensrc_x11wrappers/sizes.64.verification.tmp to /home/jdk8u/build/linux-ppc64-normal-server-release/jdk/gensrc_x11wrappers/sizes.64
[Error] encoded value was less than 0: encode(-8.326673E-17, 5.0, 11.0, 16.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was greater than 3: encode(15.029411, 1.0, 14.0, 15.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was greater than 3: encode(15.029411, 1.0, 14.0, 15.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was greater than 3: encode(15.029411, 1.0, 14.0, 15.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was greater than 3: encode(15.029411, 1.0, 14.0, 15.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was greater than 3: encode(15.029411, 1.0, 14.0, 15.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] encoded value was greater than 3: encode(15.029411, 1.0, 14.0, 15.0)
[Error] encoded value was less than 0: encode(-0.05882353, 1.0, 24.0, 25.0)
[Error] Encountered Infinity: encode(-0.00877193, 0.0, 7.0, 7.0)

【问题3 .java.class)生成异常,文件大小为0

## Starting jdk
Generating beaninfo
/root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/gensrc/sun/nio/cs/StandardCharsets.java:365: 错误: 解析时已到达文件结尾
    };
      ^
/root/openjdk/jdk8u/jdk/src/share/classes/java/io/OutputStreamWriter.java:29: 错误: 无法访问CharsetEncoder
import java.nio.charset.CharsetEncoder;
                       ^
  错误的源文件: /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/gensrc/java/nio/charset/CharsetEncoder.java
    文件不包含类java.nio.charset.CharsetEncoder
    请删除该文件或确保该文件位于正确的源路径子目录中。
/root/openjdk/jdk8u/jdk/src/share/classes/java/lang/ClassValue.java:34: 错误: 找不到符号
import static java.lang.ClassValue.ClassValueMap.probeBackupLocations;
^
  符号:   静态 probeBackupLocations
  位置: 类
/root/openjdk/jdk8u/jdk/src/share/classes/java/lang/ClassValue.java:33: 错误: 找不到符号
import static java.lang.ClassValue.ClassValueMap.probeHomeLocation;
^
  符号:   静态 probeHomeLocation
  位置: 类
/root/openjdk/jdk8u/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java:50: 错误: 找不到符号
import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
^
  符号:   静态 GET_CLASSLOADER_PERMISSION
  位置: 类
/root/openjdk/jdk8u/jdk/src/share/classes/java/lang/annotation/Retention.java:44: 错误: 找不到符号
@Retention(RetentionPolicy.RUNTIME)
                          ^
  符号:   变量 RUNTIME
  位置: 类 RetentionPolicy
/root/openjdk/jdk8u/jdk/src/share/classes/java/lang/annotation/Documented.java:40: 错误: 找不到符号
@Retention(RetentionPolicy.RUNTIME)
                          ^
  符号:   变量 RUNTIME
  位置: 类 RetentionPolicy
/root/openjdk/jdk8u/jdk/src/share/classes/java/lang/annotation/Target.java:77: 错误: 找不到符号
@Retention(RetentionPolicy.RUNTIME)
                          ^
  符号:   变量 RUNTIME
  位置: 类 RetentionPolicy
/root/openjdk/jdk8u/jdk/src/share/classes/java/lang/SuppressWarnings.java:53: 错误: 找不到符号

问题原因:由于是多线程编译导致文件生成异常或者文件大小为0

解决方案:将异常文件删除掉(也可删除掉目录)并重新执行make JOBS=1

【问题4 找不到bundle

## Starting jdk
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name sun.text.resources.BreakIteratorRules, locale 
        at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)
        at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)
        at java.util.ResourceBundle.getBundle(ResourceBundle.java:841)
        at build.tools.generatebreakiteratordata.GenerateBreakIteratorData.generateFiles(GenerateBreakIteratorData.java:86)
        at build.tools.generatebreakiteratordata.GenerateBreakIteratorData.main(GenerateBreakIteratorData.java:70)
gmake[2]: *** [/root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources/_the.bifiles] 错误 1
gmake[1]: *** [gendata-only] 错误 2
make: *** [jdk-only] 错误 2
[root@localhost jdk8u]# 

再次执行make LOG=trace,查看详细错误信息

SetupJavaCompilation(BUILD_BREAKITERATOR) 
 [2] SETUP := GENERATE_OLDBYTECODE 
 [3] SRC := /root/openjdk/jdk8u/jdk/src/share/classes 
 [4] DISABLE_SJAVAC := true 
 [5] JAVAC_SOURCE_PATH_OVERRIDE := /root/openjdk/jdk8u/jdk/src/share/classes/sun/text/resources 
 [6] INCLUDES := sun/text/resources 
 [7] INCLUDE_FILES := sun/text/resources/BreakIteratorRules.java sun/text/resources/BreakIteratorInfo.java sun/text/resources/th/BreakIteratorRules_th.java sun/text/resources/th/BreakIteratorInfo_th.java 
 [8] BIN := /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/break_iterator/classes                  
gmake[2]: 进入目录“/root/openjdk/jdk8u/jdk/make”
/usr/bin/echo  "Generating BreakIteratorData"
Generating BreakIteratorData
/usr/bin/mkdir -p /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources
/usr/bin/rm -f /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources/CharacterBreakIteratorData /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources/WordBreakIteratorData /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources/LineBreakIteratorData /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources/SentenceBreakIteratorData
/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.51-2.4.5.5.el7.x86_64/bin/java -Xms64M -Xmx1100M -XX:PermSize=32m -XX:MaxPermSize=160m -XX:ThreadStackSize=1536 -cp /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/btclasses build.tools.generatebreakiteratordata.GenerateBreakIteratorData \
    -o /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources \
    -spec /root/openjdk/jdk8u/jdk/make/data/unicodedata/UnicodeData.txt
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name sun.text.resources.BreakIteratorRules, locale 
        at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)
        at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)
        at java.util.ResourceBundle.getBundle(ResourceBundle.java:841)
        at build.tools.generatebreakiteratordata.GenerateBreakIteratorData.generateFiles(GenerateBreakIteratorData.java:86)
        at build.tools.generatebreakiteratordata.GenerateBreakIteratorData.main(GenerateBreakIteratorData.java:70)
gmake[2]: *** [/root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources/_the.bifiles] 错误 1
gmake[2]: 离开目录“/root/openjdk/jdk8u/jdk/make”
gmake[1]: *** [gendata-only] 错误 2
gmake[1]: 离开目录“/root/openjdk/jdk8u/jdk/make”
make: *** [jdk-only] 错误 2
[root@localhost jdk8u]# 

这个问题困扰了我三天,各种谷歌,githubmail list都没有找到解决方法,只能自己分析一下日志。

1)定位过程1:确定错误命令行

/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.51-2.4.5.5.el7.x86_64/bin/java -Xms64M -Xmx1100M -XX:PermSize=32m -XX:MaxPermSize=160m -XX:ThreadStackSize=1536 -cp /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/btclasses build.tools.generatebreakiteratordata.GenerateBreakIteratorData \
    -o /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources \
-spec /root/openjdk/jdk8u/jdk/make/data/unicodedata/UnicodeData.txt

单独执行这个命令行就会报这个错误。

2)定位过程2:异常信息提示找不到bundle类,但是实际目录中确实存在这个类文件:

[root@localhost linux-x86_64-normal-server-release]# find ./ -name "*BreakIteratorRules*"
./jdk/classes/sun/text/resources/th/BreakIteratorRules_th.class
./jdk/break_iterator/classes/sun/text/resources/th/BreakIteratorRules_th.class
./jdk/break_iterator/classes/sun/text/resources/BreakIteratorRules.class
[root@localhost linux-x86_64-normal-server-release]# 
[root@localhost linux-x86_64-normal-server-release]# 

猜测应该命令行参数有问题,可能需要指定目录

3)定位过程3:研究该命令行各个参数含义

参数

含义

-cp

Class搜索路径(进程java的参数)

-o

输出文件目录(类GenerateBreakIteratorData的参数

-spec

输入文件(类GenerateBreakIteratorData 的参数

尝试修改:在-cp中增加BreakIteratorRules的所在目录路径,然后再次单独执行上面命令行,例如

/root/openjdk/ppc64_openjdk/bootjdk7u79/jdk1.7.0_79/bin/java \
-Xms64M -Xmx1100M -XX:PermSize=32m -XX:MaxPermSize=160m -XX:ThreadStackSize=1536     \
-cp /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/btclasses:/root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/break_iterator/classes/ build.tools.generatebreakiteratordata.GenerateBreakIteratorData     -o /root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/classes/sun/text/resources     
-spec /root/openjdk/jdk8u/jdk/make/data/unicodedata/UnicodeData.txt 

  其实就是在-cp增加路径,格式内容为 -cp P1:P2:P3。发现这样修改,不在报异常了,说明修改正确(此时此刻非常的兴奋)。

解决方案:增加类路径,修改./jdk/make/Tools.gmk,大概在96行,在-cp后面增加路径/root/openjdk/jdk8u/build/linux-x86_64-normal-server-release/jdk/break_iterator/classes/

四、后记

  其实项目要求是编译powerpc平台下面的jdk,通过上面编译x86的平台,本以为编译powerpc应该很顺利,但是还遇到问题,而且是无法解决的问题。

  在编译过程生成了一个可执行文件,这个文件是powerpc平台下,需要运行此文件且此文件会生成一些文件以便其他编译能够正常使用。这就带来了一个问题,x86平台下是无法运行powerpc平台。所以交叉编译powerpc平台宣布失败(当然也有其他方式,比如模拟powerpc平台)。

五、总结

  以上过程就是编译openjdk整个流程,大概花费了4天时间,这个应该是我有史以来最难编译的软件。虽然辛苦,但最终编译出来了,还是挺欣慰,挺high的。希望本篇能指导更多网友(Powerpc版本是通过虚拟化PowerPc平台系统,在虚拟机中编译的)。



猜你喜欢

转载自blog.csdn.net/xxb249/article/details/79616378