获取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. persona 典型用户

    1.姓名:王涛 2.年龄:22 3.收入:基本无收入 4.代表用户在市场上的比例和重要性:王涛为铁道学生.本软件的用户主要是学生和老师,尤其是广大的铁大学子,所以此典型用户的重要性不言而喻,而且比例相 ...

  2. mysql my.cnf优化

    [mysqld] lower_case_table_names = 1sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION skip_name_r ...

  3. Tempdb--monitoring and troubleshooting

    TempDB用来存放临时表.全局临时表.表变量以及排序或HASH等操作引发的中间结果集 TempDB在每次实例重启时重新创建,TempDB数据库文件的初始化大小取决于Model数据库的文件大小或显示A ...

  4. UWP开发入门(五)——自定义Panel

    各位好,终于讲到自定义Panel了.当系统自带的几个Panel比如Gird,StackPanel,RelativePanel不能满足我们的特定要求时(其实不常见啦),自定义Panel就显得非常必要,而 ...

  5. PXE+Kickstart无人值守安装系统re

    PXE(Preboot Excute Environment)预启动执行环境,可以让计算机通过网络启动系统,主要用于无人值守安装系统中引导客户端主机安装Linux操作系统. 由于之前有过使用cobbl ...

  6. leecode刷题(18)-- 报数

    leecode刷题(18)-- 报数 报数 描述: 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数.其前五项如下: 1. 1 2. 11 3. 21 4. 1211 5. 1112 ...

  7. 洛谷P3964 [TJOI2013]松鼠聚会(坐标系变换)

    题面 传送门 题解 对于两个点\((x_i,y_i)\)和\(x_j,y_j\),我们定义它们之间的曼哈顿距离为 \[|x_i-x_j|+|y_i-y_j|\] 定义它们的切比雪夫距离为 \[\max ...

  8. 本机号码认证黑科技:极光(JG)开发者服务推出“极光认证”新产品

    近日,中国领先的大数据服务商极光(JG)推出全新产品--极光认证JVerification.极光认证是极光针对APP用户注册登陆,二次安全验证等身份验证场景打造的一款本机号码认证SDK,验证用户提供的 ...

  9. RN 中 Native 模块的注入过程

    找到所有的模块 一般来说,只要在模块中声明 RCT_EXPORT_MODULE 即可.这是个宏,展开后是声明了一个函数,定义了两个函数,如下所示. #define RCT_EXPORT_MODULE( ...

  10. 晦涩难懂的shell命令

    初学shell脚本,过程中发现许多不易于理解的脚本语言,网上各种查找学习之后,择优精简一番,做出以下总结,方便以后遗忘了回顾,也为像我一样的初学者提供方便——推荐给初学者的一本书:<Linux ...