在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时,也可能遇到我没有遇到的情况。假如不幸不到了上述问题,希望我的经验能对你有些帮助。