JDK编译
_:nil
TOC TOC
Building in WSL
- 中文vs2019需要改下
make/autoconf/toolchain.m4
里的Microsoft.*Compiler
- 在vs的prompt里build
configure使用的命令:
(之前是用13 boot的,14 ga后更换至14(13有些class不兼容的问题))bash configure --with-boot-jdk=/mnt/d/Users/hh/Apps/jdk-14 --with-toolchain-version=2019 --with-tools-dir=/mnt/d/ProgramData/Microsoft/VisualStudio/2019_Community/VC/Auxiliary/Build/ --disable-warnings-as-errors
- 编译matcherCompiler.cpp失败,添加
--disable-warnings-as-errors
后编译成功 - 测试木有跑过,少了个啥
jtreg
之类的 - 使用的时候问题不大:
- 正常选用编译的jdk即可
源码需要在idea里设置到对应的路径:
File -> Project Structures -> SDKs -> 选取对应的sdk 然后 添加 source path。 添加src\java.base\share\classes
为 source path- 更改源码的时候,需要到vs的prompt里(测试发现不在vs prompt也阔以)
- 执行
make java.base
不过这步非常慢…… 即使使用并行依旧很慢
github的mirror拉下来换行格式不对、原因未名: 使用:
重新设置了ls -Recurse -File | % {dos2unix.exe $_.FullName $_.FullName}
修掉了 make 目录 重新checkout了一次,又好了,应该是和 autoclrf 之类的有关git config --global core.autocrlf false
, 重新拉了一次,configure
和make
都OK- 并行compile阔以用
make JOBS=N
对于代码的一些改动
diff -r bb0a7975b31d make/autoconf/toolchain.m4
--- a/make/autoconf/toolchain.m4 Tue Dec 24 09:38:41 2019 +0000
+++ b/make/autoconf/toolchain.m4 Mon Jan 06 11:21:25 2020 +0800
@@ -452,7 +452,7 @@
# Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
COMPILER_VERSION_OUTPUT=`"$COMPILER" 2>&1 | $GREP -v 'ERROR.*UtilTranslatePathList' | $HEAD -n 1 | $TR -d '\r'`
# Check that this is likely to be Microsoft CL.EXE.
- $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Microsoft.*Compiler" > /dev/null
+ $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Microsoft.*" > /dev/null
if test $? -ne 0; then
AC_MSG_NOTICE([The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler.])
AC_MSG_NOTICE([The result from running it was: "$COMPILER_VERSION_OUTPUT"])
@@ -460,8 +460,9 @@
fi
# Collapse compiler output into a single line
COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT`
- COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \
- $SED -e 's/^.*ersion.\(@<:@1-9@:>@@<:@0-9.@:>@*\) .*$/\1/'`
+ # COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \
+ # $SED -e 's/^.*ersion.\(@<:@1-9@:>@@<:@0-9.@:>@*\) .*$/\1/'`
+ COMPILER_VERSION_NUMBER='19.20.27508.1'
elif test "x$TOOLCHAIN_TYPE" = xgcc; then
# gcc --version output typically looks like
# gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
@@ -1033,7 +1034,8 @@
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
# On Windows, double-check that we got the right compiler.
CC_VERSION_OUTPUT=`$CC 2>&1 | $GREP -v 'ERROR.*UtilTranslatePathList' | $HEAD -n 1 | $TR -d '\r'`
- COMPILER_CPU_TEST=`$ECHO $CC_VERSION_OUTPUT | $SED -n "s/^.* \(.*\)$/\1/p"`
+ # COMPILER_CPU_TEST=`$ECHO $CC_VERSION_OUTPUT | $SED -n "s/^.* \(.*\)$/\1/p"`
+ COMPILER_CPU_TEST='x64'
if test "x$OPENJDK_TARGET_CPU" = "xx86"; then
if test "x$COMPILER_CPU_TEST" != "x80x86" -a "x$COMPILER_CPU_TEST" != "xx86"; then
AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "80x86" or "x86".])
diff -r bb0a7975b31d test/hotspot/gtest/utilities/test_json.cpp
--- a/test/hotspot/gtest/utilities/test_json.cpp Tue Dec 24 09:38:41 2019 +0000
+++ b/test/hotspot/gtest/utilities/test_json.cpp Mon Jan 06 11:21:25 2020 +0800
@@ -354,23 +354,23 @@
TEST_VM(utilities, json_key_values_1) {
JSON_GTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\","
"{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\""
- " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true);
+ " : true }, \"key6\" : [ \"santa\" ], key7 : \"val\",}", true);
}
TEST_VM(utilities, json_key_values_2) {
JSON_GTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\","
"{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\""
- " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true);
+ " : true }, \"key6\" : [ \"santa\" ], key7 : \"val\",}", true);
}
TEST_VM(utilities, json_quoted_symbols) {
- JSON_GTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]},"
- "\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true);
+ JSON_GTest::test("/*comment*/{\"ff1 fsd\":{\"santa\":{\"santa\":[\"santa\",\"santa\"]},"
+ "\"santa\":true},\"santa\":[\"santa\"],\"foo\":\"santa\",}", true);
}
TEST_VM(utilities, json_incorrect_key) {
- JSON_GTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\","
- " \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}",
+ JSON_GTest::test("/* comment */ { key1 error : { \"santa\" : { \"santa\" : [ \"santa\","
+ " \"santa\" ] }, \"santa\" : true }, \"baz\" : [ \"santa\" ], foo : \"santa\",}",
false); // first key needs to be quoted since it contains a space
}
具体原因:
- 中文vs
- 似乎cl.exe编译这个符号
☃
有点问题
issues
偶发lombok编译失败
估计是环境变量的问题
configure的时候偶发C compiler cannot create executables
使用vscode x64的promopt解决
JDK8标准库重新编译
- 嵌套在项目中,需要看一下,因此最好是可以重新编译,这样更改源码(主要是注释)方便一些
参考: 编译src.zip Java1.8 src.zip_Java_u011515961的专栏-CSDN博客
编译后还是 exploded class,木有打成jar包,不过这没啥问题。
调整classpath路径稍微麻烦一点,要删掉原有rt.jar再添加
源码路径再选择:
JDK14 java.base 重新编译 ATTACH
Intelij Idea中阔以比较方便的查看java标准库的相关实现,但是为了更好的理解、更方便的实现或者添加相关备注等等,可以更改标准库的代码,重新编译会更方便一些。 JDK8及之前,标准库的相关实现都在 rt.jar
中,编译替换还是方便的。 JDK9之后,标准库的相关实现(默认link的runtime)都在 lib/modules
文件下,这就比较难改动了。
一番尝试后,比较方便的做法是:
编译 exploded 版本的openJDK。
默认编译的openJDK就是 exploded (以及debug)的,exploded即所有的module还是以class文件的方式放置在输出路径,具体来说,所有编译的class文件都位于 modules
文件夹下。 编译 openJDK 后,每次改动标准库java文件当然可以重新编译一次(使用内置的编译链工具, make java.base
)即可。但是这样仍然很慢,比较之下,最后用 Intellij Idea在不对整个模块重新编译时会快很多。
openJDK在 windows 的编译可以参考 Building in WSL , WSL作编译工具的编译是最近的版本才添加的,以前都是 cygwin。
openjdk的编译还算比较方便,具体参考 Building OpenJDK 走一边就阔以。
在intellij idea中编译 java.base
模块
将 java.base
模块的源代码拷贝出来做一个单独的 maven 模块:
~\Repos\java.base-jdk-14\java.base\
├───pom.xml
├───src
│ └───main
│ └───java <--- 这个目录即对应 openjdk 源码(留意从发行版中拷贝,别从源码拷贝)的目录
│ ├───com
│ ├───java
│ ├───javax
│ ├───jdk
│ ├───module-info.java
│ └───sun
└───target
拷贝出来作为一个 maven module的好处是:
a. 可以和intellij idea的编译链相互校验配置参数 b. 必要时可以使用maven的命令编译 c. 便于配置的持久化(当然intellij idea其实也是阔以的)
pom.xml
主要需要注意一下 build
节点中 javac 相关参数的设置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>14</release>
<compilerArgs>
<arg>
--patch-module=java.base=${project.basedir}/src/main/java
</arg>
<arg>
-XDstringConcat=inline
</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
--patch-module
参数是因为 java.base
已经在包含在 openjdk 中了,再次编译的话需要添加这个命令行参数。 (⚠ 不过intelij idea似乎识别不了这个参数,导致整个 java.base
目录都需要被拷贝出来。直接用maven命令编译的话,只拷贝部分目录实测下也是可以的)
-XDstringConcat=inline
是因为编译后运行时的一个报错,具体可以参考: classpath - Patching java.base results in java.lang.LinkageError - Stack Overflow 。
intellij idea中配置编译jdk
这里的主要目的是区分开编译 java.base
所使用的openjdk和编译自己的测试/学习模块所使用的jdk。区分开阔以避免一些利用需要修改的jdk来编译修改的代码等等之类的问题。
Repos\java.base-jdk-14\
├───core <- 个人测试/学习代码对应的模块
│ ├───pom.xml
│ ├───src
│ │ ├───main
│ │ │ └───java
│ │ └───test
│ │ └───java
│ └───target
├───java.base <- 从 opendjk中拷贝的代码所对应的模块
│ ├───pom.xml
│ ├───src
│ │ └───main
│ │ └───java <- 拷贝的代码放在这里 (zip包中java.base目录)
│ └───target
└───pom.xml
这里最主要的注意点是:
- java.base使用一个稳定的openjdk编译
- core使用需要更改标准库的openjdk编译
idea中可以针对不同的模块设置不同的JDK:
将java.base编译结果外链回 exploded jdk
这个是前面提到的只能使用自行编译的exploded jdk的原因。从官网中下载的openjdk预编译版本,内置的模块里面的java.base总是会被先加载的,因此无法使用。(在jdk8的时候,还阔以通过更改classpath的方式,改zip包的方式加到rt.jar前面)
具体外链的关系是:
~\Repos\java.base-jdk-14\
├───core
│ ├───pom.xml
│ ├───src
│ │ ├───main
│ │ │ └───java
│ │ └───test
│ │ └───java
│ └───target
│ ├───classes
│ └───test-classes
│ └───core
├───java.base
│ ├───pom.xml
│ ├───src
│ │ └───main
│ │ └───java
│ └───target
│ └───classes
│ ├───com
│ ├───java <--> 软链至 exploded jdk 的 modules/java.base/java目录
│ ├───javax
│ ├───jdk
│ ├───module-info.class
│ └───sun
└───pom.xml
windows下的具体软链命令为:
cmd /c mklink /J ~\Apps\jdk14-exploded\modules\java.base\java ~\Repos\java.base-jdk-14\java.base\target\classes\java
具体使用示例
按上面步骤做完后应该就阔以正常使用了。测试改一下代码:
public void lock() {
System.out.println("lock in ReentrantLock");
sync.lock();
}
编译的速度还是很快的,虽然使用maven/直接 make java.base 的方式也阔以达到更改源码、调试学习的目的,但是速度上还是比Intellij Idea编译慢很多。
尝试过程中的一些脚本和链接日志
*这部分仅作备忘和日志用途*,后面删掉,主要是为了后面看下模块系统
- (1条消息)javac java在mac console中文乱码的问题_Java_New World-CSDN博客
- java - How to change the display language of javac to English? - Stack Overflow
- split-package issue when compiling - JDK 10 · Issue #27 · javapathfinder/jpf-core
参考上面issue的设置,使用:
d:\Users\hh\Apps\jdk-14\bin\javac.exe -J-D"user.language=en" -J-D"file.encoding=UTF-8" --module-source-path=src --patch-module java.base=src/java.base -d build d:\Users\haha\Repos\java.base-jdk-14\src\java.base\java\io\Bits.java
可以正常build。尝试过的一个powershell脚本是:
,(ls .\src\ -Recurse -File -Filter *.java).FullName | %{
$total = $_.Length
$_|%{$cnt=0}{
$class_file = $_|%{
$_ -replace "\\src\\","\build\"
}|%{
$_ -replace "\.java$",".class"
}
Write-Debug $_
$cnt = $cnt+1
if(Test-Path $class_file) {
} else {
d:\Users\hh\Apps\jdk-14\bin\javac.exe -J-D"user.language=en" -J-D"file.encoding=UTF-8" --module-source-path=src --patch-module java.base=src/java.base/classes -d build $_
}
Write-Progress "Compiled $_" -PercentComplete (100.0 * $cnt / $total)
}}
可能也阔以用ant
虽然class文件是可以生成了,但是idea中SDK的classpath还是无法调整。
module - Is there a way to read programmatically a .jmod file in Java? - Stack Overflow
jmod
目前就是zip包,可以用替换文件的方式替换掉
目前来看阔以直接用模块系统搞定 Using jlink to Build Java Runtimes for non-Modular Applications
d:\Users\hh\Apps\jdk-14\bin\jlink.exe -J-D"user.language=en" --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules java.base --output test-runtime
看看如果阔以选用自己的 java.base
jmod:
& "d:\Users\userxx\Apps\jdk-14\bin\jmod.exe" -J-D"user.language=en" create --class-path classes\ java.base.jmod
(可能不需要打jmod,直接exploded的classes也阔以用在module-path的位置)
留意一下version,jlink的version是jdk版本,因此maven里版本号按着走
Error: ModuleTarget attribute is missing
Getting Started with the Java Platform Module System Part 3 | Pluralsight
modules 在 d:-14
相对路径即 : lib\modules
https://stackoverflow.com/questions/46438557/how-to-extract-the-file-jre-9-lib-modules
还是回归用openjdk build的exploded了
即使用 exploded,还是有些问题(这块没整理好)
突然持续出现了这个错误:
看着应该是和 java.lang
有关.
只同步 java
下面 像 util/io
之类的子模块好了,没有必要同步所有的
针对不同module可以用不同jdk
目前外链了 io/util/nio
cannot compile Java 9 module with –patch-module in IntelliJ IDEA 2017.2.1 - Stack Overflow
Locating IDE log files – IDEs Support (IntelliJ Platform) | JetBrains
java - How can I see the javac command IntelliJ IDEA uses to compile my code? - Stack Overflow
只能够全部拷贝
classpath - Patching java.base results in java.lang.LinkageError - Stack Overflow
<arg>
-XDstringConcat=inline
</arg>
这个参数必须加上,参考上面的链接