本篇文章主要介紹在MacOS系統(tǒng)和Ubuntu系統(tǒng)上如何編譯OpenJDK項(xiàng)目代碼,并使用IDE工具JetBrains CLion(下文簡(jiǎn)稱CLion)來(lái)運(yùn)行/調(diào)試OpenJDK。
文中僅包含兩種操作系統(tǒng)的特定版本(MacOS 10.15和Ubuntu 16.04)下的方法,不同版本下可能會(huì)略有差異。希望對(duì)讀者有一定的參考價(jià)值。
總體來(lái)說(shuō),編譯OpenJDK11在兩種系統(tǒng)上都沒(méi)有太大的阻礙,難度低于OpenJDK8。編譯OpenJDK8在Ubuntu上比較簡(jiǎn)單,在MacOS上比較繁瑣復(fù)雜。
編譯調(diào)試OpenJDK的基本步驟
完成編譯并實(shí)現(xiàn)調(diào)試OpenJDK流程可以分為以下幾個(gè)步驟:
- 獲取
OpenJDK項(xiàng)目源代碼 - 下載一個(gè)合適版本的
JDK作為BootJDK - 下載所需工具鏈,包括編譯器、調(diào)試器、構(gòu)建工具等
- 下載所需依賴庫(kù)
-
Running Configure(配置) -
Running Make(構(gòu)建) - 導(dǎo)入
CLion并進(jìn)行Run/Debug配置
其中3-6步對(duì)于不同操作系統(tǒng)和不同OpenJDK版本差異較大,其余步驟差異較小,所以本文的行文順序是先將1-2、7三部分以及一些前置知識(shí)做詳細(xì)介紹。在之后的具體場(chǎng)景(不同操作系統(tǒng) + 不同OpenJDK版本)中針對(duì)對(duì)這些部分只做差異點(diǎn)的特殊說(shuō)明。
開(kāi)始之前
如何獲取 OpenJDK 源代碼?
編譯調(diào)試的第一步當(dāng)然是獲取到OpenJDK的源代碼,獲取方式主要有以下三種:
1. 通過(guò)OpenJDK官方的Mercurial倉(cāng)庫(kù)下載
OpenJDK官方使用Mercurial來(lái)進(jìn)行版本控制。Mercurial倉(cāng)庫(kù)地址:http://hg.openjdk.java.net/,主要項(xiàng)目地址:
| 項(xiàng)目 | 地址 |
|---|---|
| jdk | http://hg.openjdk.java.net/jdk/jdk |
| jdk8u | http://hg.openjdk.java.net/jdk8u/jdk8u/ |
| jdk11u | https://hg.openjdk.java.net/jdk-updates/jdk11u/ |
通過(guò)這種方式下載源代碼,需要先安裝Mercurial工具,并使用hg clone <url>下載源代碼。比如下載 jdk8u使用如下命令:
hg clone http://hg.openjdk.java.net/jdk8u/jdk8u/
這種方式下載比較慢,而且會(huì)有中斷的情況,不推薦使用。
2. 通過(guò)鏡像Git倉(cāng)庫(kù)下載
OpenJDK官方在GitHub上有JDK項(xiàng)目的倉(cāng)庫(kù)鏡像,主頁(yè)地址:https://github.com/openjdk,主要項(xiàng)目地址:
| 項(xiàng)目 | 地址 |
|---|---|
| jdk | https://github.com/openjdk/jdk |
| jdk11u | https://github.com/openjdk/jdk11u |
| jdk12u | https://github.com/openjdk/jdk12u |
但在官方git倉(cāng)庫(kù)中沒(méi)有看到 jdk11 以下的版本。
除此之外還有一些非官方的鏡像Git倉(cāng)庫(kù)。比如AdoptOpenJDK項(xiàng)目,主頁(yè)地址:https://github.com/AdoptOpenJDK/,主要項(xiàng)目地址:
| 項(xiàng)目 | 地址 |
|---|---|
| jdk | https://github.com/AdoptOpenJDK/openjdk-jdk |
| jdk8u | https://github.com/AdoptOpenJDK/openjdk-jdk8u |
| jdk11u | https://github.com/AdoptOpenJDK/openjdk-jdk11u |
使用這種方式需要安裝git工具,并使用git clone <url>下載源代碼。比如下載jdk8u使用如下命令:
git clone https://github.com/AdoptOpenJDK/openjdk-jdk8u
git工具使用方便,并且比從官方Mercurial倉(cāng)庫(kù)下載要快很多,推薦使用。
3. 下載Mercurial倉(cāng)庫(kù)或者Git倉(cāng)庫(kù) 打包文件
除此之外,OpenJDK官方的Mercurial倉(cāng)庫(kù)還提供了直接下載壓縮包的入口,入口在各個(gè)項(xiàng)目頁(yè)面左側(cè)bz2,zip,gz三個(gè)鏈接,點(diǎn)擊即可下載。如下圖所示:

同樣在GitHub上的每個(gè)項(xiàng)目都可以下載ZIP格式的打包文件。如下圖所示:

顯然這種方式的缺點(diǎn)是缺少版本控制的能力,如果對(duì)項(xiàng)目代碼進(jìn)行了改動(dòng)想要恢復(fù)是做不到的,也不能夠方便地獲取最新代碼改動(dòng),但是相比前兩種方式更下載更快,也不要任何額外工具。
如何下載JDK?
讓人覺(jué)得矛盾的是,編譯JDK之前我們需要一個(gè)已經(jīng)編譯好的JDK作為Boot JDK。一般需要的JDK版本是編譯版本前一版本的JDK,比如編譯JDK8需要JDK7,編譯JDK11需要JDK10。
有幾種途徑可以下載JDK:
- 在Oracle官網(wǎng)下載
Oracle JDK。下載需要登錄賬號(hào) - 下載
OpenJDK- 在https://jdk.java.net/可以找到
Oracle提供的基于OpenJDK的參考實(shí)現(xiàn)。但大部分只有Linux版本
image
image - 也可以使用其他組織預(yù)編譯好的
OpenJDK。比如AdoptOpenJDK,但是沒(méi)有jdk8以下版本
- 在https://jdk.java.net/可以找到
- 在
Linux系統(tǒng)下,還可以通過(guò)軟件包管理器(比如Ubuntu下的apt,Centos下的yum)下載安裝JDK
JSON Compilation Database
CLion對(duì)CMake構(gòu)建的項(xiàng)目支持很友好,但OpenJDK項(xiàng)目是基于Make構(gòu)建的,對(duì)于使用Make構(gòu)建的項(xiàng)目,CLion仍然可以通過(guò)Compilation Database來(lái)導(dǎo)入項(xiàng)目,而不用將其修改為CMake項(xiàng)目。同時(shí)也能通過(guò)Compilation Database實(shí)現(xiàn)代碼的分析、跳轉(zhuǎn)等功能,這對(duì)于我們進(jìn)行代碼調(diào)試很有幫助。
有關(guān)于Compilation Database的介紹可以參考這幾篇文章:
-
Clang官方的Compilation Database介紹頁(yè)面:JSON Compilation Database Format Specification — Clang 11 documentation - 這篇文章介紹了在不同場(chǎng)景下生成
Compilation database的各種工具:Compilation database — Sarcasm notebook -
CLion的幫助頁(yè)面簡(jiǎn)要介紹了Compilation Database,以及在CLion的使用:Compilation Database - Help | CLion
對(duì)于基于Make構(gòu)建的OpenJDK項(xiàng)目來(lái)說(shuō),有一些工具可以生成Compilation Database,比如下面幾個(gè):
- https://github.com/rizsotto/Bear
- https://github.com/rizsotto/scan-build
- https://github.com/nickdiego/compiledb
通常默認(rèn)生成的Compilation Database是一個(gè)compile_commands.json文件。
除此之外,在OpenJDK 11u及之后版本中,OpenJDK官方提供了對(duì)于IDE的支持,可以使用make compile-commands命令生成Compilation Database,不需要使用額外的工具,具體命令可以查看看源代碼目錄下的\doc\ide.md
如何將OpenJDK項(xiàng)目導(dǎo)入CLion中并運(yùn)行/調(diào)試
讀者可以選擇先跳過(guò)本小節(jié),然后在完成前面幾個(gè)步驟之后再來(lái)根據(jù)本小節(jié)進(jìn)行導(dǎo)入調(diào)試。
對(duì)于如何在CLion中管理基于Make構(gòu)建的項(xiàng)目,CLion的官方幫助文檔中有詳細(xì)的介紹:
Managing Makefile Projects。
參考上述文檔,本小節(jié)簡(jiǎn)要介紹了如何在CLion中導(dǎo)入OpenJDK項(xiàng)目并運(yùn)行/調(diào)試的方法。請(qǐng)注意小節(jié)中所展示的圖示是基于Ubuntu 16.04系統(tǒng) + CLion 2020.1.1 環(huán)境下的,操作步驟基本也適用于MacOS 系統(tǒng)下同版本的CLion。
下載安裝
CLion,并安裝Makefile Support插件。建議使用最新版本,比較老的版本是不支持Make構(gòu)建的項(xiàng)目的。-
導(dǎo)入項(xiàng)目。打開(kāi)
CLion,選擇Open Or Import,選擇項(xiàng)目目錄中的compile_commands.json文件,彈出框選擇Open as Project,等待文件索引完成。compile_commands.json的生成方法及生成位置根據(jù)不同的OpenJDK版本略有不同,具體位置請(qǐng)看下文具體場(chǎng)景的介紹。image -
創(chuàng)建自定義
Build Target。點(diǎn)擊File菜單欄,Settings | Build, Execution, Deployment | Custom Build Targets,點(diǎn)擊+新建一個(gè)Target。-
Name:Target的名字,之后在創(chuàng)建Run/Debug配置的時(shí)候會(huì)看到這個(gè)名字 - 點(diǎn)擊
Build或者Clean右邊的三點(diǎn),彈出框中點(diǎn)擊+新建兩個(gè)External Tool配置如下:# 第一個(gè)配置如下,用來(lái)指定構(gòu)建指令 # Program 和 Arguments 共同構(gòu)成了所要執(zhí)行的命令 "make all" Name: make Program: make Arguments: all Working directory: {項(xiàng)目的根目錄} # 第二個(gè)配置如下,用來(lái)清理構(gòu)建輸出 # Program 和 Arguments 共同構(gòu)成了所要執(zhí)行的命令 "make clean" Name: make clean Program: make Arguments: clean Working directory: {項(xiàng)目的根目錄}image -
ToolChain選擇Default;Build選擇make(上面創(chuàng)建的第一個(gè)External Tool);Clean選擇make clean(上面創(chuàng)建的第二個(gè)External Tool)
其中兩個(gè)
External Tool配置中make的參數(shù)可以根據(jù)需要改變。一般情況用于Build的配置與執(zhí)行構(gòu)建時(shí)make的target保持一致即可。 -
-
創(chuàng)建自定義的
Run/Debug configuration。點(diǎn)擊Run菜單欄,Edit Configurations, 點(diǎn)擊+,選擇Custom Build Application,配置如下:# Executable 和 Program arguments 可以根據(jù)需要調(diào)試的信息自行選擇 # NameL:Configure 的名稱 Name: linux-x86_64-normal-server-slowdebug # Target:選擇上一步創(chuàng)建的 “Custom Build Target” Target: linux-x86_64-normal-server-slowdebug # Executable:程序執(zhí)行入口,也就是需要調(diào)試的程序 Executable: 這里我們調(diào)試`java`,選擇`{source_root}/build/{build_name}/jdk/bin/java`。 # Program arguments: 與 “Executable” 配合使用,指定其參數(shù) Program arguments: 這里我們選擇`-version`,簡(jiǎn)單打印一下`java`版本。image如果不想每次運(yùn)行/調(diào)試前都執(zhí)行
Build操作(在這里就是Make構(gòu)建過(guò)程,比較耗時(shí)),可以在編輯頁(yè)下方Before launch框中刪除Build條目。 -
點(diǎn)擊
Run/Debug開(kāi)始運(yùn)行/調(diào)試。- 如果使用的調(diào)試器是
gdb(Ubuntu下默認(rèn)),調(diào)試的時(shí)候可能會(huì)發(fā)現(xiàn)gdb報(bào)錯(cuò):Signal: SIGSEGV (Segmentation fault)。解決辦法是,創(chuàng)建用戶家目錄創(chuàng)建.gdbinit,內(nèi)容如下:handle SIGSEGV pass noprint nostop handle SIGBUS pass noprint nostop - 如果使用的調(diào)試器是
lldb(MacOS下默認(rèn)),調(diào)試的時(shí)候可能會(huì)發(fā)現(xiàn)lldb報(bào)錯(cuò):SIGSEGV (signal SIGSEGV)。解決辦法是,在用戶家目錄創(chuàng)建.lldbinit,內(nèi)容如下:break set -n main -C "process handle --pass true --stop false SIGSEGV" -C "process handle --pass true --stop false SIGBUS"
- 如果使用的調(diào)試器是
-
配合
File Watchers插件自動(dòng)更新Compilation Database(可選)如果修改了項(xiàng)目代碼,需要重新生成
Compilation Database,一般情況需要重新構(gòu)建才可以。如果不想每次都重新手動(dòng)構(gòu)建,可以使用
Files Watcher插件來(lái)實(shí)現(xiàn)監(jiān)聽(tīng)變更自動(dòng)重新生成。詳見(jiàn):https://www.jetbrains.com/help/clion/managing-makefile-projects.html#filewatcher-plugin
Ubuntu 16.04 環(huán)境
OpenJDK 8
1. 下載OpenJDK8源代碼
我們這里選擇從AdoptOpenJDK的GitHub倉(cāng)庫(kù)下載源代碼。
# 首先需要安裝git工具(如果沒(méi)有的話)
sudo apt-get install git
# 克隆項(xiàng)目代碼,可能耗時(shí)較長(zhǎng)
git clone git@github.com:AdoptOpenJDK/openjdk-jdk8u.git
2. 安裝工具鏈及依賴
# 首先需要下載安裝 JDK7 作為 BootJDK
方法見(jiàn)上文
# 安裝編譯器及構(gòu)建工具
sudo apt-get install gcc g++ gdb make
# 下載安裝依賴包
sudo apt-get install libasound2-dev libfreetype6-dev libcups2-dev libfontconfig1-dev libxext-dev libxrender-dev libxtst-dev libxt-dev
3. 配置及構(gòu)建
# 首先進(jìn)入 OpenJDK8 源碼目錄
# 配置
sh ./configure --with-debug-level=slowdebug --disable-zip-debug-info --with-target-bits=64 --with-boot-jdk=/home/jiajiawang/software/jdk/jdk1.7.0_80 --with-freetype-include=/usr/include/freetype2 --with-freetype-lib=/usr/lib/x86_64-linux-gnu/
configure參數(shù)說(shuō)明:
| 參數(shù) | 含義 |
|---|---|
| --with-debug-level | 調(diào)試信息的級(jí)別,可選值有release,fastdebug,slowdebug
|
| --disable-zip-debug-info | 禁止壓縮調(diào)試信息,設(shè)置為true有助于調(diào)試 |
| --with-target-bits | 選擇32位或者64位,根據(jù)操作系統(tǒng)選擇 |
| --with-boot-jdk |
BootJDK的位置 |
| --with-freetype-include --with-freetype-lib |
指定freetype依賴位置,如果提示找不到freetype,需要配置這兩個(gè)參數(shù) |
參數(shù)的更多說(shuō)明及更多參數(shù)請(qǐng)參考:OpenJDK 8 Build README - Configure
我們可以使用兩種工具來(lái)生成Compilation Database
使用Bear工具
# 下載Bear工具
sudo apt-get install bear
# 構(gòu)建,并使用bear工具生成Compilation Database
bear make all
使用compiledb工具
# 需要保證有python環(huán)境
# 安裝pip
sudo apt-get install python-pip
# pip安裝 compiledb
pip install compiledb
# 構(gòu)建,并使用compiledb工具生成Compilation Database
compiledb make all
更多make的target請(qǐng)參考OpenJDK 8 Build README - Make
如果沒(méi)有報(bào)錯(cuò),完成之后應(yīng)該可以在./build/linux-x86_64-normal-server-slowdebug/jdk目錄下找到編譯之后的JDK,驗(yàn)證一下是否成功
~: cd build/linux-x86_64-normal-server-slowdebug/jdk/bin/
~: ./java -version
openjdk version "1.8.0-internal-debug"
......
同時(shí)項(xiàng)目根目錄下應(yīng)該同時(shí)有一個(gè)compile_commands.json文件,并且不為空。
4. 導(dǎo)入CLion并調(diào)試
步驟參見(jiàn)上文
OpenJDK 11
1. 下載OpenJDK11源代碼
# 首先需要安裝git工具(如果沒(méi)有的話)
sudo apt-get install git
# 克隆項(xiàng)目代碼,可能耗時(shí)較長(zhǎng)
git clone git@github.com:AdoptOpenJDK/openjdk-jdk11u.git
2. 安裝工具鏈及依賴
# 需要下載安裝 JDK10 作為 BootJDK
方法見(jiàn)上文
# 安裝編譯器及構(gòu)建工具
sudo apt-get install gcc g++ gdb make autoconf
# 下載安裝依賴包
sudo apt-get install libfreetype6-dev libcups2-dev
sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev
sudo apt-get install libasound2-dev libffi-dev
sudo apt-get install libfontconfig1-dev
3. 配置及構(gòu)建
# 配置
sh ./configure --with-debug-level=slowdebug --with-native-debug-symbols=internal --with-target-bits=64 --with-boot-jdk=/home/jiajiawang/software/jdk/jdk-10.0.2
如果不成功,一般可能是缺少部分依賴,根據(jù)腳本給出的提示安裝相應(yīng)依賴即可。
configure參數(shù)說(shuō)明:
| 參數(shù) | 含義 |
|---|---|
| --with-debug-level | 調(diào)試信息的級(jí)別,可選值有release,fastdebug,slowdebug
|
| --with-native-debug-symbols | 指定如何構(gòu)建debug symbol,可選值有none,internal, external, zipped,設(shè)置為internal可以更好地調(diào)試 |
| --with-target-bits | 選擇32位或者64位,根據(jù)操作系統(tǒng)選擇 |
| --with-boot-jdk |
bootjdk位置 |
| --with-freetype-include --with-freetype-lib |
指定freetype依賴位置。如果提示找不到freetype,需要配置這兩個(gè)參數(shù) |
參數(shù)的更多說(shuō)明及更多參數(shù)請(qǐng)參考:OpenJDK 11 Build README - Configure
# 生成Compilation Database
make compile-commands
# 構(gòu)建
make all
更多make的target請(qǐng)參考OpenJDK 11 Build README - Make
完成之后應(yīng)該可以在./build/linux-x86_64-normal-server-slowdebug/jdk目錄下找到編譯之后的jdk,驗(yàn)證一下是否成功
~: cd build/linux-x86_64-normal-server-slowdebug/jdk/bin/
~: ./java -version
openjdk version "11.0.8-internal" 2020-07-14
......
同時(shí)在/build/linux-x86_64-normal-server-slowdebug/目錄下會(huì)有compile_commands.json文件,并且不為空。
4. 導(dǎo)入CLion并調(diào)試
大致步驟與前文介紹相同。
需要注意的是在選擇/build/linux-x86_64-normal-server-slowdebug/目錄下的compile_commands.json文件導(dǎo)入項(xiàng)目之后需要更改項(xiàng)目的根目錄為源碼的根目錄(這里也就是openjdk-11u目錄)。點(diǎn)擊菜單Tools | Compilation Database | Change Project Root,選擇源碼根目錄(openjdk-11u),等待重新索引完成。

MacOS 10.15 環(huán)境
OpenJDK 8
MacOS 10.15.5環(huán)境下構(gòu)建OpenJDK與Linux下步驟相似,但是由于OpenJDK 8版本較老,其中一些依賴在MacOS 10.15.5版本中已經(jīng)無(wú)法找到,導(dǎo)致在配置構(gòu)建過(guò)程中會(huì)出現(xiàn)各種問(wèn)題,本文給出了一種比較簡(jiǎn)單方便的辦法。
1. 下載OpenJDK8源代碼
我們選擇從AdoptOpenJDK的github倉(cāng)庫(kù)下載源代碼
git clone git@github.com:AdoptOpenJDK/openjdk-jdk8u.git
2. 安裝工具鏈及依賴
- 首先需要下載安裝
jdk7作為bootjdk,方法見(jiàn)文章開(kāi)頭。 - 安裝
HomeBrew。Homebrew是一款MacOS系統(tǒng)上的軟件包管理系統(tǒng)。/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" - 安裝
Xcode??梢灾苯釉?code>App Store搜索安裝,也可以在https://developer.apple.com/download/more/下載離線安裝包安裝??梢允褂?code>xcodebuild命令驗(yàn)證是否安裝成功,正確輸出版本號(hào)則表明正確安裝。
如果是離線安裝的話,可能會(huì)報(bào)xcodebuild -versionxcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance錯(cuò)誤,這是因?yàn)?code>xcodebuild找不到新安裝的Xcode,只需要執(zhí)行下面這個(gè)命令即可。sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/ - 安裝編譯工具
# 安裝構(gòu)建工具 brew install make - 安裝所需依賴
# 安裝freetype brew install freetype
3. 配置及構(gòu)建
3.1 修改代碼
如果不對(duì)代碼進(jìn)行修改,在執(zhí)行configure的時(shí)候,會(huì)報(bào)各種錯(cuò)誤。網(wǎng)上也有很多針對(duì)每種錯(cuò)誤來(lái)修改源文件來(lái)解決報(bào)錯(cuò)的方法, 這里給出一種更為方便的方法。
GitHub上的stooke/jdk8u-xcode10這個(gè)項(xiàng)目,提供了對(duì)openjdk8的代碼進(jìn)行修改的patch文件,對(duì)代碼修改之后,就可以正常地configure。
git clone git@github.com:stooke/jdk8u-xcode10.git
這個(gè)項(xiàng)目本身提供了腳本來(lái)完成下載源碼、下載依賴、代碼修改、配置、編譯、測(cè)試等工作,但我們這里只使用其中的修改代碼這部分。原項(xiàng)目中的README可能已經(jīng)過(guò)時(shí)了,通過(guò)查看其源代碼中的build8.sh文件,能夠大概了解其中的執(zhí)行邏輯,據(jù)此我將其中的修改OpenJDK8代碼的部分抽取出來(lái),簡(jiǎn)化如下:
新建一個(gè)shell腳本patch.sh,內(nèi)容如下:
#!/bin/bash
# JDK8 源碼所在目錄
JDK_DIR=`pwd`
# 下載的jdk8u-xcode10項(xiàng)目所在目錄
PATCH_DIR="$(dirname $JDK_DIR)/jdk8u-xcode10"
PATCH_DIR="$PATCH_DIR/jdk8u-patch"
applypatch() {
cd "$JDK_DIR/$1"
echo "applying $1 $2"
patch -p1 <$2
}
patchjdkbuild() {
echo "patch jdk"
# JDK-8019470: Changes needed to compile JDK 8 on MacOS with clang compiler
applypatch . "$PATCH_DIR/jdk8u-8019470.patch"
# JDK-8152545: Use preprocessor instead of compiling a program to generate native nio constants
# (fixes genSocketOptionRegistry build error on 10.8)
applypatch jdk "$PATCH_DIR/jdk8u-jdk-8152545.patch"
# fix WARNINGS_ARE_ERRORS handling
applypatch hotspot "$PATCH_DIR/jdk8u-hotspot-8241285.patch"
# fix some help messages and Xcode version checks
applypatch . "$PATCH_DIR/jdk8u-buildfix1.patch"
# use correct C++ standard library
#applypatch . "$PATCH_DIR/jdk8u-libcxxfix.patch"
# misc clang-specific cleanup
applypatch . "$PATCH_DIR/jdk8u-buildfix2.patch"
# misc clang-specific cleanup; doesn't apply cleanly on top of 8019470
# (use -g1 for fastdebug builds)
#applypatch . "$PATCH_DIR/jdk8u-buildfix2a.patch"
# fix for clang crash if base has non-virtual destructor
applypatch hotspot "$PATCH_DIR/jdk8u-hotspot-8244878.patch"
applypatch hotspot "$PATCH_DIR/jdk8u-hotspot-mac.patch"
# libosxapp.dylib fails to build on Mac OS 10.9 with clang
applypatch jdk "$PATCH_DIR/jdk8u-jdk-8043646.patch"
applypatch jdk "$PATCH_DIR/jdk8u-jdk-minversion.patch"
}
patchjdkbuild
然后執(zhí)行這個(gè)腳本:
bash patsh.sh
3.2 配置
sh ./configure MAKE=/usr/bin/make --with-toolchain-type=clang --with-debug-level=slowdebug --disable-zip-debug-info --with-target-bits=64 --with-boot-jdk=/Users/jiajiawang/Software/jdk/jdk1.7.0_80.jdk/Contents/Home/ --with-freetype-include=/usr/local/Cellar/freetype/2.10.2/include/freetype2 --with-freetype-lib=/usr/local/Cellar/freetype/2.10.2/lib/
MAKE=/usr/bin/make是可選的,如果下文使用Bear來(lái)生成Compilation Database,可以不加這個(gè)參數(shù)。
configure部分參數(shù)說(shuō)明如下:
| 參數(shù) | 含義 |
|---|---|
| --with-toolchain-type | 使用的工具鏈類型,取值有gcc,clang等,可以使用--help來(lái)查看所有可選值 |
| --with-debug-level | 調(diào)試信息的級(jí)別,可選值有release,fastdebug,slowdebug
|
| --disable-zip-debug-info | 禁止壓縮調(diào)試信息,設(shè)置為true可以更好地調(diào)試 |
| --with-target-bits | 選擇32位或者64位,根據(jù)操作系統(tǒng)選擇 |
| --with-boot-jdk |
bootjdk位置 |
| --with-freetype-include --with-freetype-lib |
指定freetype依賴位置,在執(zhí)行configure時(shí)如果找不到freetype,需要指定這兩個(gè)參數(shù) |
參數(shù)的更多說(shuō)明及更多參數(shù)請(qǐng)參考:OpenJDK 8 Build README - Configure
3.3 構(gòu)建
同樣我們?nèi)匀豢梢允褂?code>bear或者compiledb來(lái)生成Compilation Database,但是使用bear過(guò)程中遇到一些問(wèn)題比較繁瑣,推薦使用compiledb。
使用compiledb
# 1. 請(qǐng)先確保安裝了Python及pip
方法請(qǐng)自行搜索
# 2. 安裝compiledb工具
pip install compiledb
# 3. 構(gòu)建,并使用compiledb工具生成Compilation Database
compiledb make all COMPILER_WARNINGS_FATAL=false
# 可以使用 LOG=debug 選項(xiàng)來(lái)輸出更為詳細(xì)的信息
# compiledb make all LOG=debug COMPILER_WARNINGS_FATAL=false
使用compiledb可能會(huì)存在的問(wèn)題是生成的compile_commands.json文件中所有項(xiàng)的directory項(xiàng)都是項(xiàng)目的根目錄,導(dǎo)致一個(gè)頭文件無(wú)法找到,導(dǎo)入CLion時(shí)報(bào)錯(cuò),代碼定義及跳轉(zhuǎn)無(wú)效。原因是在MacOS平臺(tái),編譯構(gòu)建使用的可能是gmake,而compiledb對(duì)gmake切換路徑的操作無(wú)法捕捉到,導(dǎo)致路徑全部都是根目錄。解決辦法就是顯示指定使用make而不是gmake,指定方法就是上一小節(jié)中在Configure時(shí)指定的MAKE=/usr/bin/make參數(shù)。
使用bear
上面我們使用compiledb工具來(lái)生成Compilation Database,同樣也可以使用bear工具來(lái)生成:
# 1. 首先需要關(guān)閉SIP,否則生成的 Compilation Database 可能會(huì)是空的
關(guān)閉SIP的方法請(qǐng)自行搜索
# 2. 安裝bear
brew install bear
# 3. 構(gòu)建,并使用bear工具生成Compilation Database
bear make all COMPILER_WARNINGS_FATAL=false
# 可以使用 LOG=debug 選項(xiàng)來(lái)輸出更為詳細(xì)的信息
# compiledb make all LOG=debug COMPILER_WARNINGS_FATAL=false
如果遇到執(zhí)行命令遇到報(bào)如下錯(cuò)誤:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/stdio.h:107:15: fatal error: 'stdio.h' file not found"
可以嘗試執(zhí)行如下命令:
sudo mount -uw /
sudo cp -R /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include /usr
更多make的target請(qǐng)參考OpenJDK 8 Build README - Make
如果沒(méi)有報(bào)錯(cuò),完成之后應(yīng)該可以在./build/macosx-x86_64-normal-server-slowdebug/jdk目錄下找到編譯之后的JDK,驗(yàn)證一下是否成功
~: cd build/macosx-x86_64-normal-server-slowdebug/jdk/bin/
~: ./java -version
openjdk version "1.8.0-internal-debug"
......
同時(shí)項(xiàng)目根目錄下應(yīng)該同時(shí)有一個(gè)compile_commands.json文件,并且不為空。
4. 導(dǎo)入CLion并調(diào)試
需要注意在創(chuàng)建Custom Build Targets時(shí),新建的用于Build的External Tool中make的參數(shù)中也要加上COMPILER_WARNINGS_FATAL=false
OpenJDK 11
1. 下載OpenJDK11源代碼
git clone git@github.com:AdoptOpenJDK/openjdk-jdk11u.git
2. 安裝工具鏈及依賴
首先需要下載安裝
jdk10作為bootjdk,方法見(jiàn)文章開(kāi)頭。-
安裝
HomeBrew。Homebrew是一款MacOS系統(tǒng)上的軟件包管理系統(tǒng)。/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" -
安裝
Xcode。可以直接在App Store搜索Xcode安裝,也可以在https://developer.apple.com/download/more/下載離線安裝包安裝。可以使用xcodebuild命令驗(yàn)證是否安裝成功,正確輸出版本號(hào)則表明正確安裝。xcodebuild -version如果是離線安裝的話,可能會(huì)報(bào)
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance錯(cuò)誤,這是因?yàn)?code>xcodebuild找不到新安裝的Xcode,只需要執(zhí)行下面這個(gè)命令即可。sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/ -
安裝編譯工具
brew install autoconf brew install make -
安裝所需依賴
# 安裝freetype brew install freetype
3. 配置及編譯
# 配置
sh ./configure --with-debug-level=slowdebug --with-native-debug-symbols=internal --with-target-bits=64 --with-boot-jdk=/Users/jiajiawang/Software/jdk/jdk-10.0.2+13/Contents/Home
configure參數(shù)說(shuō)明:
| 參數(shù) | 含義 |
|---|---|
| --with-debug-level | 調(diào)試信息的級(jí)別,可選值有release,fastdebug,slowdebug
|
| --with-native-debug-symbols | 指定如何構(gòu)建debug symbol,可選值有none,internal, external, zipped,設(shè)置為internal可以更好地調(diào)試 |
| --with-target-bits | 選擇32位或者64位,根據(jù)操作系統(tǒng)選擇 |
| --with-boot-jdk |
bootjdk位置 |
| --with-freetype-include --with-freetype-lib |
指定freetype依賴位置,在執(zhí)行configure時(shí)如果找不到freetype,需要指定這兩個(gè)參數(shù) |
參數(shù)的更多說(shuō)明及更多參數(shù)請(qǐng)參考:OpenJDK 11 Build README - Configure
# 生成Compilation Database
make compile-commands
# 構(gòu)建
make all
完成之后,應(yīng)該在/build/linux-x86_64-normal-server-slowdebug/目錄下會(huì)有compile_commands.json文件。
更多make的target請(qǐng)參考OpenJDK 11 Build README - Make
完成之后應(yīng)該可以在./build/macosx-x86_64-normal-server-slowdebug/jdk目錄下找到編譯之后的jdk,驗(yàn)證一下是否成功
~: cd build/macosx-x86_64-normal-server-slowdebug/jdk/bin/
~: ./java -version
openjdk version "11.0.8-internal" 2020-07-14
......
同時(shí)在./build/macosx-x86_64-normal-server-slowdebug/目錄下會(huì)有compile_commands.json文件,并且不為空。
4. 導(dǎo)入CLion并調(diào)試
大致步驟與前文介紹相同。
需要注意的是在選擇/build/macosx-x86_64-normal-server-slowdebug/目錄下的compile_commands.json文件導(dǎo)入項(xiàng)目之后需要更改項(xiàng)目的根目錄為源碼的根目錄(這里也就是openjdk-11u目錄)。點(diǎn)擊菜單Tools | Compilation Database | Change Project Root,將項(xiàng)目的根目錄設(shè)置為源碼根目錄(openjdk-11u),等待重新索引完成。

參考
- OpenJDK
- OpenJDK 8 Build README
- OpenJDK 11 Build README
- rizsotto/Bear: Bear is a tool that generates a compilation database for clang tooling
- nickdiego/compiledb: Tool for generating Clang's JSON Compilation Database files for make-based build systems.
- Managing Makefile Projects
- Dealing with Makefile Projects in CLion: Status Update
- Tips & Tricks: Develop OpenJDK in CLion with Pleasure
- Debugging OpenJDK - DZone DevOps
- Compilation database — Sarcasm notebook
- More Software Downloads - Apple Developer
- stooke/jdk8u-xcode10: How to compile JDK 8u with Xcode 9, 10 or 11 on macOS.




