- 學(xué)習(xí)JVM往往會(huì)需要自行編譯一個(gè)jdk. 由于Oracle Jdk不是開(kāi)源的, 因此本文選用openJdk, 據(jù)官方稱(chēng)兩者的代碼極其近似.
- 在編譯OpenJdk的過(guò)程中主要問(wèn)題分為如下幾個(gè):
- 選擇什么版本的jdk, 源碼如何獲取
- 如何編譯
一 源碼獲取
- 本機(jī)環(huán)境: MacOS-10.14.2, XCode-10.1
- 編譯版本: jdk13
- 建議編譯jdk8之后的版本, 因?yàn)樵缙诘膉dk版本中使用的是gcc編譯器, 而高版本的XCode自帶的是clang編譯器(會(huì)在
/usr/bin/
目錄創(chuàng)建gcc映射) - 當(dāng)然也可以在電腦上安裝低版本的XCode, 如jdk8編譯時(shí)安裝XCode-4.5.2.
- 此外, 還有解決方案是在本機(jī)安裝gcc4.9, 使用gcc編譯, 但是非常容易踩坑
- 建議編譯jdk8之后的版本, 因?yàn)樵缙诘膉dk版本中使用的是gcc編譯器, 而高版本的XCode自帶的是clang編譯器(會(huì)在
- 獲取jdk源碼的途經(jīng)分成三種
- 使用mercurial代碼管理工具直接獲取, 如
hg clone http://hg.openjdk.java.net/jdk10/master openjdk10
- 可能會(huì)由于網(wǎng)絡(luò)問(wèn)題特別慢
- 通過(guò)瀏覽器獲取, 參考https://my.oschina.net/u/2518341/blog/1931088
- 通過(guò)git, 該項(xiàng)目類(lèi)似鏡像. https://github.com/unofficial-openjdk/openjdk
- 本文是通過(guò)方法3獲取到的jdk源碼, 因?yàn)榫W(wǎng)絡(luò)太差前面兩個(gè)都有問(wèn)題
- 使用mercurial代碼管理工具直接獲取, 如
二 依賴與環(huán)境
在開(kāi)始編譯之前首先需要安裝幾個(gè)插件, 因?yàn)槊總€(gè)人的環(huán)境不同可能沒(méi)有涵蓋全部
可以仔細(xì)研究一下
doc/building.html
和doc/building.md
文件
1 xcode命令行工具
- 檢查是否有安裝, 如果已有則會(huì)輸出版本
xcode-select -v
xcode-select version 2354.
- 如果沒(méi)有, 則安裝
xcode-select --install
2 freetype, autoconf
brew install freetype
brew install autoconf
3 BootStrap JDK
JDK的源碼中包含了c代碼, c++代碼, java代碼... 因此需要一個(gè)jdk.
本文選用的是jdk11, 具體什么版本需要根據(jù)待編譯jdk的版本而定.
4 環(huán)境變量設(shè)置
- 將下述環(huán)境變量設(shè)置生效
source init.sh
# 設(shè)定語(yǔ)言選項(xiàng)嘴拢,必須設(shè)置
export LANG=C
# Mac平臺(tái)偎球,C編譯器不再是GCC沾歪,是clang
export CC=clang # 使用clang
# 跳過(guò)clang的一些嚴(yán)格的語(yǔ)法檢查丹拯,不然會(huì)將N多的警告作為Error
export COMPILER_WARNINGS_FATAL=false
# 鏈接時(shí)使用的參數(shù)
export LFLAGS='-Xlinker -lstdc++'
# 是否使用clang
# export USE_CLANG=false
# 使用64位數(shù)據(jù)模型
export LP64=1
# 告訴編譯平臺(tái)是64位航闺,不然會(huì)按32位來(lái)編譯
export ARCH_DATA_MODEL=64
# 允許自動(dòng)下載依賴
export ALLOW_DOWNLOADS=true
# 并行編譯的線程數(shù)
export HOTSPOT_BUILD_JOBS=6
# 是否跳過(guò)與先前版本的比較
export SKIP_COMPARE_IMAGES=true
# 是否使用預(yù)編譯頭文件奋刽,加快編譯速度
export USE_PRECOMPILED_HEADER=true
# 是否使用增量編譯
export INCREMENTAL_BUILD=true
# 編譯內(nèi)容
export BUILD_LANGTOOLS=true
export BUILD_JAXP=true
export BUILD_JAXWS=true
export BUILD_CORBA=true
export BUILD_HOTSPOT=true
export BUILD_JDK=true
# 編譯版本
export SKIP_DEBUG_BUILD=true
export SKIP_FASTDEBUG_BUILD=false
export DEBUG_NAME=debug
# 避開(kāi)javaws和瀏覽器Java插件之類(lèi)的部分的build
export BUILD_DEPLOY=false
export BUILD_INSTALL=false
unset JAVA_HOME
# ALT_.* 已經(jīng)廢棄
# export ALT_BOOTDIR=/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/
三 編譯
生成配置
- 這一部會(huì)生成配置, 并且檢查依賴是否正確
bash ./configure --with-debug-level=slowdebug --with-boot-jdk=/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home
--with-debug-level
設(shè)置了debug級(jí)別, 一共可以指定三種級(jí)別: release, fastdebug, slowdebug, slowdebug 含有最豐富的調(diào)試信息滞磺,沒(méi)有這些信息诫欠,很多執(zhí)行可能被優(yōu)化掉涵卵,我們單步執(zhí)行時(shí),可能看不到一些變量的值荒叼。所以最好指定slowdebug 為編譯級(jí)別--with-boot-jdk
設(shè)置了bootstrap jdk, 本次示例中沒(méi)有設(shè)置具體的bootstrap jdk, 這種情況會(huì)采用本地的默認(rèn)jdk, 本機(jī)默認(rèn)jdk11
編譯
make all
- 居然一次通過(guò), 沒(méi)有任何error. 如此順利的原因是本次編譯采用了較高版本的jdk, 配合其所需求的xcode版本, 因此沒(méi)有遇到什么詭異的問(wèn)題.
檢驗(yàn)
./build/macosx-x86_64-server-slowdebug/jdk/bin/java --version
# 結(jié)果如下
openjdk 13-internal 2019-09-17
OpenJDK Runtime Environment (slowdebug build 13-internal+0-adhoc.chinshii.openjdk13)
OpenJDK 64-Bit Server VM (slowdebug build 13-internal+0-adhoc.chinshii.openjdk13, mixed mode)