目录
一、前言
在上篇的文章中我们详细介绍了OpenJDK11、OpenJDK12源码、Cygwin、VS Code2017社区英文版安装过程以及为什么要安装这些软件/源码,主要给新手提供一个详细的步骤流程图。在本篇文章中我们就进行OpenJDK的编译工作。
二、正文
1.已安装软件列表及路径
软件、文件名称 | Windows路径 |
OpenJDK11 | F:\jdk-11 |
OpenJDK12源码 | F:\jdk12-06222165c35f |
CygWin | 注意:需要安装autoConf、tar、mak、zip、unzip |
VS Code2017社区英文版 | C:\Program Files (x86)\Microsoft Visual Studio\2017\Community |
2.编译OpenJDK12
2.1 OpenJDK12源码编译文件介绍
官网在源码中提供了编译过程介绍(具体见源码中doc/building/building.md),以下对该文档内容进行简单汇总整理介绍。
2.1.1 编译流程介绍(可忽略)
1. [Get the complete source code]:hg clone http://hg.openjdk.java.net/jdk/jdk
解释:文档hg clone命令是Mercurial命令,没接触过可以忽略按照我上篇文档下载源码。
2. [Run configure]: If `configure` fails due to missing dependencies (to either the [toolchain](#native-compiler-toolchain-requirements), [build tools]( #build-tools-requirements), [external libraries]( #external-library-requirements) or the [boot JDK](#boot-jdk-requirements)), most of the time it prints a suggestion on how to resolve the situation on your platform. Follow the instructions, and try running `bash configure` again.
解释:如果运行configure命令失败,请检查boot JDK以及各组件。
3. [Run make]: make images
解释:运行make命令编译映像文件。
4. Verify your newly built JDK: ./build/*/images/jdk/bin/java -version
解释:查看编译的JDK是否成功
5. [Run basic tests]: make run-test-tier1
解释:进行基础测试
2.1.2 编译参数介绍(可忽略)
参数格式 | 参数介绍 |
--with-<lib>=<path> | 依赖包的具体路径,通常使用在安装了多个不同版本的Bootstrap JDK和依赖包的情况。其中lib的可选值包括boot-jdk、freetype、cups、x、alsa、libffi、jtreg、libjpeg、giflib、libpng、lcms、zlib |
--with-boot-jdk=<path> | boot-jdk(自举)路径,可以理解为OpneJDK11路径,具体解释详见上篇文章。 |
--with-freetype=<path> | freetype是字体引擎路径,configurate可以正确定位,一般使用默认即可。 |
--with-cups=<path> | cups是通用UNIX打印系统,configurate可以正确定位,一般使用默认即可。 |
--with-x=<path> | x这里指代x11(x的11版本),是linux的图形界面,configurate可以正确定位,一般使用默认即可。 |
--with-alsa=<path> | alsa是linux的声音结构,configurate可以正确定位,一般使用默认即可。 |
--with-libffi=<path> | libffi是外部函数接口库,configurate可以正确定位,一般使用默认即可。 |
--with-jtreg=<path> | jtreg测试框架,具体详见源码doc/testing/testing.md,一般使用默认即可,有特殊测试需求可以自定义路径。 |
--with-libjpeg=<source> | jdk的第三方类库libjpeg,默认使用JDK库内的libjpeg,可自定义。 |
--with-giflib=<source> | jdk的第三方类库giflib,默认使用JDK库内的giflib,可自定义。 |
--with-libpng=<source> | jdk的第三方类库libpng,默认使用JDK库内的libpng,可自定义。 |
--with-lcms=<source> | jdk的第三方类库lcms,默认使用JDK库内的lcms,可自定义。 |
--with-zlib=<source> | jdk的第三方类库zlib,默认使用JDK库内的zlib,可自定义。 |
--with-target-bits=<bits> | 虚拟机位数,默认64位(在64位机器可以编译32位和64位虚拟机) |
--with-jvm-variants=<variant>[,<variant>...] | 编译特定模式的HotSpot虚拟机,可以多个模式并存,可选值为server、client、minimal、core、zero、custom。 |
--with-jvm-features=<feature>[,<feature>...] | 针对--with-jvm-variants=custom时的自定义虚拟机特性列表,可以多个特性并存,由于可选值较多,可以运行“bash configure--help”命令输出。 |
--with-version-string=<string> | 设置编译JDK的版本号,譬如java-version的输出就会显示该信息。 这个参数还有--with-version-<part>=<value>的形式,其中part可以是pre、opt、build、major、minor、 security、patch之一,用于设置版本号的某一个部分。 |
--with-native-debug-symbols=<method> | 确定调试符号信息的编译方式,可选值为none、 internal、external、zipped。 |
--with-debug-level=<level> | 设置编译的级别,可选值为release、fastdebug、slowde-bug,越往后进 行的优化措施就越少,带的调试信息就越多。默认值为release。 |
--with-extra-<flagtype>=<flags> | 用于设定额外编译器参数,其中 flagtype可选值为cflags、cxxflags、ldflags,分别代表C、C++和Java代码的参数。 |
--with-conf-name=<name> | 指定编译配置名称,默认会根据编译的操作系统、指令集架构、调试级别自动生成一个配置名称,譬如“windows-x86_64-serverrelease”,如果要保存不同的编译参数,可以使用这个参数来自定义配置名称 |
2.1.3 开始编译OpenJDK12
OpenJDK编译是通过源码中的Makefile进行的,Unix程序员应该十分清楚Makefile,Windows程序员可能不是很了解Makefile,因为Windows的IDE已经帮我们做好了这些操作,有兴趣可以自行了解,没兴趣也无关紧要,按照以下步骤操作即可。
首先,我们打开已安装的Cygwin。
切换至我们的OpenJDK12源码目录,我的目录是F:\jdk12-06222165c35f。
上图可以看出,我们切换至F:\jdk12-06222165c35f目录,但是cygwin显示的目录是cygdrive/f/jdk12-06222165c35f,这是因为cygwin会将我们的目录结构修改为unix目录结构,这个不用太在意。
这个就是我们目前OpenJDK12的目录结构,configure命令承担了依赖项检查、参数配置和构建输出目录结构等多项职责,命令执行后将会得到明确的提示,我们先执行该命令检查是否能正常编译。命令如下。
bash ./configure --with-ucrt-dll-dir="/cygdrive/c/Program Files (x86)/Windows Kits/10/Redist/10.0.17763.0/ucrt/DLLs/x64" --with-boot-jdk=/cygdrive/f/jdk-11 --with-target-bits=64 --disable-warnings-as-errors
说明:
1. --with-ucrt-dll-dir指代VS Code安装Windows10 SDK产生的文件夹目录。在c/Program Files (x86)/Windows Kits下面,其中10代码Win10 SDK,10.0.17763.0代表SKD版本号,因为我在上篇文章安装的SDK版本为10.0.17763.0,所以此处为10.0.17763.0。
2.--with-boot-jdk指代OpenJDK11目录。
3.--with-target-bits=64指代我要编译64位OpenJDK12,默认64,可删除该参数。
4.--disable-warnings-as-errors指代如果是由warnings引发的error,请跳过继续configure。
执行该命令
报错信息:
configure: error: Could not find any dlls in /cygdrive/c/Program Files (x86)/Windows Kits/10/Redist/10.0.17763.0/ucrt/DLLs/x64
搜索源码“Could not find any dlls in”发现了有两处问题,OK,我们加一行打印确认一下哪个地方报错。
加注释截图如下
继续执行configure命令,报错日志如下
This is 60269 line prinf message
configure: error: Could not find any dlls in /cygdrive/c/Program Files (x86)/Windows Kits/10/Redist/10.0.17763.0/ucrt/DLLs/x64
仔细查看“This is 60269 line prinf message”添加日志代码,发现是由于$with_ucrt_dll_dir变量找不到dll导致的,全局搜索“$with_ucrt_dll_dir”,在make/autoconf/toolchain_windows.m4发现了问题,如下图
由于该目录是/cygdrive/c/Program Files (x86)/Windows Kits/10/Redist/10.0.17763.0/ucrt/DLLs/x64,由于Program Files和Windows Kits目录中都有空格,所以要把*.dll放到外面才可以,其实就是"$with_ucrt_dll_dir/*.dll" 改成 "$with_ucrt_dll_dir"/*.dll修改如下图。
继续执行configure命令
configure成功,内存是16318 MB。
执行“make all”命令进行编译。(make all包含make images,安装官方文档执行make images也可以)
报错信息:
ERROR: Build failed for target 'all' in configuration 'windows-x86_64-server-release' (exit code 2)
这个问题是由于make版本导致“make all”命令无法,所以我又重新安装了Cygwin,在选择make的时候,我选择了4.2.1-2,Cygwin重新安装不需要卸载,双击安装包直接安装就好,它会自动覆盖之前安装包。
再次执行“make all”命令进行编译
不可思议,官方的hotspot虚拟机的测试文件test_json.cpp syntax error,行吧,既然如此,我们就全部注释掉吧,找到源码中的test/hotspot/gtest/utilities/test_json.cpp文件,我做了如下修改,其实红框是添加的,注释掉的是原有的。
再次执行“make all”命令进行编译,编译成功。
经过20多分钟的等待,编译成功。第一次编译耗时会久一点,后面耗时会缩短到10秒内。因为第一次是全量编译,后面是增量编译。
编译完成之后,进入OpenJDK源码的“build/配置名称/jdk”目录下就可以看到OpenJDK的完整编译结果了,我的目录是:F:\jdk12-06222165c35f\build\windows-x86_64-server-release\jdk,因为我没设置配置名称,所以系统默认是windows-x86_64-server-release,这个是可以通过--with-conf-name=<name>指定的。下面的JDK的编译结果。
把该目录复制到JAVA_HOME目录,就可以作为一个完整的JDK来使用,因为我本地安装JDK8没有更换的想法,就没有切换JAVE_HOME,下面直接进入OpenJDK源码的目录查看版本吧。