Java Solaris 加入Sun中国技术社区 我的社区 注册说明
 
JDK 6.0 API 中文版
 
 
 
 
Java API 文档中文版
OpenSolaris Developer's Reference Guide
 
By admin, 12/11/06  

OpenSolaris 开发者参考


1 介绍

欢迎使用 OpenSolaris!

本指南旨在为开发者提供有关使用 OpenSolaris 工具和源代码的综合信息。本章提供有关什么是 OpenSolaris 的简要概述,还提供指向其他信息的链接。

1.1 概述

本章是对 OpenSolaris 和本指南自身的介绍。由于本指南中的许多信息随着时间的推移将发生改变,因此我们始终建议您阅读最新的版本。1.2 节介绍可以从何处找到最新指南和其他文档以及更多相关资源,包括常见问题解答、与其他开发者联系的方法和有关源代码的信息。尽管我们强烈建议阅读本指南中与您的兴趣相关的部分,但这并不是参与开发所必需的。有 关可以立即开始使用 OpenSolaris 的方法,请参见 1.3 节“快速入门”。1.4 节详细介绍在本指南其余部分中使用的印刷约定。

本指南目前主要侧重于 OS 和联网 (OS and Networking, ON) 的整合。随着时间的推移,会逐步在本指南中增加有关其他整合的类似信息。

1.2 获取帮助

OpenSolaris Web 站点提供了多种寻求问题解答的方法,以帮助您解决疑难杂症。一组技术性和非技术性常见问题解答在 http://opensolaris.org/os/about/faq/ 上维护。一组更大、更 深入的技术文档在 http://opensolaris.org/os/community/documentation/ 上维护。

如果您的问题没有在常见问题解答或其中任何文档中解答,或者您不知道从何处查找,可以使用论坛的邮件列表进行提问。有许多可用的邮件列表;有关当前的讨论列表以及如何注册,请参见 http://opensolaris.org/os/discussions/

如果使用 OpenSolaris Web 站点本身时有困难,请向 mailto:webmaster@opensolaris.org 发送邮件。请注意,不 应使用此地址提出有关 OpenSolaris 本身的技术问题。

最后,如果您对本文档有任何问题或意见,请发送邮件或加入 OpenSolaris 文档讨论,网址是 http://opensolaris.org/os/community/documentation/ discussions/。

始终可以在 http://opensolaris.org/os/community/onnv/devref_to c 上找到本文档的最新版本。

1.3 快速入门

本节跳过稍后将在本文档中介绍的大多数重要内容,并做出许多有关开发和生成环境的假设。其目的是提供一组逐步说明,帮助您在不到一小时内开始进行开发,即使您以前没有 Solaris 开发经验也可以快速入门。虽然此过程适用于大多数用户,但是它无法适合所有用户。有数十种工具和实用程序用于开发 OpenSolaris,而且大多数都具有至少几个选项和参数。存在这一巨大灵活性的原因如下:每 个开发者都具有独特的需求。如果在按照这些说明操作时遇到困难,请勿放弃!每项说明都列出相关的章节,可以阅读它们了解有关该步骤中所用命令和过程的更多信息。如果所有其他方法都失败了,请参见 1.2 获取帮助以了解可供 OpenSolaris 开发者社区使用的许多资源。

1.3.1 示例环境

1.3 节其余部分中的说明介绍如何在 x86 环境(只能处理 32 位或能够处理 64 位;没有任何差异)和 SPARC 环境中生成和安装。它们已经进行了测试,证实可以工作。由 于不可能对每个可想象到的硬件、软件和策略配置进行测试,因此我们的测试仅限于此处介绍的环境。尽管我们期望这些说明的适用面可以很广,但是您的环境越类似,不经修改即可使用它们的可能性就越大。

1.3.1.1 x86 环境

我们假定整个系统专用于基于 OpenSolaris 的分发,如 Solaris Express。测试计算机的配置如下:启用了超线程技术的两个 2.8 GHz Intel Pentium 4 Xeon 处理器,512MB 内存、标准 ATA 控制器和 Broadcom 57xx 以太网适配器。该计算机配有 2 个 40GB ATA 磁盘,其分区情况如下:

c0d0p0 和 c1d0p0 都具有一个为 Solaris 指定整个磁盘的单个 fdisk 分区。

 c0d0s0 包含一个在 / 上挂载的 35GB UFS 文件系统。

c0d0s1 包含一个 2GB 的交换空间。
c0d0s8 是一个 1MB 的引导片。
 c1d0s0 包含一个在 /aux0 上挂载的 37GB UFS 文件系统。

您的系统无需与此系统完全相同,甚至也无需与此系统类似,同样可以工作;此配置只是所支持系统的一个示例。有关安装、开发和生成 OpenSolaris 各部分的更多信息,请参见 2 先决条件。某些整合可能具有其他一些要求,因此务必参阅最新的发行说明。

1.3.1.2 SPARC 环境

SPARC 测试环境是一台 Sun Fire V210 服务器,配有 2 个 1.0 GHz UltraSPARC-IIIi CPU 和 2 GB 内存。该计算机配有两个 36GB SCSI 磁盘,其分区情况如下:

 c1t0d0s0 包含一个在 / 上挂载的 8GB UFS 文件系统。

c1t0d0s1 包含一个 4GB 的交换空间。
c1t0d0s3 包含一个在 /export1 上挂载的 22GB UFS 文件系统。
 c1t1d0s0 包含一个在 /export2 上挂载的 35GB UFS 文件系统。

您的系统无需与此系统完全相同,甚至也无需与此系统类似,同样可以工作;此配置只是所支持系统的一个示例。有关安装、开发和生成 OpenSolaris 的更多信息,请参见 2 先决条件

1.3.2 安装二进制分发

生成自己的源代码或安装提供的二进制归档文件之前,必须安装基于 OpenSolaris 的完整分发。这是因为您很可能需要的驱动程序、打包工具和其他组件不在随 OpenSolaris 发行的“ 操作系统和联网”组件中。在编写本文时,可以在其上生成或安装 OpenSolaris 二进制代码的唯一分发是 Solaris Express 内部版本 22 或更高版本。

如果您是 ON 开发者,并要运行最新的位或已对内核或核心库进行更改,则还需要将系统更新为比分发的最新可用内部版本更新的一组二进制代码。执行此操作的过程称为 BFU,将在下面详细说明。BFU 过程使用包含从 ON 生成的二进制代码的 CPIO 归档文件;可以从 http://opensolaris.org/os/downloads/on/ 下载这些归档文件,也可以自己生成它们(如果已对系统进行大的更改,则需要安装您自己生成的归档文件)。如果您只是更改简单的用户级应用程序,则通常可以使用以下方法:逐个生成这些应用程序,然 后通过系统的现有二进制代码复制它们(而不是进行 BFU)。

此处介绍了该过程的两个部分:初始系统安装(有时称为 the suninstall manpage,以与 BFUInstall(尤其是后者)区分开)和 BFU;所有用户和开发者都将需要执行 1.3.2.1 安装基于 OpenSolaris 的分发 (Solaris Express) 中所述的步骤,而只有对使用最新的 ON 位或对核心系统组件进行重大修改的开发者才需要阅读 1.3.2.3 升级到最新的位

在创建可以用作生成和安装 OpenSolaris 位的基础的新分发后,每个分发下面都会具有与 1.3.2.1 类似的一节。如果此处未提及您喜爱的分发,请添加一节以说明如何安装它。

1.3.2.1 安装基于 OpenSolaris 的分发 (Solaris Express)

Solaris 安装过程在 http://docs.sun.com/app/docs/coll/1236.1 上有详尽的介绍。尽管在交互式安装过程中提供的大多数缺省选项对于创建开发或生成系统是可接受的,但是应该注意以下事项:

不需要语言环境 (Locale)。

除非由于其他原因需要任何语言环境,否则无需安装它们。建议选择 C (POSIX) 语言环境作为缺省语言环境。

按照本地策略进行操作。

必须按照本地策略设置网络配置、时区、IPv6 和 Kerberos 的使用、名称服务和其他环境特定的参数。它们不直接影响 OpenSolaris 开发。

为源代码以及内部版本(可选)保留空间。

要安装源代码,将需要至少 300MB 的空闲空间(建议使用更大的空闲空间)。如果还希望生成 OpenON,则将需要数个 GB 的空闲空间。建议创建单独的本地文件系统,以 存储这些源代码和对象以及用户起始目录和其他独立数据(如果适合于您的配置);我们的示例系统在 /aux0 上挂载此文件系统。有关更多详细信息,请参见 2.1 硬件

安装完整分发软件包簇。

如果因磁盘空间不足而无法安装完整分发,则需要升级到大小至少为 9GB 的磁盘。也许还可以改为安装开发者软件包元簇,但是尚未对此进行测试,所以可能还无法成功生成。有关软件需求的更多信息,请参见 2.2 操作 环境软件包

1.3.2.2 安装所需的工具

生成 OpenON 需要以下两组工具:编译程序和 ON 特定的生成工具。有关详细信息,请参见 2.3 获取和安装编译程序2.4 获取和安装自 定义工具。此处假定您希望使用 Studio 10 编译程序(您尚不能使用 Studio 11 生成 OpenON)。请注意,许多 ON 生成工具也由其他整合使用,其中包括 SFW 和网络存储 (Network Storage, NWS)。

将已安装的映像(而不是完整产品)下载到临时区域(如 /var/tmp)中。该文件通常称为 sunstudio10-DATE.PLATFORM.tar.bz2。开始之前,确保 /opt 上至少有 900MB 的空闲空间。通过检查以下命令的输出,可以做到这一点:

$ df -klh /opt Filesystem size used avail capacity Mounted on /dev/dsk/c1t0d0s0 7.9G 3.8G 4.0G 50% /

如果 'avail' 字段为 900M 或更大,则说明有足够的空间,可以继续。

$ su Password: # cd /opt # bzip2 -dc /var/tmp/sunstudio10-20050614.sparc.tar.bz2 | tar xf -

请注意,文件名可能稍有不同,具体取决于所用平台和将来的编译程序发行版。

然后,下载 ON 特定的生成工具。此文件通常称为 SUNWonbld-DATE.PLATFORM.tar.bz2,它包含一个 SVR4 软件包。假定已将它下载到 /var/tmp,现在您将要执行以下操作:

$ cd /var/tmp $ bzip2 -dc SUNWonbld-DATE.PLATFORM.tar.bz2 | tar xf - $ su Password: # pkgadd -d onbld SUNWonbld

请注意,如果已安装这些工具的以前版本,则需要首先使用 pkgrm(1m) 删除它们。

安装分发、编译程序和 ON 特定的生成工具后,就可以从源代码生成或从二进制代码安装。如果要从源代码生成,请继续参照下一节。否则,向前跳到 1.3.4 升级到最新的 ON 位

1.3.3 从源代码生成 ON

1.3.3.1 创建源工作区

假定要将 /aux0/testws 用作 工作区

首先,转到 /aux0/testws,然后解压缩源代码和不公开的二进制代码,例如,

$ mkdir /aux0/testws $ cd /aux0/testws $ bzip2 -dc opensolaris-src-DATE.tar.bz2 | tar xf - $ bzip2 -dc opensolaris-closed-bins-DATE.PLATFORM.tar.gz | tar xf -

源代码将解压缩到 usr/src 中,二进制代码将解压缩到 closed/root_PLATFORM(即 closed/root_i386closed/root_sparc)中。

1.3.3.2 执行基本生成

首先,创建一个环境文件以指导诸如 nightly(1)bldenv(1) 之类的工具。

  • 复制到模板环境文件中

    /aux0/testws/usr/src/tools/env/opensolaris.sh 复制到 /aux0/testws。不一定必须将它复制到 /aux0/testws,b b b 但这是一个放置它的方便位置。也不一定必须保持名称 opensolaris.sh,但这是将在这些注释中使用的名称。

     $ cp /aux0/testws/usr/src/tools/env/opensolaris.sh /aux0/testws
    
  • 进行所需的更改

    首先,将 /opt/onbld/bin 添加到 PATH 环境变量。您可能希望通过编辑 .login.profile 文件(根据哪个文件适合于您的 shell)使此更改成为永久更改。

    然后,使用喜爱的文本编辑器,对 opensolaris.sh 进行以下更改:

    将 GATE 更改为顶层目录的名称(例如 testws)。

    将 CODEMGR_WS 更改为顶层路径(例如 /aux0/testws)。

    将 STAFFER 更改为您的登录名。

  • (可选)自定义 VERSION。

    VERSION 是 ``uname -v'' 将打印的字符串。

然后,为了生成完整的 BFU 归档文件集,转到 /aux0/testws,发出

 $ nightly ./opensolaris.sh &

并查找要花费几小时进行处理的其他内容。可以使用 ptree(1) 监视生成的进度。nightly(1) 在完成后将向 $MAILTO 发送邮件。该邮件将包含生成结果的概述。将在 工作区中提供邮件文本的副本和更详细的日志文件(例如 /aux0/testws/log/log.MMDD/nightly.log,其中 MMDD 是生成日期)。在生成过程中也会提供日志文件(位置略有不同);要实时监视生成的进度,d d d 可以执行以下命令:

$ tail -f /aux0/testws/log/nightly.log

该日志的位置由 LOGFILE 和 ATLOG 变量控制;有关更多详细信息,请参见 nightly(1)。

如果生成失败,则可以更正问题,然后使用 '-i' 选项在夜间运行增量生成,从而跳过初始销毁。有关更多信息,请参见 nightly(1) 手册和 4 生成 OpenSolaris

要生成特定组件,请首先使用 bldenv(1) 设置各种环境变量,然后转到要生成的子树。例如:

 $ cd /aux0/testws

$ bldenv ./opensolaris.sh
[来自 bldenv 的状态信息]
$ cd usr/src/cmd/vi
$ dmake all

要生成内核,请从 usr/src/uts 运行 dmake(1)。

有关生成过程和工具的更多信息,请参见 4 生成 OpenSolaris。成功完成生成后,请参见 5 安装和测试 ON,了解有关可对其执行哪些操作的更多信息。

1.3.4 升级到最新的 ON 位

警告!本节介绍的步骤仅对于高级开发者是可选的,查看和编辑源代码时不必执行这些步骤。冒然地执行此过程会导致系统的可管理性下降,并给您带来与使用开发软件关联的巨大风险。 如果不确定,请跳过此步骤。有关此过程的风险和优点的更多详细信息,请参见 5.3 使用 BFU 安装 ON

如果希望生成一个或多个 OpenSolaris 整合,有时可能需要先更新系统的所有或部分软件。在有关整合的发行说明中为每个生成列出了这样的需求;大多数情况下,现有安装足以生成和使用最新源代码。通 常,使用正式的 suninstall、升级或 LiveUpgrade 过程安装较新的 Solaris Express 内部版本比使用 BFU 过程更安全且更有效;正式升级可升级所有系统软件,而 BFU仅升级少数几个部分。除非需要使用最新的 ON 位,否则应该跳过此步骤。

在继续之前,请完整地阅读 5.3 使用 BFU 安装 ON。本节的其余部分提供了 bfu(1) 的用法示例,但是您必须了解 BFU 的工作原理、什么是 BFU 冲突以及如何解决这些冲突,这样才能成功使用 BFU。以下内容再怎么强调也不为过: 您或许一定希望让 acr(1) 为您解决冲突。手动解决冲突可能是很困难的,很耗时间,而且容易出错。解决冲突时出现的错误通常会使计算机处于非工作状态。此 处假定您将自动解决冲突。

首先,从 http://opensolaris.org/os/downloads/on/ 下载适用于您系统体系结构的 BFU 归档文件。然后,将归档文件解压缩到所选的临时目录中。在本示例中,将使用 /var/tmp/bfu 存储归档文件,并将 LATEST 作为要安装的内部版本。

# mkdir /var/tmp/bfu # cd /var/tmp/bfu # bzip2 -dc /path/to/opensolaris-bfu-LATEST.sparc.tar.bz2 | tar xf -

这将创建该目录和 /var/tmp/bfu/archives-LATEST/sparc。其中包含一组 CPIO 归档文件;这些文件由 bfu(1) 用来覆写您的系统二进制代码。接下来,退出窗口系统,以超级用户身份登录到控制台,然后发出以下命令:

 # /opt/onbld/bin/bfu

/var/tmp/bfu/archives-LATEST/sparc

可能会看到有关升级非 ON 软件包的警告;如果尚未这样做,则将需要先升级它们,才能安全地使用 BFU。如果 BFU 由于尝试升级不可用的软件包而失败,请查看您内部版本的发行说明,以 了解有关问题的原因和解决方案的信息。如果找不到所需内容,请向 mailto:opensolaris-help@opensolaris.org 发送一封说明消息和情况的邮件。

BFU 完成后,您必须在配置文件中解决冲突。BFU 将完成,如果成功,则会向您显示一些警告和 bfu# 提示符。 您尚未完成!现在必须解决冲突,然后重新引导:

bfu# acr

如果 acr 失败或者输出警告或错误,则在重新引导之前将需要手动解决冲突。有关完整的详细信息,请参见 <5.3 使用 BFU 安装 ON>。否则,重新引导:

 bfu# reboot

在您的系统启动时,请记下新的内核版本。系统上的 ON 位已升级。

1.3.5 微型项目

这些活动旨在帮助开发者熟悉 OpenSolaris 工具和环境,同时为满足他们自己以及社区的需求做出有用的贡献。我们希望,通过参与其中一些微型项目,新开发者可以了解 OpenSolaris 的各个方面,并找到对大量现有工作进行新改进的灵感。项目建议大致按最简单到最复杂的顺序排列;对于经验较少的开发者,前几个项目提供了非常有价值的 OpenSolaris 入门参考,而 经验较多的开发者则可能希望完成一些更有挑战性的任务。当然,所有这些都只是建议;您完全可以根据自己的兴趣参与开发该系统的任何一个部分。我们仅恳请您利用邮件列表与他人协调您的活动,以减少重复工作。& amp; lt; /p>

  1. 启动博客

    许多开发者都习惯在笔记本或日记中保存笔记、书签、指向有用文档的相关链接和其他历史资料。随着您对 OpenSolaris 逐步加深了解,您积累的笔记和体验对您和社区中的其他人将是非常有价值的。您 可以在众多免费的博客站点中的任意一个站点上创建自己的博客。建议的主题包括您进行的任何观察、所遇到的困难或者想出的改进 OpenSolaris 的做法。在博客中描写您的想法和经验,即 可以其为焦点引发更广泛的社区参与和讨论,提出错误或 RFE 或者创建新的开发项目。

  2. 修复简单的错误

    我们在 OpenSolaris 中跟踪的许多错误都属于低优先级问题,在很长一段时间内一直没有进行修复;修复它们并不是十分困难,而且它们往往会带来麻烦而不会造成灾难。此外,我们使用了 'oss-bite-size' 关键字来标识那些可轻松修复的错误,以便新开发者可以获取最新的起始点。

    可以在 http://bugs.opensolaris.org 上查看有关这些错误的信息以及搜索可轻松修复的错误。& amp; lt; /p>

  3. 增强 cstyle(1)

    改进自动化 C/C++ 样式检查工具 cstyle(1)hdrchk(1) 以实现更多的样式指导要求。例如,可以将 cstyle(1) 改进为检测已初始化变量的不良声明。有关更多信息,请参见 7.2.1 自动化样式工具

  4. 清理和改进代码

    使更多的命令和库通过 lint 检查。虽然使用 lint 检查整个内核 (uts/...) 时不出现警告,但是许多命令和库由于包含 lint 错误而不能通过 lint 检查。更 正这些错误通常不是很困难;首先启用 lint(请参见 3.3.3 修改 ON 生成系统),然后重新使用 lint 检查相应的命令或库。在一些情况下,修复特定的 lint 错误也许很困难或者是不可能的,因此必须改为禁用该错误。可以在相关邮件列表中讨论此类情况。

  5. 简化 Install(1) 用法

    生成用于特定平台的内核软件包时,将 Install(1) 的 '-i' 选项改进为除使用代码名称外还使用正式的平台名称。有关更多信息,请参见 5.2 使用 Cap-Eye-Install 安装内核

  6. 修复困扰您的某个问题

    搜索并修复某个常用程序中的错误,或您自己意识到的某个错误。可以在 http://bugs.opensolaris.org 上搜索错误。许多错误可能已经在进行修复,因 此在开始修复某个错误时应该向 mailto:request-sponsor@opensolaris.org 发送邮件以避免重复工作。发起人应确保没有其他人正在修复该错误,并帮助您确保按照正确的过程以并入您的修复。

1.4 约定

本文档的印刷约定尚未最终确定。随着文档的增大和改进,它最终将以多种格式进行排版,且每种格式都具有特定的约定。此处提供有关这些约定的信息。

1.5 参与者

许多人参与了本文档的撰稿工作。本节包含在其编辑过程中使用的源代码的部分列表。如果您知道其他源代码,请在此处添加它们。

注:一些引用可能指向 SWAN 内部 URL。如果今后公开此内容,则应该更新这些 URL。但是,不管怎样,其目的都旨在尽可能收集一些源代码,而不是提供完全可用的参考书目。

Adams, Jonathan;Bustos, David;Rhyason, Jeff。``Creating an Install Archive with Install''。 http://on-faq.eng.sun.com/onbld-serve/cache/94.htm l。

未知。``What are BFU Conflicts and How Do I Resolve Them?'' http://on-faq.eng.sun.com/onbld-serve/cache/189.ht ml。

未知。``BFU''。/ws/onnv-gate/public/bfu.README。

ARC Chairs,Interface Taxonomy。 http://opensolaris.org/os/community/arc/policies/i nterface-taxonomy/。

各种源代码:

/shared/ON/general_docs/keyword_info.txt、 /shared/ON/general_docs/lint_tips.txt、u sr/src/uts/README、 usr/src/lib/README.Makefiles、/ws/onnv-gate/public/README

感谢 Ben Rockwood 对本文档初期草稿所作的突出贡献。Alan Burlison 添加了初始 POD 标记。Mike Sullivan、Mike Kupfer、John Beck 和 Shanon Loveridge 提供了审阅注释。


2 先决条件

本章介绍开发、生成和测试 OpenSolaris 的硬件和软件需求。在任何 Solaris Express 安装上,可以轻松地满足其中的大多数需求(其他分发也可能适用)。根据您的兴趣,您 可能需要通过不太容易使用的硬件或软件测试您的工作。如果是这样,请向项目引导人寻求帮助。Sun 以及其他公司和组织提供了可能对 OpenSolaris 社区开发者可用的各种工具。如果您是项目引导人,请 与 mailto:community_liaison@opensolaris.org 联系,以了解有关您的项目可以使用的资源的信息。

2.1 硬件

本节详细介绍开发和生成 OpenSolaris 的硬件需求。由于一些项目可能具有其他需求(例如,驱动程序开发显然需要相应的设备),此信息用作指南而不是确定的规则集。例如,可 以在一个无法运行任何基于 OpenSolaris 的分发的系统上进行开发,将差异或其他工作转移到远程环境进行生成和测试。但是,在本节中,我们将假定您的开发和生成系统运行 Solaris 或者其他某个完全兼容的基于 OpenSolaris 的分发。

2.1.1 开发环境

一组最简单的需求适用于开发环境:只需具有存储源代码树的足够空间以及运行文本编辑器和工具(如 cscope)的足够 CPU 和内存。如果没有源代码管理元数据,则当前源代码树大约占300MB,因 此对于要存储的每个树,应该至少预留该大小的空间(具有完整 SCCS 元数据集的树大约需要 1.9GB)。请注意,如果计划在同一系统上生成树,则将需要更多的空间;请参见下面的 2.1.2 节。

通常,将运行 Solaris 10、Solaris Express 或其他基于 OpenSolaris 的分发的任何计算机都足以进行此操作。在编写本文时,支持具有 UltraSPARC-II 或更新的 CPU(即,时钟频率比 200 MHz 快的所有 CPU)的所有 SPARC 系统;Solaris 10 支持的 SPARC 平台的特定列表可以在 http://docs.sun.com/source/817-6337-06/install-sol aris.html 上找到。对于 i386 和 amd64 系统,硬件支持更复杂一点;可以在 http://www.sun.com/bigadmin/hcl/ 上找到有关 x86 硬件兼容性的更多信息。务必查看 Solaris 的最新发行说明,以了解有关当前和将来硬件支持的信息;这些说明可以在 http://docs.sun.com/ 上找到。

请注意,基于 OpenSolaris 的其他分发可能有时支持与最新的 Solaris 发行版或更新稍有不同的一组硬件;有关硬件支持的最新信息始终可以在供应商的发行说明中找到。

表:开发系统需求

 ----------------------------------------------------------------

CPU 任何支持的 CPU
----------------------------------------------------------------
内存 建议使用 128MB
----------------------------------------------------------------
交换 无要求
----------------------------------------------------------------
存储 每个源代码树副本需要 300MB 到 1.9GB (*)
----------------------------------------------------------------

(*) 总大小将随所用源代码管理类型的不同而不同。如果没有源代码管理数据,则生成的树大约需要 3.5GB;CVS 和 SCCS 将增加 50MB 或更多,具体取决于修订历史记录的数量。

2.1.2 生成环境

生成大的复杂软件(如 ON)或任何其他 OpenSolaris 整合是一个使用大量内存、计算和空间的过程。尽管可以在几乎任何计算机上生成 OpenSolaris,但 是在小型配置上这样做可能需要极长的时间。如果要使用 dmake 执行高度并行的生成,则具有足够的交换空间尤其重要。交换空间不足将导致生成失败。以下是打算在其上生成 ON 的系统的硬件需求:

表:生成系统需求

 ----------------------------------------------------------------

CPU 300 MHz UltraSPARC 或 x86 CPU
建议使用 AMD Opteron 或 UltraSPARC-III
----------------------------------------------------------------
内存 最低 256MB,建议使用 1GB (+)
----------------------------------------------------------------
交换 最低 1GB,建议使用 2GB (+)
----------------------------------------------------------------
存储 每个源代码树副本需要 3.5 到 5GB (*) (**)
----------------------------------------------------------------

在如上所述的最低配置生成系统上,预期完整生成至少需要 14 小时。增量生成所需时间将在一定程度上减少;根据比较好的经验,它是完整生成时间的三分之一。

下表显示几个典型系统的一些近似的完整生成时间。这些是截止到 2006 年 4 月 5 日的数据;随着更多代码的添加以及不公开组件数的减少,生成时间将增加。当然,实 际的生成时间也将随系统的不同而不同。

 系统           CPU                     内存            时间

----------------------------------------------------------------
Ultra 2 2x300MHz UltraSPARC-II 512M 5 小时 9 分钟
----------------------------------------------------------------
通用 AMD Athlon64 3200 1GB 1 小时 23 分钟
----------------------------------------------------------------

生成系统可以利用多个 CPU,甚至可以将编译工作分布在多台计算机上。有关配置并行生成和分布式生成的更多信息,请参见 4 生成 OpenSolaris

(*) 总大小将随所用源代码管理类型的不同而不同。如果没有源代码管理数据,则生成的树大约需要 3.5GB;CVS 和 SCCS 将增加 50MB 或更多,具体取决于修订历史记录的数量。

(+) 如果在并行模式下使用 dmake(1),且在同一计算机上运行的作业超过 4 个,则可能需要更多的内存和/或交换空间。

(**) 编译程序和工具安装在 /opt 中,它们将需要附加的 300MB(对于 x86)或 800MB(对于 SPARC)空间。

2.1.3 测试环境

对于不同的情况,对所做更改进行测试的具体要求有很大差异。某些更改根本不会影响体系结构特定的代码,只需在每个体系结构支持的任一系统上生成和运行测试套件即可进行测试。例如,如果已将一个新的 STREAMS 模块添加到网络栈中,则在一个 86 系统(测试 32 位和 64 位内核及用户程序)和一个 SPARC 系统上生成和测试很可能就足够了。在其他情况下(例如修改 x86 引导代码时),将 需要在尽可能广泛的硬件上进行测试,以确保未破坏某个不明显的功能。

应该考虑测试的一些硬件变量包括:

        - 体系结构:i386、amd64、SPARC

- 内存大小:您的更改是否需要 32MB 内存?是否需要 32GB 内存?
- 多处理器与单处理器
- 图形控制台、串行控制台与系统 LOM 控制台
- 无盘系统与“常规”系统

并不是所有这些变量都将适用于您的特定更改,因此需要尽可能保守地考虑您的更改可能会导致哪些影响。通常,对核心内核代码(如 VM 子系统或文件系统支持)的更改要求进行最广泛的测试。大多数情况下,对 附加驱动程序或计算机特定的代码进行的更改仅需要在相关硬件上进行测试。有关更多详细信息,请参见第 5 章。

您可能经常希望进行某项更改,但无法在为您提供的硬件上完全测试该更改。如果发现自己处于这种情形,请通过 http://opensolaris.org/ 与我们联系。OpenSolaris 社区包括数个组织(其中包括 Sun),它 们也许能够为您提供对其他硬件的访问,以达到测试更改的目的。

2.2 操作环境软件包

本章的其余部分介绍生成和打包 OpenSolaris 所需的软件。如果您仅对查看源代码、编辑它们以及向他人发送修补程序感兴趣,则可以跳过此资料;无需特殊的软件包即可查看和编辑源代码。但是,如 果是第一次在计划用于开发的系统上安装 Solaris,我们建议您安装“整个”簇 (SUNWCall),因为您日后可能需要生成 OpenSolaris 组件,这样做可以节省大量的时间。其 他分发可能提供不同的安装选项;请参阅供应商提供的文档。

强烈建议您在所有开发、生成和测试系统上安装“整个”软件包簇 (SUNWCall)。虽然安装有开发者 (SUNWCdev) 软件包簇的系统也可能工作,但是此配置尚未经过测试,因此不予评估推荐。此 外,应该获取并安装 SUNWonbld 软件包,该软件包包含 usr/src/tools 中工具的预生成版本,这些工具是生成 OpenSolaris 组件所必需的。如果愿意,可以在生成 ON 时改为将 nightly(1) 与 '-t' 选项一起使用来生成这些工具(请参见 4.2 使用 nightly 和 bldenv),但是建议安装该软件包以避免出现相关性问题,其 他整合也要求安装该软件包。SUNWonbld 可以从 http://opensolaris.org/os/downloads/on/ 进行下载。最 后,将需要获取并安装 Sun Studio 编译程序、dmake 和其他工具。可以从 http://opensolaris.org/os/community/tools/sun_stud io_tools/ 获取这些工具。

如果安装并使用完全安装(例如,Solaris 或 Solaris Express CD/DVD),则将具有程序、库和内核组件的完整匹配集。但是,如果日后使用诸如 BFU (请参见 5.3 使用 BFU 安装 ON)或 Install(请参见 5.2 使用 Cap-Eye-Install 安装内核)之类的方法升级 ON 位,或 者要在您自己的几个文件更新版本中生成和复制,则可能需要首先安装一个或多个系统软件包的较新版本。出现此情况时,它称为标志日。可以在 5.1.3 标志日 和其他危险中找到有关标志日的更多信息。

2.3 获取和安装编译程序

所需的编译程序取决于要生成的整合以及要在其上生成的平台。在内部版本 19 之前,缺省情况下ON的x86内部版本既使用Sun One Studio 8编译程序也用GNU编译程序。这是因为 32 位对象是使用 cc 和 CC 生成的,而 gcc 用于 64 位对象。从内部版本 19 开始,缺省情况下 Sun Studio 10 编译程序用于所有对象。从版本38开始生效。所有平台上的所有 ON 内部版本既需要 Sun Studio 10 也需要最新版本的 gcc(来自 Solaris Express 中的 /usr/sfw)。其他整合需要的编译程序和/或编译程序修补程序可能略有不同,因 此应始终查看最新的发行说明。

由于用于生成 OpenSolaris 的编译程序可能需要特殊的修补程序,因此将始终在 OpenSolaris Web 站点上维护指向当前 Studio 编译程序二进制代码的链接。使用编译程序、汇 编程序、链接程序、make(1) 或 dmake(1) 的其他版本是不受支持的,而且这样生成或创建的二进制代码可能无法正常工作。因此,必须使用整合的发行说明中列出的编译程序,以确保成功生成。所 需的工具将不定期进行更新;在适当的时候将张贴通知和提供较新的版本。

只有以下编译程序可以用来生成主线 OpenSolaris 源代码:Sun Studio 10 工具(在 http://opensolaris.org/os/community/tools/sun_stud io_tools/ 上提供)以及 Solaris Express 内部版本 22 和更高版本附带的 GNU 编译程序集合。如果希望将 gcc 用作主编译程序(即,希望归档文件包含使用 gcc 生成的对象),请参见 http://opensolaris.org/os/community/tools/gcc/。t t t 不管使用哪个编译程序,都将需要一组 ON 特定的生成工具 (onbld)。可以在 http://opensolaris.org/os/downloads/on/ 上找到适用于 SPARC 平台和 x86 平台的这些工具。

可以使用两种方法安装 Studio 10 编译程序:从已安装的映像进行安装,或作为完整产品进行安装。已安装的映像只是一个压缩的 tar 文件,它包含Studio 10的许多内容(但不是所有),带 有已应用的修补程序和有效的许可证密钥。这些内容足以生成 ON;可以在 http://opensolaris.org/os/community/tools/sun_stud io_tools/faqs/ 上了解所含具体内容的更多信息。已安装的映像将被提取到在其中提取它的目录下的 opt/SUNWspro;如果如下所述在根目录中提取它(建议这样做),则它将安装在与完整产品相同的位置中。请注意,无法将其他修补程序应用于已安装的映像。

示例:从已安装的映像安装 Studio 10 编译程序

假定将已安装映像下载到了 /var/tmp/sunstudio10-sparc.tar.bz2 中,并希望将它安装到 /opt/SUNWspro 中(建议这样做)。可以按如下所示进行安装:

 $ su

Password:
# cd /
# bzip2 -dc /var/tmp/sunstudio10-sparc.tar.bz2 | tar xf
-

完整产品的安装具有自己的安装程序和一个包括安装说明在内的完整手册。有关详细的安装说明(包括如何使用图形和文本安装方法),请参见 http://docs.sun.com/app/docs/doc/819-0485。如 果使用完整产品,则在生成 OpenSolaris 组件之前,需要安装所需的修补程序;下载的产品通常附带有这些修补程序。有关所需修补程序的更多信息,请参见 http://opensolaris.org/os/community/tools/sun_stud io_tools/。缺省情况下,Studio 10 产品安装到 /opt/SUNWspro 中。除非具有需要保留的现有 Sun Workshop/Forte/Studio 安装,否则不应更改此安装位置。

示例:作为完整产品安装 Studio 10 编译程序

假定已将产品下载到 /var/tmp/sunstudio10-x86.tar 中,您希望将其在 /var/tmp/studio-install 中解压缩,并已收到许可证密钥 'ABC123'。可以按如下所示进行安装:

 $ mkdir /var/tmp/studioinstall

$ cd /var/tmp/studioinstall
$ tar xf /var/tmp/sunstudio10-x86.tar
$ su
Password:
# ./batch_installer -s ABC123
...
# cd patches
# patchadd -M . patchlist
...

缺省情况下,所需的 gcc 版本作为 Solaris Express 内部版本 22 和更高版本的一部分安装。如果使用其他分发,请参阅供应商的文档以确定您的 gcc 版本是否充分。

2.4 获取和安装自定义工具

除了常规开发工具和编译程序外,还需要名为 ``onbld'' 的一组自定义工具。这包括用于处理编译程序与汇编程序兼容性、 CTF 数据、ABI 审计、 ON 位的安装等的脚本和程序。其中的许多实用程序是平台特定的;因此,我们为支持的所有平台(当前为 x86 和 SPARC)提供了 SUNWonbld 软件包版本。请 注意,这些工具是通过 ON 源代码 gate 的 usr/src/tools 子目录中的源代码生成的。有关源代码位置的更多信息,请参阅 3.2 节中的“ON 工作区介绍”。如果具有可用的源代码,则 不必安装 SUNWonbld;但是,在引导 ON 安装时可能会遇到相关性问题。可以从 http://opensolaris.org/os/downloads/on/ 获取此软件包。请注意,生成某些范围的 ON 源代码可能需要某些版本的 onbld;如果需要使用较早版本的源代码,请务必检查该版本的 onbld 版本需求。

对于每个支持的生成计算机体系结构,ON 特定的生成工具作为 SVR4 (pkgadd(1M)) 软件包提供。该软件包将安装到 /opt/onbld 中。

示例:安装 ON 生成工具

假定已将生成工具软件包下载到 /var/tmp/SUNWonbld-20050613.tar.bz2 中,而且希望安装它。可以按如下所示进行安装:

$ cd /var/tmp $ bzip2 -dc SUNWonbld-20050613.i386.tar.bz2 | tar xf - $ su Password: # pkgadd -d . SUNWonbld

2.5 环境变量

为了成功使用源代码管理和生成工具,需要正确设置几个环境变量。其中的大多数变量是 工作区特定的(请参见 3.3.1 节)或生成特定的(请参见 4.1 节)。但是,为了成功使用已安装的工具,需要正确设置 PATH 环境变量。这 通常应该作为登录脚本的一部分完成,以便它可以自动完成。

始终可以从网关的 public/README 文件中获取有关建议的 PATH 组件的最新信息。可以在 http://opensolaris.org/os/community/onnv/gate_info /README 上找到此文件的副本。

PATH 由 shell 和其他程序用来确定在何处查找程序。此功能与 OpenSolaris 没有任何关系,但是为了查找生成工具所需的各种程序,PATH 除了需要标准系统目录外,还需要几个元素。a a a 通常,这些元素是:

        /opt/SUNWspro/bin

/opt/onbld/bin
/opt/onbld/`uname -p`/bin

如果已在非标准位置(未建议使用的位置)中安装了编译程序或 onbld 工具,则需要相应地修改这些位置。此外,必须确保将 /usr/ccs/bin 包括在 PATH 中;更具体地说,它必须在 /usr/ucb 之前(如果 PATH 中包括 /usr/ucb 目录的话)。例如,综上所述,一个有效的 PATH 可能与以下示例类似:

        $ echo $PATH

/usr/bin:/usr/sbin:/usr/ccs/bin:/usr/dt/bin:/usr/o
penwin/bin: \

/opt/onbld/bin:/opt/onbld/bin/sparc:/opt/sfw/bin:/usr
/sfw/bin

有关详细信息,请参见网关的 public/README 文件。

建议不要在 PATH 中包括 /usr/ucb,而且生成过程不需要此位置中的任何程序。如果由于其他某种原因而必须包括它,请确保它是最后一个组件。否则,包括 /usr/ucb 将导致生成失败,尤 其是它在 /usr/sbin 之前时。

请注意,一些工具的路径是在 usr/src/Makefile.master 和其他 makefile (make 程序的描述文件)中显式设置的,因此更改 PATH 本身可能达不到您期望的效果。具 体来说,编译程序路径是固定的。如果需要对此进行更改,则必须覆盖用于指定编译程序位置的 make 宏。有关这一点的更多信息,请参见 4.1 节。

除了 PATH 外,您可能发现将 /opt/onbld/man 和 /opt/SUNWspro/man 添加到 MANPATH 是很有帮助的。这样,就 可以更轻松地阅读与本文档中讨论的许多实用程序关联的手册页。或者,需要将 '-M /opt/onbld/man' 或 '-M /opt/SUNWspro/man' 添加到对 man(1) 的调用,以便查看这些页。


3 源代码树

本章讨论如何获取、管理和修改 OpenSolaris。与本文档的大部分内容一样,本章着重介绍 ON 整合。不过,其他大多数整合所需步骤与之非常类似。应始终查阅整合的发行说明以了解最新信息。始终欢迎为非 ON 整合的这一参考撰稿。

3.1 检索源代码

大多数的整合是作为 tarball 提供的;在接下来的几个月中,有几个整合还将开始提供只读的 Subversion 系统信息库。不管使用什么方法获取源代码,内容都是相同的。

3.1.1 通过 Tarball 获取源代码

可以在 http://opensolaris.org/os/downloads/ 上获取所有已发行整合的 tarball。如果计划生成源代码,并希望生成完整的安装集,则可能还需要不公开的二进制代码(倘若感兴趣的整合未完全公开),您可以从同一位置获取这些代码。务必获取适合于您平台的二进制代码。之后,请 按如下所示创建您的 工作区

$ mkdir /path/to/workspace $ cd /path/to/workspace $ bzip2 -dc /path/to/tarball/on-src-<ver>.tar.bz2 | tar xf - $ bzip2 -dc /path/to/tarball/on-bins-<ver>.{x86,sparc}.tar.gz | tar xf -

3.2 ON 工作区介绍

创建和填充 工作区后,可以开始浏览源代码树的内容。本节介绍 ON 工作区的布局和内容。

3.2.1 结构

最初, 工作区将只有一个目录:usr。完成生成后,可能具有几个其他目录,其中包括 archives、log、packages 和 proto。在此处包括了一个图表,g g g 以显示所有这些目录及其子目录。还包括了生成子目录(它们包含对象文件),将在下面的 2-4 小节中进行更详细的介绍。

如果已完成 nightly(1) 生成,则在顶层中还将具有一个日志目录。它将包含来自 nightly(1) 生成过程的完整输出。有关 nightly(1) 和它生成的日志文件的更多信息,请参见 4.2 使用 nightly 和 bldenv

在 usr/src 下可找到所有的源代码。这包括用于生成 ON 整合的源代码,以及需要生成但未作为 Solaris 的一部分提供的工具和其他外围设备实用程序的源代码。由于它仅包括 ON 源代码,因此它不包含 Java、窗 口系统或打包和安装工具。由于合同中有规定,所以不能包括第三方硬件供应商的所有代码。usr/src 目录具有若干个子目录,以下将分别加以介绍。

cmd

此目录包含属于 ON 的可执行程序和脚本的源代码。它包括所有的基本命令、守护进程、启动脚本和相关数据。大多数子目录根据其中包含的一个或多个命令命名,但也有例外情况,此 处将列出一些属于这些例外情况的目录。

cmd/Adm

各种关键系统文件,如安装在 /etc 中的 crontab 和数据。

cmd/cmd-crypto

基本的加密实用程序,如 elfsign 和 kcfd。

cmd/cmd-inet

网络命令和守护进程,包括 Berkeley r 命令、PPP、telnet、inetd 超级服务器和其他网络相关的实用程序。

cmd/fs.d

用于检查、挂载、取消挂载和分析文件系统的实用程序。

cmd/netfiles

安装到 /etc 中的 IP 端口定义和名称服务转换器配置文件。

cmd/ptools

用于处理和观察进程的实用程序;它们基于 proc(4) 和 libproc 接口。

cmd/sgs

软件生成系统。此目录包含二进制实用程序(如 ld(1)、ar(1) 和 mcs(1))和开发工具(如 lex(1)、yacc(1) 和 m4(1))。请注意,此目录还包括几个这些工具所用的库和头。

common

cmd、lib、stand 和 uts 的公用文件。这些文件通常包括由内核和用户程序使用的基本库的头和源代码。

head

用户区头文件(内核头在 uts/ 中)。请注意,应仅将 libc 头存储在此处;其他库应该在 lib/ 下它们自己的子目录中存储其头。

lib

库。大多数子目录是根据其中包含的源代码所属的库命名的,或者是使用其他可自解释的名称。

pkgdefs

对于从 ON 源代码生成的每个软件包都将包含一个子目录。每个子目录都包含打包信息文件;有关这些文件的内容的更多信息,请参见 pkginfo(4)、 depend(4)、prototype(4)、pkgmap(1) 和 pkgproto(1)。

prototypes

显示格式和版权声明的样例文件。

psm

平台特定的模块。目前,仅包含 OBP 和大多数引导代码。

stand

独立环境代码。此代码用于引导;例如,用于从 UFS 和网络进行读取的代码就位于此处。

tools

开发工具和源代码。有关每种工具的更多信息,请参见 README.tools;添加或删除工具后,应该更新该文件。

ucbcmd

安装到 /usr/ucb 中的命令和守护进程(用于 SunOS 4.x 兼容性)。

ucbhead

安装到 /usr/ucb 中的头文件(用于 SunOS 4.x 兼容性)。

ucblib

安装到 /usr/ucb 中的库(用于 SunOS 4.x 兼容性)。

uts

内核源代码位于此处(UTS == UNIX 分时)。需要关注 uts 的许多子目录:

uts/adb

adb 包含过时的内核调试器宏;不再支持它,此目录现在为空。请改用 mdb(1),编写 mdb dcmds 而不是 adb 宏。

uts/common

所有与平台无关的内核源代码。几乎所有的 Solaris 内核都位于此处;只有几个比较小的部分是与体系结构有关的。

uts/common/c2

用于支持 C2 美国政府安全标准的审计代码。

uts/common/conf

系统配置参数。

uts/common/contract

用于支持进程合同的代码。有关进程合同的更多信息,请参见 contract(4) 和 libcontract(3LIB)。

uts/common/cpr

对检查点和恢复的支持。用于实现暂停和恢复功能。

uts/common/crypto

内核加密框架。有关更多信息,请参见 kcfd(1M) 和 cryptoadm(1M)。

uts/common/ctf

用于处理紧凑 C 类型格式数据的代码。

uts/common/des

实现旧的数据加密标准。由 KCF 使用。

uts/common/disp

分发程序、线程处理和调度类。

uts/common/dtrace

与 CPU 无关的 dtrace(7D) 内核支持。

uts/common/exec

用于处理用户区二进制可执行文件类型(a.out、ELF 等)的代码。

uts/common/fs

文件系统。

uts/common/ssapi

通用安全服务 API。

uts/common/inet

IP 联网子系统,包括 IPv6。

uts/common/io

I/O 子系统。此目录中的大多数代码是设备驱动程序(以及伪设备驱动程序)。

uts/common/ipp

IP 策略框架;包括 QoS 和其他通信管理。

uts/common/kmdb

内核模块化调试器。请参见 kmdb(1)。

uts/common/krtld

内核运行时链接程序/装载器。它负责处理可装入的模块和符号解析;它与 ld.so.1 类似,并与其共享代码。

uts/common/ktli

内核 TLI(Transport Layer Interface,传输层接口)。

uts/common/net

头文件;大多数头文件在 /usr/include/net 中提供。

uts/common/netinet

头文件;大多数头文件在 /usr/include/netinet 中提供。

uts/common/nfs

在 /usr/include/nfs 中提供的网络文件系统头。

uts/common/os

核心操作系统的实现。这包括诸如权限、区域、计时器、DDI/DKI 接口和高级锁定机制等在内的各个方面。

uts/common/pcmcia

PCMCIA I/O 子系统和驱动程序。

uts/common/rpc

由诸如 NFS 和 NIS 之类的服务使用的远程过程调用子系统。

uts/common/rpcsvc

在 /usr/include/rpcsvc 中提供的已生成的 RPC 头文件。

uts/common/sys

在 /usr/include/sys 中提供的头文件。这些相同的头还用于生成内核(如果定义了 _KERNEL 预处理程序符号)。

uts/common/syscall

系统调用的实现。大多数系统调用是在与其名称匹配的文件中实现的。请注意,一些系统调用是在 os/ 或其他子目录中实现的。

uts/common/tnf

旧的跟踪子系统,与 dtrace(7D) 无关。

uts/common/vm

虚拟内存子系统。

uts/common/zmod

压缩/解压缩库。

uts/i86pc

用于 x86 计算机的与体系结构有关的文件。与体系结构有关的目录(i86pc、 sun、sun4、sun4u)都具有一组与上面的 common/ 类似的子目录。

uts/intel

用于 x86 计算机的与 ISA 有关但与体系结构无关的文件。请注意,所有与体系结构无关的源文件都内置到此分层结构的对象中。

uts/sfmmu

特定于 SpitFire 内存管理单元 (UltraSPARC) 的代码。

uts/sparc

用于 SPARC 计算机的与 ISA 有关但与体系结构无关的文件。请注意,所有与体系结构无关的源文件都内置到此分层结构的对象中。

uts/sun

所有 Sun 实现的公用源代码。目前,包含少数设备驱动程序和在 /usr/include/sys 中提供的一些头。

uts/sun4

所有 sun4* 计算机体系结构的公用源代码。

uts/sun4u

用于 sun4u 体系结构的与体系结构有关的源代码。每个系统实现在此处都有一个相应的子目录:

* blade Serverblade1
* chalupa Sun-Fire-V440
* cherrystone Sun-Fire-480R
* daktari Sun-Fire-880
* darwin Ultra-5_10
* enchilada Sun-Blade-2500
* ents Sun-Fire-V250
* excalibur Sun-Blade-1000
* fjlite UltraAX-i2
* grover Sun-Blade-100
* javelin Ultra-250
* littleneck Sun-Fire-280R
* lw2plus Netra-T4
* lw8 Netra-T12
* makaha UltraSPARC IIe-NetraCT-40、UltraSPARC IIe-NetraCT-60
* montecarlo UltraSPARC IIi-NetraCT
* mpxu Sun-Fire-V240
* quasar Ultra-80
* serengeti Sun-Fire
* snowbird Netra-CP2300
* starcat Sun-Fire-15000
* starfire Ultra-Enterprise-10000
* sunfire Ultra-Enterprise
* taco Sun-Blade-1500
* tazmo Ultra-4

3.2.2 对象目录

创建对象文件和最终的二进制代码(可执行文件和库)时,可以使用以下两种基本策略:

(a) 将对象放置在与源代码平行的专用目录分层结构中

(b) 将对象放置在用于生成这些对象的源代码所在的同一目录中

实际上,ON 在树的不同部分中使用了以上这两种方法之一。策略 (a) 必须用于所有内核代码和许多库,对于新代码应首选此策略,此处将对其进行详细介绍。在策略 (a) 以及仍使用策略 (b) 的实例中有几处传统变动;其中大部分在 cmd 分层结构中。整个 uts 分层结构都已转换为策略 (a),如下所述;您将看到在树的其余部分中大都使用此方法。

3.2.2.1 内核对象的常规策略

首先,每个与平台无关的模块在每个体系结构中都有零个或一个生成目录。在这里体系结构可以指计算机(sun4u、i86pc)或处理器体系结构(intel、 sparc)。此位置的路径始终是 usr/src/uts/<platform>/<module>。这里的模块名称是指在 /kernel/drv 或类似位置中找到的内容,而且前提是这些设备驱动程序或 STREAMS 模块应始终与描述它们的手册页的名称匹配。

对于原始树,此目录中通常包含的文件只有 makefile。在生成后,这些目录包含 obj32、obj64、debug32 和 debug64 目录中的一个或多个。这 些目录包含对象文件和最终链接的模块(它们稍后将安装到原型中的内核目录和其他位置)。

在“指令集体系结构”目录(即:sparc)下的各个目录中生成与“实现体系结构”无关的模块(每个模块对应一个目录)。同样,在“实现体系结构” 目录(即:sun4、sun4u、i86pc)下 的各个目录中生成与“实现体系结构” 有关的模块。

与平台有关的模块(包括 ``unix'')可能会在不同位置多次生成。将在 <节> 中更详细地介绍与平台有关的模块。

源代码未包含在这些生成目录中。

3.2.2.2 命令/库对象的常规策略

用于生成大多数的库以及一些命令和守护进程的 makefile 与用于生成内核的 makefile 非常类似。因此,中间对象、共享对象、库和可执行文件是由小的 makefile 片段生成的,并 放置在 ISA 特定的专用子目录中。

其他命令的生成系统将对象放置在与源代码相同的目录中。有关如何生成命令的更多信息,请参阅 3.2.2.3、3.2.3.2 和 3.2.5 节。

3.2.2.3 cmd 和 lib 中的例外

大多数的 cmd 树直接基于原始的 System V Release 4 源代码,使用如上所述的策略 (b)。由于大多数的命令和守护进程无需同时提供 32 位版本和 64 位版本,或 者在针对不同的体系结构生成时无需执行任何特殊操作,因此对于大多数命令来说,此策略非常适用,甚至已应用于新的子目录。在需要使用与体系结构有关的生成选项或者必须提供某程序的多个 ISA 版本的情况下,此 策略是不可行的,必须改用按不同 ISA 建立多个对象目录的更常规方法。后一种方法与用于内核模块的方法类似。

lib 分层结构更简单一点;几乎所有的子目录都必须使用按 ISA 的对象文件位置和 makefile。

有几个目录看起来未遵循任何规则或模式,如 cmd/cmd-inet 和 cmd/agents。这些目录主要是 Sun 的内部项目结构遗留下来的目录。

3.2.3 makefile 布局

此论述旨在提供有关存在哪些目标以及它们如何由 makefile 生成的逐步说明。此处忽略了平台特定的模块体系结构,因为它不大可能是大家所重点关注的,当然硬件支持工程师除外。所 关注的三个主要子树是内核 (uts)、命令和守护进程 (cmd) 以及库 (lib)。接下来的三个小节依次介绍这三个子树。还有少数几个适用于所有内部版本的 makefile:

usr/src/Makefile

这是顶层 makefile。它促使在每个子目录中生成各个目标。它识别需要在每个子目录中生成的特定目标以便执行完整的生成,而且它自己知道如何创建框架 proto 区域,以便供 install 和 install_h 目标日后使用。

usr/src/Makefile.lint

从顶层开始的所有 lint 检查都由此 makefile 驱动。它包含已知要进行 lint 检查的目录的长列表,还包含用于重新生成每个子目录的 lint 目标的简单递归规则。实际的 lint 检查由较低级别的 makefile 驱动。& amp; lt; /p>

usr/src/Makefile.master
usr/src/Makefile.master.64

这两个 makefile 包含通用定义(如生成和安装工具的位置、其他 makefile 在定义规则时使用的编译程序、链接程序和其他工具的模板宏)和全局定义(如适用于此生成的 ISA 和计算机名称)。Makefile.master.64 包含特定于 64 位生成的定义,这些定义将覆盖通用定义。

usr/src/Makefile.msg.targ

此处定义了用于生成信息目录的公共目标。信息目录提供信息转换,以用于全球化目的。

usr/src/Makefile.psm

此 makefile 定义平台特定的模块的安装位置。这些位置与其他内核模块安装位置 /kernel 和 /usr/kernel 类似(有关内核模块安装的更多信息,请参见下面的 3.2.6 节)。/ / < /p>

usr/src/Makefile.psm.targ

此处定义平台特定的模块的安装目标定义。它指示生成系统如何将文件安装到 Makefile.psm 定义的目录中。

usr/src/Targetdirs

这是将在安装过程中创建的每个目录的属主、组和权限的一组定义。它还包含有关为某些 64 位库版本安装的特殊符号链接的信息。

3.2.3.1 内核 makefile 布局

任何模块的驱动 makefile 都位于叶目录(生成目录)中,模块及其组件对象是在该目录中生成的。在执行 'make clobber' 操作后,makefile 应该是该目录中剩余的唯一文件。树 中存在两种其他类型的 makefile:带后缀的和不带后缀的。所有叶 makefile 所需的公共定义和规则包含在带后缀的 makefile 中;这些带后缀的 makefile 包括在叶 makefile 中。不带后缀的 makefile 通常调用具有相同目标的多个较低级 makefile,以便可以通过单个生成调用来生成多个模块。

uts/Makefile
uts/sparc/Makefile
uts/sun4u/Makefile
uts/intel/Makefile
uts/intel/ia32/Makefile
uts/i86pc/Makefile

这些 makefile 通常可识别在子目录中建立的组件,并调用这些子目录中的 makefile 以执行实际的生成。一些目标(或伪目标)可以直接在此级别上生成(如 cscope 数据库)。& amp; lt; /p>

uts/Makefile.uts

包含所有可能的体系结构的公共定义。

uts/Makefile.targ

包含所有可能的体系结构的公共目标。

uts/common/Makefile.files
uts/sun/Makefile.files
uts/sparc/Makefile.files
uts/sun4/Makefile.files
uts/sun4u/Makefile.files
uts/intel/Makefile.files
uts/intel/ia32/Makefile.files
uts/i86pc/Makefile.files

这些 makefile 被分为两部分。第一部分定义构成每个模块的对象列表。第二部分定义相应的头搜索路径和其他计算机特定的全局生成参数。

uts/common/Makefile.rules
uts/sun/Makefile.rules
uts/sparc/Makefile.rules
uts/sun4/Makefile.rules
uts/sun4u/Makefile.rules
uts/intel/Makefile.rules
uts/intel/ia32/Makefile.rules
uts/intel/amd64/Makefile.rules
uts/i86pc/Makefile.rules

这些文件提供允许 make 在多目录环境中起作用的生成规则(目标)。该目录下包含 makefile 的每个源代码树都在文件中具有一个生成规则。

uts/sun4/Makefile.sun4
uts/sun4u/Makefile.sun4u
uts/intel/Makefile.intel
uts/intel/ia32/Makefile.ia32
uts/i86pc/Makefile.i86pc

这些 makefile 包含特定于明显的“实现体系结构”的定义(缺省定义)。如有必要,可以在特定的叶节点 makefile 中覆盖这些规则。

Makefile.*.shared

这些 makefile 提供在开放源代码 makefile 和仅在 Sun 内部使用的不公开源代码 makefile 之间共享的设置。有关更多详细信息,请参见 3.2.8 未包括的源文件

uts/sun4u/unix/Makefile
uts/i86pc/unix/Makefile

用于生成 unix 的主驱动 makefile。

uts/sun4u/MODULE/Makefile(用于 cgsix、c pu、kb 等中的 MODULE)

用于生成 MODULE 的主驱动 makefile。

uts/sun4u/genunix/Makefile
uts/i86pc/genunix/Makefile

用于生成 genunix 的主驱动 makefile。

在 uts 目录中发出命令 'make',将导致生成所有支持的模块化内核和模块。

在 uts/ARCHITECTURE 目录(即:uts/sparc)中发出命令 'make',将导致生成用于 ARCHITECTURE 的所有支持的与“实现体系结构”无关的模块。

在 uts/MACHINE 目录(即:uts/sun4u)中发出命令 'make',将导致生成该内核和用于 MACHINE 的所有支持的与“实现体系结构”有关的模块。

对 makefile 进行了详细注释。要求它们应保持这样。

3.2.3.2 命令 makefile 布局

大多数的命令和守护进程子目录遵循两个常规布局规则之一,具体取决于对象文件所在的位置(请参见 3.2.2.2 和 3.2.2.3 节)。对于与 ISA 有关的程序,布局类似于内核所用的布局。不 需要与 ISA 有关的生成行为的程序使用简化的 makefile 布局。在此处的描述中,我们以其源代码位于 usr/src/cmd/foocmd 中的通用命令 ``foocmd'' 为例。与生成 foocmd 有关的 makefile 是:

usr/src/cmd/Makefile

所有命令/守护进程的顶层驱动 makefile。这是一个简单的递归 makefile,它知道应该生成哪些子目录,并将导致在每个子目录中重新生成给定的目标。

usr/src/cmd/Makefile.cmd

此 makefile 定义安装目录和用于向其中安装可执行文件的规则。

usr/src/cmd/Makefile.cmd.64

此处提供特定于 64 位生成的其他定义。

usr/src/cmd/Makefile.cmd.bsm

此专用 makefile 仅由 auditstat 和 dminfo 使用。它提供一些通用模板规则。

usr/src/cmd/Makefile.targ

clobber、lint 和安装的基本目标定义。

usr/src/cmd/foocmd/Makefile

用于 foocmd 的驱动 makefile。通常定义 PROG,但在其他情况下仅包含模板定义和目标。它几乎始终是从其他类似的 makefile 复制的。如果 foocmd 不需要与 ISA 有关的生成行为,则通常会直接指定规则,包括安装目标的规则。如果 foocmd 确实需要与 ISA 有关的生成行为,则此 makefile 将改为定义 SUBDIRS,以包括必须生成的、ISA 特定的版本,并以递归方式定义目标。这通常会保留每个 ISA makefile 的安装目标定义,并导致创建指向 $(ISAEXEC) 的链接。有关平台相关性和 $(ISAEXEC) 的更多信息,请参见 3.2.5 节。

usr/src/cmd/foocmd/Makefile.com

定义 PROG、OBJS、SRCS,并包括 Makefile.cmd。可能还包含用于编译或链接的其他标志。此 makefile 通常定义 all、$(PROG)、clean 和 lint 的目标;此部分通常是通用的,而且通常是从其他类似的 makefile 复制的。

usr/src/cmd/foocmd/*/Makefile

ISA 特定的 makefile,它可能定义 ISA 特定的其他标志或目标,通常包括自己的安装目标,以便安装由它生成的、ISA 特定的程序。

3.2.3.3 库 makefile 布局

大多数的库子目录遵循相同的常规布局,与命令布局类似。与命令不同,大多数的库是为 32 位和 64 位体系结构变体生成的,这样 ISA 特定的目录几乎始终存在。因此,每 个库的总体生成结构与内核的总体生成结构类似。有关库 makefile 的更多详细信息,请参见 3.3.3.3 添加新库

3.2.4 makefile 操作

本节详细介绍如何构建生成相关性和规则,以及每个单独的 makefile 如何在生成过程中起作用。了解 makefile 的工作原理后,修改现有生成规则和创建新生成规则就变得非常简单,只 需复制现有文件并对其进行少量修改即可。首先介绍内核 makefile 操作,然后介绍非常类似的命令和库 makefile 操作。

3.2.4.1 内核 makefile 操作

生成相关性由两部分组成:一组目标和一组规则。

规则包含在 uts 下每个目录的 Makefile.rules 文件中。它们涉及如何将某个其他目录(例如 common/io)中的源文件编译到如上所述的生成目录的对象文件中。它 们还说明生成给定的对象文件需要哪些源代码。如果存在多个与同一基本名称匹配的源文件,则指定它们的顺序将决定需要哪些源文件。理解所有这一切的关键是了解所有规则和目标都是静态的且与模块无关,而 在每个模块的生成目录(叶)makefile 中设置的变量定义了模块特定的生成信息。

目标分为两种:第一种是“生成目标”,即可以为 make 指定的通用指令(如 ``all'' 或 ``install''),它们在每个生成目录中执行。生成目录 makefile 又包括含有用于生成对象和模块的规则的其他 makefile。第二种目标类型更有趣-它们是必须生成的实际模块名称(实际上为目录)。这些变量称为 KMODS 和 XMODS。

例如,如果 KMODS 包含 ``aac ata asy'',则对于 aac、ata 和 asy 这些生成目录的每一个,生成系统都将转到该目录,对提供的任何目标(all,install 等)重 新运行make。该模块的规则源自包括的所有 makefile;要查找的关键变量的格式是 XXX_OBJS,其中 XXX 是模块名称。由于生成模块可能需要每个平台上的不同对象,因此可能有多个 makefile 包含将添加到其中每个对象列表的定义。

XMODS 仅用于生成商业 Solaris 产品的输出版本;而在生成 ON 时不使用它。

因此,我们可能看到以下内容:

        common/Makefile.files:ASY_OBJS +=      asy.o

这指示需要有 asy.o 对象才能生成 ASY 模块。<platform>/asy 目录中的 makefile 将引用 ASY_OBJS,这样就知道要生成的内容。因此,在 intel/asy/Makefile 中将看到:

        MODULE          = asy

OBJECTS = $(ASY_OBJS:%=$(OBJS_DIR)/%)

那么,这有什么作用?当然,有很多作用。由于还定义了 ALL_TARGET:

        ALL_TARGET      = $(BINARY) $(SRC_CONFILE)

Makefile.uts 将按如下所示定义 BINARY:

        BINARY             = $(OBJS_DIR)/$(MODULE)

OBJS_DIR 是在开头介绍的单个模块生成目录。这样,make 即知道我们需要生成 usr/src/uts/intel/asy/obj32/asy。Makefile.targ 也定义这样做的规则:

        $(BINARY):              $(OBJECTS)

$(LD) -r $(LDFLAGS) -o $@ $(OBJECTS)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
$(ELFSIGN_MOD)

我们马上就要完成了-OBJECTS 必须来自某个位置。我们发现这已在 intel/asy/Makefile 中定义:

        OBJECTS         = $(ASY_OBJS:%=$(OBJS_DIR)/%)

就是它了。我们有一个模块 (asy),它具有依赖于从 ASY_OBJS 生成的 OBJECTS 的 BINARY (obj32/asy)。ASY_OBJS 中每个项的规则在其中一个 Makefile.rules 文件中;它们看起来与以下内容类似:

        $(OBJS_DIR)/%.o:             

$(UTSBASE)/common/io/%.c
$(COMPILE.c) -o $@ ___FCKpd___23lt;
$(CTFCONVERT_O)

每个对象都是根据这些规则生成的。然后 $(BINARY) 的规则将它们链接到模块。

现在,我们可以将其汇集在一起。宏和本地按模块定义的广泛使用大大提高了灵活性,但是在所给的示例中,等效的 makefile 片段看似非常熟悉:

        KMODS +=        asy

        all:    $(KMODS)

        asy:    obj32/asy.o

$(LD) -r $(LDFLAGS) -o $@ obj32/asy.o
...
        obj32/asy.o:    ../../common/io/asy.c

$(CC) $(CFLAGS) $(CPPFLAGS) -c ___FCKpd___27lt; -o $@
...

3.2.4.2 命令 Makefile 操作

不同的命令 makefile 有很大差异,如上面所述。因此,要提供命令 makefile 的一个“典型示例”是不可能的。但是,如果理解了第 3.2.4.1 和 3.3.3.3 节中的示例,您 就可以了解如何使用命令 makefile。与往常一样,如果要查找有关特定命令的信息,最好使用邮件列表和其他社区资源。

3.2.4.3 库 Makefile 操作

第 3.3.3.3 节详细介绍了库 makefile 操作。

3.2.5 ISA 相关性

OpenSolaris 中的大多数代码为一般代码,并且与平台和 ISA 无关;即,这些代码是可移植代码,可以在任何能够使用适当编译器的系统上进行编译和运行。但是,即 使可移植的代码有时也必须处理运行这些代码的系统的特定属性,或者必须针对多种支持的体系结构进行编译,以便用户可以运行或链接他们选择的特定于体系结构的版本。

两种不同情况下必须提供多种特定于体系结构的版本:命令(本质上,必须可以查看系统的硬件特征)和库(必须针对开发者可能希望实现的每一种体系结构而单独生成)。在下面的小节中将分别讨论每一种情况。& amp; lt; /p>

3.2.5.1 与 ISA 有关的命令

命令(一般为可执行程序或守护进程)通常不依赖于执行这些命令的 ISA;即,无论这些命令面向的 ISA 类型如何,它们的生成和安装方式都是相同的。但是,根据系统和/或其目标支持的 ISA,一 些命令(主要是那些操作其他进程或处理二进制对象的命令)的行为必须不同。/usr/lib/isaexec 包装程序按照以下方法提供此行为:

首先,将一个或多个特定于 ISA 的程序安装到系统中特定于 ISA 的目录。这些目录是通常包含可执行程序(如 /usr/bin)的那些目录的子目录。在 SPARC 系统中,ISA 子目录可能包括 /usr/bin/sparcv7 和 /usr/bin/sparcv9,它们分别包含 32 位和 64 位二进制程序。其他系统可能支持其他 ISA;可以使用 isalist(1) 了解您的系统支持哪些 ISA。

接下来,将指向 /usr/lib/isaexec 的硬链接安装到普通二进制程序目录(在上面的示例中,为 /usr/bin)。这将导致使用用户已执行的与 ISA 有关的程序的名称调用 isaexec。

发生此情况时,isaexec 将选择在第一步中安装的最合适的特定于 ISA 的程序,并执行 (exec(2)) 它。此操作是透明的,因此用户不会注意到调用了独立的程序。

特定于平台的程序存在类似的机制 (/usr/lib/platexec);这些程序远不及特定于 ISA 的程序常用。

由于需要与用户进程和内核数据结构交互,dtrace(1) 即是一种必须提供多个特定于 ISA 的版本的命令。

cmd/dtrace 包含两个 makefile:Makefile 和 Makefile.com。它还包含一个源文件 (dtrace.c) 和四个 ISA 目录:amd64、i386、s parc 和 sparcv9。每个目录包含一个 makefile。在浏览 uts makefile 之后,顶层 makefile 看上去会很熟悉;Makefile 主要为模板文本,其 自定义的目的仅仅是指定生成的程序是特定于 ISA 的,因此需要在样例区域的 /usr/sbin 中安装指向 isaexec 程序的链接:

        install:        $(SUBDIRS)

-$(RM) $(ROOTUSRSBINPROG)
-$(LN) $(ISAEXEC) $(ROOTUSRSBINPROG)

否则,它就只会将所有生成和安装任务留给 ISA 子目录中的 makefile 来完成。Makefile.com 也为样本文件;它指定要生成的程序的名称和必须通过其生成的对象。

        PROG = dtrace

OBJS = dtrace.o

然后,它将这些对象转换为源代码:

        SRCS = $(OBJS:%.o=../%.c)

并包括用于选取生成规则的一般顶层 Makefile.cmd 片段。

指定编译和链接标志:

        CFLAGS += $(CCVERBOSE)

CFLAGS64 += $(CCVERBOSE)
LDLIBS += -ldtrace -lproc

其余部分由少量通用生成规则组成。值得注意的一个特征是:此片段的所有路径之前都加上了额外的 ../。这是因为由特定于 ISA 的生成目录(比 Makefile.com 本身要低一层)解释的 makefile 始终包括该项。

特定于 ISA 的生成目录中的 makefile 甚至更简单;它们分别都仅由两行组成。

        include ../Makefile.com

        install: all $(ROOTUSRSBINPROG32)

第一行选取所查看的 makefile 中的所有通用定义,第二行指定(间接)将安装程序的位置。要完成该描述,需要简单查看 usr/src/cmd/Makefile.cmd ( 定义可以安装程序的各种位置)。由于尚未定义 ROOTUSRSBINPROG32,因此必须在该位置进行定义,实际定义如下:

        ROOTUSRSBIN=    $(ROOT)/usr/sbin

ROOTUSRSBINPROG=$(PROG:%=$(ROOTUSRSBIN)/%)
ROOTUSRSBIN32= $(ROOTUSRSBIN)/$(MACH32)
ROOTUSRSBINPROG32=
$(PROG:%=$(ROOTUSRSBIN32)/%)

请注意,程序实际安装在 /usr/sbin/$(MACH32) 中,该目录通常不位于用户的搜索路径中。但是请记住,我们还创建了从 $(ROOTUSRSBINPROG) 到 $(ISAEXEC) 的链接;扩展这些变量将显示,实际上将安装两个独立的文件:

        $(ROOT)/usr/sbin/dtrace         ->

$(ROOT)/usr/lib/isaexec
$(ROOT)/usr/sbin/$(MACH32)/dtrace (our executable
program)

由于 isaexec 程序负责从依赖于系统支持的指令集的多个选项中选择特定于 ISA 的程序,因此可以看到,典型系统都将安装一个或多个 dtrace(1) 二进制程序,并且用户运行 dtrace(1) 时,isaexec 将从那些安装位置为 /usr/sbin 的特定于 ISA 的子目录的程序中选择一个合适的程序。正如所期望的一样,cmd/dtrace 下的其他特定于 ISA 的 makefile 将其二进制程序安装到 ROOTUSRSBIN64 中,并在 usr/src/cmd/Makefile.cmd 中进行定义。

3.2.5.2 与 ISA 有关的库

与命令不同,库必须始终针对所有支持的 ISA 生成,且必须至少在支持该 ISA 的每个系统上安装独立的特定于 ISA 的版本。实际上,将针对系统的处理器系列中每个 ISA 分别安装库。这 使系统的开发者可以使用任何支持的 ISA 编写程序,并将这些程序与适当的系统库链接(有时候会无法链接,例如,无法将 32 位对象文件和 64 位库链接,反之亦然)。

这些库使用的生成系统与命令(必须提供多种特定于 ISA 的可执行程序的命令)所使用的生成系统非常相似。此时,检查 dtrace(1) 的对应库 libdtrace(3LIB) 使用的 makefile,以及这些 makefile 支持生成和安装多种特定于 ISA 的 dtrace 库版本的方式。

lib/libdtrace 包含两个 makefile:Makefile 和 Makefile.com。它还包含一个用于存储通用代码的目录和四个以下 ISA 目录:amd64、i386、s parc 和 sparcv9。每个 ISA 目录都包含一个 makefile,在某些情况下,会包含一些特定于 ISA 的源代码。顶层 Makefile 应同样看上去很熟悉;与 uts 和 cmd makefile 非常相似,主要为样板文件。其中包括一些自定义,用于添加 yydebug 目标和指示顶层 makefile:lex 和 yacc 生成的文件不应具有针对这些文件的交叉引用。

        yydebug := TARGET = yydebug

...
lint yydebug: $(SUBDIRS)

        XRDIRS = common i386 sparc sparcv9

XRDEL = dt_lex.c dt_grammar.c Makefile*

否则,它就只会将所有生成和安装任务留给 ISA 子目录中的 makefile 来完成。Makefile.com 更有意义一些。它首先指定要生成的库的名称(采用静态格式;共享库名称将被转换,可 以在下文中看到)和库版本。它们对于所有库 makefile 是通用的。接下来,可以看到用于生成库的源文件的长列表和 OBJECTS 规范。此特定库还具有一些唯一的特征,包括 D 运行时初始化代码( 作为独立的对象文件 (drti.o) 生成)和一些 D ``header'' 文件(安装到独立目录 /usr/lib/dtrace 中)。从下面可以看到这些唯一特征:

        DRTISRC = drti.c

DRTIOBJ = $(DRTISRC:%.c=%.o)
        DLIBSRCS += \

errno.d \
io.d \
procfs.d \
regs.d \
sched.d \
signal.d \
unistd.d
...
ROOTDLIBDIR = $(ROOT)/usr/lib/dtrace
ROOTDLIBDIR64 = $(ROOT)/usr/lib/dtrace/64
...
$(ROOTDLIBDIR):
$(INS.dir)
        $(ROOTDLIBDIR64): $(ROOTDLIBDIR)

$(INS.dir)
        $(ROOTDLIBDIR)/%.d: ../common/%.d

$(INS.file)
        $(ROOTDLIBDIR)/%.d: ../$(MACH)/%.d

$(INS.file)
        $(ROOTDLIBDIR)/%.d: %.d

$(INS.file)

请注意,一些 D ``header'' 又由其他文件生成;此 makefile 包括执行这些转换的规则。

一旦定义了 LIBSRCS 和 OBJECTS,则将包括通用库 makefile 片段 Makefile.lib,以提供目标和目录定义。

二进制对象生成到 pics/ 子目录中。pics 表示与位置无关的代码,这说明以该方法生成的动态共享库可装入任何地址。这是历史产物;基于 OpenSolaris 的产品不支持静态链接系统库,因 此将不会生成用于生成归档样式库的非 PIC 对象。生成规则如下:

        pics/%.o: ../$(MACH)/%.c

$(COMPILE.c) -o $@ ___FCKpd___44lt;
$(POST_PROCESS_O)
        pics/%.o: ../$(MACH)/%.s

$(COMPILE.s) -o $@ ___FCKpd___45lt;
$(POST_PROCESS_O)
        %.o: ../common/%.c

$(COMPILE.c) -o $@ ___FCKpd___46lt;
$(POST_PROCESS_O)

请注意,由于每个 ISA 的 makefile 都包括此 makefile 片段,因此产生的对象将放置在每个 ISA 目录中与该 makefile 相关的位置。同样,这也意味着所包括的 makefile 片段将包括其他 ../ 组件。

libdtrace Makefile.com 还包含大量的自定义规则,以适应通过 lex(1)yacc(1) 定义生成词法分析器和解析器;这些源代码然后将特别使用自定义规则进行编译,并在执行 clean 或 clobber 目标时被删除。

特定于 ISA 的生成目录中的 makefile 同样很简单。例如,特定于 SPARC 的 makefile 定义其他汇编程序标志,指定库接口映射所位于的目录,然后包括通用 makefile:& amp; lt; /p>

        ASFLAGS += -D_ASM -K PIC -P

        MAPDIR = ../spec/sparc

include ../Makefile.com

该 makefile 还可能将一些特定于 ISA 的源代码添加到生成列表中;例如, sparc/Makefile 包括:

        SRCS += dt_asmsubr.s

OBJECTS += dt_asmsubr.o

同样,提供独立的安装目标以指出应安装这些特定库和头文件的目录:

        install yydebug: all $(ROOTLIBS) $(ROOTLINKS)

$(ROOTLINT) \
$(ROOTDLIBS) $(ROOTDOBJS)

要为生成一组独立的 64 位对象提供支持,sparcv9/Makefile 应包括略有不同的定义和不同的安装目标:

        MAPDIR = ../spec/sparcv9

include ../Makefile.com
include ../../Makefile.lib.64
        CPPFLAGS += -D_ELF64

...
install yydebug: all $(ROOTLIBS64) $(ROOTLINKS64)
$(ROOTLINT64) \
$(ROOTDLIBS) $(ROOTDOBJS64)

请注意,Makefile.lib.64 的其他内容和 64 位 ELF 目标的其他标志。此外,还使用了安装文件的特定于 64 位的版本,正如在 Makefile.lib 中看到的一样,该 版本将会导致这些文件安装到 /usr/lib/sparcv9 中:

        ROOTLIBDIR=     $(ROOT)/usr/lib

ROOTLIBDIR64= $(ROOT)/usr/lib/$(MACH64)
...
ROOTLIBS= $(LIBS:%=$(ROOTLIBDIR)/%)
ROOTLIBS64= $(LIBS:%=$(ROOTLIBDIR64)/%)

链接程序 (ld(1)) 和运行时装入器 (ld.so.1(1)) 分别根据要链接的对象或要运行的程序的位,确定要在这其中哪些目录中搜索库。有关 32 与 64 位链接的更多信息,请参阅位于 http://docs.sun.com/db/doc/816-1386 上的《Solaris Linkers and Libraries Guide》。

3.2.6 了解内核模块安装

安装目标使二进制代码和头安装在称为样例区域的分层结构中(有关样例区域的内容和目的的更多信息,请参见第 4.4.1 节)。样例区域的根由环境变量 ROOT 定义。该变量用于在 usr/src/uts/Makefile.uts 中定义 ROOT_MOD_DIR 和 USR_MOD_DIR:

        ROOT_MOD_DIR               = $(ROOT)/kernel

USR_MOD_DIR = $(ROOT)/usr/kernel

所有模块都安装到这些目录之一中。使用的具体子目录取决于模块生成目录中 ROOTMODULE 的定义,如下面所讨论。

要安装的其他文件可以在此 makefile 中通过 INSTALL_TARGET 定义指定。例如,asy makefile (usr/src/uts/intel/asy/Makefile) 指定:

        INSTALL_TARGET  = $(BINARY) $(ROOTMODULE)

$(ROOT_CONFFILE)

由于这是一组常用安装目标,可以看一下如何获取每个组件。

$(BINARY) 就是模块本身;已在上面详细讨论了其相关性和规则。此处包括模块本身要求在尝试任何安装之前完全生成该模块。

$(ROOTMODULE) 是对模块名称的名称变换,以将模块重新定位到样例区域。例如,usr/src/uts/intel/asy/Makefile 定义:

        ROOTMODULE      = $(ROOT_DRV_DIR)/$(MODULE)

ROOT_DRV_DIR 要求一些其他说明;它是 Makefile.uts 中定义的多个模块安装子目录之一。由于二进制内核模块的结尾位置取决于计算机类型(具体而言,32 与 64 位),因 此实际上有多种定义。首先,每种 64 位计算机类型的子目录定义:

        SUBDIR64_sparc          = sparcv9

SUBDIR64_i386 = amd64
SUBDIR64 = $(SUBDIR64_$(MACH))

接下来,每种类型模块的 32 和 64 位安装目录:

        ROOT_KERN_DIR_32        = $(ROOT_MOD_DIR)

ROOT_DRV_DIR_32 = $(ROOT_MOD_DIR)/drv
ROOT_DTRACE_DIR_32 = $(ROOT_MOD_DIR)/dtrace
ROOT_EXEC_DIR_32 = $(ROOT_MOD_DIR)/exec
...
        ROOT_KERN_DIR_64        =

$(ROOT_MOD_DIR)/$(SUBDIR64)
ROOT_DRV_DIR_64 =
$(ROOT_MOD_DIR)/drv/$(SUBDIR64)
ROOT_DTRACE_DIR_64 =
$(ROOT_MOD_DIR)/dtrace/$(SUBDIR64)
ROOT_EXEC_DIR_64 =
$(ROOT_MOD_DIR)/exec/$(SUBDIR64)
...

最后,根据此生成的实际位,选择 32 或 64 位目录:

        ROOT_KERN_DIR           = $(ROOT_KERN_DIR_$(CLASS))

ROOT_DRV_DIR = $(ROOT_DRV_DIR_$(CLASS))
ROOT_DTRACE_DIR =
$(ROOT_DTRACE_DIR_$(CLASS))
ROOT_EXEC_DIR = $(ROOT_EXEC_DIR_$(CLASS))
...

$(ROOT)/usr/kernel 中存在 USR_XXX_DIR 的相似定义。有关可能的 ROOT_ 和 USR_ 安装目录的完整列表,请参见 usr/src/uts/Makefile.uts。

usr/src/uts/Makefile.targ 中指定了将文件安装到这其中每个目录的规则:

        $(ROOT_MOD_DIR)/%:      $(OBJS_DIR)/% $(ROOT_MOD_DIR)

FRC
$(INS.file)
        $(ROOT_DRV_DIR)/%:      $(OBJS_DIR)/% $(ROOT_DRV_DIR)

FRC
$(INS.file)
...

这些规则将当前位于 $(OBJS_DIR)(上面已详细说明)中的文件安装到样例区域的适当目录中。

$(ROOT_CONFFILE) 是已转换到样例区域的模块配置文件(通常用于驱动程序)。CONFFILE 变量在 usr/src/uts/Makefile.uts 中定义:

        CONFFILE                = $(MODULE).conf

SRC_CONFFILE = $(CONF_SRCDIR)/$(CONFFILE)
ROOT_CONFFILE_32 = $(ROOTMODULE).conf
ROOT_CONFFILE_64 =
$(ROOTMODULE:%/$(SUBDIR64)/$(MODULE)=%/$(MODULE)).con
f
ROOT_CONFFILE = $(ROOT_CONFFILE_$(CLASS))

每个模块的 Makefile 定义 CONF_SRCDIR,以指定应在此平台中安装的配置文件的位置。asy makefile 定义:

        CONF_SRCDIR     = $(UTSBASE)/common/io

该定义将使 usr/src/uts/common/io/asy.conf 以 /kernel/drv/asy.conf 为名称安装在样例区域中。请注意,配置文件安装目录与该生成是 32 位还是 64 位无关。

请注意,尽管这可能让人混淆,但安装目标始终命名为 ROOTMODULE、 ROOT_CONFFILE 等,即使安装目标实际安装到某个 USR_ 目录中也是如此。这将简化更高级别的 makefile。

3.2.7 查找模块的源代码

如我们所见,源代码派生于 $(XXX_OBJS) 和所包括的规则。以下为技巧部分-查找这些源代码的位置。到现在为止,最简单方法是从模块的对象目录中运行make程序,观察所运行的编译命令。每 个源文件的路径将包括在输出中。这是查找生成模块需要的源文件的最简单方法,也是推荐使用的方法。但是,如果此操作无效(可能 makefile 本身有错误)或者如果要获取进一步的认识,本 节其余部分将介绍查找源文件的逻辑过程。

由于知道基本名称(即 .o 被替换为 .c 的 XXX_OBJS 项),因此可以简单地使用:

        $ find usr/src/uts -name asy.c

假设找到名称相同的两个源文件-实际应使用哪一个?有两种方法可确定要使用的文件。简单的方法是使用 make -d 显示所使用的具体相关性。或者,可以从文件推论出,方 法是首先考虑不是所有源文件都将在平台中使用(即,x86 版本不使用 usr/src/uts/sparc/*),然后查看每个 Makefile.rules 中规则的具体顺序。更具体的规则首先列出,并 优先于后面的规则(事实上,所有规则都将相关性添加到有问题的特定对象文件中,但由于这些规则都使用 $<,因此实际将仅使用第一种相关性)。

非内核源文件更容易定位,因为对于每个库或命令,cmd 目录和 lib 目录通常组织到一个子目录,并相应命名。主要例外是 cmd/sgs(包含整个二进制工具子系统)和 cmd/cmd-inet( 包含大多数 Berkeley 联网命令和守护进程,以及一些其他与网络相关的实用程序,它们都排列在 BSD 样式的目录结构中)。

3.2.8 未包括的源文件

用于生成 Solaris 品牌产品的一些源代码未包括在 OpenSolaris 中。有两个主要原因:

源代码可能受第三方权限限制。

Sun 的律师不允许任何人谈论该内容。甚至不允许提及任何一点信息。但是,他们愿意自己对其进行解释,因此,您应与 Sun 的法律部门联系并在那里咨询。很抱歉,我们不能为您提供帮助。

整合可能尚未发布。

OpenSolaris 尚未包括 Solaris 中的所有整合,并且一些整合仍未完成。有关所关注的整合的信息,请参阅 http://www.opensolaris.org/os/about/roadmap/ 上的程序指南和 http://www.opensolaris.org/os/downloads/ 上的下载页面。

为了能够在即使缺少某些源代码的情况下也可以进行完全功能生成,已提供一组不公开的二进制代码,并已将生成系统修改为可以利用这些二进制代码。makefile 变量 CLOSED_BUILD 控制生成系统将使用预生成的不公开的二进制文件还是查找不公开的源代码。

CLOSED_BUILD 通常在 makefile 行(该行建立待生成模块或子目录的列表