前言
才開始看《深入理解Java虛擬機(jī)》?這本書褥民,里面第一章就讓我們編譯jdk,記錄一下踩坑的過程洗鸵。
環(huán)境如下
Mac OS 11.1
xcode-select version 2384.
Apple clang version 12.0.0 (clang-1200.0.32.28)
CLion 20202.4
照著書上編譯完后,說需要修改CMakeList.txt瀑踢,否則用Clion進(jìn)行調(diào)試的時候一些頭文件會標(biāo)紅辨宠。
發(fā)現(xiàn)還是JetBrain官方推薦了另一種方法,Tips & Tricks: Develop OpenJDK in CLion with Pleasure
可以先看我的錯誤記錄琳省,修改了源碼之后再直接看官方的然后跳到調(diào)試部分迎吵。
但是只看源碼的話vscode 或許也是個很不錯的選擇,它最起碼不會顯示include的文件not found
編譯jdk12
從http://hg.openjdk.java.net/jdk/jdk12/file/06222165c35f下載jdk12
安裝如下依賴
brew install mercurial
brew install autoconf
brew install freetype
brew install ccache
下載jdk11针贬,我原來就下載好了jdk击费,可以用brew安裝jdk11
修改vim ~/.bash_profile
,這一步不是必須
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/
export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/
export JAVA_11_HOME=/Library/Java/JavaVirtualMachines/jdk-11.0.8.jdk/Contents/Home/
#alias命令動態(tài)切換jdk版本
alias jdk8="export JAVA_HOME=$JAVA_8_HOME"
alias jdk11="export JAVA_HOME=$JAVA_11_HOME"
之后在終端輸入jdk8或jdk11可以自動切換桦他。
執(zhí)行configure命令
bash configure --enable-debug --with-jvm-variants=server
之后可以看到一些配置信息蔫巩,其中boot jdk是jdk11,而我系統(tǒng)中當(dāng)前jdk是jdk8快压,所以它會??自動找到N-1版本的JDK圆仔,
之后可在build目錄下生成一個配置目錄,之后如果進(jìn)行多次編譯蔫劣,或者目錄產(chǎn)生后又修改了配置坪郭,記得先使用make clean
和make dist-clean
進(jìn)入這個配置目錄,查看生成文件脉幢,發(fā)現(xiàn)和書上的不太一樣
$ tree
.
├── Makefile
├── bootcycle-spec.gmk
├── buildjdk-spec.gmk
├── compare.sh
├── configure-support
│ ├── classes.jsa
│ ├── config.log
│ └── config.status
├── configure.log
└── spec.gmk
編譯
輸入命令截粗,加入compile-commands參數(shù)生成的是compilation database,如果不加這個參數(shù),導(dǎo)入clion頭文件一直都是紅的鸵隧,找不到路徑绸罗。
$ sudo make compile-commands
錯誤記錄
錯誤一:
make images時候出現(xiàn)
錯誤二:
打開該文件將這一行注釋了,重新執(zhí)行sudo make clean&&sudo make dist-clean,再執(zhí)行出現(xiàn)以下錯誤
參考https://codingnote.cc/p/234919/進(jìn)行修改,其中在sharedRuntime.cpp上有兩處
image錯誤三:
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.
參考https://github.com/openjdk/jdk/commit/4622a18a
最后出現(xiàn)下面的信息,就相當(dāng)于編譯成功了
Creating jdk image
Creating CDS archive for jdk image
Stopping sjavac server
Finished building target 'images' in configuration 'macosx-x86_64-server-fastdebug'
執(zhí)行
make CONF=macosx-x86_64-server-fastdebug
進(jìn)入jdk12/build/macosx-x86_64-server-fastdebug/jdk/bin
目錄查看編譯的java版本
$ ./java -version
openjdk version "12-internal" 2019-03-19
OpenJDK Runtime Environment (fastdebug build 12-internal+0-adhoc.root.jdk12)
OpenJDK 64-Bit Server VM (fastdebug build 12-internal+0-adhoc.root.jdk12, mixed mode)
至此豆瘫,證明我們已經(jīng)編譯完成了 JDK12
compile-commands配置方式解釋
在構(gòu)建一個slowdebug
bash configure --with-debug-level=slowdebug --with-jvm-variants=server
make CONF=macosx-x86_64-server-slowdebug compile-commands
make CONF=macosx-x86_64-server-slowdebug
我debug級別為slowdebug珊蟀,JetBrain推薦是fastdebug,我為了將兩個編譯的jdk項目區(qū)分
第一個make時候使用了CONF
參數(shù),指定了要編譯某個具體的配置育灸,如果只有一個配置腻窒,可以省略,但我是編譯了fastdebug
和slowdebug
兩個級別的JDK
磅崭,所以使用了這個參數(shù)儿子,執(zhí)行完該命令,就會在${source_root}/build/macosx-x86_64-server-slowdebug
下生成compile_commands.json
文件砸喻。
第二個make是在導(dǎo)入CLion
之前柔逼,要編譯一下,因?yàn)槟承┠K使用了預(yù)編譯頭割岛,如果不編譯愉适,CLion
會在索引過程中提示找不到各種各樣的文件。執(zhí)行以下命令進(jìn)行編譯:
CLion 調(diào)試
因?yàn)檎G闆r下直接導(dǎo)入項目文件癣漆,會生成CmakeList.txt维咸,書上說我們需要修改這個CmakeList.txt,而我不知道怎么修改惠爽,JetBrain官方給我們回答了這個問題癌蓖。Tips & Tricks: Develop OpenJDK in CLion with Pleasure
生成Compilation Database,然后導(dǎo)入的時候選擇compile_commands.json這個文件就好了
所以我用JetBrain官方的方法和通過 compile-commands參數(shù)編譯之后的jdk和不通過compile-commands參數(shù)編譯的jdk?也是和下面一樣的配置婚肆。所以可以一起使用费坊。
配置Toolchains
點(diǎn)擊configurations,通過preference進(jìn)入設(shè)置
選擇Open or Import
選擇compile-commands.json最后一定選上Open as Project
,然后會等待一段時間的索引
再點(diǎn)最上方的Tools->CMake->Change Project Root
旬痹,將根目錄修改為jdk12所在的目錄附井,就是包含build的目錄
配置 Build Targets
配置make,Arguments
要加CONF=
配置clean,注意Arguments
除了要在前面加CONF=
最后還要加上clean
配置Run/Debug configurations
這里的java是編譯之后的那個路徑下的java二進(jìn)制文件,即jdk12/macosx-x86_64-server-fastdebug/jdk/bin/java
${source_root}/src/java.base/share/native/libjli/java.c
的JavaMain函數(shù)打斷點(diǎn)两残,點(diǎn)擊Debug
永毅,效果如下:
以下內(nèi)容復(fù)制自參考博客
SIGSEGV
代表指針?biāo)鶎?yīng)的地址是無效地址,沒有物理內(nèi)存對應(yīng)該地址人弓。其實(shí)還有一個沼死,是SIGBUS
,代表指針?biāo)鶎?yīng)的地址是有效地址崔赌,但總線不能正常使用該指針意蛀,通常是未對齊的數(shù)據(jù)訪問所致。
MacOS
的CLion
默認(rèn)使用LLDB
進(jìn)行Debug
健芭,所以要避免這種情況瓷叫,可以通過在進(jìn)入第一個斷點(diǎn)時卸察,執(zhí)行以下命令避免后面出現(xiàn)此類問題:# LLDB使用如下命令埂奈,GDB暫不討論戳吝,原理基本一致,可以自行搜索 pro hand -p true -s false SIGSEGV SIGBUS
這樣雖然可以解決問題,但如果每次
Debug
都手動修改谴麦,會很繁瑣蠢沿。在JetBrains
的文章Develop OpenJDK in CLion with Pleasure中,文末也提到了解決這種問題匾效,但我試了一下舷蟀,卻總是不生效,也沒找到是什么原因面哼。不過最后在這個博客中找到了一個解決方案野宜,博主提到,
LLDB
只支持Session
級別的忽略設(shè)置(GDB
貌似支持全局精绎,感興趣的同學(xué)可以嘗試)速缨,就是需要先啟動Debug
锌妻,打斷點(diǎn)代乃,然后執(zhí)行忽略命令,才可以生效仿粹。然后博主提出了一種解決方案搁吓,在~/.lldbinit
文件中,使用如下命令吭历,實(shí)現(xiàn)每次Debug
時自動打個斷點(diǎn)堕仔,然后輸入pro hand -p true -s false SIGSEGV SIGBUS
,最后繼續(xù)執(zhí)行后續(xù)流程晌区,文件內(nèi)容如下(其中main.c
文件的路徑自行替換):breakpoint set --file /Users/XXX/XXX/XXX/jdk12/src/java.base/share/native/launcher/main.c --line 98 -C "pro hand -p true -s false SIGSEGV SIGBUS" --auto-continue true
最后摩骨,在控制臺查看輸出。
修改CMakeList.txt的一點(diǎn)思路
思路一
因?yàn)閟lowdebug和fastdebug是在jdk12下的build目錄下朗若,導(dǎo)入的時候都將jdk12設(shè)置為project的根目錄了恼五,前者是compile-commands命令生成的,使用diffmerge查看兩者有什么不一樣的地方
逐漸往下翻哭懈,發(fā)現(xiàn)它們的不同在于除了一些命名灾馒,fastdebug多了些slowdebug沒有的一點(diǎn)點(diǎn)東西,其余的slowdebug有的fastdebug的都有,那是不是可以合理猜測我根本就不用修這個CMakeList.txt了遣总?
為了驗(yàn)證睬罗,我又將fastdebug重新編譯了一遍作為對比,如下圖旭斥,左邊是新的參數(shù)為compile-commands容达,右邊是舊的
他們的區(qū)別和前面的圖其實(shí)是一樣的。只不過之前是使用了make images命令垂券,多了點(diǎn)東西董饰。
建議還是用創(chuàng)建compilation database的方法。
思路二
打開https://github.com/ojdkbuild/ojdkbuild/tree/master/src,看到只有jdk8,11,13,15卒暂,沒有12怎么辦啄栓,我去歷史記錄里找到了12的CMakeList.txt,就是如下鏈接也祠,下一步就是復(fù)制粘貼大法了
但是這條路還是走不通