最近在研究Java底层的运行逻辑,为了更好的透彻理解Java底层的C/C++的设计思想和原理,就编译了一把OpenJdk,结果遭遇了可种各样的坑,折腾了近两天时间才编译成功,中间搜索了Baidu和Google都没有找到系统的解决方案,现在及时把中间遇到的坑和大家分享出来同时也给自己留一个记录。
ps:make、gcc和g++的版本不宜过高,否则会由于语法的变更导致各种各样的兼容性的编译错误。由于Ubuntu18.04系统上make默认最新的版本是4.1,gcc/g++默认的版本是7.1,文章最后会附加修改make、gcc和g++版本的修改操作。
1、编译环境概述:
- 操作系统版本:Ubuntu18.04 x64;
- Linux内核版本:5.0.0-36(可以通过 uname -a 查看);
- OpenJdk版本:OpenJdk8;
- BootJdk版本:1.7.0_75;
- make版本:3.81;
- gcc版本:4.8.5;
- g++版本:4.8.5;
2、源码下载和配置:
下载源码:大家可以直接去openjdk的官网下载,也可以使用 hg 命令直接克隆官方的源码文件到本地。
openjdk的官网的下载地址:http://jdk.java.net/java-se-ri/8,大家可以自行下载,也可以直接使用下面的链接下载:
https://download.java.net/openjdk/jdk8u40/ri/openjdk-8u40-src-b25-10_feb_2015.zip
-
2.1、配置BootJDK环境变量
通过阅读 README-builds.html ,我们知道要编译OpenJdk8需要使用OpenJdk7作为BootJDK,
openjdk7下载地址:https://jdk.java.net/java-se-ri/7;
也可以直接下载:https://download.java.net/openjdk/jdk7u75/ri/openjdk-7u75-b13-linux-x64-18_dec_2014.tar.gz;
-
2.2、配置环境变量
sudo vim ~/.bashrc
通过 java -version 命令查看确保修改成功
-
2.3、安装hg命令:
sudo apt-get install mercurial;
-
2.4、开始克隆:
hg clone http://hg.openjdk.java.net/jdk8/jdk8;
hg克隆的只是代码的基本信息,还需要使用 sh get_source.sh 命令来下载全部的代码文件,大概15分钟就能下载完成,hg克隆完成后的原始代码:
-
2.5、执行configure配置
bash ./configure --with-target-bits=64 --with-boot-jdk=/home/ycg/workspace/java/openjdk-7u75-b13-linux-x64-18_dec_2014/java-se-7u75-ri --with-debug-level=slowdebug --enable-debug-symbols ZIP_DEBUGINFO_FILES=0
执行成功后如下图所示:
首次执行可能会提示缺少一些包,大家只要 使用 sudo apt-get install xxx下载安装对应的包即可。
-
2.6、修改Linux内核版本兼容性
默认的Makefile文件支持Linux内核版本到3,所以大家需要根据自己系统的版本号添加对应的版本号即可:
修改 jdk8/hotspot/make/linux/Makefile
3、编译源码
sudo make all ZIP_DEBUGINFO_FILES=0 ALLOW_DOWNLOADS=true
如果没有编译器和源码间的兼容性问题,一般不会出现什么问题,编译中间出现的一些警告可以直接忽略,出现下图即表示编译成功
进入build/linux-x86_64-normal-server-slowdebug/jdk/bin查看编译好的java版本:
4、源码编译就已完成,下面介绍以下make和gcc/g++编译器版本的修改问题
4.1、make修改版本到3.81
到官网下载:https://ftp.gnu.org/gnu/make/
下载完成后解压到任意一个目录,进入源码目录执行 ./configure --prefix=/usr/local/make-3.81 在编译的时候如果出现 的时候出现如下错误提示glob/glob.c:xxx: undefined reference to `__alloca' 就需要修改 glob/glo.c 文件:
然后执行:make命令;
执行成功后:执行 sudo make install 完成安装;
删除系统上原来的make:sudo apt-get move make;
把新安装的make拷贝到 /usr/bin/目录下:sudo cp /usr/local/make-3.81/bin/make /usr/bin/make;
4.2、修改gcc/g++编译器版本
ls /usr/bin/gcc* -l //遍历系统中安装的所有版本的gcc编译器
ls /usr/bin/g++* -l //遍历系统中安装的额所有版本的g++编译器
sudo apt-get install gcc-4.8 //下载安装指定版本的gcc编译器
sudo apt-get install g++-4.8 //下载安装指定版本的g++编译器
sudo rm /usr/bin/gcc //删除原来的gcc的链接
sudo ln -s /usr/bin/gcc-4.8 /usr/bin/gcc //重新创建到gcc-4.8的链接
sudo rm /usr/bin/g++ //删除原来的g++编译器
sudo ln -s /usr/bin/g++-4.8 /usr/bin/g++ //重新创建到g++编译器的链接