admin 管理员组

文章数量: 887019

背景

因为最近在看《深入理解Java虚拟机 JVM高级特性与最佳实践》,书上介绍了jdk编译的方法,所以进行实践。

目标

编译在Windows 11上运行的x64版本OpenJDK 12。

环境准备

系统

我的系统是Windows 11,源码中的build.html中对Windows的说明是高于Windows XP的应该都能构建。

Windows XP is not a supported platform, but all newer Windows should be able to build the JDK.

OpenJDK 12源码

选择以下任一方法,

  1. 使用Mercurial clone源码,
hg clone http://hg.openjdk.java/jdk/jdk
  1. 下载源码包。

本文用的是OpenJDK12+33/OpenJDK12-ga,下载的是tar.gz包

md5sum  : 760bdd74283e89940f850beb9897bb78
sha1sum : d04d49b05d3152697321b7f98156172233f63b14

下载完成后,建议对比一下md5和sha1摘要,对比主要是为了检查文件是否完整,如果文件不完整,后面执行构建的时候,可能会提示"No rule to make target"的错误[1]。

Boot JDK

(Open)JDK 11或12

强烈不建议把JDK放到包含空格的路径下,可以省去一些奇奇怪怪的麻烦。

也不建议放在包含中文的路径下,但因为我没有验证过中文路径,所以不确定会不会出现编码相关的问题。

工具链

我使用的是Visual Studio 2017 Community + cygwin 3.3.3-1

同上,强烈不建议把这些程序放到包含空格的路径下,可以省去一些奇奇怪怪的麻烦。

也不建议放在包含中文的路径下,但因为我没有验证过中文路径,所以不确定会不会出现编码相关的问题。

Visual Studio 2017

可以在微软官网下了Visual Studio的安装器,安装Visual Studio 2017 Community。

我看到其他博客提到要装英文版本[2,3],但其实中文版本也是可以的,不过需要修改构建的脚本(我因为很早之前就装了VS,所以就没有装回英文版)。

Cygwin

可以在Cygwin官网下载安装器,安装的时候选择autoconf、make、zip和unzip 4个包。

我所选择的版本是,

autoconf 15-1
make 4.2.1-2
zip 3.0-12
unzip 6.0-17

版本不需要选择太新,因为OpenJDK 12已经停止维护了,太新的工具可能不兼容源码的构建脚本。比如,make建议选择4.2.x版本的,4.3版本的对本文所使用的OpenJDK12源码构建有不兼容[4]

安装完后启动Cygwin,程序自动初始化,

Copying skeleton files.
These files are for the users to personalise their cygwin experience.

They will never be overwritten nor automatically updated.

'./.bashrc' -> '/home/frank//.bashrc'
'./.bash_profile' -> '/home/frank//.bash_profile'
'./.inputrc' -> '/home/frank//.inputrc'
'./.profile' -> '/home/frank//.profile'

执行cygcheck -d -d来查看安装的包。

$ cygcheck -c -d
Cygwin Package Information
Package              Version
_autorebase          001091-1
alternatives         1.3.30c-10
autoconf             15-1
autoconf2.1          2.13-12
autoconf2.5          2.69-5
autoconf2.7          2.71-2
base-cygwin          3.8-1
base-files           4.3-3
bash                 4.4.12-3
bzip2                1.0.8-1
ca-certificates      2021.2.52-1
coreutils            8.26-2
crypto-policies      20190218-1
cygutils             1.4.16-7
cygwin               3.3.3-1
dash                 0.5.11.5-1
diffutils            3.8-1
editrights           1.03-1
file                 5.41-2
findutils            4.8.0-1
gawk                 5.1.1-1
getent               2.18.90-4
grep                 3.7-2
groff                1.22.4-1
gzip                 1.11-1
hostname             3.13-1
info                 6.8-2
ipc-utils            1.0-2
less                 590-1
libargp              20110921-3
libattr1             2.4.48-2
libblkid1            2.33.1-2
libbz2_1             1.0.8-1
libcrypt0            2.1-1
libcrypt2            4.4.20-1
libdb5.3             5.3.28-2
libfdisk1            2.33.1-2
libffi6              3.2.1-2
libgc1               8.0.6-1
libgcc1              11.2.0-1
libgdbm6             1.18.1-1
libgdbm_compat4      1.18.1-1
libgmp10             6.2.1-2
libguile2.0_22       2.0.14-3
libguile2.2_1        2.2.7-1
libiconv2            1.16-2
libintl8             0.21-1
libltdl7             2.4.6-8
liblz4_1             1.7.5-1
liblzma5             5.2.4-1
libmpfr6             4.1.0-2
libncursesw10        6.1-1.20190727
libp11-kit0          0.23.20-1
libpcre1             8.45-1
libpcre2_8_0         10.39-1
libpipeline1         1.5.3-1
libpopt-common       1.18-1
libpopt0             1.18-1
libreadline7         8.1-2
libsigsegv2          2.10-2
libsmartcols1        2.33.1-2
libssl1.1            1.1.1l-2
libstdc++6           11.2.0-1
libtasn1_6           4.14-1
libunistring2        0.9.10-1
libuuid1             2.33.1-2
login                1.13-1
m4                   1.4.19-1
make                 4.2.1-2
man-db               2.9.4-2.1
mintty               3.5.2-1
ncurses              6.1-1.20190727
openssl              1.1.1l-2
p11-kit              0.23.20-1
p11-kit-trust        0.23.20-1
perl                 5.32.1-2
perl_autorebase      5.32.1-2
perl_base            5.32.1-2
rebase               4.5.0-1
run                  1.3.4-2
sed                  4.8-1
tar                  1.34-1
terminfo             6.1-1.20190727
terminfo-extra       6.1-1.20190727
tzcode               2021e-1
tzdata               2021e-1
unzip                6.0-17
util-linux           2.33.1-2
vim-minimal          8.2.3755-1
which                2.20-2
xz                   5.2.4-1
zip                  3.0-12
zlib0                1.2.11-1
zstd                 1.5.1-1

配置

如果是下载tar.gz源码包,则找一个目录解压,

$ tar xzf openjdk12-b67884871b5f.tar.gz
$ ls
jdk-b67884871b5f  openjdk12-b67884871b5f.tar.gz

这个版本的构建脚本有点问题,通过–with-tools-dir来配置Visual Studio的路径不起作用,因为脚本设置的相关变量被清除了[5],所以需要修改jdk-b67884871b5f\make\autoconf\toolchain_windows.m4文件(非官方做法,我只是注释,官方是删掉[6],不过我只是想说明下,实际上没有区别,可以忽略。这个问题是在OpenJDK12+33之后才改的(通过比对时间发现的),但OpenJDK12已经停止维护了,非LTS)。

# 修改前,205行
  VS_ENV_CMD=""

# 修改后,205行
  #VS_ENV_CMD=""

如果安装的Visual Studio是中文的,具体一点,找到cl.exe,然后执行,检查输出的是否包含中文,

$ /cygdrive/e/Programs/Microsoft/VisualStudio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.16.27045 版
版权所有(C) Microsoft Corporation。保留所有权利。

用法: cl [ 选项... ] 文件名... [ /link 链接选项... ]

如果输出包含中文,跟上面代码片段相似,那么就需要修改jdk-b67884871b5f\make\autoconf\toolchain.m4文件(2处),原因是构建脚本判断编译器是否存在,是根据cl.exe等命令的输出做正则判断的,正则表达式匹配的是英文版本,所以上面代码片段的输出无法被默认的表达式识别。

# 修改前,435行
    $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Microsoft.*Compiler" > /dev/null

# 修改后,435行
    $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Microsoft.*编译器" > /dev/null

# 修改前,1008-1012行
    elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
      if test "x$COMPILER_CPU_TEST" != "xx64"; then
        AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"

本文标签: cygwin Windows visual Studio