本身动手编译OpenJDK

我的技术博客:www.zhenganwen.topjava

笔者环境

  • 64bit / Windows10 / i5-7200U / 4核心CPU,在虚拟机上的Centos7(能连外网)上编译OpenJDK7u75

建议使用Ubuntu或者Centos,安装依赖的地方使用apt-get/yum替换便可(Rhelyum源使用收商业限制,所以依赖下载不方便,建议使用centos或者debain,或者更换yumcentos也行,笔者起初在rhel上编译,踩了很多坑,最后换到centos上才编译成功。没办法,linux是真的菜,不过经过此次采坑也学了很多linux上编译源码的套路,本文会穿插着提到)。python

环境准备

OpenJDK源码

openjdk7u75,主角,下载好用来编译。linux

Bootstrap JDK

在编译JDK时不全是使用C/C++,也有用到JAVA的,所以须要一个已编译好的JDK,官方称其为BOOTSTRAP JDK,要求必须是JDK6 Update14以上版本。建议到Oracle官网上下载,笔者下载的是jdk-7u4-linux-x64c++

编译环境

编译须要依赖GCCC++等环境,一键下载:git

yum -y install build-essential gawk m4 openjdk6-jdk libasound2-print-dev binutils libmotif3 libmotif-dev ant
复制代码

Xcode相关的库:github

yum install libX*
复制代码

检查编译环境

将下载好的openjdk源码和做为bootstrap jdkjdk7u4上传到centos/usr/local/java下并解压:docker

[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源码包解压以后的目录,记下这个名字,后续操做都是围绕这个目录展开的。shell

进入openjdk并检查编译环境:bootstrap

[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则可跳过此步骤)centos

  1. 设置环境变量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
    复制代码
  2. 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
    复制代码
  3. 缺乏编译依赖

    ERROR: The Compiler version is undefined.
    复制代码

    解决:

    [root@pinyoyougou-docker openjdk]# yum install gcc gcc-c++
    复制代码
  4. 取消已有的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
    复制代码
  5. 缺乏声卡依赖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,而后在搜出的结果列表中,对有着相同前缀的依赖使用后缀通配符一键下载。

  6. 缺乏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,省得老是询问是否肯定安装。

  7. 因而我再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
    复制代码
  8. 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
复制代码

其中须要注意的地方:

  1. 必须设置LANG=C、将ALT_BOOTDIR设置成boostrap jdk的根目录
  2. 若是你的系统先前配置过jdk环境变量,必定要在这里unset一下(上述的第40,41行)
  3. 上述并型线程数跟你的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

解决编译错误

  1. cannot find -lstdc++

    -l表示库,cannot find -lXXX,一般表示缺乏libXXX库。看网上说是缺乏libstdc++-static,但笔者建议最好将yum search libstdc*的搜索结果一股脑全yum install下来,反正又很少。

  2. 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 sanitymake

  3. 超过十年问题

    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年的年份:

    • 修改108行 AZ=AZM;2015-12-31-20-00-00;AZN
    • 修改381行 MZ=MZM;2015-06-30-22-00-00;MZN
    • 修改443行 RO=ROL;2015-06-30-21-00-00;RON
    • 修改535行 TR=TRL;2015-12-31-22-00-00;TRY
    • 修改561行 VE=VEB;2015-01-01-04-00-00;VEF
  4. 缺乏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位版本都下载)

使用编译好的jdk

编译成功以后,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)
复制代码

参考连接

相关文章
相关标签/搜索