1.为什么要编译JDK

  想要一探JDK内部的实现机制,最便捷的路径之一就是自己编译一套JDK,通过阅读和跟踪调试JDK源码去了解Java技术体系的原理,虽然门槛高一点,但肯定比阅读各种书籍,文章,博客更在贴切一点,另外,JDK的很多方法都是本地化(Native)的,需要跟踪这些方法的运作或对JDK进行Hack的时候,都需要自己编译一套JDK。
 

2.选择JDK

  现在网上有不少开源的JDK实现可以供我们选择,如Apache Harmony,OpenJDK等,考虑到Sun系列的JDK是现在使用得最广泛的JDK版本,所以我们选择openJDK进行编译。
关于openJDK?
  openJDK是sun在2006年末把java开源而形成的项目。开源是通常意义上的源码形式上开放,等同于源码可被复用。商业版的oracle jdk和open jdk 除了版权注释之外,其余代码基本上都是相同的,都是建立在两者共有的组件基础上。oracle jdk还会存在一些open jdk没有的,商用闭源的功能。oracle的项目发布经理Joe Darcy 在OSCON2011 上对两者的关系上也证实了oracle jdk和open jdk程序上市非常接近。
 

3.环境准备

1.openJDK下载,获取openJDk源码有两种方式.
  (1)其中一种是通过一款代码版本管理Mercurial上获取
    hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8
    cd jkd8
    bash ./get_source.sh
  这种是最直接的方式,但是由于文件很多,国内的网络对Mercurial不如对git svn上不够快,经常可能失败,可以把镜像换成国内的,这个可以自己找找。
  (2)从https://download.java.net/openjdk/jdk8直接下载打包好的源码文件,这里openjdk在下载源码有个bug,如图:
  
把这里的下载地址前面的域名弄错了,应该是http://download.java.net,把前面的http://www.java.net/download/换掉,后面的不变,就能下载打包好的源码文件。参考1.7地址: http://download.java.net/openjdk/jdk7/promoted/b147/openjdk-7-fcs-src-b147-27_jun_2011.zip
最终的地址: http://download.java.net/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip
 
2.安装依赖软件,如果没有brew命令,可以先看看brew怎么安装再继续执行以上安装命令。
(1)Xcode-select:安装命令:xcode-select –install  进行x11链接
  sudo ln -s /usr/X11/include/X11 /usr/include/X11 or sudo ln -s /usr/local/X11/include/X11 /usr/include/X11  (如果软连接失败,重启mac时按住command+R 进入恢复模式,然后打开terminal  执行 csrutil disable,再重启,这是mac对安全的一种校验)
这里重点说一句: 重启mac时按住command+R 进入恢复模式. 在弹出的面板上是没有终端的,终端要去上面的菜单栏选择. 
这一步很重要, 包括软链,如果不操作, 后面编译会报异常
(2)安装XQuartz 下载地址: https://www.xquartz.org/
(3)安装freetype,安装命令:brew install freetype
(4)安装GC 安装命令: brew install gcc49 据说安装往上的版本会报错。
(5) 安装ccache提升编译速度 brew install ccache
(6) 安装ant 一般mac都会有这个环境,如果没有执行:brew install ant
 
 
3.修改源码

(1). 修改generated-configure.sh(路径:common/autoconf/generated-configure.sh)
  注释20061行
  // as_fn_error $? "GCC compiler is required. Try setting --with-tools-dir." "$LINENO" 5
  注释21640行
  // as_fn_error $? "GCC compiler is required. Try setting --with-tools-dir." "$LINENO" 5

(2). 修改relocInfo.hpp(路径:hotspot/src/share/vm/code/relocInfo.hpp)
  修改367行
  inline friend relocInfo prefix_relocInfo(int datalen);
  修改472行
  inline relocInfo prefix_relocInfo(int datalen = 0) {
    assert(relocInfo::fits_into_immediate(datalen), "datalen in limits");
    return relocInfo(relocInfo::data_prefix_tag, relocInfo::RAW_BITS, relocInfo::datalen_tag | datalen);
  }

(3). 修改openjdk/hotspot/src/share/vm/opto/loopPredicate.cpp
  修改775行为
  assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int()->_lo >= 0, "must be");

(4).修改openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp
  修改331行为
  if (base() != 0) {

4.设置环境变量

  cd ~
  open .bash_profile (这个在安装jdk都会设置的,如果没有这个文件去看看jdk安装的教程)
添加变量:

# 设定语言选项,必须设置
export LANG=C
# Mac平台,C编译器不再是GCC,是clang
export CC=clang
# 跳过clang的一些严格的语法检查,不然会将N多的警告作为Error
export COMPILER_WARNINGS_FATAL=false
# 链接时使用的参数
export LFLAGS='-Xlinker -lstdc++'
# 是否使用clang
export USE_CLANG=true
# 使用64位数据模型
export LP64=1
# 告诉编译平台是64位,不然会按32位来编译
export ARCH_DATA_MODEL=64
# 允许自动下载依赖
export ALLOW_DOWNLOADS=true
# 并行编译的线程数,编译时间长,为了不影响其他工作,我选择为2
export HOTSPOT_BUILD_JOBS=2
export ALT_PARALLEL_COMPILE_JOBS=2
# 是否跳过与先前版本的比较
export SKIP_COMPARE_IMAGES=true
# 是否使用预编译头文件,加快编译速度
export USE_PRECOMPILED_HEADER=true
# 是否使用增量编译
export INCREMENTAL_BUILD=true
# 编译内容
export BUILD_LANGTOOLS=true
export BUILD_JAXP=true
export BUILD_JAXWS=true
export BUILD_CORBA=true
export BUILD_HOTSPOT=true
export BUILD_JDK=true
# 编译版本
export SKIP_DEBUG_BUILD=true
export SKIP_FASTDEBUG_BUILD=false
export DEBUG_NAME=debug
# 避开javaws和浏览器Java插件之类的部分的build
export BUILD_DEPLOY=false
export BUILD_INSTALL=false

最后干掉这两个变量,不然会有诡异的事发生
unset JAVA_HOME
unset CLASSPATH

 将变量添加到base_profile以后, 把中午注释去掉, 否则会乱码,编译报错

5.编译, ( 遇到问题可以先看看下面的问题描述)

(1)cd 到下载好的openSDK目录下,先授予权限给openJDK目录 如: chmod -R 777 openjdk
 
(2)./configure 如果找不freetype 可以执行./configure --with-freetype-include=/usr/local/include/freetype2 --with-freetype-lib=/usr/local/lib/
 

sh configure --with-debug-level=slowdebug --with-boot-jdk=`/usr/libexec/java_home -v 1.7` --with-freetype-include=/usr/local/include/freetype2 --with-freetype-lib=/usr/local/lib/ --with-target-bits=64 --with-jvm-variants=server --with-jdk-variant=normal --with-milestone=internal --with-update-version=b25 --with-build-number=b25 --with-zlib=system --with-num-cores=2 --with-jobs=4 CC=clang CXX=clang++

使用这种方式编译, 在build文件夹生成两个文件. 如果使用第一种, 只会生成一个

参考文章: https://blog.csdn.net/lizhengjava/article/details/60138890

 
  (3) 开始执行make命令: 在执行make命令需要指定编译环境,环境路径在:./openjdk/build/下面 一般有两个 macosx-x86_64-normal-server-release 和 macosx-x86_64-normal-server-slowdebug
  如果一般编译失败会有失败的文件,为了保险起见先执行:
    make CONF=macosx-x86_64-normal-server-release clean 或者
    make CONF=macosx-x86_64-normal-server-slowdebug clean
  再执行:
    make CONF=macosx-x86_64-normal-server-release install 或者
    make CONF=macosx-x86_64-normal-server-slowdebug install
 
我使用的是第一个: make CONF=macosx-x86_64-normal-server-release clean因为我的文件夹下没有第二个
编译成功如图:
  

6.我执行./configure和编译遇到的问题:

问题1和问题2是原作者遇到的,我并没有遇到. 后面的问题是我遇到的

(1)./configure问题: configure: error: GCC compiler is required
  解决方法:
   jdk8/common/autoconf/generated-configure.sh文件中 注释两处代码:第20061,21640行 #as_fn_error $? "GCC compiler is required. Try setting --with-tools-dir." "$LINENO" 5
 
  (2)make问题:
  Running nasgen
  Exception in thread "main" java.lang.VerifyError:
  class jdk.nashorn.internal.objects.ScriptFunctionImpl overrides final method setPrototype.(Ljava/lang/Object;)V
  解决方法:
  修改:vim ./openJDk/nashorn/make/BuildNashorn.gmk
  80行原来 -cp 修改为:-Xbootclasspath/p:  如图: 
  
 (3) 在执行sudo ln -s /usr/X11/include/X11 /usr/include/X11 的时候提示: sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set
 
  这个问题的原因是提示sudo没有权限, 最终结觉办法是, 使用root用户登录. 然后将/usr/bin/sudo 授与4755权限
  如果不知道怎么使用root用户登录, 可以看这篇文章: https://www.jianshu.com/p/be9f1d57c710.   我是重置了root的密码, 因为不知道原密码是什么, 然后退出当前用户, 使用root重新登录. 
  执行: chmod 4755 /usr/bin/sudo 就可以使用了
 
  (4) 在root用户授权sudo以后, 回到luo***用户登录的时候, 终端显示异常. 内容如下:

  Could not determine audit condition  [Process completed]

  [进程已完成]

  处理办法参考: https://www.jianshu.com/p/d764d2840071. 很多说是因为./bash_profile文件配置错误导致的, 但我这个不是. 将/usr/bin 下的login文件改名login1, 再打开终端, 然后执行

  sudo chown root:wheel /usr/bin/login

  sudo chmod u+s /usr/bin/login

  在将login1的名字改回login. 已经恢复了.

 (4) 报异常<iostream> not found. 这个问题应该是和Xcode没有进行软链有关系. 我第一次操作的时候没有进行软链
 
 
(5) 
7.测试是否编译成功
  cd ./openjdk/build/macosx-x86_64-normal-server-release/jdk/bin
  执行java -version
  如图则编译成功:
   
 
 

第一篇: openJDK源码编译安装--mac版本的更多相关文章

  1. 分布式架构高可用架构篇_06_MySQL源码编译安装(CentOS-6.7+MySQL-5.6)

    redhat: 下载:http://dev.mysql.com/downloads/mysql/ 选择5.6 source包 解压 cmake . -DCMAKE_INSTALL_PREFIX=/us ...

  2. Linux环境PostgreSQL源码编译安装

    Linux环境PostgreSQL源码编译安装 Linux版本: Red Hat 6.4 PostgreSQL版本: postgresql-9.3.2.tar.gz 数据存放目录: /var/post ...

  3. zabbix源码编译安装以及添加第一台host监控

    基础准备 硬件需求 数据库需求   软件需求 其他软件需求 安装 安装方式 source code 编译好的二进制包 rpm或者deb 源码编译安装部署zabbix以及附件 前提准备 最小化安装操作系 ...

  4. Centos 7源码编译安装 php7.1 之生产篇

    Centos 7源码编译安装 php7.1 之生产篇 Published 2017年4月30日 by Node Cloud 介绍: 久闻php7的速度以及性能那可是比php5系列的任何一版本都要快,具 ...

  5. WordPress安装篇(5):源码编译安装LNMP并部署WordPress

    与YUM方式安装相比,源码编译安装方式更灵活,安装过程中能自定义功能和参数,特别是在批量部署服务器又要求软件版本及配置一致时,源码编译安装的优势很明显.本文介绍如何通过源码编译方式安装Nginx1.1 ...

  6. Linux 下源码编译安装 vim 8.1

    前言 目前 linux 的各个发行版基本上都是带了一个 vi 编辑器的,而本文要说的 vim 编辑器对 vi 做了一些优化升级,更好用.当我们需要远程操作一台 linux 服务器的时候,只能使用命令行 ...

  7. 烂泥:mysql5.5数据库cmake源码编译安装

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 以前也写过一篇有关mysql5.0源码编译的文章,该文章为<烂泥:mysql5.0数据库源码编译安装>.但是MySQL自5.5版本以后,就开 ...

  8. 保姆级教程——Ubuntu16.04 Server下深度学习环境搭建:安装CUDA8.0,cuDNN6.0,Bazel0.5.4,源码编译安装TensorFlow1.4.0(GPU版)

    写在前面 本文叙述了在Ubuntu16.04 Server下安装CUDA8.0,cuDNN6.0以及源码编译安装TensorFlow1.4.0(GPU版)的亲身经历,包括遇到的问题及解决办法,也有一些 ...

  9. Zabbix 源码编译安装

    简介: Zabbix 分布式监控系统,源码编译安装记录 ( 记不得是第多少次了 ) 下载地址:http://jaist.dl.sourceforge.net/project/zabbix/ZABBIX ...

随机推荐

  1. 实验吧之【因缺思汀的绕过】(group by with rollup的注入利用)

    打开页面,查看源代码,发现存在source.txt(http://ctf5.shiyanbar.com/web/pcat/source.txt),如下: <?php error_reportin ...

  2. [HDU2294] Pendant - 矩阵加速递推

    Pendant Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  3. python soket服务和客户端Demo

    #服务端from socket import * s=socket(AF_INET,SOCK_STREAM)#IVP4 寻址 tcp协议 s.bind(('',6666))#补丁端口 s.listen ...

  4. python编程系列---白痴女朋友(我没有女朋友!)看了都能懂的TCP/IP协议介绍

    前言 早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Microsoft都有各自的网络协议,互不兼容:为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,为 ...

  5. vue系列---Mustache.js模板引擎介绍及源码解析(十)

    mustache.js(3.0.0版本) 是一个javascript前端模板引擎.官方文档(https://github.com/janl/mustache.js) 根据官方介绍:Mustache可以 ...

  6. scp -本地文件上传服务器,指定端口

    scp 命令可以将本地文件上传服务器,或者将服务器上的文件下载到本地, 1.  上传服务器: scp [本地文件目录]  [服务器用户名]@[服务器名]:/[服务器上文件路径] 比如 scp /Doc ...

  7. unity 内置shader

    几个有用的Unity 内置shader: (一)Standard RenderingMode:Opaque为实体渲染,更改Color的透明通道不会有影响:Cutout会把图片的透明通道显示出来,非严格 ...

  8. TCP Socket服务端客户端(二)

    本文服务端客户端封装代码转自https://blog.csdn.net/zhujunxxxxx/article/details/44258719,并作了简单的修改. 1)服务端 此类主要处理服务端相关 ...

  9. 详细讲解IPython

    ipython是一个python的交互式shell,比默认的python shell好用得多,支持变量自动补全,自动缩进,支持bash shell命令,内置了许多很有用的功能和函数.学习ipython ...

  10. 省市区三级联动(vue)

    vue项目中使用到三级联动,现在自己实现一个三级联动,仅供大家参考一下,直接上代码. <template> <section class="container"& ...