您的位置:首页 > 编程语言 > Java开发

OpenJDK:构建JDK

2014-02-27 21:39 148 查看
编者注:在这一期的 开源之路 中,作者和 Cafe Au Lait 的创始人 Elliotte Rusty Harold 接管了目前的 Java SE 7 开发系列文章。因为 OpenJDK 项目 的目标和流程已经在 第一期 介绍过,所以 Elliotte 将在此教程中直接介绍 JDK 7 的实际构建。

在此之前, 如果 OpenJDK 项目有更新,我们会将其发布在每期“开源之路”的开始部分。最新的 发行版 是 b23,发行日期是 10 月 30 日。此发行版解决了一小部分缺陷和功能要求,这些内容可详见其 发行说明,其中许多都与管理问题相关,比如顶层 README 文件、空格清理和遗留 "j2se" 引用的移除。上一个版本 b22 解决的问题比较多,集成了 65 个缺陷修复和 14 个功能,其中包括 将 CORBA、JAXP 和 JAXWS 分割到各自的工作区中,将 Swing ThreadPool 创建 替换为
java.util.concurrent 功能,支持各种时间区更改,以及 OpenJDK RenderingEngine 插件的创建,这意味着“为 Open JDK 提供了替代 Ductus 库的起点。”

但如何达到所有这些新目标呢?这正是 Elliotte 将在在本文中阐述的内容,他将介绍如何从源码构建 JDK。

由于 Sun 的 Java 开发工具包是自由软件(只需在替换的过程中对一些小组件建模),因此我们不妨对经进行一些修改。无论您的激情在于优化、实验、语言设计、调试还是文档,都有大量的工作需要您来做,都有大量的机会提供给各种技能水平的开发人员。在本系列的后续文章中,我将详述 Java 7 或更高版本中可能出现的各种 API 开发。但是,要玩转这些 API,您将需要浴血奋战,所以立即甩掉您的急救箱,撕掉止血带,准备流一些血吧!我们要开始构建 JDK 了。

系统需求

首先,构建 JDK 需要一个受支持的操作系统。这包括 Linux、Solaris、Windows XP 和 Windows Vista。不支持 Mac OS X。Apple 负责将 JDK 迁移至 Mac 中,然而,这往往滞后于潮流。但是,Mac 用户可以使用 Parallels、VMWare Fusion 或 Boot Camp 来运行 Windows 或 Linux,并在其中构建 JDK。的确,我撰写此文时用的就是这种方法,当时我电脑中的以太网卡在项目完成前两天意外死亡了。然而,在 Apple 发布最新的
JDK 之前,我们仍然无法在 Mac OS 中运行 Java 7(或 6)应用程序。这可能发生在明天,可能发生在明年,也可能永远都不会发生。

其次,我们需要一个最新的 Java 6 SDK。Java 7 不能通过 Java 5 来编译。就我个人来说,我在设计软件时不喜欢太多的版本依赖,这对于开源软件尤其重要。但是,JDK 只是在最近才开放源码,而且显示了公司 IT 的一些遗留态度:“我们可以控制每个人的构建环境”。移除其中的一些依赖是一项正在进行的并将花费数年的任务,但是,这个过程已经取得了初步进展。就在最近,Sun 将其源码库从专用 Teamware 转移到了开源的 Mercurial 中。从封闭开发模式切换到开放开发模式是一项艰巨的任务,但最终结果是更强大、更灵活、更健壮的代码库。

第三,我们需要一个 C 编译器。其中一些 JDK 是用原生代码编写的。它们不可能都是纯 Java 编写的。对于 Linux,我们需要使用 gcc4。结于 Windows,需要使用 Microsoft Visual Studio .NET。对于 Solaris,需要使用 Sun Studio 11。

在 Linux 中,可能还需要安装或更新一些库。具体要安装哪些库,取决于您的发行版和版本。您可能还需要为现有库安装一组 C 头文件。在本文中,我使用现有的 Ubuntu 7.10 Gutsy Gibbon 发行版。大多数其他合理流通的发行版应该也能工作。如果您发现有一些发行版无法工作,不妨找出其原因并记录缺陷。

最后,在 Windows 中,您可以在 NTFS 文件系统上进行构建。您不能在 FAT-32 上构建 JDK。您还需要安装 Cygwin,因为在 Windows 上构建的 JDK 是 Windows 和 Unix 实用工具的奇异混合物。

获取源码

大约每隔一个月,Sun 会在 OpenJDK 源码发布页面 上发布一组完整的 JDK 源码。下面列出了几种不同的包:

OpenJDK 源码 JDK 7 大约 95% 的主要源码。 平台的二进制插件 Sun 实际并不拥有 JDK 中的所有代码,并且他们无法重新注册他们不拥有的代码。相反,一些代码段必须以闭源二进制软件包来提供。您将需要为您的平台下载其中一些代码。Linux、Solaris 和 Windows 在 32 位和 64 位版本中都受支持 。 Jtreg 测试工具二进制软件包下载 代码的测试框架。您不必真正使用测试框架来构建或修改代码,但是不论如何您都应该掌握它。 OpenJDK 模块项目 这包括 Java 7 的新模块系统。(我将在本系列的后续文章中介绍。)
最终,此项目将汇总到 JDK 中,但现在您并不立即需要它。

因为这些项目所占空间在 120MB 以上,下载服务器的速度可能不是一直都特别快,所以要想全部下载可能需要一段时间。开源的一个好处就是不用单击通过令人讨厌的使用许可。从普通的 URL 中可以下载任何开源软件。这使得 curl、wget 等类似工具的使用更加容易。设置批处理作业来获取这些工具,然后您就可以悠闲地喝一杯咖啡。事实上,无点击还使正常浏览器的使用更加容易。点击通过注册的方式应该可以废除了。点击通过注册只是使律师更加忙碌,除了律师谁还需要这些东西?

jars@jars-desktop:~/openjdk$ wget

  http://www.java.net/download/openjdk/jdk7/promoted/b23/openjdk-7-ea-src-b23-30_oct_2007.zip

--18:02:02-- 
http://www.java.net/download/openjdk/jdk7/promoted/b23/openjdk-7-ea-src-b23-30_oct_2007.zip

      => `openjdk-7-ea-src-b23-30_oct_2007.zip'

Resolving www.java.net... 64.125.132.37, 64.125.132.39

Connecting to www.java.net|64.125.132.37|:80... connected.

HTTP request sent, awaiting response... 301 Moved Permanently

Location:

  http://download.java.net/openjdk/jdk7/promoted/b23/openjdk-7-ea-src-b23-30_oct_2007.zip

[following]

--18:02:02--

  http://download.java.net/openjdk/jdk7/promoted/b23/openjdk-7-ea-src-b23-30_oct_2007.zip

      => `openjdk-7-ea-src-b23-30_oct_2007.zip'

Resolving download.java.net... 72.5.124.114

Connecting to download.java.net|72.5.124.114|:80... connected.

HTTP request sent, awaiting response... 200 OK

Length: 84,617,174 (81M) [application/zip]

44% [===============>       ] 37,717,212  55.36K/s  ETA 12:19


现在,我们只需要前两个条件:OpenJDK 源码和二进制插件。但是,将来您可能还需要其他两个条件。

Mercurial

Sun 尚未完全开放 JDK 源码控制库。然而,这随时都可能发生。他们正在使用的系统是 Sun 专用产品,名为 Teamware。他们正在转换到开源的 Mercurial(不是子版本或 CVS)。转换完成之后,您就能够使用绝对最新的商业版本。

忽略 OpenJDK 站点上对子版本的所有引用。这些仅是 java.net 项目模板的标准部分。Sun 实际并未使用 java.net 库或子版本来管理 OpenJDK。子版本中实际上只有 openjdk.java.net 网站的 HTML 代码。真正的 JDK 源码并不在子版本中。

下载快照版本会为您提供可能不会构建的代码(虽然有一些快照已经完全破坏)。然而,代码也可能过时一个多月或更久了。检查 Mercurial 中的代码会得到绝对最新的代码。然而,这些代码可能完全破坏了,您无法确定如果构建失败到底是您的错误还是代码的错误。完成库的开发之后,我建议您首先从已知的好快照开始构建,来解开整个过程的所有疙瘩,然后在您确信自己的设置之后,前进到版本控制中最新的部分。

编译

现在,下载以下软件包,并解压它们:

$ unzip openjdk-7-ea-src-b23-30_oct_2007.zip

  inflating: openjdk/control/make/Makefile 

  inflating: openjdk/control/make/README 

  inflating: openjdk/control/make/jprt.config 

  inflating: openjdk/control/make/jprt.properties 

  inflating: openjdk/control/make/make/Defs-internal.gmk 

  inflating: openjdk/control/make/make/README.pre-components 

  ...


然后,将二进制插件 JAR 文件移动到一个方便的目录中。在 Linux 中,默认目录是 /opt/java/openjdk-binary-plugs。在 Solaris 中,默认目录是 /usr/jdk/instances/openjdk-binary-plugs。在 Solaris 中,默认目录是 C:\openjdk-binary-plugs. 可以将 JAR 置于您喜欢的其他位置,但是在构建之前,必须设置 ALT_BINARY_PLUGS_PATH 环境变量指向此位置。

将仅用于构建的二进制插件分布到太多位置是一种愚蠢的做法。由于这是一个开源项目,任何人都能修复问题,所以将此作为我们的第一个 TODO:

TODO:重写构建文件,以便它首先查找其他源码所在的标准 openjdk/binary-plugs 目录。

事实上,二进制插件真正并没有多大,因此只将其全部分布在第一个位置的源码包中可能很明智。

解压后的 openjdk 目录包含一些 readme 文件和各个子项目的目录,其中包括 jdk、hotspot、langtools、jaxws 和 jaxp。这些目录应该能够单独构建 ,但是我曾这样做,却没有成功。

生成 Make 文件

要构建 JDK,需要制作 jdk_generic_profile.sh 可执行脚本并运行它。在顶层 openjdk 目录中,键入:

$ chmod +x ./jdk/make/jdk_generic_profile.sh

$ ./jdk/make/jdk_generic_profile.sh


多半可能,这将失败。第一次我这样做,得到如下消息:

WARNING: Cannot access ALT_BOOTDIR=/opt/java/jdk1.6.0

WARNING: Missing ALT_BINARY_PLUGS_PATH: /opt/java/openjdk-binary-plugs


我已经安装了这些软件,但是 makefile 没有在预期的正确位置找到它们。ALT_BINARY_PLUGS_PATH 和 ALT_BOOTDIR 环境变量需要分别设置为 JDK 的安装位置和二进制插件目录。所以我这样做了:

$ export ALT_BOOTDIR=/usr/local/java;

$ export ALT_BINARY_PLUGS_PATH=~/plugs


然后,jdk_generic_profile 脚本运行并创建 makefile。

完整性检查

在下一个源码库中,可能有顶层 makefile, 但是如果使用 b23,则需要更改为 control/make 目录。然后,在您的构建环境中使用 make sanity 进行完整性检查:

$ cd control/make

$ make sanity


这将警告您一些忘记安装的软件和忘记设置的环境变量。下面是我的第一次完整性检查的结果:

$ make sanity

/bin/sh: /usr/bin/gawk: not found

/bin/sh: /usr/bin/gawk: not found

/bin/sh: /NOT-SET/devtools/share/ant/latest/bin/ant: not found

/bin/sh: /NOT-SET/devtools/share/findbugs/latest/bin/findbugs: not found

../make/common/shared/Sanity-Settings.gmk:121: WARNING: ANT_VER should not be empty [Sanity-Settings.gmk]

../make/common/shared/Sanity-Settings.gmk:122: WARNING: FINDBUGS_VER should not be empty [Sanity-Settings.gmk]

../make/common/shared/Sanity-Settings.gmk:191: WARNING: TEMP_FREE_SPACE should not be empty [Sanity-Settings.gmk]

../make/common/shared/Sanity-Settings.gmk:192: WARNING: FREE_SPACE should not be empty [Sanity-Settings.gmk]

../build/linux-i586/tmp/alsaversioncheck.c:1:28: error: alsa/asoundlib.h: No such file or directory

../build/linux-i586/tmp/alsaversioncheck.c: In function 'main':

../build/linux-i586/tmp/alsaversioncheck.c:3: warning: incompatible implicit declaration of built-in function 'printf'

../build/linux-i586/tmp/alsaversioncheck.c:3: error: 'SND_LIB_VERSION_STR' undeclared (first use in this function)

../build/linux-i586/tmp/alsaversioncheck.c:3: error: (Each undeclared identifier is reported only once

../build/linux-i586/tmp/alsaversioncheck.c:3: error: for each function it appears in.)

make: *** [../build/linux-i586/tmp/alsaversioncheck] Error 1


我缺少了 gawk、ant、findbugs 和 ALSA。继续安装缺少的内容并重试。安装完这些代码段(使用 Synaptic)之后,构建仍然没有找到 Ant,虽然 Ant 就在我的路径中:

$ make sanity

/bin/sh: /NOT-SET/devtools/share/ant/latest/bin/ant: not found

/bin/sh: /NOT-SET/devtools/share/findbugs/latest/bin/findbugs: not found

../make/common/shared/Sanity-Settings.gmk:121: WARNING: ANT_VER should not be empty [Sanity-Settings.gmk]

...

$ /usr/bin/ant -v

Apache Ant version 1.7.0 compiled on August 29 2007

Buildfile: build.xml does not exist!

Build failed


我断定如果尝试设置 ANT_VER 将会行得通,但我已经对 Ant 做了足够的工作,我猜想 ANT_HOME 可能是 make 脚本真正需要的。我试着设置 ANT_HOME 并再次运行完整性检查:

$ export ANT_HOME=/usr/share/ant

$ make sanity

/bin/sh: /NOT-SET/devtools/share/findbugs/latest/bin/findbugs: not found

../make/common/shared/Sanity-Settings.gmk:122: WARNING: FINDBUGS_VER should not be empty [Sanity-Settings.gmk]

...


系统不再抱怨 Ant,但仍想运行 FindBugs。就个人而言,尽管我非常喜欢 FindBugs,但我发现代码库构建是否需要它是可质疑的。当前,我们应该试着移除依赖,而不是引入依赖。尽管如此,构建脚本需要它,因此我必须安装。FindBugs 在 Synaptic 中不可用,因此我不得不手动安装它。系统发出错误消息,抱怨:

../make/common/shared/Sanity-Settings.gmk:122: WARNING: FINDBUGS_VER should not be empty [Sanity-Settings.gmk]


因此,我将 FINDBUGS_VER 设置为 1.3.0。

$ export FINDBUGS_VER=1.3.0


这没有起作用,因此我花了十五分钟浏览构建文件,并尝试使用不同的值,直到我无意中发现了 FINDBUGS_HOME。将此环境变量设置为 FindBugs 的位置修复了这个问题。

$ export FINDBUGS_HOME=/opt/java/findbugs-1.3.0


TODO:如果问题是缺少 FINDBUGS_HOME 或 ANT_HOME 环境变量,则将得到上述错误消息,而非“FINDBUGS_VER/ANT_VER 为空”。较好的方法是完全移除对 FindBugs 的依赖。

下一个问题似乎是 Freetype。我又返回到 Synaptic 来安装它。结果是,尽管默认情况下已经在 Ubuntu 中安装了 Freetype,但开发的库和头文件还没安装。因此我需要去安装 libfreetype6-dev 软件包。这将成为其余安装的公共课。如果您使用 Ubuntu 开发者配置而非基本桌面配置来开始,可能会碰到一点小麻烦。

无论如何,现在我们总算有些进展了。我承认,我还不能随心所欲:

$ make sanity

make[1]: Entering directory `/home/jars/openjdk/jdk/make/tools/freetypecheck'

make[1]: Nothing to be done for `all'.

make[1]: Leaving directory `/home/jars/openjdk/jdk/make/tools/freetypecheck'

Bootstrap Settings:

  BOOTDIR = /usr/local/java

   ALT_BOOTDIR = /usr/local/java

  BOOT_VER = 1.6 [requires at least 1.5]

  OUTPUTDIR = ./../build/linux-i586

   ALT_OUTPUTDIR =

  ABS_OUTPUTDIR = /home/jars/openjdk/jdk/build/linux-i586

Build Tool Settings:

  SLASH_JAVA = /NOT-SET

   ALT_SLASH_JAVA =

  VARIANT = OPT

  JDK_DEVTOOLS_DIR = /NOT-SET/devtools

   ALT_JDK_DEVTOOLS_DIR =

  ANT_HOME = /usr/share/ant

  FINDBUGS_HOME = /home/jars/findbugs-1.3.0

  UNIXCOMMAND_PATH = /bin/

   ALT_UNIXCOMMAND_PATH =

  COMPILER_PATH = /usr/bin/

   ALT_COMPILER_PATH =

  DEVTOOLS_PATH = /usr/bin/

   ALT_DEVTOOLS_PATH =

  UNIXCCS_PATH = /usr/ccs/bin/

   ALT_UNIXCCS_PATH =

  USRBIN_PATH = /usr/bin/

   ALT_USRBIN_PATH =

  COMPILER_NAME = GCC

  COMPILER_VERSION =

  CC_VER = 4.1 [requires at least 3.2]

  ZIP_VER = 2.32 [requires at least 2.2]

  UNZIP_VER = 5.52 [requires at least 5.12]

  ANT_VER = 1.7 [requires at least 1.6.3]

  FINDBUGS_VER = 1.3 [requires at least 1.1]

  TEMPDIR = ./../build/linux-i586/tmp

Build Directives:

  OPENJDK = true

  USE_HOTSPOT_INTERPRETER_MODE =

  PEDANTIC =

  DEV_ONLY =

  NO_DOCS =

  NO_IMAGES =

  TOOLS_ONLY =

  INSANE =

  COMPILE_APPROACH = parallel

  PARALLEL_COMPILE_JOBS = 2

   ALT_PARALLEL_COMPILE_JOBS =

  FASTDEBUG =

  COMPILER_WARNINGS_FATAL = false

  COMPILER_WARNING_LEVEL =

  INCREMENTAL_BUILD = false

  CC_HIGHEST_OPT = -O3

  CC_HIGHER_OPT = -O3

  CC_LOWER_OPT = -O2

  CXXFLAGS = -O2 -fPIC -DCC_NOEX -W -Wall -Wno-unused

  -Wno-parentheses -fno-omit-frame-pointer -D_LITTLE_ENDIAN

  CFLAGS = -O2  -fno-strict-aliasing -fPIC -W -Wall 

  -Wno-unused -Wno-parentheses -fno-omit-frame-pointer -D_LITTLE_ENDIAN

  BOOT_JAVA_CMD = /usr/local/java/bin/java -client -Xmx375m -Xms128m

  -XX:PermSize=32m -XX:MaxPermSize=160m

  BOOT_JAVAC_CMD = /usr/local/java/bin/javac 

  -J-XX:ThreadStackSize=768 -J-client -J-Xmx375m -J-Xms128m

  -J-XX:PermSize=32m -J-XX:MaxPermSize=160m -encoding ascii

  BOOT_JAR_CMD = /usr/local/java/bin/jar

  BOOT_JARSIGNER_CMD = /usr/local/java/bin/jarsigner

  JAVAC_CMD = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/bin/javac

  -J-XX:ThreadStackSize=768 -J-client -J-Xmx375m -J-Xms128m

  -J-XX:PermSize=32m -J-XX:MaxPermSize=160m -source 1.5 -target 5

  -encoding ascii -Xbootclasspath:./../build/linux-i586/classes

  JAVAH_CMD = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/bin/javah

  -bootclasspath ./../build/linux-i586/classes

  JAVADOC_CMD = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/bin/javadoc

  -J-client -J-Xmx375m -J-Xms128m -J-XX:PermSize=32m -J-XX:MaxPermSize=160m

Build Platform Settings:

  USER = jars

  PLATFORM = linux

  ARCH = i586

  LIBARCH = i386

  ARCH_FAMILY = i586

  ARCH_DATA_MODEL = 32

  ARCHPROP = i386

  LINUX_VERSION = Unknown linux

  ALSA_VERSION = 1.0.14a

  OS_VERSION = 2.6.22-14-generic [requires at least 2.4.9-e.3]

  OS_NAME = linux

  TEMP_FREE_SPACE = 7515236

  FREE_SPACE = 7515236

  MB_OF_MEMORY = 503

GNU Make Settings:

  MAKE = make

  MAKE_VER = 3.81 [requires at least 3.78]

  MAKECMDGOALS = sanity

  MAKEFLAGS =

  SHELL = /bin/sh

Target Build Versions:

  JDK_VERSION = 1.7.0

  MILESTONE = internal

  RELEASE = 1.7.0-internal

  FULL_VERSION = 1.7.0-internal-jars_17_nov_2007_21_32-b00

  BUILD_NUMBER = b00

External File/Binary Locations:

  USRJDKINSTANCES_PATH = /opt/java

  BUILD_JDK_IMPORT_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries

   ALT_BUILD_JDK_IMPORT_PATH =

  JDK_IMPORT_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586

   ALT_JDK_IMPORT_PATH =

  LANGTOOLS_DIST =

   ALT_LANGTOOLS_DIST =

  CORBA_DIST =

   ALT_CORBA_DIST =

  JAXP_DIST =

   ALT_JAXP_DIST =

  JAXWS_DIST =

   ALT_JAXWS_DIST =

  HOTSPOT_DOCS_IMPORT_PATH = /NO_DOCS_DIR

   ALT_HOTSPOT_DOCS_IMPORT_PATH =

  HOTSPOT_IMPORT_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586

   ALT_HOTSPOT_IMPORT_PATH =

  HOTSPOT_CLIENT_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/jre/lib/i386/client

   ALT_HOTSPOT_CLIENT_PATH =

  HOTSPOT_SERVER_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/jre/lib/i386/server

   ALT_HOTSPOT_SERVER_PATH =

  CACERTS_FILE = ./../src/share/lib/security/cacerts

   ALT_CACERTS_FILE =

  CUPS_HEADERS_PATH = /usr/include

   ALT_CUPS_HEADERS_PATH =

OpenJDK-specific settings:

  FREETYPE_HEADERS_PATH = /usr/include

   ALT_FREETYPE_HEADERS_PATH =

  FREETYPE_LIB_PATH = /usr/lib

   ALT_FREETYPE_LIB_PATH =

OPENJDK Import Binary Plug Settings:

  BINARY_PLUGS_JARFILE = /home/jars/plugs/jre/lib/rt-closed.jar

   ALT_BINARY_PLUGS_JARFILE =

  BINARY_PLUGS_PATH = /home/jars/plugs

   ALT_BINARY_PLUGS_PATH = /home/jars/plugs

  BUILD_BINARY_PLUGS_PATH = /NOT-SET/re/jdk/1.7.0/promoted/latest/openjdk/binaryplugs

   ALT_BUILD_BINARY_PLUGS_PATH =

  PLUG_LIBRARY_NAMES =

Previous JDK Settings:

  PREVIOUS_RELEASE_PATH = /NOT-SET/re/jdk/1.6.0/archive/fcs/bundles/linux-i586

   ALT_PREVIOUS_RELEASE_PATH =

  PREVIOUS_JDK_VERSION = 1.6.0

   ALT_PREVIOUS_JDK_VERSION =

  PREVIOUS_JDK_FILE = jdk-6-linux-i586.tar.gz

   ALT_PREVIOUS_JDK_FILE =

  PREVIOUS_JRE_FILE = jre-6-linux-i586.tar.gz

   ALT_PREVIOUS_JRE_FILE =

  PREVIOUS_RELEASE_IMAGE =

   ALT_PREVIOUS_RELEASE_IMAGE =

WARNING: This machine appears to only have 503Mb of physical memory,

     builds on this machine could be slow.

WARNING: LANG has been set to en_US.UTF-8, this can cause build failures.

     Try setting LANG to "C".

WARNING: The directory HOTSPOT_IMPORT_PATH=/NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586

    does not exist, check your value of ALT_HOTSPOT_IMPORT_PATH.

WARNING: HOTSPOT_IMPORT_PATH does not contain the interface file jvmti.h.

     Check your value of ALT_HOTSPOT_IMPORT_PATH.

WARNING: File /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/lib/sa-jdi.jar

     does not exist. The JDI binding for the Serviceability Agent will not be

     included in the build.

     Please check your access to

      /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/lib/sa-jdi.jar

     and/or check your value of ALT_HOTSPOT_IMPORT_PATH.

ERROR: You do not have access to valid Cups header files.

    Please check your access to

      /usr/include/cups/cups.h

    and/or check your value of ALT_CUPS_HEADERS_PATH,

    CUPS is frequently pre-installed on many systems,

    or may be downloaded from http://www.cups.org

ERROR: HOTSPOT_CLIENT_PATH does not point to a valid HotSpot VM.

    Please check your access to

      /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/jre/lib/i386/client/libjvm.so

    and/or check your value of ALT_HOTSPOT_CLIENT_PATH.

ERROR: HOTSPOT_SERVER_PATH does not point to a valid HotSpot VM.

    Please check your access to

      /NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586/jre/lib/i386/server/libjvm.so

    and/or check your value of ALT_HOTSPOT_SERVER_PATH.

Exiting because of the above error(s). 


按顺序继续查看实际的错误消息,下一个问题似乎是默认情况下 Ubuntu 将 LANG 环境变量设置为 en_US.UTF-8,构建脚本想要设置为 C。Ubuntu 刚好在此。在 2007 年,UTF-8 任何人做任何事都应使用的惟一默认编码。尽管如此,我们进行了修复并继续前进:

$ export LANG=C


TODO: 弄清楚构建脚本为什么坚持使用 C 作为 LANG。我怀疑两种基本不同的属性(自然语言和编程语言)在相同的环境变量名称上发生了冲突。

下一个错误是:

HOTSPOT_IMPORT_PATH=/NOT-SET/re/jdk/1.7.0/promoted/latest/binaries/linux-i586 does not exist, check your value of ALT_HOTSPOT_IMPORT_PATH.

到底应该是什么呢?正式构建指令 没有提到。看起来实际上应该是 Java 7 的事,甚至没有引导程序 JDK 的份。或许我在构建 JDK 之前必须构建 HotSpot?

又读了 15 分钟不同的博客之后,我发现 Sun 发布的构建指令是错误的(大吃一惊)。他们谈论的“顶层 Makefile”根本不存在。相反,我必须在 control/make 目录下运行 makefile 并应该构建一切:openjdk、hotspot 等等一切。我们来试一下:

$ make sanity

make[1]: Entering directory `/home/jars/openjdk/jdk/make'

make[2]: Entering directory `/home/jars/openjdk/jdk/make/tools/freetypecheck'

freetypecheck.c: In function 'main':

freetypecheck.c:45: warning: comparison is always false

due to limited range of data type

freetypecheck.c:54: warning: comparison is always false

due to limited range of data type

make[2]: Leaving directory `/home/jars/openjdk/jdk/make/tools/freetypecheck'

make[1]: Leaving directory `/home/jars/openjdk/jdk/make'


该死,我以为我已经修复了 freetype 问题。但是仔细一看,似乎这些消息只是针对 Sun 包括在构建中的 freetypecheck C 程序的一个问题,而非 freetype 本身有问题。相关的代码行是:

if (strcmp(v, QUOTEMACRO(REQUIRED_FREETYPE_VERSION)) < 0) {

    printf("Failed: headers are too old.\n");

  }


and

  if (strcmp(v, QUOTEMACRO(REQUIRED_FREETYPE_VERSION)) < 0) {

    printf("Failed: too old library.\n");

  }


似乎是如果这个测试总是失败,那么 freetype 就是好的,所以我们就忽略这个问题吧。

TODO: 弄清楚正在进行的问题并进行修复。

现在只剩下一个警告和一个错误:

WARNING: This machine appears to only have 503Mb of physical memory,

     builds on this machine could be slow.

ERROR: You do not have access to valid Cups header files.

    Please check your access to

      /usr/include/cups/cups.h

    and/or check your value of ALT_CUPS_HEADERS_PATH,

    CUPS is frequently pre-installed on many systems,

    or may be downloaded from http://www.cups.org 


我已经为这台笔记本订购了 4GB 的 RAM ,但货还没到。与此同时,我只能忍受缓慢的构建。但是,CUPS 可能是一个问题。返回到 Synaptic。好像又是一个设备安装问题。似乎是我需要的 libcupsys2-dev。我安装了并重试:

$ make sanity

make[1]: Entering directory `/home/jars/openjdk/jdk/make'

make[2]: Entering directory `/home/jars/openjdk/jdk/make/tools/freetypecheck'

make[2]: Nothing to be done for `all'.

make[2]: Leaving directory `/home/jars/openjdk/jdk/make/tools/freetypecheck'

make[1]: Leaving directory `/home/jars/openjdk/jdk/make'

Build Machine Information:

  build machine = jars-desktop

...

Previous JDK Settings:

  PREVIOUS_RELEASE_PATH = /NOT-SET/re/jdk/1.6.0/archive/fcs/bundles/linux-i586

   ALT_PREVIOUS_RELEASE_PATH =

  PREVIOUS_JDK_VERSION = 1.6.0

   ALT_PREVIOUS_JDK_VERSION =

  PREVIOUS_JDK_FILE = jdk--linux-i586.tar.gz

   ALT_PREVIOUS_JDK_FILE =

  PREVIOUS_JRE_FILE = jre--linux-i586.tar.gz

   ALT_PREVIOUS_JRE_FILE =

  PREVIOUS_RELEASE_IMAGE =

   ALT_PREVIOUS_RELEASE_IMAGE =

WARNING: This machine appears to only have 503Mb of physical memory,

     builds on this machine could be slow.

Sanity check passed. 


终于!在开始了大约 7 个小时之后,完整性检查通过了。现在试着用 make 开始实际构建:

构建 Make 文件
$ make

linux i586 1.7.0-internal build started: 07-11-17 22:33

/bin/mkdir -p ../../control/build/linux-i586/j2sdk-image

/bin/mkdir -p /home/jars/openjdk/control/build/linux-i586/j2sdk-image

...

# Running javac:

Check_ALT_JDK_IMPORT_PATH/bin/javac -J-XX:ThreadStackSize=768

  -J-client -J-Xmx375m -J-Xms128m -J-XX:PermSize=32m

  -J-XX:MaxPermSize=160m -source 1.5 -target 5 -encoding ascii

  -classpath /usr/local/java/lib/tools.jar -sourcepath 

/home/jars/openjdk/control/build/linux-i586/corba/gensrc:

../../../src/solaris/classes:

../../../src/share/classes -d

/home/jars/openjdk/control/build/linux-i586/corba/classes

@/home/jars/openjdk/control/build/linux-i586/corba/tmp/sun

/javax.transaction.xa/.classes.list

/bin/sh: Check_ALT_JDK_IMPORT_PATH/bin/javac: not found

make[3]: *** [.compile.classlist] Error 127

make[3]: Leaving directory `/home/jars/openjdk/corba/make/javax/xa'

make[2]: *** [build] Error 1

make[2]: Leaving directory `/home/jars/openjdk/corba/make/javax'

make[1]: *** [build] Error 1

make[1]: Leaving directory `/home/jars/openjdk/corba/make'

make: *** [corba-build] Error 2


嗯,好像是需要一个 ALT_JDK_IMPORT_PATH 环境变量。完整性检查没有捕获到这一点。系统似乎正试着加载 javac。我不知道为什么 JAVA_HOME 不够好,但是我们可以尝试只将其设置为正常的 JDK 目录:

$ export ALT_JDK_IMPORT_PATH=/usr/local/java


现在构建似乎在前进。系统出现了许多不同类型的错误消息,比如:

../../../../../../../src/share/classes/org/omg/CORBA/ORB.java:593: warning:

non-varargs call of varargs method with inexact argument type for last parameter;

cast to java.lang.Object for a varargs call

cast to java.lang.Object[] for a non-varargs call and to suppress this warning

       return (org.omg.CORBA.NVList)meth.invoke(this, argx);


似乎并非 JDK 中的所有代码都要遵循最新的 Sun 编码规范。但是,这仅仅是警告。代码仍在构建。

TODO:修复此问题以获得无警告的构建。

构建机器上的风扇/硬盘驱动器现在已过度疲劳了,整个房间都可以听到旋转的噪音。这只是一台笔记本。我希望它不要烧坏。如果它烧坏了,至少我还在 90 天的保修期内。好了,它安静了一点。哇。噢,等一下。它安静下来的原因是因为它出错了:

/home/jars/openjdk/hotspot/agent/src/share/classes/sun/jvm

/hotspot/debugger/remote/x86/RemoteX86Thread.java:42:

cannot find symbol

symbol : class RemoteX86ThreadContext

location: class sun.jvm.hotspot.debugger.remote.x86.RemoteX86Thread

   RemoteX86ThreadContext context = new RemoteX86ThreadContext(debugger);

   ^

/home/jars/openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot

/debugger/remote/x86/RemoteX86Thread.java:42: cannot find symbol

symbol : class RemoteX86ThreadContext

location: class sun.jvm.hotspot.debugger.remote.x86.RemoteX86Thread

   RemoteX86ThreadContext context = new RemoteX86ThreadContext(debugger);

                     ^

注意:/home/jars/openjdk/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/SAJDIClassLoader.java uses or overrides a deprecated API.

注意:Recompile with -Xlint:deprecation for details.

2 errors

make[6]: *** [/home/jars/openjdk/control/build/linux-i586/hotspot/outputdir

/linux_i486_compiler2/product/../generated/sa-jdi.jar] Error 1

make[6]: Leaving directory

`/home/jars/openjdk/control/build/linux-i586/hotspot/outputdir

/linux_i486_compiler2/product'

make[5]: *** [all] Error 2

make[5]: Leaving directory

`/home/jars/openjdk/control/build/linux-i586/hotspot/outputdir

/linux_i486_compiler2/product'

make[4]: *** [sa_stuff] Error 2

make[4]: Leaving directory

`/home/jars/openjdk/control/build/linux-i586/hotspot/outputdir

/linux_i486_compiler2/product'

make[3]: *** [product] Error 2

make[3]: Leaving directory

`/home/jars/openjdk/control/build/linux-i586/hotspot/outputdir'

make[2]: *** [generic_build2] Error 2

make[2]: Leaving directory `/home/jars/openjdk/hotspot/make'

make[1]: *** [product] Error 2

make[1]: Leaving directory `/home/jars/openjdk/hotspot/make'

make: *** [hotspot-build] Error 2


但仍有进展。至少这像是一个真正的 Java 缺陷,而不是环境问题或 C 缺陷。指定的缺陷似乎是没有可访问的把 RemoteThreadContext 构造器,该构造器接受 RemoteDebuggerClient 作为参数。打开 RemoteX86Thread.java 来查看可能正在发生的事情,我没查到任何问题,但是当我打开 RemoteThreadContext.java 时,问题显而易见:文件是空的!我想知道发生了什么。

当我解压或下载原始文件时,也许一些事情中断操作了。我又弄到了一个新的副本,它似乎包含 RemoteThreadContext.java,因此我将其完全复制到它该在的位置,并再次运行 make。这一次,在 make 中止之前,我设法在 Arathi Basin 中完整地玩了一圈:

Timing: 00000 seconds or 0s for make-java-jvm

<<<finished recursively="" making="" jvm="" all="" @="" sat="" nov="" 17="" 23:54:14="" cet="" 2007.

 >>>Recursively making redist all @ Sat Nov 17 23:54:14 CET 2007 ...

make[3]: Entering directory `/home/jars/openjdk/jdk/make/java/redist'

BinaryPlugs import started: Sat Nov 17 23:54:14 CET 2007

BINARY_PLUGS_PATH=/home/jars/plugs

make[3]: *** No rule to make target `/home/jars/plugs/jre/lib/i386/libjsoundhs.so', needed by `/home/jars/openjdk/control/build/linux-i586/lib/i386/libjsoundhs.so'. Stop.

make[3]: Leaving directory `/home/jars/openjdk/jdk/make/java/redist'

make[2]: *** [all] Error 1

make[2]: Leaving directory `/home/jars/openjdk/jdk/make/java'

make[1]: *** [all] Error 1

make[1]: Leaving directory `/home/jars/openjdk/jdk/make'

make: *** [jdk-build] Error 2


也许是我没有正确安装插件?也许我必须将其 unjar?不。不会是一个恶作剧吧。等一下:它是一个自运行的 JAR:

$ java -jar jdk-7-ea-plug-b23-linux-i586-30_oct_2007.jar

Error: Install failed: java.awt.HeadlessException:

No X11 DISPLAY variable was set, but this program performed

an operation which requires it.

java.awt.HeadlessException:

No X11 DISPLAY variable was set, but this program performed

an operation which requires it.

  at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)

...


嗯,我猜我不能在控制台中运行它。我必须把椅子转向笔记本,在它上面运行。

TODO:让二进制插件安装程序能够无头运行。

好了。现在我在 /home/jars/plugs/openjdk-binary-plugs 中找到了未压缩的二进制插件。我需要更新环境变量以再次匹配 make:

$ export ALT_BINARY_PLUGS_PATH=/home/jars/openjdk-binary-plugs

$ make


Make 再次运行,但不久在另一个位置中止了:

In file included from

/home/jars/openjdk/jdk/src/share/native/sun/awt/../java2d/pipe/Region.h:34,

  from /home/jars/openjdk/jdk/src/share/native/sun/awt/../java2d/pipe/Region.c:30:

/home/jars/openjdk/jdk/src/solaris/native/sun/awt/utility/rect.h:31:22: error:

X11/Xlib.h: No such file or directory

In file included from

...

/home/jars/openjdk/jdk/src/solaris/native/sun/awt/img_util_md.h:32:

  error: expected specifier-qualifier-list before 'XID'

/home/jars/openjdk/jdk/src/share/native/sun/awt/image/BufImgSurfaceData.c:

  In function 'Java_sun_awt_image_BufImgSurfaceData_freeNativeICMData':

/home/jars/openjdk/jdk/src/share/native/sun/awt/image/BufImgSurfaceData.c:95:

  warning: cast to pointer from integer of different size

make[4]: ***

[/home/jars/openjdk/control/build/linux-i586/tmp/sun/sun.awt/awt/obj/BufImgSurfaceData.o]

Error 1

make[4]: Leaving directory `/home/jars/openjdk/jdk/make/sun/awt'

make[3]: *** [library_parallel_compile] Error 2

make[3]: Leaving directory `/home/jars/openjdk/jdk/make/sun/awt'

make[2]: *** [all] Error 1

make[2]: Leaving directory `/home/jars/openjdk/jdk/make/sun'

make[1]: *** [all] Error 1

make[1]: Leaving directory `/home/jars/openjdk/jdk/make'

make: *** [jdk-build] Error 2


也许是我丢掉了一些 X11 开发库?返回到 Synaptic。让我们安装 libx11-dev 并重试。不,不能那样做。看起来像是 libxt-dev 的一个小 Googling 是缺少的部分。我次我又前进了一点。现在又缺少了另一个文件:

/home/jars/openjdk/jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_config.h:33:34: error: X11/extensions/shape.h: No such file or directory.

这次我直接转到 Google,发现“包括文件是非矩形窗口形状扩展标准的一部分”。似乎 libext-dev 是我需要的软件包。又一次突破。

我想这可能是最后一个了。我似乎已经编译了所有的东西。当然,这是 C 而不是 Java,这并不意味着我完成了。现在出现了链接器错误:

/usr/bin/ld: cannot find -lXtst


因此我安装 libxtst-dev 头文件。

越来越烦人了。我仅列出我必须安装的其他库:

libXi-dev

嗯,可能就是它。现在它似乎正在生成 JavaDoc。有许多已破坏的但容易固定的 JavaDoc 标记,但是我想实际上已经完成了。现在,我只能弄清楚构建将每件东西放在哪里。:-)

安装

输出似乎位于 openjdk/control/build/linux-i586/j2sdk-image。(其他一些构建产品,比如无开发工具的 JRE,也位于 openjdk/control/build/linux-i586/。) 试着将其复制到 /opt/java 中,设置为 JAVA_HOME,并将其添加到以下路径中:

$ sudo cp -R j2sdk-image /opt/java

$ export JAVA_HOME=/opt/java

$ export PATH=/opt/java/bin:$PATH


现在到了实现真理的时刻了:

$ java -version

openjdk version "1.7.0-internal"

OpenJDK Runtime Environment (build 1.7.0-internal-jars_18_nov_2007_01_03-b00)

OpenJDK Client VM (build 12.0-b01, mixed mode)

$ javac -version

javac 1.7.0-internal


成功了!此时正好是上午 12:32 ,我大约在 10:00(上午而非下午)左右开始;但毕竟完成了。既然已经安装了所有正确的库,也许下一个安装只用七个小时就够了。

更简单的方法

带有 make 的原始构建对于自动化、测试、接口和连续集成是十分重要的。然而,对于日复一日的开发,它们通常都不是最容易的方法。如果这对于您来说似乎太繁琐的话,那么还有其他方法,但它们都有各自的类似问题。

预建的二进制软件包

如果您觉得调试 makefile 不是度过周末的好方法,那么您可能就需要从 JDK 7 二进制快照页面 中安装预建的二进制软件包。

IDE

我已经集中从命令行开始构建了,因为这是最通用的且能交互操作的方法。它还使得自动化和测试更加容易。命令行构建应该被所有好的开源软件支持。也就是说,有时 IDE 也有用。Sun 积极鼓励使用 NetBeans 来构建和修改 JDK,而且 openjdk 下载附带了预配置的 NetBeans 项目 openjdk/jdk/make/netbeans。仅在 NetBeans 中打开并运行。更多指令,请访问 NetBeans 网站。一定要小心,这些指令并不完全准确,或者您可能仍需进行一些调试以达到完全构建,甚至是在 NetBeans
中。

结束语

我们学到了什么?可以构建 JDK 了。第一次做这件事仅花费一天或两天的时间,而且熟练一下 Unix 和 C 库不是一件坏事。希望它能够让您比我花费更少的时间。从现有 Ubuntu 桌面配置开始,您需要进行如下操作:

从 Sun 中安装最新的 JDK 6。(Ubuntu 仅附带 JRE。)

从 OpenJDK 源码发布页面 下载源码包并解压,以创建 openjdk 目录。

从同一页面下载二进制插件 JAR 并运行以创建 openjdk-binary-plugs 目录。

安装以下软件包:

gawk

ant

findbugs

ALSA

libcupsys2-dev

libext-dev

libXi-dev

libxt-dev

libxtst-dev

手动安装 FindBugs

设置以下环境变量:

ALT_BOOTDIR= JDK 6 的安装位置

ALT_BINARY_PLUGS_PATH= 二进制插件的任意安装位置

ANT_HOME= Ant 的任意安装位置

FINDBUGS_HOME= wherever 的任意安装位置

ALT_JDK_IMPORT_PATH= JDK 6 的安装位置

LANG=C

生成 openjdk/jdk/make/jdk_generic_profile.sh 可执行文件并运行。

移至 openjdk/control/make 并键入 make sanity。调试所发生的任何问题。

通过完整性检查之后,请键入 make。去拿一杯咖啡。这将需要一段时间。

构建完成之后,请将 openjdk/control/build/linux-i586/j2sdk-image 目录复制到您想放置 JDK 的任意位置。/opt/java7 目录可能是一个不错的选择。

在其他 Linux 发行版中,可能需要添加 Ubuntu 默认打包的另外一些库,或者可能不需要添加此处列出的所有库。在其他操作系统(比如 Solaris)中,可能需要指定 gnumake 而非 make(gnumake 是 Ubuntu 上的默认 make)。在 Windows 中,祝您好运。我确信它能够完成,但是我没有完整的一天来调试这一环境了。也许会在另一篇文章中完成这些。

来源:http://www.shangxueba.com/jingyan/87309.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息