编译你的第一个Java虚拟机--Centos 7 编译openJdk1.7源码

一、前言

最近在看《深入java虚拟机》,看完后,打算自己实际编译一个jvm出来看看,实践一下。

书上提到了Oracle JDK和OpenJdk的关系,Oracle Jdk7 和OpenJdk 7共用了相当多的代码,所以还是很有学习的必要的:

二、环境

我这里的编译的操作系统是CentOS Linux release 7.4.1708 (Core)  (通过 cat /etc/centos-release查看)。

编译环境相当重要,因为编译openjdk的过程中,网上的文章里,大家遇到的各个问题都不一样,就是因为操作系统不一致。

我主要参考了某位园友的博客:https://www.cnblogs.com/gotodsp/p/8975387.html

该博客里有他用到的工具的百度网盘链接。大家可自行下载。我是下载了之后,通过centos中安装的lrzsz命令来上传的。

命令为rz(上传),sz(下载)。

没安装的话,执行 yum install lrzsz

下面是另一个参考的博客:

http://blog.51cto.com/wangyahui/1612838

我这里引用了不少原博客的内容,但是中间还是有很多问题。我这里会补充说明。

2.1 卸载原jdk

rpm -qa | grep java

yum -y remove XXXX   --XXXX是第一条命令查出来的jdk信息

2.2 编译相关的工具

yum -y install gcc gcc-c++ alsa-lib alsa-lib-devel libXrender libXrender-devel libXi-devel libXt-devel libXtst-devel cups cups-devel

2.3 FreeType

注意:我这边,会把所有工具,最后都解压到/usr/local目录下。先上一张我最后成功了的图:

tar -zxvf freetype-2.4.0.tar.gz -C /usr/local

cd /usr/local/freetype-2.4.0

./configure && make && make install    # 编译安装

##注意:如果安装中出现以下错误

rmdir /usr/local/include/freetype2/freetype/internal 
rmdir: failed to remove `/usr/local/include/freetype2/freetype/internal‘: No such file or directory 
make: [install] Error 1 (ignored) 
/usr/bin/install -c -m 644 ./builds/unix/ft2unix.h \ 
/usr/local/include/ft2build.h 
/usr/bin/install -c -m 644 ./builds/unix/ftconfig.h \ 
/usr/local/include/freetype2/freetype/config/ftconfig.h

执行以下命令处理:

mkdir -p /usr/local/include/freetype2/freetype/internal

重新安装

./configure && make && make install

2.4 Apache Ant

tar -zxvf apache-ant-1.9.7-bin.tar.gz -C /usr/local # 解压

ln -s /usr/local/apache-ant-1.9.7/bin/ant /usr/bin/ant  # 软链接到bin

2.5 BootstrapJDK

上传到你的虚拟机上后,

chmod +x jdk-6u45-linux-x64.bin

./jdk-6u45-linux-x64.bin    # 解压

mv jdk1.6.0_45 /usr/local/  # 移动目录

然后 vim /etc/profile,配置:

#java environment
export JAVA_HOME=/usr/local/jdk1.6.0_45
export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
export PATH=$PATH:${JAVA_HOME}/bin

然后执行 source /etc/profile.

再执行java -version试试,看看是不是生效。

2.6 OpenJdk

unzip openjdk-7-fcs-src-b147-27_jun_2011.zip   # 解压

原文章中说得有点乱,不管怎样,做成下面我这种目录效果就行:

三、准备环境变量

vim /etc/profile #在末尾加以下内容。注意其中的目录的路径,另外,先不要忙着执行,先把这一节看完:

export ANT_HOME=/usr/local/apache-ant-1.9.7

export ALT_FREETYPE_HEADERS_PATH=/usr/local/include/freetype2
export ALT_FREETYPE_LIB_PATH=/usr/local/lib
export ALT_DROPS_DIR=/usr/local/src/openjdk/drop
export ALT_BOOTDIR=/usr/local/jdk1.6.0_45
export ALT_JDK_IMPORT_PATH=/usr/local/jdk1.6.0_45
export ALT_OUTPUTDIR=/usr/local/openjdk_output
export LANG=C
export HOTSPOT_BUILD_JOBS=8
export ALT_PARALLEL_COMPILE_JOBS=8
export SKIP_COMPARE_IMAGES=true
export USE_PRECOMPILED_HEADER=true
export ALLOW_DOWNLOADS=true
export SKIP_DEBUG_BUILD=false
export SKIP_FASTDEBUG_BUILD=true
export DEBUG_NAME=debug
export BUILD_LANGTOOLS=true
export BUILD_HOTSPOT=true
export BUILD_JDK=true
export BUILD_DEPLOY=false
export BUILD_INSTALL=false
unset JAVA_HOME
unset CLASSPATH
unset LD_LIBRARY_PATH

这里依次解释下各个选项:

  • ANT_HOME   # 编译工具ant的路径
  • ALT_FREETYPE_HEADERS_PATH  #  freetype2头文件安装目录,一般无需替换
  • ALT_FREETYPE_LIB_PATH # 这个也无需修改
  • ALT_DROPS_DIR #这个目录很重要,下图来自参考的那位园友的博客里的:

  • ALT_BOOTDIR  #启动jdk的路径
  • ALT_JDK_IMPORT_PATH #看文章里是配成一致的,暂时还不知道配成不一致的结果
  • ALT_OUTPUTDIR  #最终编译输出的位置,来个直观图展示下

  

  • LANG  ##语言选项,这个必须设置,否则编译好后会出现一个HashTable的NPE错
  • HOTSPOT_BUILD_JOBS #并行编译的线程数,设置为和CPU内核数量一致即可
  • ALT_PARALLEL_COMPILE_JOBS #并行编译的线程数,设置为和CPU内核数量一致即可
  • SKIP_COMPARE_IMAGES  #比较本次build出来的映像与先前版本的差异。这对我们来说没有意义,必须设置为true,否则sanity检查会报缺少先前版本JDK的映像的错误提示。
  • USE_PRECOMPILED_HEADER #使用预编译头文件,不加这个编译会更慢一些
  • ALLOW_DOWNLOADS  #允许自行下载依赖
  • SKIP_DEBUG_BUILD  #要编译的版本
  • SKIP_FASTDEBUG_BUILD 要编译的版本
  • BUILD_LANGTOOLS # 是否编译语言工具
  • BUILD_HOTSPOT #编译虚拟机
  • BUILD_JDK 编译jdk
  • BUILD_DEPLOY #把它设置为false可以避开javaws和浏览器Java插件之类的部分的build
  • BUILD_INSTALL #把它设置为false就不会build出安装包。因为安装包里有些奇怪的依赖,但即便不build出它也已经能得到完整的JDK映像,所以还是别build它好了
  • unset JAVA_HOME  unset CLASSPATH  unset LD_LIBRARY_PATH #这三个环境变量必须去掉,不然会有很诡异的事情发生(我没有具体查过这些"诡异的#事情",Makefile脚本检查到有这2个变量就会提示警告)

设置完了后,保存,刷新一下。 source /etc/profile

四、检查

在/usr/local/src/openjdk下运行 make sanity。

如果最后一行显示:

Sanity check passed.

则表示检查通过。

五、编译jvm

在同上目录下,执行 make DISABLE_HOTSPOT_OS_VERSION_CHECK=ok

之所以加DISABLE_HOTSPOT_OS_VERSION_CHECK=ok,是因为遇到了下面的异常:

ERROR:××× recipe for target ‘check_os_version’ failed ×××

为了跳过版本校验,所以加了上述参数。

参考了:https://blog.csdn.net/desiyonan/article/details/80801830

好了,接下来静静等待,我最后那一次成功的编译,花了大概20-30分钟,成功了,会有如下显示(突然发现前面tree了一把,刷屏了,只能网上去找个图了。。。):

(别人家怎么那么快,10分钟。。。)

我这边还是贴一个我这边编译好的虚拟机的version显示吧:

如果你没那么幸运,发生了各种error,导致make中断的话,不要走开。参考下面一节。

六、遇到的问题

ps:如果看到提示某个文件报错,又不知道在哪,大家直接用find / -name abc.txt查找吧。

1、Error: time is more than 10 years from present: 1136059200000

通过修改CurrencyData.properties文件, 把10年之前的时间修改为10年之内即可
Index: /usr/openjdk/jdk/src/share/classes/java/util/CurrencyData.properties

注意,该文件内有5,6处要修改的地方。不要漏了,漏了又是10+分钟。。

2、 /usr/bin/ld: cannot find -lstdc++

Linking vm...
/usr/bin/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status
/usr/bin/chcon: cannot access ‘libjvm.so‘: No such file or directory
ERROR: Cannot chcon libjvm.so
/usr/bin/objcopy --only-keep-debug libjvm.so libjvm.debuginfo
/usr/bin/objcopy: ‘libjvm.so‘: No such file
make[4]: *** [libjvm.so] Error 1
make[4]: Leaving directory `/usr/src/openjdk/hotspot/build/hotspot_debug/linux_amd64_compiler2/debug‘
make[3]: *** [the_vm] Error 2
make[3]: Leaving directory `/usr/src/openjdk/hotspot/build/hotspot_debug/linux_amd64_compiler2/debug‘
make[2]: *** [debug] Error 2
make[2]: Leaving directory `/usr/src/openjdk/hotspot/build/hotspot_debug‘
make[1]: *** [generic_build2] Error 2
make[1]: Leaving directory `/usr/src/openjdk/hotspot/make‘
make: *** [debug] Error 2


解决:

yum search libc++ 
yum install libstdc++-static

3、不识别‘-mimpure-text‘参数

报错:gcc: error: unrecognized command line option ‘-mimpure-text‘

make[5]: *** [/openjdk/build/linux-amd64/../linux-amd64-debug/lib/amd64/libverify.so] Error 1

解决:

就在 openjdk源码中的,/make/common/shared/Compiler-gcc.gmk 中去掉 -mimpure-text 命令

4、constantPoolOop.cpp

Error:/openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp:272:39: error: converting ‘false‘ to pointer type ‘methodOop‘ [-Werror=conversion-null]

将return false 改为return NULL

5、__LEAF 头文件重复定义问题

/openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp:430:0: error: "__LEAF" redefined [-Werror]
 #define __LEAF(result_type, header)

/usr/include/x86_64-linux-gnu/sys/cdefs.h:42:0: note: this is the location of the previous definition
 #  define __LEAF , __leaf__

在interfaceSupport.hpp代码的最前面增加:(后面的\也是需要的,宏定义中的换行符)

#ifdef __LEAF
#undef __LEAF

#define __LEAF(result_type, header)                                  \
  TRACE_CALL(result_type, header)                                    \
  debug_only(NoHandleMark __hm;)                                     \
  /* begin of body */
#endif

6、/hotspot/src/share/vm/opto/loopnode.cpp:896:49: error: converting ‘fals‘ to pointer type ‘Node*‘ [-Werror=conversion-null]

解决:修改openjdk/hotspot/src/share/vm/opto/loopnode.cpp: 第896行 return false改为return (Node*)false; 或者 return NULL;

7、无法下载包问题 Redirection detected from https to http. Protocol switch unsafe, not allowed

解决:其实前面已经提到了,网盘里提供了jdk6-jaf-b20.zip、jdk6-jaxp-b20.zip、jdk6-jaxws-b20.zip三个文件即为了解决该问题。将这三个文件复制到openjdk/drop目录下。

同时要配置ALT_DROPS_DIR指向该目录。

七、总结

今天搞这个+写博客,差不多大半天了。。。

一千个人编译jdk,就会有一千个错误。。。

关键是等得又久,错了又得重来。。。不过再怎么说,还是很有成就感的。

看了书,就得实践,毕竟老祖宗说的:纸上得来终觉浅,绝知此事要躬行。

原文地址:https://www.cnblogs.com/grey-wolf/p/10327321.html

时间: 2024-10-19 07:49:56

编译你的第一个Java虚拟机--Centos 7 编译openJdk1.7源码的相关文章

CentOS 6.4 64位 源码编译hadoop 2.2.0

CentOS 6.4 64位 源码编译hadoop 2.2.0 搭建环境:Centos 6.4 64bit 1.安装JDK 参考这里2.安装mavenmaven官方下载地址,可以选择源码编码安装,这里就直接下载编译好的wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.zip解压文件后,同样在/etc/profie里配置环境变量vim /etc/profieexport

Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 概要  和学习ArrayList一样,接下来呢,我们先对LinkedList有个整体认识,然后再学习它的源码:最后再通过实例来学会使用LinkedList.内容包括:第1部分 LinkedList介绍第2部分 LinkedList数

Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解ArrayList.先对ArrayLis

Java 集合系列 06 Stack详细介绍(源码解析)和使用示例

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 Java 集合系列 05 Vector详细介绍(源码解析)和使用示例 Java 集合系列 06 Stack详细介绍(源码解析)和使用示例 第1部分 Stack介绍 Stack简介 Stack是栈.它的特性是:先进后出(FILO, F

Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 Java 集合系列 05 Vector详细介绍(源码解析)和使用示例 Java 集合系列 06 Stack详细介绍(源码解析)和使用示例 Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和

java中的==、equals()、hashCode()源码分析(转载)

在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. ==  java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: 1 public class ComAddr{ 2 public static void main(String[] args) throws Exception { 3 String s1 = "nihao"; 4 String s2 = "nihao"; 5 Str

Java新手练习项目、毕业设计项目源码下载

最近自己做了个技术博客网站,整理了一下学习java过程中做的例子和小项目,都放在了网站了提供下载,有新手入门的例子,也有java web例子,还有本人大学期间的毕业设计源码,都可以下载.地址:微儿博客-Java新手练习项目.毕业设计项目源码下载

java socket控制台版本聊天室程序源码下载

原文:java socket控制台版本聊天室程序源码下载 代码下载地址:http://www.zuidaima.com/share/1550463257578496.htm java socket控制台版本聊天室程序源码下载,学习的时候写的,适合学习java基础 java网络编程基础用 标签: java socket 控制台 聊天室 源码话题: 网络编程 java socket控制台版本聊天室程序源码下载,布布扣,bubuko.com

Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例

此页面为WP8"Surface Pro 3"应用的发布页面. "Surface Pro 3"是一款收集Surface Pro 3的玩机技巧的WP8程序,更好的帮助Surface用户理解并使用它. 此页面主要记录开发进度.APP发布等情况. -------------------相关进度--------------------- 目前进度:UI相关资源前期准备中,各相关开放平台的AppID申请中... Java 集合系列 09 HashMap详细介绍(源码解析)和使用