第6章 特殊情况

本节解释了创建port时要考虑的最常见事项。

分割长文件

有时,port Makefile 可能会非常长。例如,rust ports 可能会有一个非常长的 CARGO_CRATES 列表。在其他情况下,Makefile 可能会有根据架构变化的代码。在这种情况下,将原始 Makefile 拆分为多个文件可能很方便。bsd.port.mk 会自动将某些类型的 Makefile 包含到主 port Makefile 中。

这些是框架自动处理的文件(如果找到的话):

  • Makefile.crates。 在 audio/ebur128 中可以找到一个示例。

  • Makefile.inc。 在 net/ntp 中可以找到一个示例。

  • Makefile.${ARCH}-${OPSYS}

  • Makefile.${OPSYS}. 一个示例可在 net/cvsup-static 中找到。

  • Makefile.${ARCH}

  • Makefile.local

将port的打包清单拆分为多个文件也是通常做法,如果清单在不同架构之间变化很大或取决于所选的风味。在这种情况下,每个架构的 pkg-plist 文件的命名遵循 pkg-plist.${ARCH}或 pkg-plist.${FLAVOR}的模式。如果存在多个 pkg-plist 文件,框架不会自动创建打包清单。选择适当的 pkg-plist 并将其分配给 PLIST 变量是 porter 的责任。如何处理这种情况的示例可以在 audio/logitechmediaserver 和 deskutils/libportal 中找到。

6.2. 分阶段

bsd.port.mk 期望ports与“阶段目录”一起工作。这意味着port不能直接将文件安装到常规目标目录(例如,在 PREFIX 下),而是安装到一个单独的目录,然后从该目录构建软件包。在许多情况下,这不需要 root 权限,使得可以作为非特权用户构建软件包。使用分阶段,port被构建并安装到阶段目录 STAGEDIR 中。从阶段目录创建软件包,然后安装到系统上。Automake 工具将此概念称为 DESTDIR ,但在 FreeBSD 中, DESTDIR 有不同的含义(请参阅 PREFIX 和 DESTDIR )。

元 ports,或者不安装文件而只依赖其他 ports 的 ports,必须避免不必要地将 mtree(8) 提取到阶段目录。这是软件包的基本目录布局,这些空目录将被视为孤立文件。为了防止 mtree(8) 提取,添加以下行:

NO_MTREE=	yes

通过在 pre-install , do-install 和 post-install 目标中使用路径之前添加 STAGEDIR 来启用分段(请参阅本书中的示例)。通常,这包括 PREFIX , ETCDIR , DATADIR , EXAMPLESDIR , DOCSDIR 等。目录应作为 post-install 目标的一部分创建。尽量避免使用绝对路径。

6.2.1. 处理符号链接

当创建符号链接时,强烈建议使用相对路径。使用 ${RLN} 来创建相对符号链接。它在幕后使用 install(1)自动计算要创建的相对链接。

例子 1. 自动创建相对符号链接

${RLN} 使用 install(1)的相对符号功能,使得端口的计算相对路径得到释放。

${RLN} ${STAGEDIR}${PREFIX}/lib/libfoo.so.42 ${STAGEDIR}${PREFIX}/lib/libfoo.so
${RLN} ${STAGEDIR}${PREFIX}/libexec/foo/bar ${STAGEDIR}${PREFIX}/bin/bar
${RLN} ${STAGEDIR}/var/cache/foo ${STAGEDIR}${PREFIX}/share/foo

将生成:

% ls -lF ${STAGEDIR}${PREFIX}/lib
lrwxr-xr-x  1 nobody  nobody    181 Aug  3 11:27 libfoo.so@ -> libfoo.so.42
-rwxr-xr-x  1 nobody  nobody     15 Aug  3 11:24 libfoo.so.42*
% ls -lF ${STAGEDIR}${PREFIX}/bin
lrwxr-xr-x  1 nobody  nobody    181 Aug  3 11:27 bar@ -> ../libexec/foo/bar
% ls -lF ${STAGEDIRDIR}${PREFIX}/share
lrwxr-xr-x  1 nobody  nobody    181 Aug  3 11:27 foo@ -> ../../../var/cache/foo

6.3. 捆绑库

本节解释为什么捆绑依赖项被视为不好,并介绍如何处理它们。

6.3.1. 为什么捆绑库是不好的

有些软件要求制作者找到第三方库并将所需的依赖项添加到定制中。其他软件将所有必要的库捆绑到分发文件中。起初,第二种方法似乎更容易,但存在一些严重的缺点:

这个列表基本上是基于 Fedora 和 Gentoo 维基百科,两者都在 CC-BY-SA 3.0 许可下授权。

如果在上游库中发现漏洞并进行修复,可能不会在与 port 捆绑的库中修复。一个原因可能是作者不知道这个问题。这意味着移植者必须修复它们,或者升级到一个非易受攻击的版本,并将补丁发送给作者。所有这些都需要时间,这导致软件比必要的时间更容易受到攻击。这反过来使得更难协调修复,而不必要地泄露有关漏洞的信息。

Bug 这个问题类似于上一段中安全性问题,但一般来说不那么严重。

分叉对于作者来说更容易在捆绑后分叉上游库。虽然乍一看很方便,但这意味着代码与上游不同,使得更难解决软件的安全或其他问题。这样做的原因之一是补丁变得更加困难。

另一个分叉的问题是,由于代码与上游分歧,错误会一遍又一遍地被解决,而不是在一个中心位置解决一次。这背离了开源软件的初衷。

符号冲突当一个库被安装在系统上时,它可能与捆绑版本冲突。这可能导致在编译或链接时立即出现错误。它还会导致运行程序时出现错误,这可能更难追踪。后一问题可能是由于两个库的版本不兼容造成的。

许可证问题当从不同来源捆绑项目时,许可证问题可能更容易出现,特别是当许可证不兼容时。

资源浪费打包的库会在多个层面上浪费资源。构建实际应用程序需要更长的时间,特别是如果这些库已经存在于系统上。在运行时,当系统范围的库已被一个程序加载,而打包的库被另一个程序加载时,它们可能占用不必要的内存。

努力的浪费当一个库需要为 FreeBSD 打补丁时,这些补丁必须在打包的库中再次复制。这会浪费开发人员的时间,因为这些补丁可能无法干净地应用。很难注意到这些补丁是必需的。

如何处理打包的库

尽可能使用库的非捆绑版本,通过向 LIB_DEPENDS 添加port来实现。如果尚未存在这样的port,请考虑创建它。

仅当上游在安全方面有良好记录且使用非捆绑版本会导致过于复杂的补丁时才使用捆绑库。

6.4. 共享库

如果port安装了一个或多个共享库,请定义一个 USE_LDCONFIG 的 make 变量,这将指导 bsd.port.mk 在安装新库的目录(通常为 PREFIX/lib)上运行 ${LDCONFIG} -m ,以便在 post-install 目标期间将其注册到共享库缓存中。当定义了这个变量时,还将有助于在 pkg-plist 中添加适当的 @exec /sbin/ldconfig -m 和 @unexec /sbin/ldconfig -R 对,以便安装了该软件包的用户可以立即开始使用共享库,卸载不会导致系统仍然认为库仍然存在。

USE_LDCONFIG=	yes

默认目录可以通过将 USE_LDCONFIG 设置为要安装共享库的目录列表来覆盖。例如,如果port将共享库安装到 PREFIX/lib/foo 和 PREFIX/lib/bar,请在 Makefile 中使用此命令:

USE_LDCONFIG=	${PREFIX}/lib/foo ${PREFIX}/lib/bar

请仔细检查,通常这根本不必要,或者可以通过 -rpath 或在链接过程中设置 LD_RUN_PATH 来避免(请参阅 lang/mosml 中的示例),或者通过一个在调用二进制文件之前设置 LD_LIBRARY_PATH 的shell包装器,就像 www/seamonkey 一样。

在 64 位系统上安装 32 位库时,请使用 USE_LDCONFIG32 。

如果软件使用 autotools,并且特别是 libtool ,请添加 USES=libtool 。

当主要库版本号在更新到新版时递增时,所有其他链接到受影响库的ports必须递增,以强制使用新库版本重新编译。

6.5. Ports带有分发限制或法律问题

许可证各不相同,其中一些对应用程序的打包方式、是否可出售以获取利润等方面设置了限制。

在这种情况下,可以设置下一节中描述的变量。

6.5.1. NO_PACKAGE

此变量表示我们可能不会生成应用程序的二进制软件包。例如,许可证可能禁止二进制重新分发,或者可能禁止从打补丁的源代码创建的软件包的分发。

但是,port的 DISTFILES 可以在 FTP/HTTP 上自由镜像。除非 NO_CDROM 也被设置,否则它们也可以在 CD-ROM(或类似媒体)上分发。

如果二进制软件包没有普遍用途,并且应用程序必须始终从源代码编译,请使用 NO_PACKAGE 。例如,如果应用程序在编译时将站点特定的配置信息硬编码到其中,请设置 NO_PACKAGE 。

将 NO_PACKAGE 设置为描述软件包无法生成原因的字符串。

6.5.2. NO_CDROM

单独这个变量表明,尽管我们可以生成二进制软件包,但我们既不能将这些软件包也不能将port的 DISTFILES 放入光盘(或类似媒体)进行转售。然而,二进制软件包和port的 DISTFILES 仍然可以通过 FTP/HTTP 获得。

如果设置了这个变量以及 NO_PACKAGE ,那么只有port的 DISTFILES 将可用,并且只能通过 FTP/HTTP 获得。

将 NO_CDROM 设置为描述port无法在光盘上重新分发的原因的字符串。例如,如果port的许可证仅限于“非商业”使用,请使用此选项。

6.5.3. NOFETCHFILES

在 NOFETCHFILES 中定义的文件不能从任何 MASTER_SITES 获取。此类文件的一个示例是供应商通过 CD-ROM 提供的文件。

检查这些文件在 MASTER_SITES 上的可用性的工具必须忽略这些文件并且不报告它们。

6.5.4. RESTRICTED

如果应用程序的许可证既不允许镜像应用程序的 DISTFILES 也不允许以任何方式分发二进制包,则单独设置此变量。

不要设置 NO_CDROM 或 NO_PACKAGE 以及 RESTRICTED ,因为后一个变量意味着前面的变量。

将 RESTRICTED 设置为描述为什么port 不能重新分发的字符串。通常,这表示port 包含专有软件,用户需要手动下载 DISTFILES ,可能需要在注册软件或同意接受 EULA 条款后进行。

6.5.5. RESTRICTED_FILES

当设置 RESTRICTED 或 NO_CDROM 时,此变量默认为 ${DISTFILES} ${PATCHFILES} ,否则为空。如果仅限制一些发布文件,则将此变量设置为列出它们。

如果port存在未在上述变量中解决的法律问题,请将 LEGAL_TEXT 设置为解释该问题的字符串。例如,如果为了 FreeBSD 重新分发二进制文件而获得了特殊许可,则此变量必须指示如此。

设置任何上述变量的port也必须添加到/usr/ports/LEGAL。第一列是匹配受限制的分发文件的通配符。第二列是port的来源。第三列是 make -VLEGAL 的输出。

6.5.8。 示例

陈述“此 port 的 distfiles 必须手动获取”的首选方式如下:

.if !exists(${DISTDIR}/${DISTNAME}${EXTRACT_SUFX})
IGNORE=	may not be redistributed because of licensing reasons. Please visit some-website to accept their license and download ${DISTFILES} into ${DISTDIR}
.endif

这既通知用户,又为自动化程序在用户机器上设置正确的元数据。

请注意,此段必须由 bsd.port.pre.mk 的包含形式先导。

6.6. 构建机制

6.6.1. 并行构建 Ports

FreeBSD ports 框架支持使用多个 make 子进程进行并行构建,这允许 SMP 系统利用所有可用的 CPU 力量,从而使 port 构建更快更有效。

通过在运行供应商代码的 make(1) 上添加 -jX 标志来实现这一目标。这是 ports 的默认构建行为。不幸的是,并非所有 ports 都能很好地处理并行构建,可能需要通过添加 MAKE_JOBS_UNSAFE=yes 变量来显式禁用此功能。当已知某个 port 由于竞争条件导致间歇性构建失败时,就会使用它。

6.6.2. make , gmake 和 imake

存在几种不同的 make 实现。移植软件通常需要特定的实现,如 GNU make ,在 FreeBSD 中称为 gmake 。

如果port使用 GNU make,请将 gmake 添加到 USES 。

MAKE_CMD 可以用来引用在 port 的 Makefile 中配置的特定命令。 只在应用程序 Makefiles 中使用 MAKE_CMD ,以调用在移植软件中期望的 make 实现。

如果 port 是一个使用 imake 从 Imakefiles 创建 Makefiles 的 X 应用程序,请设置 USES= imake 。 查看《使用 USES 宏》一节以获取更多详细信息。

如果 port 的源 Makefile 中除了 all 以外还有其他主要构建目标,请相应设置 ALL_TARGET 。 对于 install 和 INSTALL_TARGET 也是如此。

6.6.3. configure 脚本

如果 port 使用 configure 脚本从 Makefile.in 生成 Makefile,请设置 GNU_CONFIGURE=yes 。要向 configure 脚本传递额外参数(默认参数为 --prefix=${PREFIX} --infodir=${PREFIX}/${INFO_PATH} --mandir=${PREFIX}/man --build=${CONFIGURE_TARGET} ),请在 CONFIGURE_ARGS 中设置这些额外参数。可以使用 CONFIGURE_ENV 传递额外环境变量。

表 1. 使用 configure 的 Ports 变量

变量意味着

GNU_CONFIGURE

port 使用 configure 脚本准备构建。

HAS_CONFIGURE

与 GNU_CONFIGURE 相同,只是默认配置目标不添加到 CONFIGURE_ARGS 中。

CONFIGURE_ARGS

传递给 configure 脚本的附加参数。

CONFIGURE_ENV

用于 configure 脚本运行的附加环境变量。

CONFIGURE_TARGET

重写默认配置目标。默认值为 ${MACHINE_ARCH}-portbld-freebsd${OSREL} 。

6.6.4. 使用 cmake

对于使用 CMake 的 ports,定义 USES= cmake 。

Ports使用的 cmake 变量表 2 变量

变量手段

CMAKE_ARGS

要传递给二进制文件 cmake 的Port 特定 CMake 标志。

CMAKE_ON

对于 CMAKE_ON 中的每个条目,将添加一个启用布尔值到 CMAKE_ARGS 。看 CMAKE_ON 和 CMAKE_OFF 。

CMAKE_OFF

对于 CMAKE_OFF 中的每个条目,将添加一个禁用布尔值到 CMAKE_ARGS 。看 CMAKE_ON 和 CMAKE_OFF 。

CMAKE_BUILD_TYPE

构建类型(CMake 预定义的构建配置文件)。默认为 Release ,如果设置了 WITH_DEBUG ,则为 Debug 。

CMAKE_SOURCE_PATH

源目录路径。默认为 ${WRKSRC} 。

CONFIGURE_ENV

要设置的其他环境变量与 cmake 二进制文件相关。

cmake 建造的用户可定义的变量表 3

变量意味

CMAKE_NOCOLOR

禁用彩色构建输出。默认情况下未设置,除非设置 BATCH 或 PACKAGE_BUILDING 。

CMake 支持这些构建配置文件: Debug , Release , RelWithDebInfo 和 MinSizeRel 。 Debug 和 Release 配置文件遵循系统 FLAGS , RelWithDebInfo 和 MinSizeRel 将分别设置 CFLAGS 为 -O2 -g 和 -Os -DNDEBUG 。 CMAKE_BUILD_TYPE 的小写值被导出到 PLIST_SUB ,如果port根据构建类型安装.cmake(请参阅 devel/kf5-kcrash 的示例)。请注意,一些项目可能定义自己的构建配置文件和/或通过在 CMakeLists.txt 中设置 CMAKE_BUILD_TYPE 来强制特定的构建类型。为了使这样一个项目的port遵循 CFLAGS 和 WITH_DEBUG ,这些文件中的 CMAKE_BUILD_TYPE 定义必须被移除。

大多数基于 CMake 的项目支持一种离源代码构建的方法。对于port,离源代码构建是默认设置。可以通过使用 :insource 后缀来请求源代码内构建。使用离源代码构建时, CONFIGURE_WRKSRC , BUILD_WRKSRC 和 INSTALL_WRKSRC 将被设置为 ${WRKDIR}/.build ,并且该目录将用于保存在配置和构建阶段生成的所有文件,保持源代码目录不变。

示例 2. USES= cmake 示例

此片段演示了使用 CMake 构建 port 的方法。通常情况下不需要 CMAKE_SOURCE_PATH ,但当源代码不位于顶级目录中,或者只打算构建项目的子集时,可以设置 port。

USES=			cmake
CMAKE_SOURCE_PATH=	${WRKSRC}/subproject

示例 3. CMAKE_ON 和 CMAKE_OFF

当向 CMAKE_ARGS 添加布尔值时,最好使用 CMAKE_ON 和 CMAKE_OFF 变量。这样做会更容易:

CMAKE_ON=	VAR1 VAR2
CMAKE_OFF=	VAR3

等同于:

CMAKE_ARGS=	-DVAR1:BOOL=TRUE -DVAR2:BOOL=TRUE -DVAR3:BOOL=FALSE

使用 scons 6.6.5。

如果 port 使用 SCons,请定义 USES=scons 。

要使第三方 SConstruct 尊重通过环境传递给 SCons 的所有内容(即,最重要的是 CC/CXX/CFLAGS/CXXFLAGS ),请修补 SConstruct,以便构建 Environment 如下所示:

env = Environment(**ARGUMENTS)

它可以然后通过 env.Append 和 env.Replace 进行修改。

6.6.6. 用 cargo 构建 Rust 应用程序

对于使用 Cargo 的ports,定义 USES=cargo 。

用户可以为 cargo 构建定义的变量表 4

变量默认描述

CARGO_CRATES

列出port依赖的箱子列表。每个条目都需要像 cratename-semver 这样的格式,例如, libc-0.2.40 。Port的维护者可以使用 make cargo-crates 从 Cargo.lock 生成此列表。手动提升箱子版本是可能的,但要注意传递依赖关系。如果 make cargo-crates 生成的列表很大,可能将其放在顶层port目录中的 Makefile.crates 文件中更方便。如果存在,ports框架会自动源自该文件。这有助于保持主port Makefile 处于可管理的大小范围内。

CARGO_FEATURES

要构建的应用功能列表(以空格分隔)。要禁用所有默认功能,请向 CARGO_FEATURES 添加特殊令牌 --no-default-features 。手动传递给 CARGO_BUILD_ARGS , CARGO_INSTALL_ARGS 和 CARGO_TEST_ARGS 不是必需的。

CARGO_CARGOTOML

${WRKSRC}/Cargo.toml

使用的 Cargo.toml 路径。

CARGO_CARGOLOCK

${WRKSRC}/Cargo.lock

用于 make cargo-crates 的 Cargo.lock 路径。必要时可以指定多个锁定文件。

CARGO_ENV

要传递给 Cargo 类似 MAKE_ENV 的环境变量列表。

RUSTFLAGS

传递给 Rust 编译器的标志。

CARGO_CONFIGURE

yes

使用默认的 do-configure 。

CARGO_UPDATE_ARGS

在配置阶段传递给 Cargo 的额外参数。可以使用 cargo update --help 查找有效参数。

CARGO_BUILDDEP

yes

在 lang/rust 上添加构建依赖。

CARGO_CARGO_BIN

${LOCALBASE}/bin/cargo

cargo 二进制文件的位置。

CARGO_BUILD

yes

使用默认 do-build 。

CARGO_BUILD_ARGS

在构建阶段传递给 Cargo 的额外参数。可以使用 cargo build --help 查找有效参数。

CARGO_INSTALL

yes

使用默认 do-install 。

CARGO_INSTALL_ARGS

在安装阶段传递给 Cargo 的额外参数。可以使用 cargo install --help 查找有效参数。

CARGO_INSTALL_PATH

.

安装木筏的路径。 这通过它的 --path 参数传递给 cargo install 。 当指定多个路径时, cargo install 会多次运行。

CARGO_TEST

yes

使用默认的 do-test 。

CARGO_TEST_ARGS

在测试阶段传递给货物的额外参数。 可以使用 cargo test --help 查找有效参数。

CARGO_TARGET_DIR

${WRKDIR}/target

货物输出目录的位置。

CARGO_DIST_SUBDIR

rust/crates

相对于 DISTDIR 的目录,将存储板块分发文件。

CARGO_VENDOR_DIR

${WRKSRC}/cargo-crates

存放供应商目录的位置,所有的板条箱都将被提取到这里。尽量保持在 PATCH_WRKSRC 以下,这样可以更容易地应用补丁。

CARGO_USE_GITHUB

no

通过 GH_TUPLE 启用对 GitHub 上特定 Git 提交锁定的板条箱的提取。这将尝试对所有 Cargo.toml 进行修补,使其指向离线源而不是在构建过程中从 Git 存储库获取它们。

CARGO_USE_GITLAB

no

与 CARGO_USE_GITHUB 相同,但适用于 GitLab 实例和 GL_TUPLE 。

创建一个简单的 Rust 应用程序Port的示例 4。

创建基于 Cargo 的port是一个三阶段的过程。首先,我们需要提供一个ports模板,用于获取应用程序分发文件:

PORTNAME=	tokei
DISTVERSIONPREFIX=	v
DISTVERSION=	7.0.2
CATEGORIES=	devel

MAINTAINER=	tobik@FreeBSD.org
COMMENT=	Display statistics about your code
WWW=		https://github.com/XAMPPRocky/tokei/

USES=		cargo
USE_GITHUB=	yes
GH_ACCOUNT=	Aaronepower

.include <bsd.port.mk>

生成初始的 distinfo:

% make makesum
=> Aaronepower-tokei-v7.0.2_GH0.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://codeload.github.com/Aaronepower/tokei/tar.gz/v7.0.2?dummy=/Aaronepower-tokei-v7.0.2_GH0.tar.gz
fetch: https://codeload.github.com/Aaronepower/tokei/tar.gz/v7.0.2?dummy=/Aaronepower-tokei-v7.0.2_GH0.tar.gz: size of remote file is not known
Aaronepower-tokei-v7.0.2_GH0.tar.gz                     45 kB  239 kBps 00m00s

现在分发文件已准备就绪,我们可以继续从捆绑的 Cargo.lock 中提取箱依赖项:

% make cargo-crates
CARGO_CRATES=   aho-corasick-0.6.4 \
                ansi_term-0.11.0 \
                arrayvec-0.4.7 \
                atty-0.2.9 \
                bitflags-1.0.1 \
                byteorder-1.2.2 \
                [...]

此命令的输出需要直接粘贴到 Makefile 中:

PORTNAME=	tokei
DISTVERSIONPREFIX=	v
DISTVERSION=	7.0.2
CATEGORIES=	devel

MAINTAINER=	tobik@FreeBSD.org
COMMENT=	Display statistics about your code
WWW=		https://github.com/XAMPPRocky/tokei/

USES=		cargo
USE_GITHUB=	yes
GH_ACCOUNT=	Aaronepower

CARGO_CRATES=   aho-corasick-0.6.4 \
                ansi_term-0.11.0 \
                arrayvec-0.4.7 \
                atty-0.2.9 \
                bitflags-1.0.1 \
                byteorder-1.2.2 \
                [...]

.include <bsd.port.mk>

需要重新生成 distinfo 以包含所有箱分发文件:

% make makesum
=> rust/crates/aho-corasick-0.6.4.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://crates.io/api/v1/crates/aho-corasick/0.6.4/download?dummy=/rust/crates/aho-corasick-0.6.4.tar.gz
rust/crates/aho-corasick-0.6.4.tar.gz         100% of   24 kB 6139 kBps 00m00s
=> rust/crates/ansi_term-0.11.0.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://crates.io/api/v1/crates/ansi_term/0.11.0/download?dummy=/rust/crates/ansi_term-0.11.0.tar.gz
rust/crates/ansi_term-0.11.0.tar.gz           100% of   16 kB   21 MBps 00m00s
=> rust/crates/arrayvec-0.4.7.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://crates.io/api/v1/crates/arrayvec/0.4.7/download?dummy=/rust/crates/arrayvec-0.4.7.tar.gz
rust/crates/arrayvec-0.4.7.tar.gz             100% of   22 kB 3237 kBps 00m00s
=> rust/crates/atty-0.2.9.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://crates.io/api/v1/crates/atty/0.2.9/download?dummy=/rust/crates/atty-0.2.9.tar.gz
rust/crates/atty-0.2.9.tar.gz                 100% of 5898  B   81 MBps 00m00s
=> rust/crates/bitflags-1.0.1.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
[...]

port现在已准备好进行测试构建和进一步调整,如创建 plist,撰写描述,添加许可信息,选项等等,一切如常。

如果您没有在像 poudriere 这样的干净环境中测试您的port,请记得在任何测试之前运行 make clean 。

示例 5. 启用额外的应用程序功能

一些应用程序在其 Cargo.toml 中定义了额外的功能。可以通过在 port 中设置 CARGO_FEATURES 来进行编译。

在这里,我们启用 Tokei 的 json 和 yaml 功能:

CARGO_FEATURES=	json yaml

示例 6. 将应用程序功能编码为 Port 选项。

Cargo.toml 中的一个示例 [features] 部分可能如下所示:

[features]
pulseaudio_backend = ["librespot-playback/pulseaudio-backend"]
portaudio_backend = ["librespot-playback/portaudio-backend"]
default = ["pulseaudio_backend"]

pulseaudio_backend 是一个默认功能。除非我们通过向 CARGO_FEATURES 添加 --no-default-features 来明确关闭默认功能,否则它始终启用。在这里,我们将 portaudio_backend 和 pulseaudio_backend 功能转换为 port 选项:

CARGO_FEATURES=	--no-default-features

OPTIONS_DEFINE=	PORTAUDIO PULSEAUDIO

PORTAUDIO_VARS=		CARGO_FEATURES+=portaudio_backend
PULSEAUDIO_VARS=	CARGO_FEATURES+=pulseaudio_backend

示例 7. 列出 Crate 许可证

包有它们自己的许可证。在向 LICENSE 块添加到 port 时,了解它们是很重要的(请参阅许可证)。助手目标 cargo-crates-licenses 将尝试列出在 CARGO_CRATES 中定义的所有包的所有许可证。

% make cargo-crates-licenses
aho-corasick-0.6.4  Unlicense/MIT
ansi_term-0.11.0    MIT
arrayvec-0.4.7      MIT/Apache-2.0
atty-0.2.9          MIT
bitflags-1.0.1      MIT/Apache-2.0
byteorder-1.2.2     Unlicense/MIT
[...]

使用 meson 6.6.7。

对于使用 Meson 的 ports,定义 USES=meson 。

表 5. 使用 meson 的 Ports 的变量

变量描述

MESON_ARGS

要传递给 meson 二进制文件的 Port 特定 Meson 标志。

MESON_BUILD_DIR

相对于 WRKSRC 的构建目录路径。默认为 _build 。

示例 8. USES=meson 示例

此片段演示了使用 Meson 进行 port 的用法。

USES=		meson
MESON_ARGS=	-Dfoo=enabled

6.6.8. 构建 Go 应用程序

对于使用 Go 的ports,定义 USES=go 。有关可以设置以控制构建过程的变量列表,请参阅 go 。

示例 9. 为基于 Go 模块的应用程序创建Port。

在大多数情况下,将 GO_MODULE 变量设置为 go.mod 中 module 指令指定的值就足够了。

PORTNAME=       hey
DISTVERSIONPREFIX=	v
DISTVERSION=    0.1.4
CATEGORIES=     benchmarks

MAINTAINER=     dmgk@FreeBSD.org
COMMENT=        Tiny program that sends some load to a web application
WWW=            https://github.com/rakyll/hey/

LICENSE=        APACHE20
LICENSE_FILE=   ${WRKSRC}/LICENSE

USES=           go:modules
GO_MODULE=      github.com/rakyll/hey

PLIST_FILES=    bin/hey

.include <bsd.port.mk>

如果“简单”方法不够或需要更多对依赖项的控制,则下面描述了完整的移植过程。

创建基于 Go 的 port 是一个五阶段的过程。首先,我们需要提供一个 ports 模板,用于获取应用程序分发文件:

PORTNAME=	ghq
DISTVERSIONPREFIX=	v
DISTVERSION=	0.12.5
CATEGORIES=	devel

MAINTAINER=	tobik@FreeBSD.org
COMMENT=	Remote repository management made easy
WWW=		https://github.com/x-motemen/ghq/

USES=		go:modules
USE_GITHUB=	yes
GH_ACCOUNT=	motemen

.include <bsd.port.mk>

生成初始的 distinfo:

% make makesum
===>  License MIT accepted by the user
=> motemen-ghq-v0.12.5_GH0.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://codeload.github.com/motemen/ghq/tar.gz/v0.12.5?dummy=/motemen-ghq-v0.12.5_GH0.tar.gz
fetch: https://codeload.github.com/motemen/ghq/tar.gz/v0.12.5?dummy=/motemen-ghq-v0.12.5_GH0.tar.gz: size of remote file is not known
motemen-ghq-v0.12.5_GH0.tar.gz                          32 kB  177 kBps    00s

现在分发文件已准备就绪,我们可以提取所需的 Go 模块依赖项。此步骤需要安装ports-mgmt/modules2tuple:

% make gomod-vendor
[...]
GH_TUPLE=	\
		Songmu:gitconfig:v0.0.2:songmu_gitconfig/vendor/github.com/Songmu/gitconfig \
		daviddengcn:go-colortext:186a3d44e920:daviddengcn_go_colortext/vendor/github.com/daviddengcn/go-colortext \
		go-yaml:yaml:v2.2.2:go_yaml_yaml/vendor/gopkg.in/yaml.v2 \
		golang:net:3ec191127204:golang_net/vendor/golang.org/x/net \
		golang:sync:112230192c58:golang_sync/vendor/golang.org/x/sync \
		golang:xerrors:3ee3066db522:golang_xerrors/vendor/golang.org/x/xerrors \
		motemen:go-colorine:45d19169413a:motemen_go_colorine/vendor/github.com/motemen/go-colorine \
		urfave:cli:v1.20.0:urfave_cli/vendor/github.com/urfave/cli

此命令的输出需要直接粘贴到 Makefile 中:

PORTNAME=	ghq
DISTVERSIONPREFIX=	v
DISTVERSION=	0.12.5
CATEGORIES=	devel

MAINTAINER=	tobik@FreeBSD.org
COMMENT=	Remote repository management made easy
WWW=		https://github.com/x-motemen/ghq/

USES=		go:modules
USE_GITHUB=	yes
GH_ACCOUNT=	motemen
GH_TUPLE=	Songmu:gitconfig:v0.0.2:songmu_gitconfig/vendor/github.com/Songmu/gitconfig \
		daviddengcn:go-colortext:186a3d44e920:daviddengcn_go_colortext/vendor/github.com/daviddengcn/go-colortext \
		go-yaml:yaml:v2.2.2:go_yaml_yaml/vendor/gopkg.in/yaml.v2 \
		golang:net:3ec191127204:golang_net/vendor/golang.org/x/net \
		golang:sync:112230192c58:golang_sync/vendor/golang.org/x/sync \
		golang:xerrors:3ee3066db522:golang_xerrors/vendor/golang.org/x/xerrors \
		motemen:go-colorine:45d19169413a:motemen_go_colorine/vendor/github.com/motemen/go-colorine \
		urfave:cli:v1.20.0:urfave_cli/vendor/github.com/urfave/cli

.include <bsd.port.mk>

需要重新生成 distinfo 以包含所有分发文件:

% make makesum
=> Songmu-gitconfig-v0.0.2_GH0.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://codeload.github.com/Songmu/gitconfig/tar.gz/v0.0.2?dummy=/Songmu-gitconfig-v0.0.2_GH0.tar.gz
fetch: https://codeload.github.com/Songmu/gitconfig/tar.gz/v0.0.2?dummy=/Songmu-gitconfig-v0.0.2_GH0.tar.gz: size of remote file is not known
Songmu-gitconfig-v0.0.2_GH0.tar.gz                    5662  B  936 kBps    00s
=> daviddengcn-go-colortext-186a3d44e920_GH0.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch https://codeload.github.com/daviddengcn/go-colortext/tar.gz/186a3d44e920?dummy=/daviddengcn-go-colortext-186a3d44e920_GH0.tar.gz
fetch: https://codeload.github.com/daviddengcn/go-colortext/tar.gz/186a3d44e920?dummy=/daviddengcn-go-colortext-186a3d44e920_GH0.tar.gz: size of remote file is not known
daviddengcn-go-colortext-186a3d44e920_GH0.tar.        4534  B 1098 kBps    00s
[...]

port现在已准备好进行测试构建和进一步调整,如创建 plist,编写描述,添加许可信息,选项等等,与正常操作一样。

如果您没有在像 poudriere 这样的干净环境中测试您的port,请记得在任何测试之前运行 make clean 。

示例 10. 设置输出二进制名称或安装路径

一些 ports 需要将结果二进制文件安装到不同名称或默认路径以外的路径。这可以通过使用 GO_TARGET 元组语法来实现,例如:

GO_TARGET=  ./cmd/ipfs:ipfs-go

将 ipfs 二进制文件安装为 ${PREFIX}/bin/ipfs-go

GO_TARGET=  ./dnscrypt-proxy:${PREFIX}/sbin/dnscrypt-proxy

将 dnscrypt-proxy 安装到 ${PREFIX}/sbin

使用 cabal 来构建 Haskell 应用程序的 6.6.9

对于使用 Cabal 的ports,构建系统定义了 USES=cabal 。请参考 cabal 以查看可设置以控制构建过程的变量列表。

示例 11. 为一个 Hackage 托管的 Haskell 应用程序创建Port

在准备 Haskell Cabal port 时,需要安装 devel/hs-cabal-install 和 ports-mgmt/hs-cabal2tuple 程序,因此请确保事先安装它们。首先,我们需要定义通用的 ports 变量,以便 cabal-install 可以获取软件包分发文件:

PORTNAME=	ShellCheck
DISTVERSION=	0.6.0
CATEGORIES=	devel

MAINTAINER=	haskell@FreeBSD.org
COMMENT=	Shell script analysis tool
WWW=		https://www.shellcheck.net/

USES=		cabal

.include <bsd.port.mk>

这个最小的 Makefile 使用 cabal-extract 辅助目标来获取分发文件:

% make cabal-extract
[...]
Downloading the latest package list from hackage.haskell.org
cabal get ShellCheck-0.6.0
Downloading  ShellCheck-0.6.0
Downloaded   ShellCheck-0.6.0
Unpacking to ShellCheck-0.6.0/

现在我们在 ${WRKSRC} 下有 ShellCheck.cabal 软件包描述文件,我们可以使用 cabal-configure 来生成构建计划:

% make cabal-configure
[...]
Resolving dependencies...
Build profile: -w ghc-8.10.7 -O1
In order, the following would be built (use -v for more details):
 - Diff-0.4.1 (lib) (requires download & build)
 - OneTuple-0.3.1 (lib) (requires download & build)
[...]

一旦完成,可以生成所需依赖项列表:

% make make-use-cabal
USE_CABAL=	QuickCheck-2.12.6.1 \
		hashable-1.3.0.0 \
		integer-logarithms-1.0.3 \
[...]

Haskell 软件包可能包含修订版本,就像 FreeBSD ports 一样。修订版本只会影响 .cabal 文件。请注意 _ 符号后面的附加版本号。请将新生成的 USE_CABAL 列表放在旧列表的位置。

最后,需要重新生成 distinfo 以包含所有分发文件:

% make makesum
=> ShellCheck-0.6.0.tar.gz doesn't seem to exist in /usr/local/poudriere/ports/git/distfiles/cabal.
=> Attempting to fetch https://hackage.haskell.org/package/ShellCheck-0.6.0/ShellCheck-0.6.0.tar.gz
ShellCheck-0.6.0.tar.gz                                136 kB  642 kBps    00s
=> QuickCheck-2.12.6.1/QuickCheck-2.12.6.1.tar.gz doesn't seem to exist in /usr/local/poudriere/ports/git/distfiles/cabal.
=> Attempting to fetch https://hackage.haskell.org/package/QuickCheck-2.12.6.1/QuickCheck-2.12.6.1.tar.gz
QuickCheck-2.12.6.1/QuickCheck-2.12.6.1.tar.gz          65 kB  361 kBps    00s
[...]

port现在已准备好进行测试构建和进一步调整,如创建 plist,编写描述,添加许可信息,选项等等,一切如常。

如果您没有在像 poudriere 这样的干净环境中测试您的port,请记得在任何测试之前运行 make clean 。

一些 Haskell ports 在 share/${PORTNAME} 下安装各种数据文件。对于这种情况,需要在port端进行特殊处理。port应定义 CABAL_WRAPPER_SCRIPTS 旋钮,列出每个将使用数据文件的可执行文件。此外,在罕见情况下,被移植程序使用其他 Haskell 软件包的数据文件,这时 FOO_DATADIR_VARS 就派上用场了。

示例 12. 在 Haskell 中处理数据文件 Port

devel/hs-profiteur 是一个 Haskell 应用程序,用于生成带有一些内容的单页面 HTML。

PORTNAME=	profiteur

[...]

USES=		cabal

USE_CABAL=	OneTuple-0.3.1_2 \
		QuickCheck-2.14.2 \
		[...]

.include <bsd.port.mk>

它在 share/profiteur 下安装 HTML 模板,因此我们需要添加 CABAL_WRAPPER_SCRIPTS 旋钮:

[...]

USE_CABAL=	OneTuple-0.3.1_2 \
		QuickCheck-2.14.2 \
		[...]


CABAL_WRAPPER_SCRIPTS=		${CABAL_EXECUTABLES}

.include <bsd.port.mk>

该程序还尝试访问 jquery.js 文件,该文件是 js-jquery-3.3.1 Haskell 软件包的一部分。为了找到该文件,我们需要使包装脚本也查找 share/profiteur 中的 js-jquery 数据文件。我们用 profiteur_DATADIR_VARS 来实现这一点。

[...]

CABAL_WRAPPER_SCRIPTS=		${CABAL_EXECUTABLES}
profiteur_DATADIR_VARS=		js-jquery

.include <bsd.port.mk>

现在port将实际的二进制文件安装到 libexec/cabal/profiteur 中,并将脚本安装到 bin/profiteur 中。

除了运行该程序并检查一切正常之外,没有更容易找到 FOO_DATADIR_VARS 旋钮的正确值的方法。幸运的是,使用 FOO_DATADIR_VARS 的需求非常罕见。

在移植复杂的 Haskell 程序时,另一个边缘情况是 cabal.project 文件中存在 VCS 依赖项。

示例 13. 使用 VCS 依赖项移植 Haskell 应用程序

net-p2p/cardano-node 是一款极其复杂的软件。在其 cabal.project 中有很多类似这样的块:

[...]
source-repository-package
  type: git
  location: https://github.com/input-output-hk/cardano-crypto
  tag: f73079303f663e028288f9f4a9e08bcca39a923e
[...]

类型 source-repository-package 的依赖项在构建过程中会被 cabal 自动拉取。不幸的是,这会在 fetch 阶段之后使用网络。这是 ports 框架不允许的。这些来源需要在 port 的 Makefile 中列出。 make-use-cabal 辅助目标可以使托管在 GitHub 上的软件包变得更容易。在通常的 cabal-extract 和 cabal-configure 之后运行此目标将不仅生成 USE_CABAL 开关,还会生成 GH_TUPLE :

% make make-use-cabal
USE_CABAL=	Diff-0.4.1 \
		Glob-0.10.2_3 \
		HUnit-1.6.2.0 \
		[...]

GH_TUPLE=		input-output-hk:cardano-base:0f3a867493059e650cda69e20a5cbf1ace289a57:cardano_base/dist-newstyle/src/cardano-b_-c8db9876882556ed \
		input-output-hk:cardano-crypto:f73079303f663e028288f9f4a9e08bcca39a923e:cardano_crypto/dist-newstyle/src/cardano-c_-253fd88117badd8f \
		[...]

从 make-use-cabal 获取的 GH_TUPLE 项目与其他项目分开可能很有用,以便更容易更新 port:

GH_TUPLE=	input-output-hk:cardano-base:0f3a867493059e650cda69e20a5cbf1ace289a57:cardano_base/dist-newstyle/src/cardano-b_-c8db9876882556ed \
		input-output-hk:cardano-crypto:f73079303f663e028288f9f4a9e08bcca39a923e:cardano_crypto/dist-newstyle/src/cardano-c_-253fd88117badd8f \
		[...]

GH_TUPLE+=	bitcoin-core:secp256k1:ac83be33d0956faf6b7f61a60ab524ef7d6a473a:secp

Haskell ports 与 VCS 依赖项还需要暂时使用以下技巧:

BINARY_ALIAS=	git=true

6.7. 使用 GNU Autotools

如果 port 需要任何 GNU Autotools 软件,请添加 USES=autoreconf 。查看 autoreconf 获取更多信息。

6.8. 使用 GNU gettext

6.8.1. 基本用法

如果 port 需要 gettext ,设置 USES= gettext ,port 将从 devel/gettext 继承对 libintl.so 的依赖。 gettext 的其他值在 USES=gettext 中列出。

一个相当常见的情况是 port 使用 gettext 和 configure 。通常,GNU configure 应该能够自动定位 gettext 。

USES=	gettext
GNU_CONFIGURE=	yes

如果它无法成功,可以通过以下方式传递 gettext 的位置提示:在 CPPFLAGS 和 LDFLAGS 中使用 localbase 。

USES=	gettext localbase:ldflags
GNU_CONFIGURE=	yes

6.8.2. 可选用法

一些软件产品允许禁用 NLS。例如,通过将 --disable-nls 传递给 configure 。在这种情况下,port必须有条件地使用 gettext ,具体取决于 NLS 选项的状态。对于低到中等复杂度的ports,请使用这种习惯用语:

GNU_CONFIGURE=		yes

OPTIONS_DEFINE=		NLS
OPTIONS_SUB=		yes

NLS_USES=		gettext
NLS_CONFIGURE_ENABLE=	nls

.include <bsd.port.mk>

或者使用使用选项的较旧方法:

GNU_CONFIGURE=		yes

OPTIONS_DEFINE=		NLS

.include <bsd.port.options.mk>

.if ${PORT_OPTIONS:MNLS}
USES+=			gettext
PLIST_SUB+=		NLS=""
.else
CONFIGURE_ARGS+=	--disable-nls
PLIST_SUB+=		NLS="@comment "
.endif

.include <bsd.port.mk>

待办事项清单上的下一项是要安排消息目录文件在打包清单中有条件地包含。 此任务的 Makefile 部分已由该习惯提供。 在高级 pkg-plist 实践部分有解释。 简而言之,pkg-plist 中的每个 %%NLS%% 出现将在 pkg-plist 中消息目录文件的每个路径之前用" @comment " if NLS is disabled, or by a null string if NLS is enabled. Consequently, the lines prefixed by %%NLS%%will become mere comments in the final packing list if NLS is off; otherwise the prefix will be just left out. Then insert%%NLS%% 替换。 例如:

%%NLS%%share/locale/fr/LC_MESSAGES/foobar.mo
%%NLS%%share/locale/no/LC_MESSAGES/foobar.mo

在复杂情况下,可能需要更先进的技术,如动态打包清单生成。

6.8.3. 处理消息目录目录

安装消息目录文件有一个需要注意的地方。它们的目标目录,位于 LOCALBASE/share/locale 下,不得由port创建和移除。最流行的语言有它们各自的目录列在 PORTSDIR/Templates/BSD.local.dist 中。许多其他语言的目录受 devel/gettext port管理。查看其 pkg-plist,并查看port是否将为某种独特语言安装消息目录文件。

6.9. 使用 Perl

如果 MASTER_SITES 设置为 CPAN ,通常会自动选择正确的子目录。如果默认子目录错误,可以使用 CPAN/Module 进行更改。 MASTER_SITES 也可以设置为旧的 MASTER_SITE_PERL_CPAN ,然后 MASTER_SITE_SUBDIR 的首选值是顶层层次结构名称。例如, p5-Module-Name 的推荐值是 Module 。可以在 cpan.org 上查看顶层层次结构。这样可以在模块作者更改时保持 port 的正常工作。

例外情况是相关目录不存在或者在该目录中不存在 distfile 时。在这种情况下,允许使用作者的 id 作为 MASTER_SITE_SUBDIR 。可以使用 CPAN:AUTHOR 宏,它将被转换为散列作者目录。例如, CPAN:AUTHOR 将被转换为 authors/id/A/AU/AUTHOR 。

当 port 需要 Perl 支持时,必须使用 perl5 USES 描述中描述的可选 USE_PERL5 设置 USES=perl5 。

表 6. 使用 Perl 的 Ports 只读变量

只读变量方法

PERL

Perl 5 解释器的完整路径,可以是系统中的或者从软件包中安装的,但不包括版本号。当软件需要 Perl 解释器的路径时使用此路径。要替换脚本中的 " #! "行,请使用 shebangfix 。

PERL_VERSION

已安装的 Perl 完整版本(例如, 5.8.9 )。

PERL_LEVEL

已安装的 Perl 版本为形式为 MNNNPP 的整数(例如, 500809 )。

PERL_ARCH

存储架构相关库的位置。默认为 ${ARCH}-freebsd .

PERL_PORT

安装的 Perl port的名称(例如, perl5 )。

SITE_PERL

站点特定 Perl 软件包所在的目录名。此值将添加到 PLIST_SUB 中。

示例 14. Perl 依赖示例

p5-IO-Tee>=0.64:devel/p5-IO-Tee

对于安装手册页的 Perl ports,在 pkg-plist 中可以使用宏 PERL5_MAN3 和 PERL5_MAN1 。例如,

lib/perl5/5.14/man/man1/event.1.gz
lib/perl5/5.14/man/man3/AnyEvent::I3.3.gz

可以替换为

%%PERL5_MAN1%%/event.1.gz
%%PERL5_MAN3%%/AnyEvent::I3.3.gz

例 15. 一个 Port 只需要 Perl 来构建

由于默认的 USE_PERL5 值是构建和运行,将其设置为:

USES=		perl5
USE_PERL5=	build

例 16. 一个 Port 也需要 Perl 来修补

有时候,仅仅使用 sed(1)进行补丁不够。当使用 perl(1)更容易时,请使用:

USES=		perl5
USE_PERL5=	patch build run

例子 17. 一个需要 ExtUtils::MakeMaker 构建的 Perl 模块

大多数 Perl 模块附带 Makefile.PL 配置脚本。在这种情况下,请设置:

USES=		perl5
USE_PERL5=	configure

示例 18. 一个需要 Module::Build 构建的 Perl 模块

当一个 Perl 模块带有一个 Build.PL 配置脚本时,它可能需要 Module::Build,在这种情况下,设置

USES=		perl5
USE_PERL5=	modbuild

如果它需要 Module::Build::Tiny,设置

USES=		perl5
USE_PERL5=	modbuildtiny

6.10. 使用 X11

6.10.1. X.Org 组件

The X11 实现在 The Ports Collection 中提供的是 X.Org。如果应用程序依赖于 X 组件,请添加 USES= xorg 并将 USE_XORG 设置为所需组件列表中的一部分。完整列表可以在 xorg 中找到。

Mesa 项目是提供免费的 OpenGL 实现的努力。要指定对该项目各组件的依赖关系,请使用 USES= gl 和 USE_GL 。请查看 gl 以获取可用组件的完整列表。为了向后兼容, yes 的值映射到 glu 。

例 19. USE_XORG 示例

USES=		gl xorg
USE_GL=		glu
USE_XORG=	xrender xft xkbfile xt xaw

表 7. 使用 X 的 Ports 变量

USES= imake

port 使用 imake 。

XMKMF

如果不在 PATH 中,则设置为 xmkmf 的路径。默认为 xmkmf -a 。

示例 20. 使用 X11 相关变量

# Use some X11 libraries
USES=		xorg
USE_XORG=	x11 xpm

6.10.2. Ports 需要 Motif 的

如果 port 需要 Motif 库,请在 Makefile 中定义 USES= motif 。默认的 Motif 实现是 x11-toolkits/open-motif。用户可以通过在他们的 make.conf 中设置 WANT_LESSTIF 来选择 x11-toolkits/lesstif。类似地,x11-toolkits/open-motif-devel 可以通过在 make.conf 中设置 WANT_OPEN_MOTIF_DEVEL 来选择。

MOTIFLIB 将被 motif.mk 设置为引用适当的 Motif 库。请对 port 的源代码进行补丁,以便在原始 Makefile 或 Imakefile 中引用 Motif 库的地方使用 ${MOTIFLIB} 。

有两种常见情况:

  • 如果port在其 Makefile 或 Imakefile 中将 Motif 库称为 -lXm ,请用 ${MOTIFLIB} 替换它。

  • 如果port在其 Imakefile 中使用 XmClientLibs ,请将其更改为 ${MOTIFLIB} ${XTOOLLIB} ${XLIB} 。

注意, MOTIFLIB (通常)会扩展到 -L/usr/local/lib -lXm -lXp 或 /usr/local/lib/libXm.a ,因此无需在前面添加 -L 或 -l 。

6.10.3. X11 字体

如果 port 安装 X Window 系统的字体,请将它们放在 LOCALBASE/lib/X11/fonts/local 中。

6.10.4. 使用 Xvfb 获取虚假 DISPLAY

一些应用程序需要一个正常工作的 X11 显示来确保编译成功。这对于无头操作的机器构成了问题。当使用这个变量时,构建基础设施将启动虚拟帧缓冲 X 服务器。然后将工作的 DISPLAY 传递给构建。查看 USES=display 以获取可能的参数。

USES=	display

6.10.5. 桌面条目

桌面条目(Freedesktop 标准)提供一种在安装新程序时自动调整桌面功能的方式,无需用户干预。例如,新安装的程序会自动出现在兼容桌面环境的应用程序菜单中。桌面条目起源于 GNOME 桌面环境,但现在是一个标准,并且也适用于 KDE 和 Xfce。这种自动化提供了真正的用户福利,鼓励将桌面条目用于可以在桌面环境中使用的应用程序。

6.10.5.1. 使用预定义的 .desktop 文件

Ports 包括预定义的 *.desktop 文件的软件包必须在 pkg-plist 中包含这些文件,并将它们安装在 $LOCALBASE/share/applications 目录中。 INSTALL_DATA 宏对于安装这些文件很有用。

6.10.5.2. 更新桌面数据库

如果port在其 portname.desktop 中有 MimeType 条目,则在安装和卸载后必须更新桌面数据库。要做到这一点,请定义 USES = desktop-file-utils。

6.10.5.3. 使用 DESKTOP_ENTRIES 创建桌面条目

使用 DESKTOP_ENTRIES 可以轻松地为应用程序创建桌面条目。将创建一个名为 name.desktop 的文件,该文件将自动安装并添加到 pkg-plist 中。语法为:

DESKTOP_ENTRIES=	"NAME" "COMMENT" "ICON" "COMMAND" "CATEGORY" StartupNotify

可在 Freedesktop 网站上找到可能的类别列表。 StartupNotify 指示应用程序是否与启动通知兼容。这些通常是图形指示器,比如一个在鼠标指针、菜单或面板上出现的时钟,用于向用户指示程序何时正在启动。与启动通知兼容的程序在启动后会清除指示器。不兼容启动通知的程序永远不会清除指示器(可能会使用户感到困惑和愤怒),必须将 StartupNotify 设为 false 以便根本不显示指示器。

示例:

DESKTOP_ENTRIES=	"ToME" "Roguelike game based on JRR Tolkien's work" \
			"${DATADIR}/xtra/graf/tome-128.png" \
			"tome -v -g" "Application;Game;RolePlaying;" \
			false

DESKTOP_ENTRIES 被安装在变量指向的目录中。 DESKTOPDIR 默认为${PREFIX}/share/applications

6.11. 使用 GNOME

6.11.1. 介绍

本章节解释了 ports 使用的 GNOME 框架。该框架可以大致分为基本组件、GNOME 桌面组件以及一些简化 port 维护者工作的特殊宏。

6.11.2. 使用 USE_GNOME

将此变量添加到 port 允许使用在 bsd.gnome.mk 中定义的宏和组件。bsd.gnome.mk 中的代码添加了所需的构建时、运行时或库依赖项,或者处理特殊文件。FreeBSD 下的 GNOME 应用程序使用 USE_GNOME 基础设施。将所有所需组件作为以空格分隔的列表包含。这些 USE_GNOME 组件被分为基本组件、GNOME 3 组件和遗留组件这些虚拟列表。如果 port 只需要 GTK3 库,这是定义的最简单方式:

USE_GNOME=	gtk30

USE_GNOME 组件会自动添加它们所需的依赖关系。请查看 GNOME 组件,了解所有 USE_GNOME 组件及它们隐含的其他组件以及它们的依赖关系的详尽列表。

这是一个示例 Makefile,用于一个使用了本文档中概述的许多技术的 GNOME port。请将其用作创建新 ports 的指南。

PORTNAME=	regexxer
DISTVERSION=	0.10
CATEGORIES=	devel textproc gnome
MASTER_SITES=	GNOME

MAINTAINER=	kwm@FreeBSD.org
COMMENT=	Interactive tool for performing search and replace operations
WWW=		http://regexxer.sourceforge.net/

USES=		gettext gmake localbase:ldflags pathfix pkgconfig tar:xz
GNU_CONFIGURE=	yes
USE_GNOME=	gnomeprefix intlhack gtksourceviewmm3

GLIB_SCHEMAS=	org.regexxer.gschema.xml

.include <bsd.port.mk>

6.11.3。变量

本节解释了可用的宏及其如何使用。就像它们在上面的例子中使用的那样。 GNOME 组件有更深入的解释。 必须为这些宏设置 USE_GNOME 才能发挥作用。

GLIB_SCHEMAS 所有 glib 模式文件的列表port 安装。该宏将添加这些文件到{{1002} plist,并处理这些文件在安装和卸载中的注册。

glib 模式文件是用 XML 编写的,并以 gschema.xml 扩展名结尾。它们安装在 share/glib-2.0/schemas/目录中。这些模式文件包含所有应用程序配置值及其默认设置。应用程序实际使用的数据库是由 glib-compile-schema 构建的,该程序由 GLIB_SCHEMAS 宏运行。

GLIB_SCHEMAS=foo.gschema.xml

GCONF_SCHEMAS 列出所有 gconf 模式文件。该宏将向port plist 添加模式文件,并在安装和卸载时处理其注册。

GConf 是基于 XML 的数据库,几乎所有的 GNOME 应用程序都用它来存储它们的设置。这些文件被安装到 etc/gconf/schemas 目录中。这个数据库是由安装的模式文件定义的,这些文件用于生成%gconf.xml 关键文件。对于port安装的每个模式文件,Makefile 中必须有一个条目:

GCONF_SCHEMAS=my_app.schemas my_app2.schemas my_app3.schemas

INSTALLS_OMF 开放源码元数据框架(OMF)文件通常被 GNOME 2 应用程序使用。这些文件包含应用程序帮助文件信息,并需要通过 ScrollKeeper/rarian 进行特殊处理。在从软件包安装 GNOME 应用程序时正确注册 OMF 文件,请确保 omf 文件在 pkg-plist 中列出,并且port的 Makefile 中定义了 INSTALLS_OMF :

INSTALLS_OMF=yes

当设置了 bsd.gnome.mk 后,自动扫描 pkg-plist,并为每个 .omf 添加适当的 @exec 和 @unexec 指令,以便在 OMF 注册数据库中跟踪。

6.12. GNOME 组件

若要进一步了解关于 GNOME port 的帮助,请查看一些现有的 ports 以获取示例。如果需要更多帮助,FreeBSD GNOME 页面上有联系信息。这些组件分为当前正在使用的 GNOME 组件和旧版组件。如果组件支持参数,则在描述中将它们列在括号内。第一个是默认设置。“Both” 是指组件默认添加到构建和运行依赖项中。

GNOME 组件表 8

组件相关程序描述

atk

accessibility/atk

无障碍工具包 (ATK)

atkmm

辅助功能/atkmm

atk 的 C++绑定

cairo

图形/cairo

具有跨设备输出支持的矢量图形库

cairomm

graphics/cairomm

用于 cairo 的 C++绑定

dconf

开发/dconf

配置数据库系统(构建、运行)

evolutiondataserver3

数据库/evolution-data-server

用于 Evolution 集成邮件/PIM 套件的数据后端

gdkpixbuf2

图形/gdk-pixbuf2

用于 GTK+ 的图形库

glib20

开发/glib20

GNOME 核心库 glib20

glibmm

开发/glibmm

为 glib20 提供的 C++ 绑定

gnomecontrolcenter3

sysutils/gnome-control-center

GNOME 3 控制中心

gnomedesktop3

x11/gnome-desktop

GNOME 3 桌面 UI 库

gsound

audio/gsound

用于播放系统声音的 GObject 库(构建和运行)

gtk-update-icon-cache

图形/gtk-update-icon-cache

来自 Gtk+ 工具包的 Gtk-update-icon-cache 实用程序

gtk20

x11-toolkits/gtk20

Gtk+ 2 工具包

gtk30

x11-toolkits/gtk30

Gtk+ 3 工具包

gtkmm20

x11-toolkits/gtkmm20

c++ 为 gtk20 工具包提供的绑定 2.0

gtkmm24

x11-toolkits/gtkmm24

为 gtk20 工具包提供的 c++绑定 2.4

gtkmm30

x11-toolkits/gtkmm30

C++绑定 3.0 用于 gtk30 工具包

gtksourceview2

x11 工具包/gtksourceview2

向 GtkTextView 添加语法高亮显示的小部件

gtksourceview3

GtkTextView 小部件,为 GtkTextView 小部件添加语法高亮

在 GtkTextView 小部件添加语法高亮的文本小部件

gtksourceviewmm3

GtkTextView 小部件,为 GtkTextView 小部件添加语法高亮

C++绑定用于 gtksourceview3 库

gvfs

devel/gvfs

GNOME 虚拟文件系统

intltool

国际化工具(另请参阅 intlhack)

国际化工具(另请参阅 intlhack)

introspection

gobject-introspection 的开发

基本的内省绑定和生成内省绑定工具。大多数情况下:构建足够了,:both/:run 只需要用于使用内省绑定的应用程序。(both, build, run)

libgda5

数据库/libgda5

提供对不同类型数据源的统一访问

libgda5-ui

数据库/libgda5-ui

来自 libgda5 库的 UI 库

libgdamm5

数据库/libgdamm5

用于 libgda5 库的 c++ 绑定

libgsf

devel/libgsf

用于处理结构化文件格式的可扩展 I/O 抽象

librsvg2

图形/ librsvg2

用于解析和渲染 SVG 矢量图形文件的库

libsigc++20

devel/libsigc++20

C++的回调框架

libxml++26

textproc/libxml++26

libxml2 库的 C++绑定

libxml2

XML 解析器库(构建和运行)

XML 解析器库(构建和运行)

libxslt

文本处理/libxslt

XSLT C 库(构建、运行)

metacity

x11-wm/metacity

来自 GNOME 的窗口管理器

nautilus3

文件管理器

GNOME 文件管理器

pango

Pango 工具包

用于布局和呈现 i18n 文本的开源框架

pangomm

x11 工具包/pangomm

pango 库的 c++绑定

py3gobject3

Python 3,GObject 3.0 绑定

Python 3,GObject 3.0 绑定

pygobject3

Python 3,GObject 3.0 绑定

Python 2,GObject 3.0 绑定

vte3

x11-toolkits/vte3

具有改进的辅助功能和 I18N 支持的终端部件

GNOME 宏组件表 9

组件描述

gnomeprefix

为 configure 提供一些默认位置。

intlhack

与 intltool 相同,但补丁确保使用 share/locale/。请仅在 intltool 单独不足时使用。

referencehack

此宏用于帮助将 API 或参考文档拆分为其自己的 port。

桌面 10. GNOME 传统组件

组件相关程序描述

atspi

辅助功能/at-spi

辅助技术服务提供者接口

esound

音频/esound

启蒙音效包

gal2

x11 工具包/gal2

从 GNOME 2 gnumeric 中提取的小部件集合

gconf2

devel/gconf2

用于 GNOME 2 的配置数据库系统

gconfmm26

开发/gconfmm26

用于 gconf2 的 C++绑定

gdkpixbuf

图形/gdk-pixbuf

GTK+的图形库

glib12

devel/glib12

glib 1.2 核心库

gnomedocutils

文本处理/ GNOME 文档实用程序

GNOME 文档实用程序

gnomemimedata

杂项/ GNOME MIME 数据

GNOME 2 的 MIME 和应用程序数据库

gnomesharp20

x11-toolkits/gnome-sharp20

用于.NET 运行时的 GNOME 2 界面

gnomespeech

辅助功能/ GNOME 语音

GNOME 2 文字转语音 API

gnomevfs2

devel/gnome-vfs

GNOME 2 虚拟文件系统

gtk12

x11-toolkits/gtk12

Gtk+ 1.2 工具包

gtkhtml3

轻量级 HTML 渲染/打印/编辑引擎

轻量级 HTML 渲染/打印/编辑引擎

gtkhtml4

www/gtkhtml4

輕巧型 HTML 渲染/打印/編輯引擎

gtksharp20

x11-toolkits/gtk-sharp20

.NET 執行階段的 GTK+ 和 GNOME 2 介面

gtksourceview

包含语法高亮显示的小部件

在 GtkTextView 中添加语法高亮显示的小部件

libartgpl2

图形库 art_lgpl

高性能 2D 图形库

libbonobo

devel/libbonobo

用于 GNOME 2 的组件和复合文档系统

libbonoboui

x11-toolkits/libbonoboui

GNOME 2 的 libbonobo 组件的 GUI 前端

libgda4

databases/libgda4

提供对不同类型数据源的统一访问

libglade2

devel/libglade2

GNOME 2 glade 库

libgnome

x11/libgnome

用于 GNOME 2 的库,一个 GNU 桌面环境

libgnomecanvas

graphics/libgnomecanvas

GNOME 2 图形库

libgnomekbd

x11/libgnomekbd

GNOME 2 键盘共享库

libgnomeprint

打印/libgnomeprint

Gnome 2 打印支持库

libgnomeprintui

x11 工具包/libgnomeprintui

Gnome 2 打印支持库

libgnomeui

x11-toolkits/libgnomeui

用于 GNOME 2 GUI 的库,一个 GNU 桌面环境

libgtkhtml

轻量级 HTML 渲染/打印/编辑引擎

轻量级 HTML 渲染/打印/编辑引擎

libgtksourceviewmm

x11-toolkits/libgtksourceviewmm

GtkSourceView 的 C++绑定

libidl

devel/libIDL

用于创建 CORBA IDL 文件树的库

libsigc++12

C++回调框架

C++回调框架

libwnck

x11-toolkits/libwnck

用于编写分页和任务列表的库

libwnck3

x11 工具包/libwnck3

用于编写分页和任务列表的库

orbit2

高级性能的 CORBA ORB,支持 C 语言

高性能 CORBA ORB,支持 C 语言

pygnome2

x11 工具包/py-gnome2

GNOME 2 的 Python 绑定

pygobject

devel/py-gobject

Python 2,GObject 2.0 绑定

pygtk2

x11-toolkits/py-gtk2

用于 GTK+的 Python 绑定集

pygtksourceview

x11-toolkits/py-gtksourceview

Python 绑定用于 GtkSourceView 2

vte

x11 工具包/vte

具有改进辅助功能和 I18N 支持的终端部件

弃用组件表 11:请勿使用

组件描述

pangox-compat

pangox-compat 已被弃用并从 pango 软件包中拆分出来。

6.13. 使用 Qt

6.13.1. Ports 需要 Qt

The Ports 集合为 Qt 5 和 Qt 6 提供支持,分别使用 USES+=qt:5 和 USES+=qt:6 。将 USE_QT 设置为所需的 Qt 组件列表(库、工具、插件)。

Qt 框架导出了一些变量,ports可以使用其中一些,以下是其中一些列出的变量:

表 12. 提供给Ports使用 Qt 的变量

QMAKE

qmake 二进制文件的完整路径。

LRELEASE

lrelease 工具的完整路径。

MOC

完整路径到 moc 。

RCC

完整路径到 rcc 。

UIC

完整路径到 uic 。

QT_INCDIR

Qt 包含目录。

QT_LIBDIR

Qt 库路径。

QT_PLUGINDIR

Qt 插件路径。

6.13.2. 组件选择

每个 Qt 工具和库依赖项必须在 USE_QT 中指定。每个组件都可以加上 _build 或 _run 后缀,后缀表示对组件的依赖是在构建时还是运行时。如果没有后缀,该组件将在构建时和运行时都有依赖。通常,库组件被指定为无后缀,工具组件大多使用 _build 后缀,插件组件使用 _run 后缀。下面列出了最常用的组件(所有可用组件都列在 _USE_QT_ALL 中,该列表是从 _USE_QT_COMMON 和 _USE_QT[56]_ONLY 生成的,位于/usr/ports/Mk/Uses/qt.mk 中):

表 13. 可用的 Qt 库组件

名称描述

3d

Qt3D 模块

5compat

Qt 6 的 Qt 5 兼容模块

assistant

Qt 5 文档浏览器

base

Qt 6 基础模块

canvas3d

Qt 画布 3D 模块

charts

Qt 5 图表模块

concurrent

Qt 多线程模块

connectivity

Qt 连接性(蓝牙/NFC)模块

core

Qt 核心非图形模块

datavis3d

Qt 5 3D 数据可视化模块

dbus

Qt D-Bus 进程间通信模块

declarative

Qt 声明性框架用于动态用户界面

designer

Qt 5 图形用户界面设计师

diag

用于报告有关 Qt 及其环境的诊断信息的工具

doc

Qt 5 文档

examples

Qt 5 示例源代码

gamepad

Qt 5 游戏手柄模块

graphicaleffects

Qt Quick 图形效果

gui

Qt 图形用户界面模块

help

Qt 在线帮助集成模块

l10n

Qt 本地化消息

languageserver

Qt 6 语言服务器协议实现

linguist

Qt 5 翻译工具

location

Qt 位置模块

lottie

Qt 6 QML API 用于渲染图形和动画

multimedia

Qt 音频、视频、收音机和相机支持模块

network

Qt 网络模块

networkauth

Qt 网络认证模块

opengl

Qt 5 兼容的 OpenGL 支持模块

paths

QStandardPaths 的命令行客户端

phonon4

KDE 多媒体框架

pixeltool

Qt 5 屏幕放大镜

plugininfo

Qt 5 插件元数据转储程序

positioning

从卫星、wifi 或文本文件等来源获取的 Qt 6 定位 API。

printsupport

Qt 打印支持模块

qdbus

Qt 命令行接口到 D-Bus

qdbusviewer

Qt 5 图形界面到 D-Bus

qdoc

Qt 文档生成器

qdoc-data

QDoc 配置文件

qev

Qt QWidget 事件内省工具

qmake

Qt Makefile 生成器

quickcontrols

用于在 Qt Quick 中构建完整界面的控件集

quickcontrols2

用于在 Qt Quick 中构建完整界面的控件集

remoteobjects

Qt 5 SXCML 模块

script

Qt 4 兼容脚本模块

scripttools

Qt 脚本附加组件

scxml

Qt 5 SXCML 模块

sensors

Qt 传感器模块

serialbus

Qt 访问工业总线系统的功能

serialport

用于访问串行ports的 Qt 函数

shadertools

用于跨平台 Qt 着色器流水线的 Qt 6 工具

speech

Qt5 的无障碍功能

sql

Qt SQL 数据库集成模块

sql-ibase

Qt InterBase/Firebird 数据库插件

sql-mysql

Qt MySQL 数据库插件

sql-odbc

Qt 开放数据库连接插件

sql-pgsql

Qt PostgreSQL 数据库插件

sql-sqlite2

Qt SQLite 2 数据库插件

sql-sqlite3

Qt SQLite 3 数据库插件

sql-tds

Qt TDS 数据库连接数据库插件

svg

Qt SVG 支持模块

testlib

Qt 单元测试模块

tools

Qt 6 各种工具

translations

Qt 6 翻译模块

uiplugin

定制 Qt 小部件插件接口用于 Qt Designer

uitools

Qt Designer UI 表单支持模块

virtualkeyboard

Qt 5 虚拟键盘模块

wayland

用于 Wayland 的 Qt 5 封装器

webchannel

用于将 C++/QML 与 HTML/js 客户端集成的 Qt 5 库

webengine

用于渲染网页内容的 Qt 5 库

webkit

具有更现代的 WebKit 代码库的 QtWebKit

websockets

WebSocket 协议的 Qt 实现

websockets-qml

WebSocket 协议的 Qt 实现(QML 绑定)

webview

用于显示网络内容的 Qt 组件

widgets

Qt C++小部件模块

x11extras

面向基于 X11 系统的 Qt 平台特定功能

xml

Qt SAX 和 DOM 实现

xmlpatterns

Qt 对 XPath、XQuery、XSLT 和 XML Schema 的支持

要确定应用程序依赖的库,请在成功编译后的主可执行文件上运行 ldd 。

可用的 Qt 工具组件表 14。

名称描述

buildtools

构建工具 ( moc , rcc ), 几乎每个 Qt 应用程序都需要。

linguisttools

本地化工具: lrelease , lupdate

qmake

Makefile 生成器/构建实用程序

可用的 Qt 插件组件表 15

名称描述

imageformats

用于 TGA、TIFF 和 MNG 图像格式的插件

示例 21. 选择 Qt 5 组件

在这个例子中,移植的应用程序使用了 Qt 5 图形用户界面库、Qt 5 核心库、所有 Qt 5 代码生成工具和 Qt 5 的 Makefile 生成器。由于 gui 库意味着对核心库的依赖,因此不需要指定 core 。Qt 5 代码生成工具 moc 、 uic 和 rcc ,以及 Makefile 生成器 qmake 仅在构建时需要,因此它们带有 _build 后缀指定:

USES=	qt:5
USE_QT=	gui buildtools_build qmake_build

6.13.3. 使用 qmake

如果应用程序提供一个 qmake 项目文件 (*.pro),则应同时定义 USES= qmake 和 USE_QT 。 USES= qmake 已经暗示了对 qmake 的构建依赖,因此可以省略 qmake 组件。类似于 CMake,qmake 支持在源码目录之外进行构建,可以通过指定 outsource 参数来启用 (请参见 USES= qmake 示例)。还请参阅 USES= qmake 的可能参数。

表 16. USES= qmake 的可能参数

变量描述

no_configure

不要添加配置目标。这是由 HAS_CONFIGURE=yes 和 GNU_CONFIGURE=yes 隐含的。当构建仅需要来自 USES= qmake 的环境设置时,它是必需的,否则会独立运行 qmake 。

no_env

抑制对配置和构建环境的修改。仅在使用 qmake 配置软件且构建无法理解 USES= qmake 设置的环境时才需要。

norecursive

不要将 -recursive 参数传递给 qmake 。

outsource

执行一个外部源码构建。

表格 17. Ports 使用的变量

变量描述

QMAKE_ARGS

要传递给 qmake 二进制文件的 Port 特定的 qmake 标志。

QMAKE_ENV

要为 qmake 二进制文件设置的环境变量。默认值为 ${CONFIGURE_ENV} 。

QMAKE_SOURCE_PATH

qmake 项目文件 (.pro) 的路径。如果请求了外部构建,则默认为 ${WRKSRC} ,否则为空。

在使用 USES= qmake 时,这些设置会被部署:

CONFIGURE_ARGS+=	--with-qt-includes=${QT_INCDIR} \
			--with-qt-libraries=${QT_LIBDIR} \
			--with-extra-libs=${LOCALBASE}/lib \
			--with-extra-includes=${LOCALBASE}/include

CONFIGURE_ENV+=	QTDIR="${QT_PREFIX}" QMAKE="${QMAKE}" \
		MOC="${MOC}" RCC="${RCC}" UIC="${UIC}" \
		QMAKESPEC="${QMAKESPEC}"

PLIST_SUB+=	QT_INCDIR=${QT_INCDIR_REL} \
		QT_LIBDIR=${QT_LIBDIR_REL} \
		QT_PLUGINDIR=${QT_PLUGINDIR_REL}

一些配置脚本不支持上述参数。要抑制 CONFIGURE_ENV 和 CONFIGURE_ARGS 的修改,设置 USES= qmake:no_env 。

示例 22. USES= qmake 示例

这段代码演示了如何在 Qt 5 中使用 qmake port:

USES=	qmake:outsource qt:5
USE_QT=	buildtools_build

Qt 应用程序通常是跨平台编写的,通常不是在 X11/Unix 平台上开发,这导致某些问题,比如:

  • 缺少额外的包含路径。许多应用程序支持系统托盘图标,但忽略在 X11 目录中查找包含和/或库。要通过命令行将目录添加到qmake的包含和库搜索路径中,请使用:

    QMAKE_ARGS+=	INCLUDEPATH+=${LOCALBASE}/include \
    		LIBS+=-L${LOCALBASE}/lib
  • 虚假的安装路径。有时,诸如图标或 .desktop 文件之类的数据默认安装到 XDG 兼容应用程序未扫描的目录中。editors/texmaker 就是一个例子 - 查看 port 的文件目录中的 patch-texmaker.pro 模板,了解如何在 qmake 项目文件中直接解决此问题。

6.14. 使用 KDE

6.14.1. KDE 变量定义

如果应用程序依赖于 KDE,请将 USES+=kde:5 和 USE_KDE 设置为所需组件列表。可以使用 _build 和 _run 后缀来强制组件依赖类型(例如, baseapps_run )。如果未设置后缀,则将使用默认的依赖类型。要强制使用两种类型,请将组件两次添加,每次都使用后缀(例如, ecm_build ecm_run )。可用组件列在下面(最新组件也列在/usr/ports/Mk/Uses/kde.mk 中):

表 18. 可用的 KDE 组件

名称描述

activities

用于在单独的活动中组织工作的 KF5 运行时和库

activities-stats

用于活动的 KF5 统计

activitymanagerd

系统服务,用于管理用户活动,跟踪使用模式

akonadi

用于 KDE-Pim 的存储服务器

akonadicalendar

Akonadi 日历集成

akonadiconsole

Akonadi 管理和调试控制台

akonadicontacts

用于在 Akonadi 中实现联系人管理的库和守护程序

akonadiimportwizard

从其他邮件客户端导入数据到 KMail

akonadimime

实现基本电子邮件处理的库和守护程序

akonadinotes

用于访问 MBox 格式邮件存储的 KDE 库

akonadisearch

在 Akonadi 中实现搜索的库和守护程序

akregator

由 KDE 提供的订阅阅读器

alarmcalendar

用于 KAlarm 闹钟的 KDE API

apidox

KF5 API 文档工具

archive

处理存档格式的类的 KF5 库

attica

开放协作服务 API 库 KDE5 版本

attica5

开放协作服务 API 库 KDE5 版本

auth

KF5 抽象到系统策略和认证功能

baloo

KF5 框架用于搜索和管理用户元数据

baloo-widgets

BalooWidgets 库

baloo5

用于搜索和管理用户元数据的 KF5 框架

blog

用于网络日志访问的 KDE API

bookmarks

用于书签和 XBEL 格式的 KF5 库

breeze

Breeze 可视样式的 Plasma5 艺术品、风格和素材

breeze-gtk

Gtk 的 Plasma5 Breeze 可视样式

breeze-icons

用于 KDE 的 Breeze 图标主题

calendarcore

KDE 日历访问库

calendarsupport

用于 KDEPim 的日历支持库

calendarutils

用于访问日历的 KDE 实用程序和用户界面函数

codecs

用于字符串操作的 KF5 库

completion

KF5 文本完成助手和小部件

config

用于配置对话框的 KF5 小部件

configwidgets

配置对话框的 KF5 小部件

contacts

管理联系信息的 KDE API

coreaddons

用于 QtCore 的 KF5 附加组件

crash

KF5 库用于处理应用程序崩溃分析和错误报告

dbusaddons

KF5 附加组件到 QtDBus

decoration

Plasma5 库用于创建窗口装饰

designerplugin

在 Qt Designer/Creator 中集成 Frameworks 小部件的 KF5

discover

Plasma5 软件包管理工具

dnssd

KF5 对系统 DNSSD 功能的抽象

doctools

从 docbook 生成 KF5 文档

drkonqi

Plasma5 崩溃处理程序

ecm

用于 CMake 的额外模块和脚本

emoticons

用于转换表情符号的 KF5 库

eventviews

用于 KDEPim 的事件视图库

filemetadata

用于提取文件元数据的 KF5 库

frameworkintegration

KF5 工作区和跨框架集成插件

gapi

基于 KDE 的库,用于访问谷歌服务

globalaccel

KF5 库,用于增加全局工作区快捷键支持

grantlee-editor

Grantlee 主题编辑器

grantleetheme

KDE PIM grantleetheme

gravatar

为 gravatar 支持提供库

guiaddons

QtGui 的 KF5 插件

holidays

日历节假日的 KDE 库

hotkeys

热键的 Plasma5 库

i18n

KF5 高级国际化框架

iconthemes

用于处理应用程序中图标的 KF5 库

identitymanagement

KDE pim 身份

idletime

用于监控用户活动的 KF5 库

imap

用于 IMAP 支持的 KDE API

incidenceeditor

用于 KDEPim 的事件编辑库

infocenter

提供系统信息的 Plasma5 实用程序

init

用于加速启动 KDE 应用程序的 KF5 进程启动器

itemmodels

用于 Qt Model/View 系统的 KF5 模型

itemviews

为 Qt Model/View 提供的 KF5 小部件附加组件

jobwidgets

用于跟踪 KJob 实例的 KF5 小部件

js

提供 ECMAScript 解释器的 KF5 库

jsembed

用于将 JavaScript 对象绑定到 QObjects 的 KF5 库

kaddressbook

KDE 联系人管理器

kalarm

个人闹钟调度程序

kalarm

个人报警计划程序

kate

KDE 系统的基础编辑器框架

kcmutils

用于处理 KCModules 的 KF5 工具

kde-cli-tools

Plasma5 非交互式系统工具

kde-gtk-config

Plasma5 GTK2 和 GTK3 配置器

kdeclarative

KF5 库,提供 QML 和 KDE 框架集成

kded

为提供系统级服务的 KF5 可扩展守护程序

kdelibs4support

从 KDELibs4 移植辅助工具的 KF5 版本

kdepim-addons

KDE PIM 插件

kdepim-apps-libs

KDE PIM 邮件相关库

kdepim-runtime5

KDE PIM 工具和服务

kdeplasma-addons

用于改善 Plasma 体验的 Plasma5 附加组件

kdesu

KF5 与 su 进行提升权限集成

kdewebkit

KF5 库提供 QtWebKit 集成

kgamma5

Plasma5 监视器的伽马设置

khtml

KF5 的 KTHML 渲染引擎

kimageformats

KF5 库提供支持额外图像格式

kio

KF5 的资源和网络访问抽象化

kirigami2

基于 QtQuick 的组件集

kitinerary

用于旅行预订信息的数据模型和提取系统

kmail

KDE 邮件客户端

kmail

KDE 邮件客户端

kmail-account-wizard

KDE 邮件帐户向导

kmenuedit

Plasma5 菜单编辑器

knotes

弹出式注释

kontact

KDE 个人信息管理器

kontact

KDE 个人信息管理器

kontactinterface

嵌入到 Kontact 中的 KParts 的 KDE 粘合剂

korganizer

日历和日程安排程序

kpimdav

带有 KJobs 的 DAV 协议实现

kpkpass

处理苹果钱包通行文件的库

kross

KF5 多语言应用程序脚本

kscreen

Plasma5 屏幕管理库

kscreenlocker

Plasma5 安全锁屏架构

ksmtp

通过 SMTP 服务器发送电子邮件的基于工作的库

ksshaskpass

Plasma5 ssh-add 前端

ksysguard

用于跟踪和控制运行中进程的 Plasma5 实用程序

kwallet-pam

Plasma5 KWallet PAM 集成

kwayland-integration

用于基于 Wayland 的桌面的集成插件

kwin

Plasma5 窗口管理器

kwrited

Plasma5 守护程序监听墙和写消息

ldap

用于 KDE 的 LDAP 访问 API

libkcddb

KDE CDDB 库

libkcompactdisc

用于与音频 CD 交互的 KDE 库

libkdcraw

用于 KDE 的 LibRaw 接口

libkdegames

由 KDE 游戏使用的库

libkdepim

KDE PIM 库

libkeduvocdocument

用于读写词汇文件的库

libkexiv2

用于 KDE 的 Exiv2 库接口

libkipi

KDE 镜像插件接口

libkleo

用于 KDE 的证书管理器

libksane

KDE 的 SANE 库接口

libkscreen

Plasma5 屏幕管理库

libksieve

KDEPim 的 Sieve 库

libksysguard

用于跟踪和控制运行进程的 Plasma5 库

mailcommon

用于 KDEPim 的常用库

mailimporter

将 mbox 文件导入 KMail

mailtransport

管理邮件传输的 KDE 库

marble

用于 KDE 的虚拟地球和世界地图

mbox

用于访问 MBox 格式邮件存储的 KDE 库

mbox-importer

将 mbox 文件导入 KMail

mediaplayer

用于媒体播放器功能的 KF5 插件接口

messagelib

处理消息的库

milou

搜索的 Plasma5 小部件

mime

处理 MIME 数据的库

newstuff

用于从网络下载应用程序资产的 KF5 库

notifications

用于系统通知的 KF5 抽象

notifyconfig

用于 KNotify 的 KF5 配置系统

okular

KDE 通用文档查看器

oxygen

气浪 5 氧气风格

oxygen-icons5

用于 KDE 的氧气图标主题

package

KF5 库加载和安装软件包

parts

KF5 文档中心插件系统

people

KF5 库提供访问联系人的功能

pim-data-exporter

导入和导出 KDE PIM 设置

pimcommon

用于 KDEPim 的常见库

pimtextedit

用于 PIM 特定文本编辑实用程序的 KDE 库

plasma-browser-integration

将浏览器集成到桌面中的 Plasma5 组件

plasma-desktop

Plasma5 桌面

plasma-framework

KF5 基于插件的 UI 运行时用于编写用户界面

plasma-integration

用于 Plasma 工作空间的 Qt 平台主题集成插件

plasma-pa

Plasma5 Plasma 脉冲音频混音器

plasma-sdk

Plasma5 应用程序,有助于 Plasma 开发

plasma-workspace

Plasma5 Plasma 工作空间

plasma-workspace-wallpapers

Plasma5 壁纸

plotting

KF5 轻量级绘图框架

polkit-kde-agent-1

Plasma5 守护程序,提供 polkit 认证界面

powerdevil

管理电力消耗设置的 Plasma5 工具

prison

生成条形码的 API

pty

KF5 Pty 抽象

purpose

为特定目的提供可用操作

qqc2-desktop-style

用于 KDE 的 Qt QuickControl2 样式

runner

KF5 并行查询系统

service

KF5 高级插件和服务内省

solid

KF5 硬件集成和检测

sonnet

KF5 基于插件的拼写检查库

syndication

KDE RSS feed 处理库

syntaxhighlighting

用于结构化文本和代码的 KF5 语法高亮引擎

systemsettings

Plasma5 系统设置

texteditor

KF5 高级可嵌入文本编辑器

textwidgets

KF5 高级文本编辑窗口小部件

threadweaver

KF5 对 QtDBus 的附加组件

tnef

处理 TNEF 数据的 KDE API

unitconversion

用于单位转换的 KF5 库

user-manager

Plasma5 用户管理器

wallet

为用户密码提供 KF5 安全且统一的容器

wayland

用于 Wayland 库的 KF5 客户端和服务器库包装器

widgetsaddons

KF5 附加组件到 QtWidgets

windowsystem

访问窗口系统的 KF5 库

xmlgui

KF5 用户可配置的主窗口

xmlrpcclient

与 XMLRPC 服务交互的 KF5

示例 23. USE_KDE 示例

这是一个简单的示例,用于 KDE port。 USES= cmake 指导 port 使用 CMake,这是 KDE 项目广泛使用的配置工具(有关详细使用说明,请参阅《使用 cmake 》)。 USE_KDE 需要依赖 KDE 库。 通过配置日志可以确定所需的 KDE 组件和其他依赖项。 USE_KDE 不意味着 USE_QT 。 如果一个 port 需要一些 Qt 组件,请在 USE_QT 中指定它们。

USES=		cmake kde:5 qt:5
USE_KDE=	ecm
USE_QT=		core buildtools_build qmake_build