Ubuntu16.04 編譯 OpenJDK7


《深入理解Java虛擬機》第二版第一章實踐

准備

  • Mercurial sudo apt-get install mercurial
  • OpenJDK7
hg clone http://hg.openjdk.java.net/jdk7u/jdk7u-dev
cd jdk7u-dev
chmod 755 get_source.sh
./get_source.sh

當前的jdk7u-dev 大小為756MB
要是對自己的網速沒有信心,也可以選擇在雲服務器上先下載好,然后進行壓縮,再傳輸至本地,實測壓縮后僅有250MB左右

編譯過程

依賴

  • sudo apt-get install build-essential gawk m4 openjdk-6-jdk libasound2-dev libcups2-dev libxrender-dev xorg-dev xutils-dev x11proto-print-dev binutils libmotif3 libmotif-dev ant


    其中,openjdk-6-jdk 是不能直接apt-get 的,google以后Github-bmaupin給出了一個解決方案,我們可以直接去到http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html,選擇合適的包下載。下載前還需要注冊一個Oracle帳號。下載好jdk-6u45-linux-x64.bin后復制到想要的目錄並運行,相同目錄下就會創建一個包含有jdk的文件夾。


    libmotif3也不能直接安裝,需要從https://launchpad.net/ubuntu/xenial/amd64/libmotif3/2.3.4-8ubuntu1下載
  • 環境變量設置 environment.sh見最后,輸入source environment.sh,然后make sanity檢查


    如果輸出是Sanity check passed,則證明檢查通過,可以進行make了

編譯

  • 輸入make 2>&1 | tee $ALT_OUTPUTDIR/build.log進行編譯
  • 若出現以下信息,則證明編譯成功
#-- Build times ----------
Target all_product_build
Start 2017-10-19 23:38:57
End   2017-10-19 23:53:03
00:00:11 corba
00:01:06 hotspot
00:00:02 jaxp
00:00:04 jaxws
00:12:41 jdk
00:00:02 langtools
00:14:06 TOTAL
-------------------------

Hotspot

  • 進入OpenJDK目錄/hotspot/make,復制environment.sh,依次運行source environment.shmake
  • Hotspot的編譯與JDK的編譯大體相似,但還是有所不同,主要修改的還是environment.sh
  • 如果是64位系統,在最后加上export ARCH_DATA_MODEL=64,否則會在編譯過程中提示部分頭文件找不到
  • 編譯的輸出路徑建議進行修改,不然jdk與hotspot的編譯輸出都會放在build下面,比較難分辨
  • 編譯完成后可以去linux_amd64_compiler2/fastdebuf下修改env.sh,添加
LD_LIBRART_PATH=.:{JAVA_HOME}/jre/lib/amd64/native_threads:%{JAVA_HOME}/jre/lib/amd64:
export LD_LIBRARY_PATH

然后依次運行source env.sh./gamma -version,如果編譯成功,就能看到結果。

Netbeans

  • 去到Netbeans官網下載最新版本並安裝
  • Netbeans 源碼調試教程
  • 該教程中有些地方與本文的介紹不太合適,這里是更正:
  1. Pre-Build Action: 此處輸入的命令應為./environment.sh
  2. Build-Action: 此處Build Command應該是${MAKE} -f Makefile clean jvmg ALT_BOOTDIR=environment.sh中的ALT_BOOTDIR ARCH_DATA_MODEL=64 LANG=C
  • Netbeans下編譯好的文件將會存放在OpenJDK目錄/hotspot/build/linux/linux_amd64_compiler2/jvmg下。

錯誤

進入hotspot/src/share/vm/gc_implementation/g1
修改g1SATBCardTableModRefBS.cpp 修改內容如下(67行開始):

template <class T> void
G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) {
  if (!JavaThread::satb_mark_queue_set().is_active()) return;
  T* elem_ptr = dst;
  for (int i = 0; i < count; i++, elem_ptr++) {
    T heap_oop = oopDesc::load_heap_oop(elem_ptr);
    if (!oopDesc::is_null(heap_oop)) {
      enqueue(oopDesc::decode_heap_oop_not_null(heap_oop));
    }
  }
}

//2017-10-19 Vicent_Chen added
void G1SATBCardTableModRefBS::write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
  if (!dest_uninitialized) {
    write_ref_array_pre_work(dst, count);
  }
}
void G1SATBCardTableModRefBS::write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
  if (!dest_uninitialized) {
    write_ref_array_pre_work(dst, count);
  }
}
//2017-10-19 Vicent_Chen added

修改g1SATBCardTableModRefBS.hpp 修改內容如下:(87行開始)

  template <class T> void write_ref_array_pre_work(T* dst, int count);
  // 2017-10-19 Vicent_Chen modified
  /*
  virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) {
    if (!dest_uninitialized) {
      write_ref_array_pre_work(dst, count);
    }
  }
  virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) {
    if (!dest_uninitialized) {
      write_ref_array_pre_work(dst, count);
    }
  }
  */
  virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized);
  virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_unintialized);
  // 2017-10-19 Vicent_Chen modified

編譯后

編譯完成后Ubuntu的圖形界面會有點卡,懷疑是內存泄漏,建議重啟

#!/bin/sh
# environment.sh

# 語言選項,若不設置則會在編譯好后出現一個HashTable的NPE錯
export LANG=C
# Bootstrap JDK的安裝路徑
export ALT_BOOTDIR=#JDK安裝路徑(上文提到的Oracel JDK安裝路徑)
# 允許自動下載依賴
export ALLOW_DOWNLOADS=true
# 並行編譯線程數,設置為和CPU內核數一樣即可
export HOTSPOT_BUILD_JOBS=4
export ALT_PARALLEL_COMPILE_JOBS=4

# 比較本次build出來的映像與先前版本的差異。這對我們來說沒有意義
# 必須設置為false,否則sanity檢查會報缺少先前版本JDK的映像的錯誤提示
# 如果已經設置 dev 或者 DEV_ONLY = true,這個不顯式設置也行
export SKIP_COMPARE_IMAGES=true

# 使用預編譯頭文件,不加這個編譯會慢些
export USE_PRECOMPILED_HEADER=true

# 要編譯的內容
export BUILD_LANGTOOLS=true
#export BUILD_JAXP=false
#export BUILD_JAXWS=false
#export BUILD_CORBA=false
export BUILD_HOTSPORT=true
export BUILD_JDK=true

# 要編譯的版本
# export SKIP_DEBUG_BUILD=false
# export SKIP_FASTDEBUG_BUILD=true
# export DEBUG_NAME=debug

# 把它設置為false可以避開javaws和瀏覽器Java插件之類的部分的build
BUILD_DEPLOY=false

# 把它設置為false就不會build出安裝包,因為安裝包里有奇怪的依賴項
# 但即便不build出它也已經能得到完整的JDK映像,所以還是不build
BUILD_INSTALL=false

# 編譯結果存放路徑
export ALT_OUTPUTDIR= #openjdk7 路徑/build

# 這兩個環境變量必須去掉,否則會有奇怪的事情發生
unset JAVA_HOME
unset CLASSPATH

# 這個環境變量是make sanity建議消除的
unset LD_LIBRARY_PATH 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM