获取OpenJDK源码有两种方式,其中一种是通过Mercurial代码版本管理工具从Repository中直接取得源码(Repository地址:http://hg.openjdk.java.net/jdk7u/jdk7u),获取过程如以下代码所示。

hg clone http://hg.openjdk.java.net/jdk7u/jdk7u-dev

cd jdk7u-dev

chmod 755 get_source.sh

./get_source.sh

这是最直接的方式,从版本管理中看变更轨迹比看Release Note效果更好。但不足之处是速度太慢,虽然代码总容量只有300 MB左右,但是文件数量太多,全部复制到本地需要数小时。另外,考虑到Mercurial不如Git、SVN、ClearCase或CVS之类的版本控制工具那样普及,建议采用第二种方式,即直接下载官方打包好的源码包,读者可以从Source Bundle Releases页面(地址:http://jdk7.java.net/source.html)取得打包好的源码,到本地直接解压即可。一般来说,源码包大概一至两个月左右会更新一次,虽然不够及时,但比起从Mercurial复制代码的确方便和快捷许多。

构建编译环境

对于MacOS来说

只有在OpenJDK 7u4和之后的版本才能编译出Mac OS系统下的JDK包,之前的版本虽然在源码和编译脚本中也包含了Mac OS目录,但是尚未完善。

对于Mac OS,需要安装最新版本的XCode和Command Line Tools for XCode,在Apple Developer网站(https://developer.apple.com/)上可以免费下载,这两个SDK包提供了OpenJDK所需的编译器以及Makefile中用到的外部命令。另外,还要准备一个6u14以上版本的JDK,因为OpenJDK的各个组成部分(Hotspot、JDK API、JAXWS、JAXP……)有的是使用C++编写的,更多的代码则是使用Java自身实现的,因此编译这些Java代码需要用到一个可用的JDK,官方称这个JDK为“Bootstrap JDK”。如果编译OpenJDK 7,Bootstrap JDK必须使用JDK6 Update 14或之后的版本。最后需要下载一个1.7.1以上版本的Apache Ant,用于执行Java编译代码中的Ant脚本。

对于Linux来说

所需要准备的依赖与Mac OS差不多,Bootstrap JDK和Ant都是一样的,在Mac OS中GCC编译器来源于XCode SDK,而Ubuntu中GCC应该是默认安装好的,需要确保版本为4.3以上,如果没有找到GCC,安装binutils即可,在Ubuntu 10.10下编译OpenJDK 7u4所需的依赖可以使用以下命令一次安装完成。

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在编译时读取的环境变量有很多,但大多都有默认值,必须设置的只有两个:LANG和ALT_BOOTDIR,前者是设定语言选项,必须设置为:

export LANG=C

否则,在编译结束前的验证阶段会出现一个HashTable内的空指针异常。另外一个ALT_BOOTDIR参数是前面提到的Bootstrap JDK,在Mac OS上设为以下路径,其他操作系统对应调整即可。

export ALT_BOOTDIR=/Library/Java/JavaVirtualMachines/jdk1.7.0_04.jdk/Contents/Home

另外,如果之前设置了JAVA_HOME和CLASSPATH两个环境变量,在编译之前必须取消,否则在Makefile脚本中检查到有这两个变量存在,会有警告提示。

unset JAVA_HOME

unset CLASSPATH

编译shell脚本:

#环境变量设置

#语言选项,这个必须设置,否则编译好后会出现一个HashTable的NPE错

export LANG=C

#Bootstrap JDK的安装路径。必须设置

export ALT_BOOTDIR=/Library/Java/JavaVirtualMachines/jdk1.7.0_04.jdk/Contents/Home

#允许自动下载依赖

export ALLOW_DOWNLOADS=true

#并行编译的线程数,设置为和CPU内核数量一致即可

export HOTSPOT_BUILD_JOBS=6

export ALT_PARALLEL_COMPILE_JOBS=6

#比较本次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_HOTSPOT=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=/Users/IcyFenix/Develop/JVM/jdkBuild/openjdk_7u4/build

#这两个环境变量必须去掉,不然会有很诡异的事情发生(我没有具体查过这些"诡异的

#事情",Makefile脚本检查到有这2个变量就会提示警告)

unset JAVA_HOME

unset CLASSPATH

make 2>&1|tee $ALT_OUTPUTDIR/build.log

全部设置结束之后,可以输入make sanity来检查我们前面所做的设置是否全部正确。Makefile的Sanity检查过程输出了编译所需的所有环境变量,如果看到“Sanity check passed.”,说明检查过程通过了,可以输入“make”执行整个OpenJDK编译(make不加参数,默认编译make all),使用Core i7 3720QM/16GB RAM的MacBook机器,启动6条编译线程,全量编译整个OpenJDK大概需20分钟,编译结束后,将输出类似下面的日志清单所示内容。如果之前已经全量编译过,只修改了少量文件,增量编译可以在数十秒内完成。

#--Build times----------

Target all_product_build

Start 2012-12-13 17:12:19

End 2012-12-13 17:31:07

00:01:19 corba

00:01:15 hotspot

00:00:14 jaxp

00:7:21 jaxws

00:8:11 jdk

00:00:28 langtools

00:18:48 TOTAL

-------------------------

编译完成之后,进入OpenJDK源码下的build/j2sdk-image目录(或者build-debug、build-fastdebug这两个目录),这是整个JDK的完整编译结果,复制到JAVA_HOME目录,就可以作为一个完整的JDK使用,编译出来的虚拟机,在-version命令中带有用户的机器名。

>./java-version

openjdk version"1.7.0-internal-fastdebug"

O p e n J D K R u n t i m e E n v i r o n m e n t(b u i l d 1.7.0-i n t e r n a l-f a s t d e b u g-icyfenix_2012_12_24_15_57-b00)

OpenJDK 64-BitServer VM(build 23.0-b21-fastdebug,mixed mode)

如果我们并不关心JDK中HotSpot虚拟机以外的内容,只想单独编译HotSpot虚拟机的话(例如调试虚拟机时,每次改动程序都执行整个OpenJDK的Makefile,速度肯定受不了,那么使用hotspot/make目录下的Makefile进行替换即可,其他参数设置与前面是一致的,这时候虚拟机的输出结果存放在build/hotspot/outputdir/bsd_amd64_compiler2目录

在不同机器上,最后一个目录名称会有所差别,bsd表示Mac OS系统(内核为FreeBSD),amd64表示是64位JDK(32位是x86),compiler2表示是Server VM(Client VM表示是compiler1)。

进入后可以见到以下几个目录。

0 drwxr-xr-x 15 IcyFenix staff 510B 12 13 17:24 debug

0 drwxr-xr-x 15 IcyFenix staff 510B 12 13 17:24 fastdebug

0 drwxr-xr-x 15 IcyFenix staff 510B 12 13 17:25 generated

0 drwxr-xr-x 15 IcyFenix staff 510B 12 13 17:24 jvmg

0 drwxr-xr-x 15 IcyFenix staff 510B 12 13 17:24 optimized

0 drwxr-xr-x 584 IcyFenix staff 19K 12 13 17:25 product

0 drwxr-xr-x 15 IcyFenix staff 510B 12 13 17:24 profiled

这些目录对应了不同的优化级别,优化级别越高,性能自然就越好,但是输出代码与源码的差距就越大,难于调试,具体哪个目录有内容,取决于make命令后面的参数。

运行虚拟机

在编译结束之后、运行虚拟机之前,还要手工编辑目录下的env.sh文件,这个文件由编译脚本自动产生,用于设置虚拟机的环境变量,里面已经发布了“JAVA_HOME、CLASSPATH、HOTSPOT_BUILD_USER”3个环境变量,还需要增加一个“LD_LIBRARY_PATH”,内容如下:

LD_LIBRARY_PATH=.:${JAVA_HOME}/jre/lib/amd64/native_threads:${JAVA_HOME}/jre/lib/amd64:

export LD_LIBRARY_PATH

然后执行以下命令启动虚拟机(这时的启动器名为gamma),输出版本号。

../env.sh

./gamma-version

Using java runtime at:/Library/Java/JavaVirtualMachines/jdk1.7.0_04.jdk/Contents/Home/jre

java version"1.7.0_04"

Java(TM)SE Runtime Environment(build 1.7.0_04-b21)

OpenJDK 64-BitServer VM(build 23.0-b21,mixed mode)

OpenJDK编译运行的更多相关文章

  1. java 11 移除的一些其他内容,更简化的编译运行程序,Unicode 10,移除了不太使用的JavaEE模块和CORBA技术,废除Nashorn javascript引擎,不建议使用Pack200 相关api

    移除的一些其他内容 移除项 移除了com.sun.awt.AWTUtilities 移除了sun.misc.Unsafe.defineClass, 使用java.lang.invoke.MethodH ...

  2. fedora下编译运行java傻瓜入门级教程

    操作步骤: 编译运行环境的搭建 fedora下默认安装为GNU公司的JDK,如下所示 $java -version java version "1.7.0_25" OpenJDK ...

  3. 如何使用Notepad++编译运行php

    安装编译运行文件的插件.插件-Plugin Manager-Show Plugin Manager. 找到NppExec插件,从这个插件的名字来看就是各位文件的执行.点击Install.需要下载安装, ...

  4. EditPlus远程编辑、语法高亮、编译运行源代码设置

    最近写代码的过程中,除了写Java时用的Eclipse.在Linux下编辑的Vi之外,有时也会用EditPlus打开一些文件,如配置文件.日志文件.脚本等.个人觉得EditPlus在很多场景下比较好用 ...

  5. 如何用javac 和java 编译运行整个Java工程 (转载)【转】在Linux下编译与执行Java程序

    如何用javac 和java 编译运行整个Java工程 (转载)  http://blog.csdn.net/huagong_adu/article/details/6929817 [转]在Linux ...

  6. 告别编译运行 ---- Android Studio 2.0 Preview发布Instant Run功能

    以往的Android开发有一个头疼的且拖慢速度的问题,就是你每改一行代码要想看到结果必须要编译运行到手机或者模拟器上,而且需要从头(可能是登录界面)一直点击到你修改的界面为止.开发一个完整的Andro ...

  7. Sublime Text 3配置C++编译运行

    2016.9.8更新: linux(Ubuntu16.04)下的配置,编译后用终端运行,解决了不能输入的问题 { "encoding": "utf-8", &q ...

  8. vim颜色选择+按<F9>自动编译运行+其他基本配置(ubuntu)

    (以下是ubuntu上的配置........ 但如果你是在window上的,直接用一下配置吧(懒得介绍了)=.= syntax on filetype indent plugin on set rul ...

  9. vim编译运行java程序

    想让你的vim可以编译运行java只要在你的配置文件里面加一句: map <F5> :!javac %&&java %:r <CR> 就可以编译运行java了

随机推荐

  1. NETSH.EXE操作SSL

    NETSH.EXE操作SSL 程序位置:c:\windows\syswow64\netsh.exe 查看当前端口配置 netsh http show sslcert 将 SSL 证书绑定至端口号 ne ...

  2. SqlServer获取字符串中数字,中文及字符部分数据

    --获取英文字符数据 Create function [dbo].[Fun_GetChar] ( ) ) ) AS BEGIN BEGIN ,'') --删掉一个非数字的字符,循环结束,剩余的为数字部 ...

  3. sqlcmd 执行SQL语句或没有足够的内存来执行脚本

    win+r命令提示框里面输入cmd sqlcmd -S . -U username -P password -d database -i url -S 数据库地址 -U 登录名称 -P 密码 -d 数 ...

  4. zstack相关学习的博客

    https://segmentfault.com/u/camile/articles?page=1

  5. 内置函数——sorted

    对List.Dict进行排序,Python提供了两个方法对给定的List L进行排序,方法1.用List的成员函数sort进行排序,在本地进行排序,不返回副本方法2.用built-in函数sorted ...

  6. httpclient post请求例子(无参数名与带参数名的例子),多线程并发处理

    版本:4.1 带参数名的情况 HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url ...

  7. BZOJ 1248--游乐园(DFS&贪心)

    1248: 游乐园Pleasure Ground Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 6  Solved ...

  8. 3分钟解决MySQL 1032 主从错误(转)

    转自  https://blog.51cto.com/suifu/1845457 3分钟解决MySQL 1032主从错误 Part1:写在最前 1032错误----现在生产库中好多数据,在从库误删了, ...

  9. React 初识

    React We built React to solve one problem: building large applications with data that changes over t ...

  10. 总结day6 ---- set集合,基本类型的相互转化,编码,数据类型总结,循环时候不要动列表或者字典,深浅copy

    python小数据池,代码块的最详细.深入剖析   一. id is == 二. 代码块 三. 小数据池 四. 总结 一,id,is,== 在Python中,id是什么?id是内存地址,比如你利用id ...