JAVA虚拟机学习笔记(一)Windows10下编译OpenJDK8
转载请注明源地址:http://www.cnblogs.com/lighten/p/5906359.html
1. 编译环境的准备
1.1 JDK源码下载
OpenJDK是JAVA发展史中的一个开源项目,本文以OpenJDK8为例进行编译。OpenJDK的官网为:http://openjdk.java.net/,直接访问http://openjdk.java.net/install/index.html进入主要界面。左侧有一系列的,找到Source code列表,其提供了两种形式的下载:Mercurial和Bundles(6)。
Mercurial是一个代码版本管理工具,和SVN、Git等相似,不过使用的人比较少而已。Bundles就是包的形式下载了,我们选择这种方式。目前只提供了jdk6的链接页面:http://download.java.net/openjdk/jdk6。要想下载到jdk8,将url改成jdk8就行了:http://download.java.net/openjdk/jdk8。进入页面后,点击下载就行了:
2019/02/13更新:上述链接失效,补充: http://jdk.java.net/java-se-ri/8
点击红色箭头所指的链接进行下载,或者点击:这里。
1.2 准备编译环境
解压下载的压缩包,进入文件夹,点击README-builds.html,这是官方给的编译指导手册。阅读第三节Building/System Setup/Windows篇。这里我就按照其上面说的继续做了。
在Windows下编译需要一个Unix类似的环境,尤其是shell,可以通过使用CYGWIN或者是MinGW/MSYS来构建环境。这些模仿环境的工具不同之处主要在于它们对于路径名称的处理。这里以CYGWIN为例。
1.2.1 CYGWIN安装
注意使用CYGWIN会导致一个忽略路径的独特问题。通常在Windows上的设置的路径目录通常用;分割,但是CYGWIN使用:来分割。这导致路径如:C:\path不能被CYGWIN设置,除非使用/cygdrive/c/path这种CYGWIN能明白的路径,但是这也只有CYGWIN能识别。
OpenJDK需要1.7.16或更高版本的CYGWIN,去www.cygwin.com下载CYGWIN。说明一下:我下载的是2.6.0,提示我的版本太老了,当时心里…。为了不重来,最好还是下载1.7.16版本高一点的,但是看见1.7.17 windows10不支持,心里…。
CYGWIN默认安装的工具并没有包含所有编译所需的工具,所以不能选择默认安装,下图为其额外所需要的工具:
注意:CYGWIN软件可能与你Windows上其它非CYGWIN的软件冲突。可以去其官网的FAQ https://cygwin.com/faq.html看看有没有解决方法,尤其要关注2.10的https://cygwin.com/faq/faq.html#faq.using.bloda (README-builds.html里面的链接失效了,我猜测应该是这两个地址)。
注意:这里还少了一个diffutils包。
具体步骤如下:
1.点击下载下来的setup-x86_64.exe
2.选择第二个选项:download without installing,然后选择下载的文件夹,遇到问题的时候网上搜了一下,发现有人推荐使用地址http://mirrors.kernel.org,我试验了一下,确实还可以。那篇文章教导如果下到一半网络不通失败了怎么处理,这时要点击关掉,关掉向导程序,然后按照之前的选择,重来一遍,目录和下载地址要一致,在选择下载安装包界面,如下图,此时All后面是Default,断线后应该为install,把其改成Reinstall,点击下载。文章详细地址如下:http://blog.chinaunix.net/uid-20178959-id-1731456.html。当然网上还有全安装包下载的方法,我没试过。最后让其下载。
3.下载完成后会下面这个界面,这个界面就需要选择上图所需的工具了:
这里找上述的包可能比较难找,主要在Search中搜索上述的Package。如第一个ar.exe,如果搜索ar,是找不到这个工具的,但是搜索binutils,可以找到。但是实际上是没有显示哪个是我们需要的,因为没有名称是ar的,此时就要对比上述的描述Description了,这样就确定了要下载哪个工具了,左击Skip选中,出现版本号即可。通过Category可以快速定位,但是不准确,实践中可行,但有些不对。总结一下就是以Package为主,Description为确定目标,这个毕竟是功能描述,包一致,功能也差不多,那就是那个包了,Category只能用于快速定位,没找到要到其它Category中寻找。
下载完成之后,就要开始安装了,下面是安装步骤:
1.再次打开安装向导,不过这次选择第三个选项,从本地仓库安装
2.选择要安装的目录,再选择刚刚文件下载的目录
3.到安装包选择界面,再选择添加一次上述所需的包,点击安装,即可
这样如果包不对,应该可以重新下载包,然后再安装包。
1.2.2 Visual Studio 2010 Compliers安装
根据指导手册,OpenJDK Windows构建需要VS2010专业版编译器。编译器以及其它工具的安装位置希望由变量VS100COMNTOOLS定义,这个会由Microsoft Visual Studio installer自动设置。VS2010所需要的部分只有C++的部分而已。尽量安装在默认安装的位置,安装完成后,重启电脑,确保环境变量VS100COMNTOOLS已经设置了。确保TMP或TEMP也在你的Windows paths中设置了,例如:C:\temp。其它的路径格式都不对,这有这一种正确。假设这个区域是用户私有的,那么在默认安装后,你应该会看到一个不同的用户路径在这些变量中。
虽然只需要C++部分,但是单独安装编译器比较麻烦,还是选择Visual Studio C++ 2010 Professional或者Visual Studio C++ 2010 Express版本。这个网上到处都是,随便下一个,用完之后就可以删了。这里提供一个比较齐全的下载地址:http://www.itellyou.cn/。下载后只需要安装C++的模块就行了。Visual Studio C++ 2010 Express是没有64位的版本的。推荐还是下载Professional版本。
1.2.3 FreeType下载
实际上这个包是我参考其它人的配置和书籍看到的,但是在官方的build文档中并没有提及这个问题。但是在给样例参数的时候提到了Windows 32bit build with freetype specified:bash ./configure --with-freetype=/cygdrive/c/freetype-i586 --with-target-bits=32,其还给了另一个样例:Debug 64bit Build: bash ./configure --enable-debug --with-target-bits=64。如果你只使用bash ./configure配置,执行的时候会报需要freetype,所以还是加上这个吧。
这是一个免费的字体渲染库,OpenJDK的Swing部分和JConsole会使用到它。要去其官网上下载:http://www.freetype.org/。目前最新版本是2.7。直接下载地址:https://sourceforge.net/projects/freetype/files/latest/download?source=files
2 编译OpenJDK
1.解压下载的FreeType和OpenJDK8到同一个根目录,目录中最好不要有中文,以免带来不好的影响。放在同一个路径下也是为了等下在CYGWIN中好操作。
2.通过CYGWIN进入OpenJDK8的解压目录。这里提一些基本的Linux知识。/路径是根路径,我们Windows上的C、D、E、F等盘都挂载在/cygdrive/路径下。通过pwd查看当前路径,一般进入的时候都是在/usr/home/xxx下面。直接通过cd /cygdrive/d/openjdk 更换盘符和其它路径,就可以进入OpenJDK解压的位置了。
3.配置参数,并检验:bash ./configure 这种情况就是什么参数都没有,还可以像上面说的加上--with-freetype=/cygdrive/c/freetype-i586 --with-target-bits=32,编译成32位的JDK,或者是--enable-debug --with-target-bits=64具有调试功能的64位JDK。具体参数看README-builds.html中的Configure Options。回车,就会开始设置参数,并检验配置是否正确,如果有错误就看具体的错误信息了。我使用的是bash ./configure --with-freetype=/cygdrive/e/freetype-2.7 --with-target-bits=64
4.配置成功之后,执行:make all进行编译。如果失败了执行make clean,清除编译信息,但是不会清除之前的配置。make dist-clean就是全部清除了。Make命令详细参数还是看README-builds.html中的Make模块,编译的时间比较漫长,我的笔记本比较渣,花了两个小时,看来可以换一台了。
5.编译结束后,你就会在OpenJDK的根路径下看见一个build文件夹,这个就是编译的输出路径了。build/*/images/j2sdk-image/bin路径必须包含配置了的OpenJDK工具的可执行文件。测试工具jtreg是有必要的。可以在http://openjdk.java.net/jtreg/网址中找到,提供了回归测试,在仓库(repositories)中运行命令:cd test && make PRODICT_HOME=`pwd`/../build/ 这个还没有实验过,一般只要在编译输出目录中看见有java javac等命令就可以了。
3 编译过程的错误
1.configure: Could not find cmp!
查了很久,最后在stackoverflow上找到了答案,还要装一个diffutils包。还是使用那个引导客户端,同样的文件目录,url。只把这个包下下来,再点击进入引导客户端。第三个选项,在安装包界面的View 选择Not Installed,就能看见这个包了。选择安装即可。
这些包都可以在官网上找到:https://cygwin.com/packages/x86/diffutils/,至于怎么安装就没研究了,上面那个方法感觉挺方便的。
2. Your cygwin is too old. You are running 2.6.0(0.304/5/3), but at least cygwin 1.7 is required. Please upgrade.
看到这个提示,一阵无语。1.7.16是OpenJDK给的最低版本需求,而我又在搜索这个版本的时候在一个网站看见1.7.17版本,刚想下载时,发现其说明Windows10不支持,2016年1月之后的版本才开始支持Windows10的。回到官网,看见一条注意消息:2.5.2是最后一个支持Windows XP系统和Windows Server 2003的版本,想这个版本连Windows XP都支持,又离目前最新的2.6.0比较接近,应该能使用吧。官网上没有找到旧版本的地址,在我不断寻找旧版本的时候在官网上https://cygwin.com/faq.html#faq.what.version看见了4.23一段话,问题是有些应用是基于旧的版本的DLL安装的,如果使用新的版本安装会中断。官方的解释是,这要取决于中断的含义了。如果应用的安装需要的DLL在另一个位置而不是/bin目录,看问题4.21。如果应用安装是由于在/bin中旧版本的DLL,你就要大声询问应用提供者了。记住,Cygwin DLL严格兼容旧版本,新版本总会运行成功,所以一般而言你要保证你的版本是最新的。
查看具体启动步骤会发现,执行bash ./configure发现是运行了一个名为generated-configure.sh的脚本,其在OpenJDK中的common/autoconf目录下。用Notepad++打开脚本,搜索Your cygwin is too old。发现在7211行开始检查CYGWIN的版本信息,具体如下:
将上面的7217-7225行注释掉,不进行版本检查即可。问题应该是出在7220行和7221行处,再执行一遍bash ./configure …。
3.configure: error: Target CPU mismatch. We are building for x86_64 but CL is for ""; expected "x64".
目前没有什么好的方法解决,由于这只是检查环境的设置,这个问题应该不大,CL.exe是被检测到了,但是为什么版本识别不对就不清楚了。直接注释掉判断语句貌似没有什么问题。如果谁知道是怎么回事,望告知。
4.configure: Could not find /cygdrive/e/plugins/freetype-2.7/lib/freetype.dll. Ignoring location.
这个就是freetype没有编译的问题了。使用Visual Studio C++ 2010对其编译一下即可。具体步骤如下:
1)用VS2010打开freetype/builds/windows/vc2010下的freetype.sln
2)选中项目右击,选择属性,出现配置框,点击配置管理器,界面如下图。
3)右击项目,选择生成即可。在freetype目录中/objs/vc2010/x64找到刚刚自己生成的freetype.dll文件。在freetype根目录中创建一个lib文件夹,将这个文件放入其中。要32位的就是修改一下相应的配置就行了。除了dll,还要生成一个lib格式。网上看到其编译64位时平台工具集要用的是WindowsXXSDK,32位用的是v100。但是实际上好像没有什么问题,姑且先记录一下。这里编译的时候警告了编码问题,但是当时没有管,不知道后面产生的乱码现象是不是这个问题。
5.E:\plugins\openjdk\hotspot/make/windows/get_msc_ver.sh: 第 69 行:[: ▒▒▒▒ 80x86 ▒▒ Microsoft (R) 32 λ C/C++ ▒Ż▒▒▒▒▒▒▒ 16: 需要整数表达式。
这里不清楚是什么原因造成的,编码乱码还是程序自身识别逻辑出错?但是看程序源码其本意是想测试cl.exe的版本,设定相应的值。cl.exe在vs2010安装目录下VC\bin\下有三个,在dos中运行一下看是哪个版本的。我的是16.00.30319.01版。然后修改openjdk\hostpot\make\windows\get_msc_ver.sh,65-73行注释掉,直接添加MSC_VER=1600,上面有个说明。。cl version 12.00.8804 MSC_VER=1200。很不幸的是我没看见16.00,最多到了15.00,就按这个规律改成了1600。
4.写在最后
实际上最后也不算完全编译成功,编译到nashorn的时候报了一个错误:Exception in thread "main" java.lang.VerifyError: class jdk.nashorn.internal.objects.ScriptFunctionImpl overrides final method setPrototype.这个我无法知道是什么问题,以目前的水平也不能像之前一样排错,这个class文件也是生成的,里面写了些什么无法得知(也许和我用高版本的jdk8去编译OpenJDK8有关系),折腾的也够久了,第一次编译JDK源码,JDK的编译算是成功了,算是向着虚拟机的学习迈出了第一步。或许等学习更深入之后,再一次编译,可能不会这么磕磕盼盼。最后,如果有朋友知道这个问题产生的原因或者能讲解一下为什么控制台编译输出乱码是由于哪方面编码导致的,那就非常感谢了。