mac 10.13.x编译openjdk8

由于 mac high sierra 系统有较大的变动,所以专门写一篇用mac high sierra 来编译 openjdk8 的博客.

准备阶段

  • mac 系统版本 10.13.3
  • 由于 openjdk 官方的源码不是用 git 管理的,源代码存放在 http://hg.openjdk.java.net/,首先需要安装版本管理工具mercurial, mac 上直接使用brew 进行安装即可.
brew install mercurial
  • 下载合适版本的源码,我用的编译版本是jdk8u-dev.
    克隆源代码
hg clone http://hg.openjdk.java.net/jdk8u/jdk8u-dev/

克隆完成后,使用脚本获取最新的源代码

cd jdk8u-dev
sh ./get_source.sh # 根据网络环境的不同,这一步花费的时间不同,一般花费时间较长

下载完成后的结构如下,已经包含了各个模块的代码

 ✘ ~/hg/jdk8u-dev ll
total 632
-rw-r--r--   1 xx  staff   1.5K Nov 11 18:02 ASSEMBLY_EXCEPTION
-rw-r--r--   1 xx  staff    19K Nov 11 18:02 LICENSE
-rw-r--r--   1 xx  staff   6.1K Nov 11 18:02 Makefile
-rw-r--r--   1 xx  staff   1.5K Nov 11 18:02 README
-rw-r--r--   1 xx  staff   126K Nov 11 18:02 README-builds.html
-rw-r--r--   1 xx  staff   142K Nov 11 18:02 THIRD_PARTY_README
drwxr-xr-x   5 xx  staff   160B Nov 11 21:55 build
drwxr-xr-x   6 xx  staff   192B Nov 11 18:02 common
-rw-r--r--   1 xx  staff   1.2K Nov 11 18:02 configure
drwxr-xr-x  12 xx  staff   384B Nov 11 18:02 corba
-rw-r--r--   1 xx  staff   3.0K Nov 11 18:02 get_source.sh
drwxr-xr-x  17 xx  staff   544B Nov 11 21:51 hotspot
drwxr-xr-x  16 xx  staff   512B Nov 11 18:03 jaxp
drwxr-xr-x  16 xx  staff   512B Nov 11 18:03 jaxws
drwxr-xr-x  13 xx  staff   416B Nov 11 18:14 jdk
drwxr-xr-x  13 xx  staff   416B Nov 11 18:04 langtools
drwxr-xr-x  12 xx  staff   384B Nov 11 18:02 make
drwxr-xr-x  20 xx  staff   640B Nov 11 18:07 nashorn
drwxr-xr-x   4 xx  staff   128B Nov 11 18:02 test
  • 当然,还需要准备一些必须的工具,比如安装最新版的 Xcode,有g++,gcc 的环境,安装 freetype, 使用命令brew install freetype进行安装
~/hg/jdk8u-dev gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 ~/hg/jdk8u-dev g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

编译阶段

  • 设置环境变量
# 设定语言选项,必须设置
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 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
  • 确保本地有现有的 java 环境,使用java -version 进行查看
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
  • 开始configure, 我这里用到的 configure 命令为如下,防止找不到 freetype的路径
bash ./configure  --with-freetype-include=/usr/local/include/freetype2 --with-freetype-lib=/usr/local/lib/

1.不出意外,接下来会有几个错误.Xcode版本不符合
错误:

...
checking flags for boot jdk java command ...
checking flags for boot jdk java command for big workloads...  -Xms64M -Xmx1600M -XX:ThreadStackSize=1536 -XX:PermSize=32m -XX:MaxPermSize=160m
checking flags for boot jdk java command for small workloads...  -XX:+UseSerialGC -Xms32M -Xmx512M
checking for jtreg... no
checking Determining if we need to set DEVELOPER_DIR... no
checking for xcodebuild... /usr/bin/xcodebuild
configure: error: Xcode 4 is required to build JDK 8, the version found was 9.2. Use --with-xcode-path to specify the location of Xcode 4 or make Xcode 4 active by using xcode-select.
configure exiting with result code 1

解决方法:
找到configure 文件并打开vim common/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

继续编译.
2,接下面马上又出现了另外一个错误, 找不到gcc 编译器,

...
checking for xcodebuild... /usr/bin/xcodebuild
checking Determining Xcode SDK path... /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk
checking for clang... /usr/local/opt/llvm@4/bin/clang
configure: Resolving CC (as /usr/local/opt/llvm@4/bin/clang) failed, using /usr/local/opt/llvm@4/bin/clang directly.
checking resolved symbolic links for CC... /usr/local/Cellar/llvm@4/4.0.1/bin/clang-4.0
checking if CC is disguised ccache... no, keeping CC
configure: The C compiler (located as /usr/local/Cellar/llvm@4/4.0.1/bin/clang-4.0) does not seem to be the required GCC compiler.
configure: The result from running with --version was: "clang version 4.0.1 (tags/RELEASE_401/final)"
configure: error: GCC compiler is required. Try setting --with-tools-dir.
configure exiting with result code 1

解决方案:
还是找到刚刚的文件common/autoconf/generated-configure.sh,有两处校验的地方,找到并且注释掉校验的逻辑.

 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

然后继续编译.

  • 配置成功.不出意外,应该就会配置成功,会出现如下信息;
====================================================
A new configuration has been successfully created in
/Users/lican/hg_bak/jdk8u-dev/build/macosx-x86_64-normal-server-release
using configure arguments '--with-freetype-include=/usr/local/include/freetype2 --with-freetype-lib=/usr/local/lib/'.

Configuration summary:
* Debug level:    release
* JDK variant:    normal
* JVM variants:   server
* OpenJDK target: OS: macosx, CPU architecture: x86, address length: 64

Tools summary:
* Boot JDK:       java version "1.7.0_80" Java(TM) SE Runtime Environment (build 1.7.0_80-b15) Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)  (at /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home)
* C Compiler:     clang version (tags/RELEASE_401/final) version 4.0.1 (at /usr/local/Cellar/llvm@4/4.0.1/bin/clang-4.0)
* C++ Compiler:    version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 (at /usr/bin/g++)

Build performance summary:
* Cores to use:   2
* Memory limit:   7883 MB
* ccache status:  not installed (consider installing)

WARNING: The result of this configuration has overridden an older
configuration. You *should* run 'make clean' to make sure you get a
proper build. Failure to do so might result in strange build problems
  • 开始make all, 真正开始编译
    接下来又会出现一堆错误
    1,指针和0比较错误
Compiling /Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/opto/library_call.cpp
/Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/opto/library_call.cpp:3829:20: warning: shifting a negative signed value is undefined [-Wshift-negative-value]
                   <<    Klass::_lh_array_tag_shift)
                   ^
/Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/opto/lcm.cpp:52:34: error: ordered comparison between pointer and zero ('address' (aka 'unsigned char *') and 'int')
  if (Universe::narrow_oop_base()>0) { // Implies UseCompressedOops.
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
1 error generated.
make[6]: *** [lcm.o] Error 1
make[6]: *** Waiting for unfinished jobs....
1 warning generated.
make[5]: *** [the_vm] Error 2
make[4]: *** [product] Error 2
make[3]: *** [generic_build2] Error 2
make[2]: *** [product] Error 2
make[1]: *** [/Users/lican/hg_bak/jdk8u-dev/build/macosx-x86_64-normal-server-release/hotspot/_hotspot.timestamp] Error 2
make: *** [hotspot-only] Error 2

解决方法:将比较的地方换为Universe::narrow_oop_base() != NULL, 保存后,继续编译
2,不久的将来,可能会出现类似的错误

Compiling /Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/services/virtualMemoryTracker.cpp
Compiling /Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/runtime/virtualspace.cpp
/Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/runtime/virtualspace.cpp:345:13: error: ordered comparison between pointer and zero ('char *' and 'int')
  if (base()>0) {
      ~~~~~~^~
1 error generated.
make[6]: *** [virtualspace.o] Error 1
make[6]: *** Waiting for unfinished jobs....
make[5]: *** [the_vm] Error 2
make[4]: *** [product] Error 2
make[3]: *** [generic_build2] Error 2
make[2]: *** [product] Error 2
make[1]: *** [/Users/lican/hg_bak/jdk8u-dev/build/macosx-x86_64-normal-server-release/hotspot/_hotspot.timestamp] Error 2
make: *** [hotspot-only] Error 2

解决方法和上面类似,替换为if (base()!=NULL),保存,重新 make all
3,接下来我这里又出现了invalid argument '-std=gnu++98' not allowed with 'C/ObjC' 的错误,仔细看错误,一脸懵,不知如何看起.

Compiling /Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/utilities/xmlstream.cpp
Compiling /Users/lican/hg_bak/jdk8u-dev/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp
Making signal interposition lib...
Making SA debugger back-end...
error: invalid argument '-std=gnu++98' not allowed with 'C/ObjC'
make[6]: *** [libsaproc.dylib] Error 1
make[6]: *** Waiting for unfinished jobs....
warning: (x86_64) /var/folders/s3/bzyrc_3d56gfl4w34ccx62_00000gn/T/jsig-d50157.o unable to open object file: No such file or directory
warning: no debug symbols in executable (-arch x86_64)
make[5]: *** [the_vm] Error 2
make[4]: *** [product] Error 2
make[3]: *** [generic_build2] Error 2
make[2]: *** [product] Error 2
make[1]: *** [/Users/lican/hg_bak/jdk8u-dev/build/macosx-x86_64-normal-server-release/hotspot/_hotspot.timestamp] Error 2
make: *** [hotspot-only] Error 2

解决方法:连蒙带猜,在最开始我们使用使用 configure 的文件中(common/autoconf/generated-configure.sh)找到了相关的配置

  case $COMPILER_NAME in
    gcc )
      COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS $COMMON_CCXXFLAGS_JDK -W -Wall -Wno-unused -Wno-parentheses \
      -pipe \
      -D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
      CXXSTD_CXXFLAG="-std=gnu++98"

解决方法:注释掉CXXSTD_CXXFLAG="-std=gnu++98"这一行,然后make clean,重新开始 configure, 即

bash ./configure  --with-freetype-include=/usr/local/include/freetype2 --with-freetype-lib=/usr/local/lib/
  • 哦了 其他错误暂时没有发现

编译完成

如果编译完成,会显示每一项编译的进度,所消耗的时间信息,大概需要10多分钟

----- Build times -------
Start 2018-03-01 15:28:52
End   2018-03-01 15:45:10
00:00:47 corba
00:01:10 demos
00:04:16 docs
00:00:29 hotspot
00:02:12 images
00:00:25 jaxp
00:00:38 jaxws
00:05:55 jdk
00:00:00 langtools
00:00:25 nashorn
00:16:18 TOTAL
-------------------------
Finished building OpenJDK for target 'all'

验证

cd build/macosx-x86_64-normal-server-release/jdk/bin && ./java -version

openjdk version "1.8.0-internal"
OpenJDK Runtime Environment (build 1.8.0-internal-lican_2018_03_01_15_28-b00)
OpenJDK 64-Bit Server VM (build 25.71-b00, mixed mode)

推荐阅读更多精彩内容