学习《深入了解java虚拟机》,按照书上的步骤试着自己编译了个jdk,耗时大半个下午,中间遇到不少问题,在这记录下。


一、环境说明

linux 版本

[root@localhost openjdk_compile]# lsb_release -a
LSB Version::base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch
Distributor ID:CentOS
Description:CentOS release 6.9 (Final)
Release:6.9
Codename:Final

openjdk版本

openjdk-7u75-src-b13-18_dec_2014.zip

二、构建编译环境

安装必要工具包

[root@localhost openjdk_compile]# yum groupinstall "Development Tools"
[root@localhost openjdk_compile]# yum install ant

设置环境变量

unset JAVA_HOME
unset CLASSPATH
export LANG=C
export ALT_BOOTDIR=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.141-1.b16.el7_3.x86_64
#允许自动下载依赖
export ALLOW_DOWNLOADS=true
#并行编译的线程数,设置为和cpu内核数量一致即可
export HOTSPOT_BUILD_JOBS=2
export ALT_PARALLEL_COMPIL_JOBS=2
#比较本次build出来的映像与先前版本的差异。这对我们来说没有意义
#必须设置为false,否则sanity检查会报缺少先前版本的JDK的映像的错误提示。
#如果已经设置dev或者DEV_ONLY=true,这个不显示设置也行
export SKIP_COMPARE_IMAGES=true
#使用预编译头文件,不加这个编译会更慢一些
export USE_PRECOMPILED_HEADER=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=false
#export SKIP_FASTDEBUG_BUILD=true
#export DEBUG_NAME=debug
#把它设置为false,可以避开javaws和浏览器java插件之类的部分的build
export BUILD_DEPLOY=false
#把它设置为false就不会build出安装包。因为安装包有些奇怪的依赖
#但即便不build出安装包也能得到完整的JDK映像,所以还是别build好了
export BUILD_INSTALL=false
#编译结果存放的路劲
export ALT_OUTPUTDIR=/root/openjdk_compile/build

切换到源代码根路径,执行make sanity,得到结果:

WARNING: LANG has been set to zh_CN.UTF-8, this can cause build failures. 
         Try setting LANG to 'C'. 
 
ERROR: Your CLASSPATH environment variable is set.  This will 
       most likely cause the build to fail.  Please unset it 
       and start your build again. 
 
ERROR: Your JAVA_HOME environment variable is set.  This will 
       most likely cause the build to fail.  Please unset it 
       and start your build again. 
 
ERROR: You seem to not have installed ALSA 0.9.1 or higher. 
       Please install ALSA (drivers and lib). You can download the 
       source distribution from http://www.alsa-project.org or go to 
       http://www.freshrpms.net/docs/alsa/ for precompiled RPM packages. 
 
ERROR: FreeType version  2.3.0  or higher is required. 
 make[2]: 进入目录“/root/openjdk_compile/openjdk/jdk/make/tools/freetypecheck”
/bin/mkdir -p /root/openjdk_compile/openjdk/build/linux-amd64/btbins
rm -f /root/openjdk_compile/openjdk/build/linux-amd64/btbins/freetype_versioncheck
make[2]: 离开目录“/root/openjdk_compile/openjdk/jdk/make/tools/freetypecheck”
Failed to build freetypecheck.  
ERROR: You do not have access to valid Cups header files. 
       Please check your access to 
           /usr/include/cups/cups.h 
       and/or check your value of ALT_CUPS_HEADERS_PATH, 
       CUPS is frequently pre-installed on many systems, 
       or may be downloaded from http://www.cups.org 
 
Exiting because of the above error(s). 
 
make: *** [post-sanity] 错误 1


分析:

1.设置环境变量方式有误: 永久环境变量(属于文件,比如profile以及home目录下的),临时环境变量(当前shell以及子线程),普通环境变量(当前shell)

解决:在当前shell执行相关export

2. FreeType 没有安装

解决:yum install freetype-devel

3. ALSA 没有安装(声卡  应该没什么关系)

解决:sudo yum install alsa*

4:You do not have access to valid Cups header files. 

解决:sudo yum install cups-devel.x86_64


二、开始编译

执行命令:

make 2>&1 | tee $ALT_OUTPUTDIR/build.log

记录下错误

错误1:

build-bootstrap-javac:
    [mkdir] Created dir: /root/openjdk_compile/build/langtools/build/bootstrap/gensrc
    [mkdir] Created dir: /root/openjdk_compile/build/langtools/build/bootstrap/classes
 [pcompile] Generating 7 resource files to /root/openjdk_compile/build/langtools/build/bootstrap/gensrc
     [copy] Copying 1 file to /root/openjdk_compile/build/langtools/build/bootstrap/gensrc
 [pcompile] Generating 1 resource files to /root/openjdk_compile/build/langtools/build/bootstrap/gensrc
    [javac] Compiling 298 source files to /root/openjdk_compile/build/langtools/build/bootstrap/classes
    [javac] /root/openjdk_compile/openjdk/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java:2182: warning: [overrides] Class Resolve.InapplicableSymbolsError.Candidate overrides equals, but neither it nor any superclass overrides hashCode method
    [javac]         private class Candidate {
    [javac]                 ^
    [javac] error: warnings found and -Werror specified
    [javac] 1 error
    [javac] 1 warning
BUILD FAILED
/root/openjdk_compile/openjdk/langtools/make/build.xml:452: The following error occurred while executing this line:
/root/openjdk_compile/openjdk/langtools/make/build.xml:795: Compile failed; see the compiler error output for details.


解决方法:Bootstrap jdk版本换成jdk1.7


错误2:

/bin/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status
ln: failed to access 'libjvm.so.1': Too many levels of symbolic links
/usr/bin/chcon: failed to get security context of 'libjvm.so': Too many levels of symbolic links
ERROR: Cannot chcon libjvm.so
/usr/bin/objcopy --only-keep-debug libjvm.so libjvm.debuginfo
/usr/bin/objcopy: Warning: could not locate 'libjvm.so'.  reason: Too many levels of symbolic links
make[6]: *** [libjvm.so] Error 1
make[6]: Leaving directory `/root/openjdk_compile/build/hotspot/outputdir/linux_amd64_compiler2/product'
make[5]: *** [the_vm] Error 2
make[5]: Leaving directory `/root/openjdk_compile/build/hotspot/outputdir/linux_amd64_compiler2/product'
make[4]: *** [product] Error 2
make[4]: Leaving directory `/root/openjdk_compile/build/hotspot/outputdir'
make[3]: *** [generic_build2] Error 2
make[3]: Leaving directory `/root/openjdk_compile/openjdk/hotspot/make'
make[2]: *** [product] Error 2
make[2]: Leaving directory `/root/openjdk_compile/openjdk/hotspot/make'
make[1]: *** [hotspot-build] Error 2
make[1]: Leaving directory `/root/openjdk_compile/openjdk'
make: *** [build_product_p_w_picpath] Error 2


解决方案:sudo yum install libstdc++-static.x86_64


错误3:

Linking vm...
/usr/bin/objcopy --only-keep-debug libjvm.so libjvm.debuginfo
/usr/bin/objcopy --add-gnu-debuglink=libjvm.debuginfo libjvm.so
strip -g libjvm.so
[ -f libjvm.debuginfo ] || ln -s libjvm.debuginfo libjvm.debuginfo
zip -q -y libjvm.diz libjvm.debuginfo libjvm.debuginfo
rm -f libjvm.debuginfo libjvm.debuginfo
[ -f libjvm.diz ] || { ln -s libjvm.diz libjvm.diz; }
echo Linking launcher...
Linking launcher...
gcc -m64 -Xlinker -O1 -Wl,--hash-style=both  -Xlinker -z -Xlinker noexecstack -m64 -Xlinker -export-dynamic  -L `pwd` -o gamma launcher/java_md.o launcher/jli_util.o launcher/wildcard.o launcher/java.o -ljvm -lm -ldl -lpthread
make[6]: Leaving directory `/root/openjdk_compile/build/hotspot/outputdir/linux_amd64_compiler2/product'
All done.
make[5]: Leaving directory `/root/openjdk_compile/build/hotspot/outputdir/linux_amd64_compiler2/product'
cd linux_amd64_compiler2/product && ./test_gamma
./gamma: relocation error: /usr/java/jdk1.7.0_80/jre/lib/amd64/libjava.so: symbol JVM_FindClassFromCaller, version SUNWprivate_1.1 not defined in file libjvm.so with link time reference
make[4]: *** [product] Error 127
make[4]: Leaving directory `/root/openjdk_compile/build/hotspot/outputdir'
make[3]: *** [generic_build2] Error 2
make[3]: Leaving directory `/root/openjdk_compile/openjdk/hotspot/make'
make[2]: *** [product] Error 2
make[2]: Leaving directory `/root/openjdk_compile/openjdk/hotspot/make'
make[1]: *** [hotspot-build] Error 2
make[1]: Leaving directory `/root/openjdk_compile/openjdk'
make: *** [build_product_p_w_picpath] Error 2



解决方案:去掉hotspot/make/linux/Makefile 文件中所有的test_gamma即可


错误4:

/bin/mkdir -p /root/openjdk_compile/build/lib
rm -f /root/openjdk_compile/build/lib/content-types.properties
/bin/cp ../../../src/solaris/lib/content-types.properties /root/openjdk_compile/build/lib/content-types.properties
/bin/mkdir -p /root/openjdk_compile/build/lib
rm -f /root/openjdk_compile/build/lib/calendars.properties
/bin/cp ../../../src/share/lib/calendars.properties /root/openjdk_compile/build/lib/calendars.properties
rm -f /root/openjdk_compile/build/lib/currency.data
/usr/java/jdk1.7.0_80/bin/java -XX:-PrintVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-LogVMOutput -Xmx512m -Xms512m -XX:PermSize=32m -XX:MaxPermSize=160m -jar /root/openjdk_compile/build/btjars/generatecurrencydata.jar -o /root/openjdk_compile/build/lib/currency.data.temp \
< ../../../src/share/classes/java/util/CurrencyData.properties
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]: *** [/root/openjdk_compile/build/lib/currency.data] Error 1
make[4]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make/java/java'
make[3]: *** [all] Error 1
make[3]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make/java'
make[2]: *** [all] Error 1
make[2]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make'
make[1]: *** [jdk-build] Error 2
make[1]: Leaving directory `/root/openjdk_compile/openjdk'
make: *** [build_product_p_w_picpath] Error 2


解决方案:修改/jdk/src/share/classes/java/util/CurrencyData.properties文件,将其中10年以前的时间都设置到10年以内


错误5:

/usr/bin/gcc  -O2   -fno-strict-aliasing -fPIC -W -Wall  -Wno-unused -Wno-parentheses -pipe -fno-omit-frame-pointer -D_LITTLE_ENDIAN   -DNDEBUG -DARCH='"amd64"' -Damd64 -DLINUX -DRELEASE='"1.7.0-internal"' -DFULL_VERSION='"1.7.0-internal-root_2017_09_02_18_24-b00"' -DJDK_MAJOR_VERSION='"1"' -DJDK_MINOR_VERSION='"7"' -D_LARGEFILE64_SOURCE -D_GNU_SOURCE -D_REENTRANT -D_LP64=1 -I. -I/root/openjdk_compile/build/tmp/sun/launcher/policytool/CClassHeaders -I../../src/solaris/javavm/export -I../../src/share/javavm/export -I../../src/share/bin -I../../src/solaris/bin -I../../src/share/native/java/util/zip/zlib-1.1.3 -DMAIN_CLASS='"sun.security.tools.policytool.PolicyTool"' -DJAVA_ARGS='{ "-J-ms8m", "sun.security.tools.policytool.PolicyTool",  }' -DLAUNCHER_NAME='"openjdk"' -DPROGNAME='"policytool"'    -c -o /root/openjdk_compile/build/tmp/sun/launcher/policytool/obj64/main.o \
-DRELEASE='"1.7.0-internal"' -DFULL_VERSION='"1.7.0-internal-root_2017_09_02_18_24-b00"' -DJDK_MAJOR_VERSION='"1"' -DJDK_MINOR_VERSION='"7"' ../../src/share/bin/main.c
Rebuilding /root/openjdk_compile/build/bin/policytool because of /root/openjdk_compile/build/tmp/sun/launcher/policytool/obj64/main.o
/usr/bin/gcc -o /root/openjdk_compile/build/bin/policytool -Xlinker -O1 -Xlinker -version-script=../java/main/java/mapfile-amd64  -Wl,--hash-style=both -Xlinker -z -Xlinker defs -L/root/openjdk_compile/build/lib/amd64 -Wl,-soname=lib.so  -L /root/openjdk_compile/build/lib/amd64/jli  -Wl,--allow-shlib-undefined -Wl,-rpath -Wl,\$ORIGIN/../lib/amd64/jli -Wl,-rpath -Wl,\$ORIGIN/../jre/lib/amd64/jli \
/root/openjdk_compile/build/tmp/sun/launcher/policytool/obj64/main.o -lpthread  -L/usr/X11R6//lib64 -lX11 -ljli  -ldl -lc
/bin/ld: cannot find -lX11
collect2: error: ld returned 1 exit status
make[6]: *** [/root/openjdk_compile/build/bin/policytool] Error 1
make[6]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make/launchers'
make[5]: *** [build] Error 2
make[5]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make/sun/security/tools'
make[4]: *** [all] Error 1
make[4]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make/sun/security'
make[3]: *** [all] Error 1
make[3]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make/sun'
make[2]: *** [all] Error 1
make[2]: Leaving directory `/root/openjdk_compile/openjdk/jdk/make'
make[1]: *** [jdk-build] Error 2
make[1]: Leaving directory `/root/openjdk_compile/openjdk'
make: *** [build_product_p_w_picpath] Error 2


解决方案:缺少X11包,yun instal *X11*


错误6:

../../../src/solaris/native/sun/awt/awt.h:38:27: fatal error: X11/Intrinsic.h: No such file or directory
 #include <X11/Intrinsic.h>

解决方案啊:yum install libXt-devel

 

 

 错误7

 ../../../src/solaris/native/sun/awt/splashscreen/splashscreen_config.h:33:34: fatal error: X11/extensions/shape.h: No such file or directory

解决方案啊:yum install libXtst-devel


 错误8

../../../src/solaris/native/sun/awt/awt_p.h:51:36: fatal error: X11/extensions/Xrender.h: No such file or directory


解决方案:yum install  libXrender-devel


编译结果:

#-- Build times ----------
Target all_product_build
Start 2017-09-02 20:39:54
End   2017-09-02 20:50:04
00:00:05 corba
00:00:08 hotspot
00:00:02 jaxp
00:00:04 jaxws
00:09:46 jdk
00:00:04 langtools
00:10:10 TOTAL
-------------------------
make[1]: Leaving directory `/root/openjdk_compile/openjdk'
[root@localhost bin]#./java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-root_2017_09_02_18_24-b00)
OpenJDK 64-Bit Server VM (build 24.0-b56, mixed mode)