自己動手,在macOS High Sierra中編譯一個可debug的JDK

since1986發表於2019-03-04

背景

由於最近想分析幾個native方法,所以需要手頭有一個可以debugJDK,因此,這兩天折騰了折騰,踩了10+個坑,看了10+篇文章,嘗試了10+次,最後總算把JDK給編出來了,當在自己編譯出來的JDK上執行javac -version輸出了那熟悉的文字後,感覺已是老淚縱橫還是很有成就感的。

前期準備

  • 瞭解一下OpenJDK的相關知識: 我們要編譯的是Open JDK 9u
  • 安裝Homebrew(可選)
  • 番羽土嗇: 因為假如編譯出錯需要查詢錯誤的解決方案時需要通過一個不存在的網站來進行
  • 準備一個好用的原始碼編輯器: 因為運氣好的話[滑稽]我們可能需要修改JDK原始碼中的八阿哥(我用的 mscode)
  • 安裝一個Boot JDK: 因為JDK中有不少程式碼是Java寫的,所以想要編譯JDK就需要用到另一個JDK來輔助(雞生蛋、蛋生雞/自己拽自己的頭髮把自己拽起來),我安裝的是Oracle官方的JDK
  • 安裝freetype:這是個依賴項brew install freetype
  • 安裝Xcode

環境描述

  • 作業系統: macOS High Sierra Version: 10.13.3 (17D47)
  • Boot JDK: 1.8.0_161
  • freetype: 2.9
  • Xcode: Version 9.2 (9C40b)
  • Open JDK原始碼: jdk9u-2e265b4b8622 corba-2ef36e70f490 hotspot-bb73b31e70e3 jaxp-95a71f690b44 jaxws-f4f878b5f01c jdk-a779673ab57d langtools-e2bf77b3f002 nashorn-fb3f7ae74bf6

前人蹚過的坑/我蹚過的坑

  1. 不要編譯JDK 8: 因為編譯8需要Xcode 4現在Xcode版本已遠高於4了(這個坑是前人蹚出來的,當然我不信邪,然後自己蹚了一遍,然後發現確實是個坑)
  2. 儘量不要使用Mercurial來下Open JDK的原始碼,而用瀏覽器直接下載打包好的原始碼: 因為你要用Mercurial下載了Open JDK的頂層工程後,還需要執行其中的get_source.sh來下載其子工程的原始碼,這個過程漫長而且失敗率高(關鍵還沒有執行百分比提示,乾等),用瀏覽器自己下載所有子工程的壓縮包要快很多,而且成功率100%(我自己蹚出來的,前人的幾篇文章中全告訴我用Mercurial,結果坑了)
  3. 編譯JDK 9u而不是JDK 9因為我當時編譯9的時候出了一堆error,所以我想帶個u的是不是會好些,當然這個有很大程度是我臆測的,我後期就都拿9u搞了,沒試9,如果各位有興趣可以自己蹚蹚這個
  4. configure的時候一定要帶上--disable-warnings-as-errors這個引數,否則編譯過程中的warning也會中斷編譯的程式,實際上這些warning並不影響編譯後的目標JDK的執行

走流程

如果前面幾點 該準備的你都準備了該注意的你也注意了,那麼開始走流程編譯吧,如果報錯(有很大機率會)不要摔鍵盤,用前面我們提到的不可描述存在的網站來找答案,我自己摸著石頭過河,反覆試了2天才搞定,魯迅先生說的好:“只要功夫深,鐵杵磨成針”,祝你好運!!

step0

所有前文提到的準備工作

step1

下載原始碼壓縮包

自己動手,在macOS High Sierra中編譯一個可debug的JDK
自己動手,在macOS High Sierra中編譯一個可debug的JDK

並將下載好的原始碼壓縮包解壓後按官方原始碼庫的層級碼放好

自己動手,在macOS High Sierra中編譯一個可debug的JDK

step2

在原始碼頂層目錄上執行sh configure --with-debug-level=slowdebug --disable-warnings-as-errors --with-freetype-include=/usr/local/Cellar/freetype/2.9/include/freetype2 --with-freetype-lib=/usr/local/Cellar/freetype/2.9/lib
(帶版本號的地方自己注意根據實際情況換)如果這一步沒問題的話應當看到這樣的輸出:

自己動手,在macOS High Sierra中編譯一個可debug的JDK

step3

如果你的編譯環境以及原始碼版本跟我的完全一樣,那麼先別make all,先來修一個bug:(patch在此)
這個bug會導致make報這個:error: ordered comparison between pointer and zero (`char *` and `int`) 。。。此處省略

開啟hotspot目錄中的

  • src/share/vm/memory/virtualspace.cpp 搜尋其中if (base() > 0) {改為if (base() != NULL) {
  • src/share/vm/opto/lcm.cpp 搜尋其中if (Universe::narrow_oop_base() > 0) { 改為 if (Universe::narrow_oop_base() != NULL) {
  • src/share/vm/opto/loopPredicate.cpp 搜尋其中assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be"); 改為 assert(rng->Opcode() == Op_LoadRange || iff->is_RangeCheck() || _igvn.type(rng)->is_int()->_lo >= 0, "must be");

step4

make all
編譯時間略長,我的機子是2017款的 MacBook Pro大概用了20分鐘+(沒仔細計),而且編譯過程中風扇狂轉,筆記本的話注意剩餘電量以及散熱,編譯若成功,指定javac全路徑執行一下javac -version看看

自己動手,在macOS High Sierra中編譯一個可debug的JDK

如果報了error,具體error具體分析,因為編譯環境不同,可能error也不同,去不存在的網站找找解決方案,耐心+運氣你就一定能成功的。

總結

原以為編一個JDK能有多難,事實證明:是不難,但是坑多,麻煩,前前後後試了10多次,一共花了兩天時間,從嘗試編譯JDK 8再到9中間出了各樣問題,之中一度想放棄,但是由於想用它來實現更遠的目標,所以還是堅持弄下來了,最終在搜尋引擎和前人的幫助下成功了,所以還是那句話:“只要功夫深鐵杵磨成針”,按正確的方向,反覆嘗試,終能成功。

參考資料

Building OpenJDK 8 on Mac OS X Mavericks

Building and Packaging OpenJDK9 for OSX

Compilation errors with clang-4.0

OpenJDK / jdk10 / jdk10 / hotspot
changeset 13502:316854ef2fa2

Ordered comparison between pointer and zero (`char *` and `int`) error #5

MAC編譯OpenJDK8

Compile&Debug openjdk

openjdk code compilation/ IDE setup

使用Clion(GDB)除錯小型JVM原始碼

解決GDB在Mac下不能除錯的問題

xcode-select active developer directory error

Mac OsX Sierra – Stuck on binaryTreeDictionary.hpp compilation

相關文章