> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man7/build.7.md).

# build.7

`build` — 构建 FreeBSD 系统的通用说明

## 名称

`build` FreeBSD 系统

## 描述

FreeBSD 系统及其应用程序的源代码包含在三个目录中，通常为：

**`/usr/src`** “基本系统”，大致定义为将系统构建到可用状态所需的一切

**`/usr/doc`** 系统文档，不包括手册页

**`/usr/ports`** 第三方软件，提供一致的构建和安装接口；参见 [ports(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/ports.7.md)

在使用 Git（来自 FreeBSD Ports Collection 的 `devel/git`）更新之前，这些目录可能初始为空或不存在

在每个目录中使用 [make(1)](/man/man1/make.1.md) 命令构建和安装该目录中的内容。在任何目录中发出 [make(1)](/man/man1/make.1.md) 命令都会在所有子目录中递归发出 [make(1)](/man/man1/make.1.md) 命令。未指定目标时，仅构建目录中的项目，不执行其他操作。

源代码树允许只读。如 [make(1)](/man/man1/make.1.md) 所述，对象通常在由环境变量 `MAKEOBJDIRPREFIX` 指定的单独对象目录层次结构中构建，若未设置变量 `MAKEOBJDIRPREFIX`，则在 `/usr/obj` 下构建。规范对象目录在下文 `buildworld` 目标的文档中说明。

`build` 可通过定义下文 Sx ENVIRONMENT 章节中描述的 [make(1)](/man/man1/make.1.md) 变量，以及 [make.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/make.conf.5.md) 中记录的变量来控制。

构建中包含的默认组件在源代码树的 `/etc/src.conf` 文件中指定。要覆盖默认文件，在 make 步骤中包含 SRCCONF 选项，指向自定义的 src.conf 文件。更多信息参见 [src.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/src.conf.5.md)。

以下列表提供构建系统支持的目标名称和操作：

**`analyze`** 对所有对象运行 Clang 静态分析器，并在 stdout 上呈现输出。

**`check`** 为给定子目录运行测试。使用的默认目录是 `${.OBJDIR}`，但可通过 `${CHECKDIR}` 更改检查目录。

**`checkworld`** 在已安装的 world 上运行 FreeBSD 测试套件。

**`clean`** 移除构建过程中创建的所有文件。

**`cleandepend`** 移除先前“`make`”和“`make depend`”步骤生成的 `${.OBJDIR}/${DEPENDFILE}*` 文件。

**`cleandir`** 如果存在规范对象目录则移除之，否则执行等效于“`make clean cleandepend`”的操作。此目标还会移除 `${.CURDIR}` 中的 `obj` 链接（如果存在）。建议运行“`make cleandir`”两次：第一次调用移除规范对象目录，第二次清理 `${.CURDIR}`。

**`depend`** 在文件 `${.OBJDIR}/${DEPENDFILE}` 中生成构建依赖列表。每个对象的依赖在构建时生成并存储在 `${.OBJDIR}/${DEPENDFILE}.${OBJ}` 中。

**`install`** 将构建结果安装到变量 `DESTDIR` 指定的安装目录层次结构中的相应位置。

**`obj`** 创建与当前目录关联的规范对象目录。

**`objlink`** 在 `${.CURDIR}` 中创建指向规范对象目录的符号链接。

**`tags`** 使用 [make(1)](/man/man1/make.1.md) 变量 `CTAGS` 指定的程序生成 tags 文件。构建系统支持 ctags(1) 和 `GNU Global`。

目录 `/usr/src` 下支持的其他目标：

* 如果正在更新旧仓库，则自上一版本以来内容未更改的包将被复制到新仓库中，以避免不必要的版本号更新。
* 如果定义了 `PKG_REPO_SIGNING_KEY`，仓库将根据 pkg-repo(8) 进行签名。

**`buildenv`** 启动一个交互式 shell，其环境变量已设置为构建系统或单个组件。对于交叉构建，需要用 [make(1)](/man/man1/make.1.md) 变量 `TARGET_ARCH` 和 `TARGET` 指定目标架构。此目标仅在完整工具链（包括编译器、链接器、汇编器、头文件和库）构建完成后才有用；参见下文的 `toolchain` 目标。执行 `BUILDENV_SHELL`，默认为 `/bin/sh`。可将其设置为在此构建环境中执行操作的命令，如交叉构建应用程序。但如果该应用程序有依赖关系，`devel/poudriere` 包或 port 提供更通用的解决方案。

**`buildenvvars`** 打印为 `buildenv` 环境设置的 shell 变量并退出。

**`buildworld`** 构建除内核、`etc` 中的配置文件和 `release` 之外的所有内容。可通过设置 `MAKEOBJDIRPREFIX` [make(1)](/man/man1/make.1.md) 变量将对象目录从默认的 `/usr/obj` 更改。使用的实际构建位置前缀取决于 [src.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/src.conf.5.md) 中的 `WITH_UNIFIED_OBJDIR` 选项。启用时，所有构建使用 `${MAKEOBJDIRPREFIX}${.CURDIR}/${TARGET}.${TARGET_ARCH}`。禁用时，原生构建使用 `${MAKEOBJDIRPREFIX}${.CURDIR}`，交叉构建和设置了变量 `CROSS_BUILD_TESTING` 的原生构建使用 `${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH}${.CURDIR}`。

**`cleankernel`** 尝试清理由先前 `buildkernel` 或类似步骤构建的目标，这些步骤从同一源目录和 `KERNCONF` 构建。

**`cleanworld`** 尝试清理由先前 `buildworld` 或类似步骤构建的目标，这些步骤从此源目录构建。

**`cleanuniverse`** 启用 `WITH_UNIFIED_OBJDIR` 时，尝试清理由先前 `buildworld`、`universe` 或类似步骤构建的目标，针对从此源目录构建的任何架构。

**`distributeworld`** 分发先前 `buildworld` 步骤编译的所有内容。文件放置在 [make(1)](/man/man1/make.1.md) 变量 `DISTDIR` 指定的目录层次结构中。此目标在构建 release 时使用；参见 [release(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/release.7.md)。

**`native-xtools`** 此目标为给定 **TARGET** 和 **TARGET\_ARCH,** 构建交叉工具链，以及主机系统的精选静态用户态工具列表。旨在 jail 中使用 QEMU 时使用，通过避免模拟不需要模拟的二进制文件来提高性能。应定义 **TARGET** 和 **TARGET\_ARCH**。

**`native-xtools-install`** 将结果安装到 `${DESTDIR}/${NXTP}`，其中 `NXTP` 默认为 `nxb-bin`。必须定义 **TARGET** 和 **TARGET\_ARCH**。

**`packages`** 创建包含可用于安装或升级基本系统的包的 [freebsd-base(7)](/man/man7/freebsd-base.7.md) 包仓库。仓库在对象目录下的 `${REPODIR}/${PKG_ABI}` 中创建，其中 `REPODIR` 是创建仓库的基目录，`PKG_ABI` 是构建目标的 pkg(7) ABI，例如 `/usr/obj/${SRCDIR}/repo/FreeBSD:15:amd64`。

**`packageworld`** 归档 `distributeworld` 的结果，将结果放入 `DISTDIR`。此目标在构建 [release(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/release.7.md) 时使用，与构建 [freebsd-base(7)](/man/man7/freebsd-base.7.md) 包无关。

**`installworld`** 将先前 `buildworld` 步骤构建的所有内容安装到 [make(1)](/man/man1/make.1.md) 变量 `DESTDIR` 指向的目录层次结构中。如果安装到 NFS 文件系统并使用 `-j` 选项运行 [make(1)](/man/man1/make.1.md)，确保 rpc.lockd(8) 在客户端和服务器上都运行。参见 [rc.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/rc.conf.5.md) 了解如何使其在启动时运行。

**`toolchain`** 创建构建系统其余部分所需的构建工具链。对于跨架构构建，此步骤创建交叉工具链。

**`universe`** 对每个架构执行 `buildworld`，然后对该架构的所有内核（包括 `LINT`）执行 `buildkernel`。此命令耗时较长。

**`kernels`** 类似于定义了 `WITHOUT_WORLDS` 的 `universe`，因此只构建每个架构的内核。

**`worlds`** 类似于定义了 `WITHOUT_KERNELS` 的 `universe`，因此只构建每个架构的 world。

**`targets`** 打印 world 和 kernel 目标支持的 `TARGET`/`TARGET_ARCH` 对列表。

**`tinderbox`** 执行与 `universe` 相同的目标。此外在结束时打印所有失败目标的摘要，如果有任何失败则以错误退出。

**`toolchains`** 为构建系统支持的每个架构创建构建工具链。

**`xdev`** 为给定 **TARGET** 和 **TARGET\_ARCH.** 构建并安装交叉工具链和 sysroot。sysroot 包含目标库和头文件。该目标是 `xdev-build` 和 `xdev-install` 的别名。安装文件的位置可通过 `DESTDIR` 控制。`DESTDIR` 中的目标位置为 `${DESTDIR}/${XDTP}`，其中 `XDTP` 默认为 `/usr/${XDDIR}`，`XDDIR` 默认为 `${TARGET_ARCH}-freebsd`。

**`update-packages`** 为基本系统创建或更新 [freebsd-base(7)](/man/man7/freebsd-base.7.md) 包仓库。

**`xdev-build`** 为 `xdev` 目标构建。

**`xdev-install`** 为 `xdev` 目标安装文件。

**`xdev-links`** 在 `${DESTDIR}/usr/bin` 中安装 autoconf 风格的符号链接，指向 `${DESTDIR}/${XDTP}` 中的 xdev 工具链。

`/usr/src` 中特定于内核的构建目标：

**`buildkernel`** 重新构建内核和内核模块。可通过设置 `MAKEOBJDIRPREFIX` [make(1)](/man/man1/make.1.md) 变量将对象目录从默认的 `/usr/obj` 更改。

**`installkernel`** 将内核和内核模块安装到目录 `${DESTDIR}/boot/kernel`，如果先前存在同名目录且包含当前运行的内核，则将其重命名为 `kernel.old`。可使用 `INSTKERNNAME` 或 `KODIR` [make(1)](/man/man1/make.1.md) 变量修改 `${DESTDIR}` 下的目标目录。

**`distributekernel`** 将内核安装到目录 `${DISTDIR}/kernel/boot/kernel`。此目标在构建 release 时使用；参见 [release(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/release.7.md)。

**`packagekernel`** 归档 `distributekernel` 的结果，将结果放入 `DISTDIR`。此目标在构建 [release(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/release.7.md) 时使用，与构建 [freebsd-base(7)](/man/man7/freebsd-base.7.md) 包无关。

**`kernel`** 等效于 `buildkernel` 后跟 `installkernel`

**`kernel-toolchain`** 重新构建内核编译所需的工具。如果未先执行 `buildworld`，请使用此目标。

**`reinstallkernel`** 重新安装内核和内核模块，覆盖目标目录的内容。与 `installkernel` 目标一样，可使用 [make(1)](/man/man1/make.1.md) 变量 `INSTKERNNAME` 指定目标目录。

清理由变量 `DESTDIR` 表示的安装目标目录的便捷目标包括：

**`check-old`** 打印系统中旧文件和目录的列表。

**`check-old-libs`** 打印过时的基本系统库列表。

**`delete-old`** 以交互方式删除过时的基本系统文件和目录。在命令行指定 `-DBATCH_DELETE_OLD_FILES` 时，删除操作将以非交互方式进行。变量 `DESTDIR`、`TARGET_ARCH` 和 `TARGET` 的设置应与“`make installworld`”相同。

**`delete-old-libs`** 以交互方式删除过时的基本系统库。此目标仅在没有第三方软件使用这些库时使用。在命令行指定 `-DBATCH_DELETE_OLD_FILES` 时，删除操作将以非交互方式进行。变量 `DESTDIR`、`TARGET_ARCH` 和 `TARGET` 的设置应与“`make installworld`”相同。

## 环境变量

影响所有构建的变量包括：

**`DEBUG_FLAGS`** 定义一组调试标志，用于构建 `/usr/src` 下的所有用户态二进制文件。定义 `DEBUG_FLAGS` 时，`install` 和 `installworld` 目标从当前 `MAKEOBJDIRPREFIX` 安装二进制文件而不剥离，以便在安装的二进制文件中保留调试信息。

**`DESTDIR`** 安装构建对象的目录层次结构前缀。未设置时，`DESTDIR` 默认为空字符串。设置时，`DESTDIR` 必须指定绝对路径。

**`MAKEOBJDIRPREFIX`** 定义构建对象树中目录名的前缀。未定义时默认为 `/usr/obj`。此变量只能在环境或 `/etc/src-env.conf` 中设置，不能通过 `/etc/make.conf` 或 `/etc/src.conf` 或命令行设置。`MAKEOBJDIRPREFIX` 必须指定绝对路径。

**`WITHOUT_WERROR`** 如果定义，编译器警告不会导致构建停止，即使 makefile 另有说明。

**`WITH_CTF`** 如果定义，构建过程将对构建对象运行 DTrace CTF 转换工具。

此外，`/usr/src` 中的构建受以下 [make(1)](/man/man1/make.1.md) 变量影响：

```sh
PORTS_MODULES=graphics/gpu-firmware-intel-kmod@kabylake
PORTS_MODULES+=graphics/drm-66-kmod
```

```sh
make some-target SUBDIR_OVERRIDE=foo/bar
```

**`CROSS_TOOLCHAIN`** 请求使用外部工具链构建 world 或内核。此变量的值可以是文件的完整路径，或 `${LOCALBASE}/share/toolchains` 中文件的基本名称。该文件应为 make 文件，设置变量以请求外部工具链，如 `XCC`。Ports 中提供 LLVM 和 GCC/binutils 的外部工具链。对于 Ports 中可用的外部工具链，`CROSS_TOOLCHAIN` 应设置为包名。LLVM 工具链包使用名称 llvm<主版本号>。GCC 工具链为每个架构提供单独的包，使用名称 ${MACHINE\_ARCH}-gcc<主版本号>。

**`INSTKERNNAME`** 如果设置，指定各种内核 make 目标的替代构建和安装名称。默认为“`kernel`”。

**`KERNCONF`** 指定一个或多个空格分隔的内核，用于各种内核 make 目标的构建和安装。如果指定多个内核，第一个列出的内核安装到 `/boot/${INSTKERNNAME}`，后续内核安装到 `/boot/${INSTKERNNAME}.NAME`。未设置时，默认为 GENERIC，但 POWER 架构例外，powerpc64 默认为 GENERIC64，powerpc64le 默认为 GENERIC64LE。

**`KERNBUILDDIR`** 覆盖默认目录以获取构建内核模块的所有 opt\_\*.h 文件。适用于依赖 [config(8)](/man/man8/config.8.md) 选项的独立模块。对于随内核构建的模块自动设置。

**`KERNCONFDIR`** 覆盖应在其中查找 `KERNCONF` 和 `KERNCONF` 包含的任何文件的目录。默认为 `sys/${ARCH}/conf`。

**`KERNFAST`** 如果设置，构建目标 `buildkernel` 默认设置 `NO_KERNELCLEAN`、`NO_KERNELCONFIG` 和 `NO_KERNELOBJ`。设置为 `1` 以外的值时，`KERNCONF` 设置为 `KERNFAST` 的值。

**`KODIR`** 如果设置，此变量指定安装内核的替代目录。

**`LOCAL_DIRS`** 如果设置，此变量提供相对于源代码树根的附加目录列表，作为 `everything` 目标的一部分构建。这些目录相互并行构建，并与基本系统目录并行构建。在 `LOCAL_DIRS` 列表开头插入 `.WAIT` 指令可确保先构建所有基本系统目录。`.WAIT` 也可根据需要在列表中的其他位置使用。

**`LOCAL_ITOOLS`** 如果设置，此变量提供 `installworld` 和 `distributeworld` 目标使用的附加工具列表。

**`LOCAL_LIB_DIRS`** 如果设置，此变量提供相对于源代码树根的附加目录列表，作为 `libraries` 目标的一部分构建。这些目录相互并行构建，并与基本系统库并行构建。在 `LOCAL_DIRS` 列表开头插入 `.WAIT` 指令可确保先构建所有基本系统库。`.WAIT` 也可根据需要在列表中的其他位置使用。

**`LOCAL_MTREE`** 如果设置，此变量提供相对于源代码树根的附加 mtree 列表，作为 `hierarchy` 目标的一部分使用。

**`LOCAL_LEGACY_DIRS`** 如果设置，此变量提供相对于源代码树根的附加目录列表，作为 `legacy` 目标的一部分构建。

**`LOCAL_BSTOOL_DIRS`** 如果设置，此变量提供相对于源代码树根的附加目录列表，作为 `bootstrap-tools` 目标的一部分构建。

**`LOCAL_TOOL_DIRS`** 如果设置，此变量提供相对于源代码树根的附加目录列表，作为 `build-tools` 目标的一部分构建。

**`LOCAL_XTOOL_DIRS`** 如果设置，此变量提供相对于源代码树根的附加目录列表，作为 `cross-tools` 目标的一部分构建。

**`OBJROOT`** 对象目录根定义为 `${OBJDIR}/${SRCDIR}/`。参见 `share/mk/src.sys.obj.mk`。

**`PKG_FORMAT`** 构建 [freebsd-base(7)](/man/man7/freebsd-base.7.md) 包时指定包压缩格式。默认：`tzst`。考虑使用 `tar` 禁用压缩。可接受的选项记录在 pkg-create(8) 的 `-f` 描述中。

**`PORTS_MODULES`** 具有内核模块的 ports 列表，应作为 `buildkernel` 和 `installkernel` 流程的一部分构建和安装。目前与构建 [freebsd-base(7)](/man/man7/freebsd-base.7.md) 包不兼容。每个 port 必须指定为 `category``/``port`\[`@``flavor`]，例如

**`LOCAL_MODULES`** 外部内核模块列表，应作为 `buildkernel` 和 `installkernel` 流程的一部分构建和安装。默认为 `LOCAL_MODULES_DIR` 的子目录列表。

**`LOCAL_MODULES_DIR`** 搜索 `LOCAL_MODULES` 指定的内核模块的目录。每个内核模块应由包含 makefile 的目录组成。默认为 `${LOCALBASE}/sys/modules`。

**`SRCCONF`** 指定覆盖默认 `/etc/src.conf` 的文件。src.conf 文件控制要构建的组件。参见 [src.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/src.conf.5.md)

**`REPODIR`** 用于创建构建 packages(7) 包仓库的根目录。默认为 `${OBJROOT}/repo/`。也可在 src-env.conf(5) 中设置。

**`STRIPBIN`** 安装时剥离二进制文件时使用的命令。确保在运行 `distributeworld` 或 `installworld` 目标之前，将运行 `STRIPBIN` 所需的任何附加工具添加到 `LOCAL_ITOOLS` [make(1)](/man/man1/make.1.md) 变量中。更多细节参见 install(1)。

**`SUBDIR_OVERRIDE`** 覆盖默认子目录列表，仅构建此变量中命名的子目录。如果与 `buildworld` 组合，则所有库和 includes 以及某些构建工具仍会构建。指定 `-DNO_LIBS` 和 `-DWORLDFAST` 将仅构建指定目录，如同历史做法。与 `buildworld` 组合时，必须用包含库的任何自定义目录覆盖 `LOCAL_LIB_DIRS`。这允许以与 `buildworld` 使用其 sysroot 处理相同的方式构建系统的子集。此变量在调试失败的构建时也很有用。

**`SYSDIR`** 指定内核源代码位置以覆盖默认的 `/usr/src/sys`。内核源代码位于从 `src.git` 仓库检出的源代码树的 `sys` 子目录中。

**`TARGET`** 目标硬件平台。类似于“`uname` `-m`”输出。交叉构建某些目标架构时需要。例如，交叉构建 ARM64 机器需要 `TARGET_ARCH`=`aarch64` 和 `TARGET`=`arm64`。未设置时，`TARGET` 默认为当前硬件平台，除非也设置了 `TARGET_ARCH`，此时默认为该架构的适当值。

**`TARGET_ARCH`** 目标机器处理器架构。类似于“`uname` `-p`”输出。设置此项以交叉构建不同架构。未设置时，`TARGET_ARCH` 默认为当前机器架构，除非也设置了 `TARGET`，此时默认为该平台的适当值。通常只需设置 `TARGET`。

`/usr/src` 目录下的构建还受通过 [make(1)](/man/man1/make.1.md) 的 `-D` 选项定义以下一个或多个符号的影响：

**`LOADER_DEFAULT_INTERP`** 定义默认加载器程序的解释器。有效值包括“4th”、“lua”和“simp”。这会创建 `/boot/loader` 到具有该解释器的加载器的默认链接。它还决定编译到 `userboot` 中的解释器。

**`NO_CLEANDIR`** 如果设置，清理对象树部分的构建目标使用等效的“make clean”而非“make cleandir”。

**`NO_CLEAN`** 如果设置，完全不清理任何对象树文件。这是 `WITH_META_MODE` 与 [filemon(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/filemon.4.md) 一起使用时的默认行为。更多细节参见 [src.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/src.conf.5.md)。设置 `NO_CLEAN` 意味着 `NO_KERNELCLEAN`，因此设置 `NO_CLEAN` 时也不清理内核对象。

**`NO_CTF`** 如果设置，构建过程不对构建对象运行 DTrace CTF 转换工具。

**`NO_SHARE`** 如果设置，构建不进入 `/usr/src/share` 子目录（即手册页、区域设置数据文件、时区数据文件和其他 `/usr/src/share` 文件不会从其源代码重新构建）。

**`NO_KERNELCLEAN`** 如果设置，构建过程不作为 `buildkernel` 目标的一部分运行“make clean”。

**`NO_KERNELCONFIG`** 如果设置，构建过程不作为 `buildkernel` 目标的一部分运行 [config(8)](/man/man8/config.8.md)。

**`NO_KERNELOBJ`** 如果设置，构建过程不作为 `buildkernel` 目标的一部分运行“make obj”。

**`NO_LIBS`** 如果设置，将跳过库阶段。

**`NO_OBJWALK`** 如果设置，不创建对象目录。仅在先前构建中已创建对象目录且未连接新目录时使用。

**`UNIVERSE_TOOLCHAIN`** 请求使用作为 `universe` 目标一部分构建的工具链作为外部工具链。

**`WORLDFAST`** 如果设置，构建目标 `buildworld` 默认设置 `NO_CLEAN`、`NO_OBJWALK`，并跳过大多数引导阶段。它仅引导库并构建所有用户态。仅在已知无需更改任何引导且未连接新目录到构建时使用此选项。

`/usr/doc` 目录下的构建受以下 [make(1)](/man/man1/make.1.md) 变量影响：

**`DOC_LANG`** 如果设置，将文档构建限制为作为其内容指定的语言子目录。默认操作是构建所有语言的文档。

使用 `universe` 及相关目标的构建受以下 [make(1)](/man/man1/make.1.md) 变量影响：

**`JFLAG`** 将此变量的值传递给用于构建 world 和内核的每次 [make(1)](/man/man1/make.1.md) 调用。可用于在单个架构构建中启用多个作业，同时仍按顺序构建每个架构。

**`MAKE_JUST_KERNELS`** 仅构建每个支持架构的内核。

**`MAKE_JUST_WORLDS`** 仅构建每个支持架构的 world。

**`WITHOUT_WORLDS`** 仅构建每个支持架构的内核。

**`WITHOUT_KERNELS`** 仅构建每个支持架构的 world。

**`UNIVERSE_LOGDIR`** 将每个支持架构的所有构建日志写入此目录。调用 `tinderbox` 时，还将所有失败目标的摘要写入此目录。

**`UNIVERSE_TARGET`** 为每个支持架构执行指定的 [make(1)](/man/man1/make.1.md) 目标，而非构建一个 world 和一个或多个内核的默认操作。此变量意味着 `WITHOUT_KERNELS`。

**`USE_GCC_TOOLCHAINS`** 使用外部 GCC 工具链构建请求的目标。如果未安装支持架构所需工具链包，则跳过该架构的构建。可通过将此变量的值设置为所需版本（例如“gcc14”）来使用特定版本的 GCC；否则使用默认版本的 GCC。

**`TARGETS`** 仅构建列出的目标，而非每个支持的架构。

**`EXTRA_TARGETS`** 除支持的架构外，还构建半支持架构。半支持架构在 FreeBSD 树中有构建支持，但测试要少得多，通常用于没有广泛吸引力的边缘用途。

## 文件

**`/usr/doc/Makefile`** **`/usr/doc/share/mk/doc.project.mk`** **`/usr/ports/Mk/bsd.port.mk`** **`/usr/ports/Mk/bsd.sites.mk`** **`/usr/src/Makefile`** **`/usr/src/Makefile.inc1`** 每个树的 [make(1)](/man/man1/make.1.md) 基础设施 **`/usr/ports/UPDATING`** **`/usr/src/UPDATING`** 每个树的显著变更 **`/usr/share/examples/etc/make.conf`** [make.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/make.conf.5.md) 示例 **`/etc/src.conf`** src 构建配置，参见 [src.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/src.conf.5.md)

## 实例

本节描述常见情况的最佳实践。需要手动干预时，将在 `UPDATING` 中提及。确保在继续之前有完整备份！

### 实例 1：就地构建和升级系统

如果使用已安装的驱动程序（如图形或虚拟机客户机驱动程序），检出 [ports(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/ports.7.md) 树，并在 [src.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/src.conf.5.md) 中指定驱动程序，使其在内核之后自动构建和安装：

```sh
git clone https://git.FreeBSD.org/ports.git /usr/ports
cat << EOF >> /etc/src.conf
PORTS_MODULES+=graphics/drm-kmod emulators/virtualbox-ose-kmod
EOF
```

检出 CURRENT 分支，构建并安装，覆盖当前系统：

```sh
git clone https://git.FreeBSD.org/src.git /usr/src
cd /usr/src
make buildworld buildkernel
make installkernel
shutdown -r now
```

对于主版本升级，引导进入单用户模式。重启后，安装用户空间并合并配置。验证不需要后，删除旧文件：

```sh
cd /usr/src
etcupdate -p
make installworld
etcupdate
make delete-old
shutdown -r now
```

测试新系统并验证应用程序不依赖它们后，删除旧库：

```sh
make delete-old-libs
```

### 实例 2：构建和升级自定义内核

通过包含现有配置并使用 `device`/`nodevice` 和 `options`/`nooption` 选择和配置组件，创建自定义内核配置 `MYKERNEL`：

```sh
cd /usr/src
cat << EOF > sys/amd64/conf/MYKERNEL
include GENERIC
ident MYKERNEL
nodevice sound
EOF
```

创建新内核配置后，构建新工具链，构建内核并直接安装，将旧内核移动到 `/boot/kernel.old/`：

```sh
make kernel-toolchain
make -DALWAYS_CHECK_MAKE buildkernel KERNCONF=MYKERNEL
make -DALWAYS_CHECK_MAKE installkernel KERNCONF=MYKERNEL
shutdown -r now
```

要将内核打包为 [freebsd-base(7)](/man/man7/freebsd-base.7.md) 包而非直接安装，使用 `update-packages` 而非 `installkernel`：

```sh
make buildworld buildkernel KERNCONF=MYKERNEL
make update-packages KERNCONF=MYKERNEL
```

要将内核直接安装到备用位置，使用 `INSTKERNNAME` 变量并通过 nextboot(8) 引导一次以测试：

```sh
make installkernel KERNCONF=MYKERNEL INSTKERNNAME=testkernel
nextboot -k testkernel
shutdown -r now
```

### 实例 3：构建和升级单个用户空间组件

重新构建并重新安装单个用户空间组件，本例中为 [ls(1)](/man/man1/ls.1.md)：

```sh
cd /usr/src/bin/ls
make clean all
make install
```

### 实例 4：构建和升级可加载内核模块

重新构建并重新安装单个可加载内核模块，本例中为 sound(4)：

```sh
cd /usr/src/sys/modules/sound
make all install clean cleandepend KMODDIR=/boot/kernel
```

重要细节是内核二进制接口受其配置影响。在常规内核构建流程之外构建的模块仍必须针对目标内核配置构建，该配置由 [config(8)](/man/man8/config.8.md) 生成的 `opt_*.h` 头文件集合定义。使用 `KERNBUILDDIR` 变量将模块构建指向已配置的内核。无需在该目录中实际构建已配置的内核，模块构建仅消耗其中的头文件。

此外，`SYSDIR` 环境变量可用于指向用于构建目标内核的特定内核源代码树，因为内核头文件定义模块的二进制接口。

假设 FreeBSD 源代码位于 `/home/user/src` 目录，使用的内核配置名为 Vd MY\_KERNEL，模块源代码在 `my-module` 目录中，以下命令序列将用 `opt_*.h` 头文件填充 `/home/user/my-kernel-builddir` 目录，然后构建与 Vd MY\_KERNEL 兼容的模块。

```sh
config -d /home/user/my-kernel-builddir -s /home/user/src/sys/amd64/conf MY-KERNEL
cd my-module
make all KERNBUILDDIR=/home/user/my-kernel-builddir SYSDIR
```

### 实例 5：就地快速重建内核

快速重建并重新安装内核，仅重新编译自上次构建以来更改的文件；注意这仅在之前已完成完整内核构建时有效，不适用于全新源代码树：

```sh
cd /usr/src
make kernel KERNFAST=1
```

### 实例 6：为不同架构交叉编译

要为另一 CPU 架构重建 FreeBSD 的部分内容，首先通过构建交叉工具链准备源代码树：

```sh
cd src
make toolchain TARGET_ARCH=aarch64
```

以下命令序列可在不同主机架构（如 amd64）上交叉构建 arm64（aarch64）架构的系统：

```sh
cd /usr/src
make TARGET_ARCH=aarch64 buildworld buildkernel
make TARGET_ARCH=aarch64 DESTDIR=/client installworld installkernel
```

之后，要构建和安装单个用户空间组件，使用：

```sh
cd src/bin/ls
make buildenv TARGET_ARCH=aarch64
make clean all install DESTDIR=/client
```

同样，要快速重建并重新安装内核，使用：

```sh
cd src
make buildenv TARGET_ARCH=aarch64
make kernel KERNFAST=1 DESTDIR=/client
```

## 诊断

* Bad system call (core dumped)
* rescue/sh check failed, installation aborted 内核由于构建过程不正确而未更新。研究上述示例。

## 参见

[cc(1)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man1/cc.1.md), install(1), [make(1)](/man/man1/make.1.md), [make.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/make.conf.5.md), [src.conf(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/src.conf.5.md), [arch(7)](/man/man7/arch.7.md), [development(7)](/man/man7/development.7.md), [freebsd-base(7)](/man/man7/freebsd-base.7.md), pkg(7), [ports(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/ports.7.md), [release(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/release.7.md), [tests(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/tests.7.md), [config(8)](/man/man8/config.8.md), etcupdate(8), nextboot(8), pkg-repo(8), [shutdown(8)](/man/man8/shutdown.8.md)

## 历史

`uname` 手册页首次出现于 FreeBSD 4.3。

## 作者

Mike W. Meyer <mwm@mired.org>

## 注意事项

旧对象可能导致模糊的构建问题；尝试 `make cleandir cleandir`。

环境污染可能导致模糊的构建问题；尝试在 [make(1)](/man/man1/make.1.md) 命令前加 `env -i`

进行主版本升级时，需要引导进入单用户模式执行 `installworld`。

更新引导 [loader(8)](/man/man8/loader.8.md) 因架构而异。有关你的架构的更多细节，请查阅 [boot(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/boot.8.md)。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man7/build.7.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
