本文主要叙述自己编译openjdk的过程
补充:jdk15采用本文叙述的方式修改文件也可以编译成功,具体我下载的jdk-15-35这个文件尝试的,使用brew install openjdk@15安装的jdk作为bootjdk
补充二:同样采用openjdk15作为bootjdk,编译jdk16也能成功,而且jdk16编译不需要进行源码修改
参考视频
该视频讲的是Mac10.5.4版本编译openjdk11的情况。由于我的mac版本是11.1,完全按照视频操作还是有一定的问题,本文主要介绍这方面问题的结局。
1.环境
编译环境需要xcode,作为bootjdk的jdk,clang,clang++,autoconf, freetype, make等
autoconf和freetype可能需要重新通过brew来安装,make好像是自带的,clang安和clang++安装xcode之后就有了,bootjdk可以通过brew来安装
-
操作系统版本
-
bootJDK
编译新的jdk版本至少需要一个稍微老一点的jdk或者是同版本的jdk作为bootjdk。本文使用openjdk11.0.9作为bootjdk。
刚开始我的电脑环境使用的jdk是openjdk 1.8.0_265
➜ jdk_11_28 git:(openjdk11) ✗ java -version openjdk version "1.8.0_265" OpenJDK Runtime Environment Corretto-8.265.01.1 (build 1.8.0_265-b01) OpenJDK 64-Bit Server VM Corretto-8.265.01.1 (build 25.265-b01, mixed mode)
后使用brew安装了11.0.9版本的jdk。系统升级后brew其实一开始还不能用,一直也没咋理会,这次编译需要用到,去官网重新安装了最新的brew才又变得可用了。
安装openjdk11命令
brew install openjdk@11
安装后配置完环境变量,查看版本:
➜ jdk_11_28 git:(openjdk11) ✗ java --version openjdk 11.0.9 2020-10-20 OpenJDK Runtime Environment (build 11.0.9+11) OpenJDK 64-Bit Server VM (build 11.0.9+11, mixed mode
-
clang 版本
➜ jdk_11_28 git:(openjdk11) ✗ clang --version Apple clang version 12.0.0 (clang-1200.0.32.29) Target: x86_64-apple-darwin20.2.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
-
clang++ version
➜ jdk_11_28 git:(openjdk11) ✗ clang++ --version Apple clang version 12.0.0 (clang-1200.0.32.29) Target: x86_64-apple-darwin20.2.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
-
autoconf
autoconf一开始也没安装,也是通过brew安装的,版本如下
➜ jdk_11_28 git:(openjdk11) ✗ autoconf --version autoconf (GNU Autoconf) 2.69 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+/Autoconf: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>, <http://gnu.org/licenses/exceptions.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by David J. MacKenzie and Akim Demaille.
-
make版本
➜ jdk_11_28 git:(openjdk11) ✗ make --version GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for i386-apple-darwin11.3.0
-
freetype
同样之前没有,通过brew安装,版本如下:
➜ jdk_11_28 git:(openjdk11) ✗ freetype-config --version 23.4.17
2. 源码下载
我觉得直接去下载源码压缩包是最快的,openjdk11源码下载链接, 当然,也可以直接在openjdk github仓库clone 参考文章【openJDK系列1】macos编译openJDK 8
3. 编译
3.1 解压源码
新建一个文件夹,解压源码文件到该目录
比如我在document下新建了jdk目录,将源码放在了里面,解压
方便起见,我将解压后的文件夹改名成了jdk11
3.2 执行configure脚本检查环境
然后cd到该目录, 并执行configure脚本
➜ ~ cd Documents/jdk/jdk11
➜ jdk11 ls
ADDITIONAL_LICENSE_INFO LICENSE README configure make test
ASSEMBLY_EXCEPTION Makefile bin doc src
➜ jdk11 sh configure
Runnable configure script is not present
Generating runnable configure script at /Users/xxx/Documents/jdk/jdk11/build/.configure-support/generated-configure.sh
Using autoconf at /usr/local/bin/autoconf [autoconf (GNU Autoconf) 2.69]
configure: Configuration created at Fri Feb 26 10:14:41 CST 2021.
checking for basename... /usr/bin/basename
...省略
configure: Found potential Boot JDK using java(c) in PATH
configure: Potential Boot JDK found at /usr is incorrect JDK version (openjdk version "1.8.0_265"); ignoring
configure: (Your Boot JDK version must be one of: 10 11)
configure: Could not find a valid Boot JDK. You might be able to fix this by running 'brew cask install java'.
configure: This might be fixed by explicitly setting --with-boot-jdk
configure: error: Cannot continue
/Users/xxx/Documents/jdk/jdk11/build/.configure-support/generated-configure.sh: line 82: 5: Bad file descriptor
configure exiting with result code 1
发现后面报错了,提示很清楚
configure: Found potential Boot JDK using /usr/libexec/java_home
configure: Potential Boot JDK found at /Users/xxx/Library/Java/JavaVirtualMachines/corretto-1.8.0_265/Contents/Home is incorrect JDK version (openjdk version "1.8.0_265"); ignoring
configure: (Your Boot JDK version must be one of: 10 11)
告诉我们需要10或者11的jdk作为bootjdk,但是我这里是8。我其实已经通过brew安装了jdk11,但是没有配置环境变量,所以还需要配置下环境变量。
查看安装的openjdk11位置
➜ jdk11 cd /usr/local
➜ local ls
Caskroom Cellar Frameworks Homebrew bin etc include lib opt sbin share var
➜ local cd Cellar
➜ Cellar ls
autoconf gcc gettext isl libmpc libunistring mpfr openjdk@11 python@3.9 sqlite wget
freetype gdbm gmp libidn2 libpng mercurial openjdk openssl@1.1 readline tcl-tk xz
➜ Cellar cd openjdk@11
➜ openjdk@11 ls
11.0.9
➜ openjdk@11 cd 11.0.9
➜ 11.0.9 ls
INSTALL_RECEIPT.json LICENSE README bin include libexec
➜ 11.0.9 pwd
/usr/local/Cellar/openjdk@11/11.0.9
➜ 11.0.9
/usr/local/Cellar/openjdk@11/11.0.9 这个路径就是我需要配置的jdk环境变量的路径
/usr/local/Cellar目录下是我通过brew安装的所有软件
配置环境变量
vim ~/.bash_profile
文件末尾添加
export JAVA_HOME=/usr/local/Cellar/openjdk@11/11.0.9
export PATH=$JAVA_HOME:$PATH
保存退出后source下该文件再查看jdk版本
➜ jdk11 source ~/.bash_profile
➜ jdk11 java --version
openjdk 11.0.9 2020-10-20
OpenJDK Runtime Environment (build 11.0.9+11)
OpenJDK 64-Bit Server VM (build 11.0.9+11, mixed mode)
➜ jdk11
再来运行下脚本,看运行结果的末尾,这次正常了
➜ jdk11 sh configure
configure: Configuration created at Fri Feb 26 10:28:46 CST 2021.
checking for basename... /usr/bin/basename
... 省略
====================================================
A new configuration has been successfully created in
/Users/xxx/Documents/jdk/jdk11/build/macosx-x86_64-normal-server-release
using default settings.
Configuration summary:
* Debug level: release
* HS debug level: product
* JVM variants: server
* JVM features: server: 'aot cds cmsgc compiler1 compiler2 dtrace epsilongc g1gc graal jfr jni-check jvmci jvmti management nmt parallelgc serialgc services vm-structs'
* OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64
* Version string: 11-internal+0-adhoc.xxx.jdk11 (11-internal)
Tools summary:
* Boot JDK: openjdk version "11.0.9" 2020-10-20 OpenJDK Runtime Environment (build 11.0.9+11) OpenJDK 64-Bit Server VM (build 11.0.9+11, mixed mode) (at /usr/local/Cellar/openjdk@11/11.0.9)
* Toolchain: clang (clang/LLVM from Xcode 12.4)
* C Compiler: Version 12.0.0 (at /usr/bin/clang)
* C++ Compiler: Version 12.0.0 (at /usr/bin/clang++)
Build performance summary:
* Cores to use: 12
* Memory limit: 16384 MB
3.3 开始编译
编译过程中一共改了3个文件才最终编译成功
第一个编译错误及修复
执行make
➜ jdk11 make
Building target 'default (exploded-image)' in configuration 'macosx-x86_64-normal-server-release'
Warning: No mercurial configuration present and no .src-rev
Compiling 8 files for BUILD_TOOLS_LANGTOOLS
/Users/xxx/Documents/jdk/jdk11/src/hotspot/share/runtime/arguments.cpp:1461:35: error: result of comparison against a string literal is unspecified (use an explicit string comparison function instead) [-Werror,-Wstring-compare]
if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
^ ~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make[3]: *** [/Users/xxx/Documents/jdk/jdk11/build/macosx-x86_64-normal-server-release/hotspot/variant-server/libjvm/objs/arguments.o] Error 1
make[3]: *** Waiting for unfinished jobs....
Compiling 90 properties into resource bundles for java.desktop
Compiling 2961 files for java.base
make[2]: *** [hotspot-server-libs] Error 2
make[2]: *** Waiting for unfinished jobs....
ERROR: Build failed for target 'default (exploded-image)' in configuration 'macosx-x86_64-normal-server-release' (exit code 2)
Stopping sjavac server
=== Output from failing command(s) repeated here ===
* For target hotspot_variant-server_libjvm_objs_arguments.o:
/Users/xxx/Documents/jdk/jdk11/src/hotspot/share/runtime/arguments.cpp:1461:35: error: result of comparison against a string literal is unspecified (use an explicit string comparison function instead) [-Werror,-Wstring-compare]
if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
^ ~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
* All command lines available in /Users/xxx/Documents/jdk/jdk11/build/macosx-x86_64-normal-server-release/make-support/failure-logs.
=== End of repeated output ===
No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.
make[1]: *** [main] Error 2
make: *** [default] Error 2
这里可以看到报错了,需要对源码进行小改动才能编译通过。
可以不用着急,先用版本控制工具给管理下。如此这样,我这边一共改了三个文件才最后编译通过。
以上编译错误通过修改如下文件
src/hotspot/share/runtime/arguments.cpp
第1461行的常量改成了0,参考了记录编译JDK11源码时遇到的两个问题这篇文章
第二个编译错误
修改源码后,make clean一下,继续执行make
➜ jdk11 make clean
Building target 'clean' in configuration 'macosx-x86_64-normal-server-release'
... ...省略
➜ jdk11 make
... ...省略
=== Output from failing command(s) repeated here ===
* For target hotspot_variant-server_libjvm_objs_sharedRuntime.o:
/Users/xxx/Documents/jdk/jdk11/src/hotspot/share/runtime/sharedRuntime.cpp:2798:85: error: expression does not compute the number of elements in this array; element type is 'double', not 'relocInfo' [-Werror,-Wsizeof-array-div]
buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
~~~~~~~~ ^
/Users/xxx/Documents/jdk/jdk11/src/hotspot/share/runtime/sharedRuntime.cpp:2797:14: note: array 'locs_buf' declared here
double locs_buf[20];
^
/Users/xxx/Documents/jdk/jdk11/src/hotspot/share/runtime/sharedRuntime.cpp:2798:85: note: place parentheses around the 'sizeof(relocInfo)' expression to silence this warning
buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
^
1 error generated.
* All command lines available in /Users/xxx/Documents/jdk/jdk11/build/macosx-x86_64-normal-server-release/make-support/failure-logs.
=== End of repeated output ===
No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.
make[1]: *** [main] Error 2
make: *** [default] Error 2
根据错误信息,第二次通过修改src/hotspot/share/runtime/sharedRuntime.cpp文件得以解决
其实就是添加了两个括号,我感觉天不添加括号没啥区别,但是添加后问题就是好了,不添加括号就是有问题
第三个编译错误
以上第二个错误修改后,同样make clean后make下,又出现了第三个编译错误
➜ jdk11 make clean
Building target 'clean' in configuration 'macosx-x86_64-normal-server-release'
... ...
➜ jdk11 make
... ... 省略
=== Output from failing command(s) repeated here ===
* For target support_native_java.desktop_libawt_lwawt_CSystemColors.o:
/Users/xxx/Documents/jdk/jdk11/src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m:134:9: error: converting the result of '?:' with integer constants to a boolean always evaluates to 'true' [-Werror,-Wtautological-constant-compare]
if (colorIndex < (useAppleColor) ? sun_lwawt_macosx_LWCToolkit_NUM_APPLE_COLORS : java_awt_SystemColor_NUM_COLORS) {
^
1 error generated.
* All command lines available in /Users/xxx/Documents/jdk/jdk11/build/macosx-x86_64-normal-server-release/make-support/failure-logs.
=== End of repeated output ===
No indication of failed target found.
Hint: Try searching the build log for '] Error'.
Hint: See doc/building.html#troubleshooting for assistance.
make[1]: *** [main] Error 2
make: *** [default] Error 2
从错误信息可以看出,这次我们要修改的是src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m这个文件,该文件的修改方式其实和的第二个编译错误的修改方式基本一致。别烦,这次修改后编译就能通过了。
修改后我们再次编译
等得时间会稍微长点,需要几分钟吧!但是最终是编译成功了。中间可能会有一些信息如下:
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
注: 某些输入文件使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译
ld: warning: directory not found for option '-F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/JavaVM.framework/Frameworks'
但这些其实并不影响结果。
我们进入到build目录里面的jdk目录,测试下我们编译的jdk
➜ jdk11 cd build
➜ build ls
macosx-x86_64-normal-server-release
➜ build cd macosx-x86_64-normal-server-release
➜ macosx-x86_64-normal-server-release ls
Makefile build.log buildjdk-spec.gmk compare.sh configure.log jdk spec.gmk
bootcycle-spec.gmk build.log.old buildtools configure-support hotspot make-support support
➜ macosx-x86_64-normal-server-release cd jdk
➜ jdk ls
_packages_attribute.done bin conf include lib modules release
➜ jdk
➜ jdk
➜ jdk cd bin
➜ bin ls
jaotc java javap.dSYM jdb.dSYM jhsdb.dSYM jjs.dSYM jmod.dSYM jshell.dSYM jstatd.dSYM rmic.dSYM serialver.dSYM
jaotc.dSYM javac jcmd jdeprscan jimage jlink jps jstack keytool rmid unpack200
jar javac.dSYM jcmd.dSYM jdeprscan.dSYM jimage.dSYM jlink.dSYM jps.dSYM jstack.dSYM keytool.dSYM rmid.dSYM unpack200.dSYM
jar.dSYM javadoc jconsole jdeps jinfo jmap jrunscript jstat pack200 rmiregistry
jarsigner javadoc.dSYM jconsole.dSYM jdeps.dSYM jinfo.dSYM jmap.dSYM jrunscript.dSYM jstat.dSYM pack200.dSYM rmiregistry.dSYM
jarsigner.dSYM javap jdb jhsdb jjs jmod jshell jstatd rmic serialver
➜ bin ./java -version
openjdk version "11-internal" 2018-09-25
OpenJDK Runtime Environment (build 11-internal+0-adhoc.xxx.jdk11)
OpenJDK 64-Bit Server VM (build 11-internal+0-adhoc.xxx.jdk11, mixed mode)
➜ bin
这样就算是编译完成了。
我们可以进一步根据我参考的视频里面的方式在idea里面关联上源码,尝试修改源码后编译尝试。少量修改源码后make编译实际上比较快。