Centos7
(能连外网)上编译 OpenJDK7u75
建议使用 Ubuntu
或者 Centos
,安装依赖的地方使用 apt-get/yum
替换即可( Rhel
的 yum
源使用收商业限制,因此依赖下载不方便,建议使用 centos
或者 debain
,或者更换 yum
为 centos
也行,笔者起初在 rhel
上编译,踩了不少坑,最后换到 centos
上才编译成功。没办法, linux
是真的菜,不过通过这次采坑也学了不少 linux
上编译源码的套路,本文会穿插着提到)。
openjdk7u75,主角,下载好用来编译。
在编译JDK时不全是使用C/C++,也有用到JAVA的,因此需要一个已编译好的JDK,官方称其为 BOOTSTRAP JDK
,要求必须是 JDK6 Update14
以上版本。建议到 Oracle
官网上下载,笔者下载的是 jdk-7u4-linux-x64
编译需要依赖 GCC
、 C++
等环境,一键下载:
yum -y install build-essential gawk m4 openjdk6-jdk libasound2-print-dev binutils libmotif3 libmotif-dev ant 复制代码
Xcode
相关的库:
yum install libX* 复制代码
将下载好的 openjdk
源码和作为 bootstrap jdk
的 jdk7u4
上传到 centos
的 /usr/local/java
下并解压:
[root@pinyoyougou-docker java]# ls jdk1.7.0_04 jdk-7u4-linux-x64.tar.gz openjdk openjdk-7u75-src-b13-18_dec_2014.zip 复制代码
上面的 openjdk
就是 openjdk
源码包解压之后的目录,记下这个名字,后续操作都是围绕这个目录展开的。
进入 openjdk
并检查编译环境:
[root@pinyoyougou-docker java]# cd openjdk [root@pinyoyougou-docker java]# make sanity WARNING: LANG has been set to zh_CN.UTF-8, this can cause build failures. Try setting LANG to 'C'. WARNING: The version of zip being used is older than the required version of '2.2'. The version of zip found was ''. ERROR: The Compiler version is undefined. 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]: 进入目录“/usr/local/java/openjdk/jdk/make/tools/freetypecheck” /bin/mkdir -p /usr/local/java/openjdk/build/linux-amd64/btbins rm -f /usr/local/java/openjdk/build/linux-amd64/btbins/freetype_versioncheck make[2]: 离开目录“/usr/local/java/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 复制代码
上面出现了两个警告和五个异常,我们需要逐个解决。(如果你 make sanity
输出的是 check pass
则可跳过此步骤)
设置环境变量 LANG=C
WARNING: LANG has been set to zh_CN.UTF-8, this can cause build failures. Try setting LANG to 'C'. 复制代码
解决方法:
[root@pinyoyougou-docker java]# export LANG=C 复制代码
zip
版本较低,需要更新
WARNING: The version of zip being used is older than the required version of '2.2'. The version of zip found was ''. 复制代码
解决方法:
yum install zip 复制代码
缺少编译依赖
ERROR: The Compiler version is undefined. 复制代码
解决:
[root@pinyoyougou-docker openjdk]# yum install gcc gcc-c++ 复制代码
取消已有的 JDK
环境变量
ERROR: Your CLASSPATH environment variable is set. This will most likely cause the build to fail. Please unset it and start your build again. 复制代码
由于我之前在这个 centos
上装过 jdk
并在 /etc/profile
中配置过 JAVA_HOME,CLASS_PATH
,因此这里提示建议我暂时取消这两项设置,否则可能出现未知错误。解决:
[root@pinyoyougou-docker openjdk]# unset JAVA_HOME [root@pinyoyougou-docker openjdk]# unset CLASS_PATH 复制代码
缺少声卡依赖 alsa
,这个是 linux
上常用的声音设备的依赖, java.awt
需要依赖这个。
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. 复制代码
解决
[root@pinyoyougou-docker openjdk]# yum search alsa 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.shu.edu.cn * updates: mirrors.aliyun.com ======================================== N/S matched: alsa ======================================== alsa-firmware.noarch : Firmware for several ALSA-supported sound cards alsa-lib.x86_64 : The Advanced Linux Sound Architecture (ALSA) library alsa-lib.i686 : The Advanced Linux Sound Architecture (ALSA) library alsa-lib-devel.i686 : Development files from the ALSA library alsa-lib-devel.x86_64 : Development files from the ALSA library alsa-plugins-arcamav.i686 : Arcam AV amplifier plugin for ALSA alsa-plugins-arcamav.x86_64 : Arcam AV amplifier plugin for ALSA alsa-plugins-maemo.i686 : Maemo plugin for ALSA alsa-plugins-maemo.x86_64 : Maemo plugin for ALSA alsa-plugins-oss.i686 : Oss PCM output plugin for ALSA alsa-plugins-oss.x86_64 : Oss PCM output plugin for ALSA alsa-plugins-pulseaudio.i686 : Alsa to PulseAudio backend alsa-plugins-pulseaudio.x86_64 : Alsa to PulseAudio backend alsa-plugins-samplerate.i686 : External rate converter plugin for ALSA alsa-plugins-samplerate.x86_64 : External rate converter plugin for ALSA alsa-plugins-upmix.i686 : Upmixer channel expander plugin for ALSA alsa-plugins-upmix.x86_64 : Upmixer channel expander plugin for ALSA alsa-plugins-usbstream.i686 : USB stream plugin for ALSA alsa-plugins-usbstream.x86_64 : USB stream plugin for ALSA alsa-plugins-vdownmix.i686 : Downmixer to stereo plugin for ALSA alsa-plugins-vdownmix.x86_64 : Downmixer to stereo plugin for ALSA alsa-tools.x86_64 : Specialist tools for ALSA alsa-tools-firmware.x86_64 : ALSA tools for uploading firmware to some soundcards alsa-utils.x86_64 : Advanced Linux Sound Architecture (ALSA) utilities alsa-plugins-speex.i686 : Rate Converter Plugin Using Speex Resampler alsa-plugins-speex.x86_64 : Rate Converter Plugin Using Speex Resampler [root@pinyoyougou-docker openjdk]# yum -y install alsa-lib* alsa-util* 复制代码
套路一:当提示缺少依赖,而你不知道要 yum install
什么时,你可以根据提示关键字搜一下 yum search
,然后在搜出的结果列表中,对有着相同前缀的依赖使用后缀通配符一键下载。
缺少 freetype
依赖
ERROR: FreeType version 2.3.0 or higher is required. 复制代码
解决:
root@pinyoyougou-docker openjdk]# yum search freetype 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.shu.edu.cn * updates: mirrors.aliyun.com ====================================== N/S matched: freetype ====================================== freetype-demos.x86_64 : A collection of FreeType demos freetype-devel.i686 : FreeType development libraries and header files freetype-devel.x86_64 : FreeType development libraries and header files freetype.x86_64 : A free and portable font rendering engine freetype.i686 : A free and portable font rendering engine 名称和简介匹配 only,使用“search all”试试。 [root@pinyoyougou-docker openjdk]# yum install freetype-devel.x86_64 复制代码
套路二:使用 yum install
时习惯性带上一个 -y
,免得总是询问是否确定安装。
于是我再 make sanity
,发现还有一个问题
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 复制代码
缺少 cups
打印框架,解决:
[root@pinyoyougou-docker openjdk]# yum search cups 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.shu.edu.cn * updates: mirrors.aliyun.com ======================================== N/S matched: cups ======================================== bluez-cups.x86_64 : CUPS printer backend for Bluetooth printers cups.x86_64 : CUPS printing system cups-client.x86_64 : CUPS printing system - client programs cups-devel.i686 : CUPS printing system - development environment cups-devel.x86_64 : CUPS printing system - development environment cups-filesystem.noarch : CUPS printing system - directory layout cups-filters.x86_64 : OpenPrinting CUPS filters and backends cups-filters-devel.i686 : OpenPrinting CUPS filters and backends - development environment cups-filters-devel.x86_64 : OpenPrinting CUPS filters and backends - development environment cups-filters-libs.i686 : OpenPrinting CUPS filters and backends - cupsfilters and fontembed : libraries cups-filters-libs.x86_64 : OpenPrinting CUPS filters and backends - cupsfilters and fontembed : libraries cups-ipptool.x86_64 : CUPS printing system - tool for performing IPP requests cups-libs.x86_64 : CUPS printing system - libraries cups-libs.i686 : CUPS printing system - libraries cups-lpd.x86_64 : CUPS printing system - lpd emulation ghostscript-cups.x86_64 : CUPS filter for interpreting PostScript and PDF gutenprint-cups.x86_64 : CUPS drivers for Canon, Epson, HP and compatible printers python-cups.x86_64 : Python bindings for CUPS python-cups-doc.x86_64 : Documentation for python-cups cups-pk-helper.x86_64 : A helper that makes system-config-printer use PolicyKit foomatic-filters.x86_64 : CUPS print filters for the foomatic package samba-krb5-printing.x86_64 : Samba CUPS backend for printing with Kerberos 名称和简介匹配 only,使用“search all”试试。 [root@pinyoyougou-docker openjdk]# yum install cups-devel.x86_64 复制代码
make sanity
检查通过:
Sanity check passed. 复制代码
经过前面一番周折,编译环境基本上准备好了,接下来就可以 make
进行编译了,但是编译前需要设置一下一些环境变量,诸如 boostrap jdk
的根目录在哪,哪些需要编译,并行编译线程数等。
在 openjdk/
下创建 compile.sh
并键入下列内容(参考《深入理解Java虚拟机》):
#语言选项,这个必须设置,否则编译好后会出现一个HashTable的NPE错 export LANG=C #Bootstrap JDK的安装路径。必须设置。 export ALT_BOOTDIR=/usr/local/java/jdk1.7.0_04 #允许自动下载依赖 export ALLOW_DOWNLOADS=true #并行编译的线程数,设置为和CPU内核数量一致即可 export HOTSPOT_BUILD_JOBS=4 export ALT_PARALLEL_COMPILE_JOBS=4 #比较本次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。 BUILD_DEPLOY=false #把它设置为false就不会build出安装包。因为安装包里有些奇怪的依赖,但即便不build出它也已经能得到完整的JDK映像,所以还是别build它好了。 BUILD_INSTALL=false #这两个环境变量必须去掉,不然会有很诡异的事情发生(我没有具体查过这些“”诡异的事情”,Makefile脚本检查到有这2个变量就会提示警告“) unset JAVA_HOME unset CLASSPATH make 2>&1 | tee $ALT_OUTPUTDIR/build.log 复制代码
其中需要注意的地方:
LANG=C
、将 ALT_BOOTDIR
设置成 boostrap jdk
的根目录 jdk
环境变量,一定要在这里 unset
一下(上述的第 40,41
行) cpu
核心个数相同即可 其它的地方可以照搬。
使用上面写好的编译启动脚本开始编译:
[root@pinyoyougou-docker openjdk]# chmod +x compile.sh [root@pinyoyougou-docker openjdk]# ./compile.sh 复制代码
这个过程通常需要几十分钟,如果一切顺利,最后会显示编译开始时间以及终止时间。(当然,大部分情况下,受挫之路相当曲折~)。
######################################################################## ##### Leaving jdk for target(s) sanity all docs images ##### ######################################################################## ##### Build time 00:10:12 jdk for target(s) sanity all docs images ##### ######################################################################## #-- Build times ---------- Target all_product_build Start 2019-01-23 16:37:02 End 2019-01-23 16:48:00 00:00:23 corba 00:00:09 hotspot 00:00:03 jaxp 00:00:06 jaxws 00:10:12 jdk 00:00:03 langtools 00:10:58 TOTAL ------------------------- make[1]: Leaving directory `/usr/local/java/openjdk' [root@pinyoyougou-docker openjdk]# 复制代码
所以下面将罗列笔者的受挫之路……如果 make
过程中发生 error
异常终止,一般解决异常之后继续 make
。笔者开始傻到每次解决异常,然后 make clean
,再 make
。
cannot find -lstdc++
-l
表示库, cannot find -lXXX
,通常表示缺少 libXXX
库。看网上说是缺少 libstdc++-static
,但笔者建议最好将 yum search libstdc*
的搜索结果一股脑全 yum install
下来,反正又不多。
libjvm.so
软连接死循环
/usr/bin/ld: cannot open output file libjvm.so: Too many levels of symbolic links collect2: error: ld returned 1 exit status ln: failed to access 'libjvm.so': Too many levels of symbolic links ln: failed to access 'libjvm.so.1': Too many levels of symbolic links /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 clean
,然后再 make sanity
、 make
超过十年问题
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) 复制代码
修改 openjdk//jdk/src/share/classes/java/util/CurrencyData.properties
,将其中表示年份的地方都改为距离今年不超过10年的年份:
缺少C头文件
fatal error: X11/Intrinsic.h: No such file or directory # include <X11/Intrinsic.h> 复制代码
/usr/include/gnu/stubs.h:7:27: fatal error: gnu/stubs-32.h: No such file or directory compilation terminated. make: *** [bitmap.o] Error 1 复制代码
套路三:如果提示你缺少 xxx/xxx.h
,可以使用 yum provides */xxx.h
查看该头文件包含于哪个库中,再将该库的全名称作为 yum install
的参数下载
本想将笔者踩过的坑都贴出来,奈何编译输出信息太多难以找到采坑痕迹。总而言之,不是缺少依赖,就是已有依赖不兼容(这时你需要32/64位版本都下载)
编译成功之后, openjdk/build/linux-amd64/j2sdk-image
就是编译好的 jdk
的根目录:
[root@pinyoyougou-docker j2sdk-image]# bin/java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-root_2019_01_23_14_04-b00) OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode) 复制代码