前言
写这篇文章的主要原因有以下三个:
话不多说,让我们开始计划建造它吧! ! !
规划工作第一步:软件规划
我这里是针对我自己的环境的,大家可以根据自己的环境来搭建,道理是一样的。
第二个环节:环境搭建IDEClion
首先你要安装一个Clion,因为HotSpot虚拟机是用C++编写的,
测试IDEClion是否可用
安装完Clion后刺客引擎源码编译,新建一个项目并进行测试,确保Clion工作正常。
我们点击创建后,发现报了下图所示的错误。 关键在于缺少xcrunat:/Library/Developer/CommandLineTools/usr/bin/xcrun这一行错误代码。 百度说缺少CommandLineTools工具,所以下载这个工具
安装命令行工具
进入苹果开发者网站:请点击这里进入,下载,下载后安装pkg文件
安装完成后,打开Clion,发现原来的错误变成灰色了,说明已经修复了
运行main函数后输出正常,说明Clion已经正确安装
下载openjdk源码
IDE准备好了,下一步就是规划openjdk源码,因为官网下载速度太慢,而且文件很可能不完整,所以直接找了一个社区维护的openjdk版本-jdk8u在互联网上
https://github.com/AdoptOpenJDK/openjdk-jdk8u
第三步:编译源码
下载最新的openjdk源码后,需要编译
规划编译工具
// 加速编译
brew install ccache
// 字体引擎,编译过程中会被依赖到
brew install freetype
brew install autoconf
// 分布式版本控制
brew install mercurial
配置BOOT_JDK非常重要,否则编译会报各种奇怪的问题。
编译之前需要配置一个叫BOOT_JDK的东西,它的版本比编译的版本低一级,即编译OpenJDK8需要安装JDK7,环境OpenJDK7或者OracleJDK7都可以
安装compiledb非常重要。 花了将近三天的时间才把头文件解决了。 最后我发现只要安装这个东西就可以了。 我吐血了。
虽然这一步的原因是为了解决编译openjdk源码时很多头文件找不到的问题。
安装要求:需要python3+,brewinstallpython3
之后,您需要安装 pip。 安装命令为:curlbootstrap.pypa.io/get-pip.py|python3
最后通过pip安装compiledb。 命令是:pipinstallcompiledb
配置环境变量
vi ~/.bash_profile
在 .bash_profile 文件顶部插入以下配置信息:
# 设定语言选项,必须设置
export LANG=C
# Mac平台,C编译器不再是GCC,而是clang
export CC=clang
export CXX=clang++
export CXXFLAGS=-stdlib=libc++
# 是否使用clang,如果使用的是GCC编译,该选项应该设置为false
export USE_CLANG=true
# 跳过clang的一些严格的语法检查,不然会将N多的警告作为Error
export COMPILER_WARNINGS_FATAL=false
# 链接时使用的参数
export LFLAGS='-Xlinker -lstdc++'
# 使用64位数据模型
export LP64=1
# 告诉编译平台是64位,不然会按照32位来编译
export ARCH_DATA_MODEL=64
# 允许自动下载依赖
export ALLOW_DOWNLOADS=true
# 并行编译的线程数,编译时长,为了不影响其他工作,可以选择2
export HOTSPOT_BUILD_JOBS=4
export PARALLEL_COMPILE_JOBS=2 #ALT_PARALLEL_COMPILE_JOBS=2
# 是否跳过与先前版本的比较
export SKIP_COMPARE_IMAGES=true
# 是否使用预编译头文件,加快编译速度
export USE_PRECOMPILED_HEADER=true
# 是否使用增量编译
export INCREMENTAL_BUILD=true
# 编译内容
export BUILD_LANGTOOL=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_BULID=false
export DEBUG_NAME=debug
# 避开javaws和浏览器Java插件之类部分的build
export BUILD_DEPLOY=false
export BUILD_INSTALL=false
# 最后需要干掉这两个环境变量(如果你配置过),不然会发生诡异的事件
unset JAVA_HOME
unset CLASSPATH
使环境变量生效:
source ~/.bash_profile
执行轮廓校准命令
进入下载的openjdk目录,执行配置文件校准命令。 注意:一定要切换到BOOT_JDK版本执行。
sh configure --with-freetype-include=/usr/local/include/freetype2 --with-freetype-lib=/usr/local/lib/ --disable-zip-debug-info --disable-debug-symbols --with-debug-level=slowdebug --with-target-bits=64 --with-jvm-variants=server
执行配置文件错误案例然后报右图错误,意思是无法测量Xcode的版本
解决方案:前往苹果开发者网站:请点击此处下载mac系统版本对应的Xcode。 下载Xcode自序列后,必须执行以下命令,否则仍然会报上图的错误
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
Xcode4isrequirestobuildJDK8错误
解决办法:找到configure文件,打开vimcommon/autoconf/ generated-configure.sh,找到确定版本的地方,把这一段全部注释掉。
#Fail-fast: verify we're building on Xcode 4, we cannot build with Xcode 5 or later
XCODE_VERSION=`$XCODEBUILD -version | grep '^Xcode ' | sed 's/Xcode //'`XC_VERSION_PARTS=( ${XCODE_VERSION//./ } )
if test ! "${XC_VERSION_PARTS[0]}" = "4"; then
as_fn_error $? "Xcode 4 is required to build JDK 8, the version found was $XCODE_VERSION. Use --with-xcode-path to specify the location of Xcode 4 or make Xcode 4 active by using xcode-select." "$LINENO" 5
fi
#
Agcc编译器是必填问题
解决办法:找到下面的校准代码,将其注释掉。 请注意,有两个地方的代码是相同的。 根据右边的标志找到它。
if test $? -ne 0; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required GCC compiler." >&5
$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required GCC compiler." >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: "$COMPILER_VERSION_TEST"" >&5
$as_echo "$as_me: The result from running with --version was: "$COMPILER_VERSION_TEST"" >&6;}
as_fn_error $? "GCC compiler is required. Try setting --with-tools-dir." "$LINENO" 5
fi
出现右图,证明校准完成。 注意:确认BootJDK的版本
开始编译 每次编译都需要花费大量的时间,所以建议在编译之前更正文中的所有错误
执行compiledbmakeWARNINGS_ARE_ERRORS=""CONF=macosx-x86_64-normal-server-slowdebugall命令进行编译
如果出现问题,请务必按照以下步骤重新编译:
generateddbmakeCONF=macosx-x86_64-normal-server-slowdebugcleancompileddbmakeWARNINGS_ARE_ERRORS=""CONF=macosx-x86_64-normal-server-slowdebugall
compiledb make WARNINGS_ARE_ERRORS="" CONF=macosx-x86_64-normal-server-slowdebug all
编译错误案例 fatalerror: 'iostream'filenotfound 问题:解决方案:设置环境变量
NEW_INCLUDE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
export CFLAGS=-I$NEW_INCLUDE
export CXXFLAGS=-I$NEW_INCLUDE
找不到库 for-lstdc++ 问题: 解决方案:按照以下步骤操作。
NEW_LIB=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib
export LDFLAGS="-L${NEW_LIB}"
export LIBRARY_PATH=$NEW_LIB:$LIBRARY_PATH
symbol(s) notfoundforarchitecturex86_64 问题:解决方案:找到文件 jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m,然后将 inlinevoidattachCurrentThread(void**env) 更改为 staticinlinevoidattachCurrentThread(void**env)
Undefined symbols for architecture x86_64:
"_attachCurrentThread", referenced from:
+[ThreadUtilities getJNIEnv] in ThreadUtilities.o
+[ThreadUtilities getJNIEnvUncached] in ThreadUtilities.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
clang:error:unknownargument:'-fpch-deps'问题,解决方案:编辑hotspot/make/bsd/makefiles/gcc.make注释掉以下代码
ifeq ($(USE_CLANG),)
ifneq ($(CC_VER_MAJOR), 2)
DEPFLAGS += -fpch-deps
endif
endif
错误:invalidargument'-std=gnu++98'notallowedwith'C'问题,解决方案:编辑common/autoconf/ generated-configure.sh,搜索字符串-std=gnu++98并注释
解决slowdebug模式下编译然后崩溃的问题:slowdebug模式下编译后,执行java-version会出现JVM crash的错误。 找到文件 hotspot/src/share/vm/runtime/perfMemory.cpp 文件。 注释掉以下内容:
Implicitdeclarationoffunction'VerifyFixClassname'isinvalidinC99问题:解决方案:包含头文件或直接在外部声明。 最好包含头文件。 如果找不到刺客引擎源码编译,则直接声明。
extern jboolean VerifyFixClassname(char* name);
extern jboolean VerifyClassname(char* name, jboolean allowArrayClass);
Implicitdeclarationoffunction'pthread_main_np'isinvalidinC99问题:和以前一样,最好包含头文件。 如果找不到,则直接声明。
extern jboolean pthread_main_np();
隐式声明libraryfunction'strchr'withtype'char*(constchar*,int)'的问题:和以前一样,最好包含头文件。 如果找不到,则直接声明。
#include
#include
C99中implicitdeclarationoffunction'time'isinvalidin的问题:和以前一样,最好包含头文件。 如果找不到,则直接声明。
#include
C99中implicitdeclarationoffunction'JVM_ActiveProcessorCount'isinvalidin的问题:直接改成jintncpus=4;
jint ncpus = 4;
第四步:导出源码到Clion并配置
如果出现如右图所示界面,则说明编译成功。 编译后最后可能会出现大量NosuchfileorDirectory警告。不要怕这个。 下一步是将编译后的源代码导出到 Clion。
因为compiledb包是用来编译OpenJDK源码的。 所以编译完成后,我们可以在源码根目录下看到多了一个compile_commands.json文件。 我们的项目导出就依赖这个json文件。
打开Clion,然后点击Open打开上面的compile_commands.json文件,在弹出的对话框中选择OpenasProject。
等待导出成功后,进入Clion的preferences->Build, Execution, Deployment->CustomBuildTargets,在配置页面点击AddTarget,配置自定义的BuildTargets。
自己输入名称并为工具链选择默认。
新建一个Tool,一个是make_jdk8,另一个是clean_jdk8,(可以自行选择)
make_jdk8:填写参数:CONF=macosx-x86_64-normal-server-slowdebug,并将源代码的根目录添加到工作目录中。
clean_jdk8:填写参数:CONF=macosx-x86_64-normal-server-slowdebugclean,并将源代码的根目录添加到工作目录中。
然后完成ClutomBuildTargets的具体配置,具体配置如下:
然后点击Clion主页上的AddConfiguration添加Run/DebugConfigurations。
第五步:开始调试
一切配置完成后,我们就可以开始调试代码了。 首先在jni.cpp的create_vm中添加断点。
至此,debug调试就搭建完成了,HotSpot源码阅读环境搭建完毕。 我希望你们都成功! ! !
唠叨
最后,如果您对文章感到困扰,请尽快留言。 如果各位读者觉得我有话要说,请点赞关注❤️请分享,对我真的很有用! ! ! 如果你想获取大量的Java资源和有用的idea插件、简历模板、设计模式、多线程、架构、编程风格、中间件……,可以关注Momo公众号Java百科。 最后,谢谢你。 感谢您的支持! ! !