在Windows下編譯OpenJDK是一個艱難的過程...
平台:WindowsXP+cygwin,OpenJDK版本:OpenJDK7,編譯器:VS2010
之所以選用OpenJDK7,是因為OpenJDK6中沒有包含對VS2010的支援,OpenJDK7考慮了VS2010。
由於過程比較漫長,我就不詳述了。類似於代碼下載,cygwin安裝等,請讀者按照OpenJDK官網的編譯說明來操作。我說一下編譯過程中遇到的問題(下面的路徑使用"~"代指我的OpenJDK7源碼存放根目錄)。
1. JDK版本問題
為求穩定,我從Sun的網站下載了rc(Release Candidate)版的JDK6作為Bootstrap JDK。但是,見鬼,OpenJDK在使用Sun JDK的javac時,用到了非標準的參數...就是說,OpenJDK的編譯其實只能用Sun的JDK6作為Bootstrap JDK,而且還必須是開發版,不能是穩定版(rc版不包含這些擴充)。
我只好重新安裝了Sun公司的6u23版JDK。
2. cygwin的make版本
好吧,OpenJDK編譯說明中指出了,cygwin的make可能要用3.8.0版。但編譯時間,OpenJDK的列印資訊指出,3.8.1版本的make是建議的“最低”版本!事實證明這是個很二的提示資訊。老老實實安裝3.8.0版並忽略這個警告。
3. 環境變數的設定
開始編譯前,要進入~/jdk/make執行jdk_generic_profile.sh。但這個批處理只考慮了VS2003,後續的VS版本都沒有考慮,需要修改。
事實上,環境變數的設定是最花時間的。不廢話,直接列出我的改動(下述資訊都是用cygwin的diff命令得到的差異)
113c113
< importjdk=jdk1.7.0
---
> importjdk=jdk1.6.0
167d166
<
169,170d167
< jdk_instances="C:"
<
195a193,207
> export INCLUDE="D:/Program Files/Microsoft Visual Studio 10.0/VC/include;C:/Program Files/Microsoft SDKs/Windows/v7.0A/Include;D:/Program Files/Microsoft Visual Studio 10.0/VC/atlmfc/include"
> export LIB="D:/Program Files/Microsoft Visual Studio 10.0/VC/lib;C:/Program Files/Microsoft SDKs/Windows/v7.0A/Lib;D:/openjdk-7/freetype/bin;D:/Program Files/Microsoft Visual Studio 10.0/VC/atlmfc/lib"
> export ALT_BINARY_PLUGS_PATH=$(${cygpath} "D:/openjdk-7/openjdk-binary-plugs")
> export ALT_COMPILER_PATH=$(${cygpath} "D:/Program Files/Microsoft Visual Studio 10.0/VC/bin")
> export ALT_BOOTDIR=$(${cygpath} "D:/Program Files/Java/jdk1.6.0")
> export ALT_JDK_IMPORT_PATH=${ALT_BOOTDIR}
> export ALT_FREETYPE_LIB_PATH=$(${cygpath} "D:/openjdk-7/freetype/lib")
> export ALT_FREETYPE_HEADERS_PATH=$(${cygpath} "D:/openjdk-7/freetype/include")
> export ALT_MSDEVTOOLS_PATH=$(${cygpath} "C:/Program Files/Microsoft SDKs/Windows/v7.0A/bin")
> export ALT_CC_VER=16.00.30319.01
> export ALT_MSC_VER_RAW=16.00.30319.01
> export ANT_HOME=$(${cygpath} "D:/openjdk-7/apache-ant-1.8.2")
> export ALLOW_DOWNLOADS=true
> export LANG=C
> jdk_instances=$(${cygpath} "D:/Program Files/Java")
221,222c233,234
< # VisualStudio .NET 2003 VC++ 7.1 (VS71COMNTOOLS should be defined)
< vs_root=$(${cygpath} "${VS71COMNTOOLS}/../..")
---
> # VisualStudio 2010 (VS100COMNTOOLS should be defined)
> vs_root=$(${cygpath} "${VS100COMNTOOLS}/../..")
224c236
< msdev_root="${vs_root}/Common7/Tools"
---
> msdev_root=$(${cygpath} "C:/Program Files/Microsoft SDKs/Windows/v7.0A")
226,228c238,240
< vc7_root="${vs_root}/Vc7"
< compiler_path="${vc7_root}/bin"
< platform_sdk="${vc7_root}/PlatformSDK"
---
> vc_root="${vs_root}/VC"
> compiler_path="${vc_root}/bin"
> platform_sdk=${msdev_root}
231,233c243,245
< include4sdk="${vc7_root}/atlmfc/include"
< include4sdk="${include4sdk};${vc7_root}/include"
< include4sdk="${include4sdk};${platform_sdk}/include/prerelease"
---
> include4sdk="${vc_root}/atlmfc/include"
> include4sdk="${include4sdk};${vc_root}/include"
> # include4sdk="${include4sdk};${platform_sdk}/include/prerelease"
235,237c247,249
< include4sdk="${include4sdk};${vs_root}/SDK/v1.1/include"
< lib4sdk="${lib4sdk};${vc7_root}/lib"
< lib4sdk="${lib4sdk};${platform_sdk}/lib/prerelease"
---
> # include4sdk="${include4sdk};${vs_root}/SDK/v1.1/include"
> lib4sdk="${lib4sdk};${vc_root}/lib"
> # lib4sdk="${lib4sdk};${platform_sdk}/lib/prerelease"
239c251,252
< lib4sdk="${lib4sdk};${vs_root}/SDK/v1.1/lib"
---
> lib4sdk="${lib4sdk};${vc_root}/atlmfc/lib"
> # lib4sdk="${lib4sdk};${vs_root}/SDK/v1.1/lib"
242,243c255,256
< path4sdk="${vs_root}/Common7/Tools/bin;${path4sdk}"
< path4sdk="${vs_root}/SDK/v1.1/bin;${path4sdk}"
---
> # path4sdk="${vs_root}/Common7/Tools/bin;${path4sdk}"
> # path4sdk="${vs_root}/SDK/v1.1/bin;${path4sdk}"
245c258
< path4sdk="${vs_root}/Common7/Tools/bin/prerelease;${path4sdk}"
---
> # path4sdk="${vs_root}/Common7/Tools/bin/prerelease;${path4sdk}"
247a261
> path4sdk="${msdevtools_path};${path4sdk}"
339a354
> PATH=$PATH:$ANT_HOME/bin
如果不熟悉cygwin的diff命令輸出格式,可以到網上查詢一下。每個人根據自己的平台環境,需要自行修改。
這裡出現了一些OpenJDK編譯說明中沒有提到的環境變數的設定(ALT_CC_VER和ALT_MSC_VER_RAW),它們的作用在後面進行說明。
另外,不要忘了設定ALLOW_DOWNLOADS=true,允許編譯時間下載缺少的第三方class檔案。
4. VS2010語言問題
你安裝的VS2010是英文版嗎?如果是,跳過這條吧。
OpenJDK分析VC版本的方法是,命令列不帶參數執行cl.exe,從輸出的版本說明中分析出版本號碼,方式是通過匹配關鍵字“Version”。中文版VS悲劇了,版本說明是中文的,沒有這個英文字...
如果將關鍵字改成中文進行分析,那遇到英文版VS又不靈了。只好設定了ALT_CC_VER和ALT_MSC_VER_RAW變數,意思是如果外部不指定具體的VC版本號碼,才採用分析關鍵字的方法擷取版本號碼。
涉及到的檔案有~/hotspot/make/windows/get_msc_ver.sh和~/jdk/make/common/shared/Compiler-msvc.gmk
get_msc_ver.sh的改動是
61c61,66
< MSC_VER_RAW=`cl 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[/ ]*/([0-9][0-9.]*/).*//1/'`
---
> # MSC_VER_RAW=`cl 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[/ ]*/([0-9][0-9.]*/).*//1/'`
> if [ "${ALT_MSC_VER_RAW}" != "" ] ; then
> MSC_VER_RAW=${ALT_MSC_VER_RAW}
> else
> MSC_VER_RAW=`cl 2>&1 | "$HEAD" -n 1 | "$SED" 's/.*Version[/ ]*/([0-9][0-9.]*/).*//1/'`
> fi
Compiler-msvc.gmk的改動是
49,50c49,53
< CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*/(Version.*/)//1/' | $(NAWK) '{print $$2}')
<
---
> ifdef ALT_CC_VER
> CC_VER := $(ALT_CC_VER)
> else
> CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*/(Version.*/)//1/' | $(NAWK) '{print $$2}')
> endif
5. 安裝jdk-7-ea-plug-b123-windows-i586-22_dec_2010.jar
這裡只是提醒一下,不要忘了安裝這個東西(我就忘了...)。OpenJDK的官網
有下載。
我安裝到了~/openjdk-binary-plugs/ 下
6. FreeType庫的安裝
由於OpenJDK編譯過程中使用的工具FreeTypeChecker有manifest問題,需要用VS2010重編,這個工具運行中需要使用FreeType的dll(事實上OpenJDK本身也要用到FreeType,但是項目中沒有帶相關庫檔案)。從FreeType官網下載了二進位檔案(雖然也提供源碼下載,但實在沒有精力折騰了...),安裝到~/freetype。注意:
1). FreeType最新版本(2.3.5版),庫已經更名,不再叫freetype.dll,而是叫freetype6.dll。同時,多了一個依賴庫!zlib1.dll。這個庫不隨FreeType一起,需要單獨下載,千萬不要忘記了。
2). OpenJDK7要求freetype.lib和freetype.dll放在一個目錄下,這不是FreeType工程的預設設定,需要手動將freetype6.dll和zlib1.dll拷貝到freetype.lib所在目錄(~/freetype/lib/)。
3). 由於FreeType庫名變了,需要修改相關的makefile檔案和java源檔案(考慮到FreeType庫後續版本不會再叫回freetype.dll,建議修改OpenJDK工程)。
涉及到的檔案有~/jdk/make/sun/font/Makefile、~/jdk/make/tools/freetypecheck/Makefile和~/jdk/src/share/classes/sun/font/FontManagerNativeLibrary.java
~/jdk/make/sun/font/Makefile的改動是
126c126,127
< FREETYPE_LIB = $(LIB_LOCATION)/$(LIB_PREFIX)freetype.$(LIBRARY_SUFFIX)
---
> FREETYPE_LIB = $(LIB_LOCATION)/$(LIB_PREFIX)freetype6.$(LIBRARY_SUFFIX)
> ZLIB1_LIB = $(LIB_LOCATION)/$(LIB_PREFIX)zlib1.$(LIBRARY_SUFFIX)
137,138c138,142
< $(FREETYPE_LIB):
< $(CP) $(FREETYPE_LIB_PATH)/$(LIB_PREFIX)freetype.$(LIBRARY_SUFFIX) $@
---
> $(FREETYPE_LIB): $(ZLIB1_LIB)
> $(CP) $(FREETYPE_LIB_PATH)/$(LIB_PREFIX)freetype6.$(LIBRARY_SUFFIX) $@
> $(install-module-file)
> $(ZLIB1_LIB):
> $(CP) $(FREETYPE_LIB_PATH)/$(LIB_PREFIX)zlib1.$(LIBRARY_SUFFIX) $@
~/jdk/make/tools/freetypecheck/Makefile的改動是
41c41,42
< FREETYPE_DLL = $(FREETYPE_LIB_PATH)/freetype.dll
---
> FREETYPE_DLL = $(FREETYPE_LIB_PATH)/freetype6.dll
> ZLIB1_DLL = $(FREETYPE_LIB_PATH)/zlib1.dll
72a74
> $(CP) $(ZLIB1_DLL) $(@D)/
FontManagerNativeLibrary.java的改動是
59c59,60
< System.loadLibrary("freetype");
---
> //System.loadLibrary("freetype");
> System.loadLibrary("freetype6");
7. javac的預設編碼問題
不知道什麼原因,OpenJDK自動產生的部分java檔案,注釋是中文的。javac卻指定了ascii編碼方式(添加了參數-encoding ascii)。遇到包含中文的java檔案,javac會報錯。將-encoding編譯選項去掉,採用作業系統預設的編碼即可解決問題。
涉及到的檔案有~/corba/make/common/shared/Defs-java.gmk、~/jdk/make/common/shared/Defs-java.gmk和~/hotspot/make/windows/makefiles/rules.make
~/corba/make/common/shared/Defs-java.gmk的改動是
133c133
< JAVACFLAGS += -encoding ascii
---
> # JAVACFLAGS += -encoding ascii
194c194,195
< BOOT_JAVACFLAGS += -encoding ascii -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
---
> # BOOT_JAVACFLAGS += -encoding ascii -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
> BOOT_JAVACFLAGS += -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
~/jdk/make/common/shared/Defs-java.gmk的改動是
134c134
< JAVACFLAGS += -encoding ascii
---
> # JAVACFLAGS += -encoding ascii
212c212,213
< BOOT_JAVACFLAGS += -encoding ascii -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
---
> # BOOT_JAVACFLAGS += -encoding ascii -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
> BOOT_JAVACFLAGS += -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
rules.make的改動是
48c48,49
< JAVAC_FLAGS=-g -encoding ascii
---
> #JAVAC_FLAGS=-g -encoding ascii
> JAVAC_FLAGS=-g
8. VC警告的問題
不知道OpenJDK哪來的自信,啟用了VC的“將警告視為錯誤”(warnings as errors)選項。就我遇到的情況,OpenJDK源碼使用了一個被VS2010標記為“過時”(deprecated
)的宏,產生了警告資訊。改源碼風險太大,所以我調整了編譯選項。涉及到的檔案有~/hotspot/make/windows/makefiles/compile.make和~/hotspot/src/share/tools/hsdis/Makefile
compile.make的改動是
53c53,54
< CPP_FLAGS=/nologo /W3 /WX
---
> # CPP_FLAGS=/nologo /W3 /WX
> CPP_FLAGS=/nologo /W3 /WX-
Makefile的改動是
92c92,93
< CFLAGS += /nologo /MD /W3 /WX /O2 /Fo$(@:.dll=.obj) /Gi-
---
> # CFLAGS += /nologo /MD /W3 /WX /O2 /Fo$(@:.dll=.obj) /Gi-
> CFLAGS += /nologo /MD /W3 /WX- /O2 /Fo$(@:.dll=.obj) /Gi-
記錄了的問題只有這些,也許會有些遺漏。各位同志在編譯自己的OpenJDK時,也可能遇到我沒有遇到的情況。假如不幸不到了上述問題,希望我的經驗能對你有些協助。