每个配方由 3 个主要部分组成:定义标识符、设置构建变量和定义构建命令。
包 "mylib" 将在此处用作示例
通用提示:
- 为了使配方更相似,mylib_foo 被写成 $(package)_foo。
- 相对于 bitcoin 二进制文件/库的二级依赖包(即,那些不在 contrib/guix/symbol-check.py
中的 ALLOWED_LIBRARIES
中的包)不需要共享,应尽可能静态构建。有关更多详细信息,请参见。
标识符
如果包未定义 $(package)_local_dir
变量,则需要定义以下变量:
```
$(package)_version:
上游库或程序的版本。如果没有版本,可以使用占位符,例如 1.0。
$(package)_download_path:
上游源的位置,不带文件名。通常是 http、https 或 ftp。如果可用,应首选像 https 这样的安全传输选项。
$(package)_file_name:
上游源文件名,可在下载路径中找到。
$(package)_sha256_hash:
上游文件的 sha256 哈希值如果包定义了 `$(package)_local_dir` 变量,则不需要上述变量,并且会被忽略。 这些变量是可选的:
$(package)_build_subdir:
在运行 configure/build/stage 命令之前,cd 到此目录。
$(package)_download_file:
上游源的文件名,如果它与本地应存储的文件名不同。这可以用来避免存储带有奇怪字符的文件名。
$(package)_dependencies:
此包依赖的任何其他包的名称。
$(package)_patches:
构建包所需的任何补丁的文件名
$(package)_extra_sources:
将通过 $(package)_fetch_cmds 获取的任何额外文件。指定这些文件是为了可以通过 "make download" 获取和验证它们。
```
本地包
如果一个包定义了一个 $(package)_local_dir
变量,指定的目录将被视为下载源,并且其内容的 tarball 将被保存到 sources/
。tarball 的哈希值也将成为包构建 ID 的一部分,因此如果目录内容发生更改,包和依赖它的所有内容将被重建。为了提高效率,tarball 在创建后会被缓存,但是如果本地目录被触及,它将被重建。
本地包可用于使用 git 子模块或子树来管理包源,或用于测试无法从外部源下载的本地更改。
构建变量:
在定义了主要标识符之后,可以在运行构建命令之前添加或自定义构建变量。应将它们添加到名为 $(package)_set_vars 的函数中。例如:define $(package)_set_vars ... endef
大多数变量都可以使用 host、architecture 或两者作为前缀,以使修改特定于该情况。例如:通用: $(package)_cc=gcc 仅 Linux: $(package)_linux_cc=gcc 仅 x86_64: $(package)_x86_64_cc = gcc 仅 x86_64 linux: $(package)_x86_64_linux_cc = gcc
可以设置这些变量以覆盖或附加其默认值。$(package)_cc $(package)_cxx $(package)_objc $(package)_objcxx $(package)_ar $(package)_ranlib $(package)_nm $(package)_cflags $(package)_cxxflags $(package)_ldflags $(package)_cppflags $(package)_config_env $(package)_build_env $(package)_stage_env $(package)_build_opts $(package)_config_opts
构建命令:
对于每个构建,都会创建一个唯一的构建目录和暂存目录。例如,work/build/mylib/1.0-1adac830f6e
和 work/staging/mylib/1.0-1adac830f6e
。
以下构建命令可用于每个配方:
```
$(package)_fetch_cmds:
运行位置:构建目录
获取源文件。如果未定义,它将被获取并根据其哈希值进行验证。
$(package)_extract_cmds:
运行位置:构建目录
根据其哈希值验证源文件并提取它。如果未定义,则假定源文件是一个 tarball。
$(package)_preprocess_cmds:
运行位置:构建目录/$(package)_build_subdir
根据需要预处理源文件。如果未定义,则不执行任何操作。
$(package)_config_cmds:
运行位置:构建目录/$(package)_build_subdir
配置源文件。如果未定义,则不执行任何操作。
$(package)_build_cmds:
运行位置:构建目录/$(package)_build_subdir
构建源文件。如果未定义,则不执行任何操作。
$(package)_stage_cmds:
运行位置:构建目录/$(package)_build_subdir
暂存构建结果。如果未定义,则不执行任何操作。以下变量可用于每个配方:
$(1)_staging_dir: 包的目标 sysroot 路径
$(1)_staging_prefix_dir: 包的暂存目录内的前缀路径
$(1)_extract_dir: 包的提取源的路径
$(1)_build_dir: 将运行 configure/build/stage 命令的路径
$(1)_patch_dir: 找到包的补丁(如果有)的路径构建命令的注意事项: 对于使用 autotools 构建的包,可以在 configure 步骤中使用 $($(package)_autoconf) 来(通常)正确地自动配置。任何 $($(package)_config_opts) 将被追加。 大多数 autotools 项目可以使用以下命令正确暂存:
$(MAKE) DESTDIR=$($(package)_staging_dir) install
```
构建输出:
通常,依赖包的输出不应包含任何 libtool 存档或 .pc
(pkg-config
) 文件。相反,包应尽可能输出 .cmake
(CMake) 文件。
来自 :
Libtool 将所有直接和间接依赖项拉入它创建的 .la 文件中。这导致了大规模的过度链接,这对 Gentoo 生态系统是有害的,因为它导致了大量不必要的重建。
在可能的情况下,使用位置无关代码构建包。要么使用 Autotools --with-pic
标志,要么使用 CMake 的 CMAKE_POSITION_INDEPENDENT_CODE
。
二级依赖项:
相对于 bitcoin 二进制文件/库的二级依赖包(即,那些不在 contrib/guix/symbol-check.py
中的 ALLOWED_LIBRARIES
中的包)不需要共享,应尽可能静态构建。这提高了总体构建可靠性,如以下示例所示:
当针对具有自身共享依赖项 libsecondary
的共享库 libprimary
链接可执行文件时,我们可能需要在链接命令上使用 -rpath/-rpath-link
选项指定 libsecondary
的路径,仅说 libprimary
是不够的。
对于我们来说,将静态 libsecondary
链接到共享 libprimary
中要容易得多。特别是,在我们的例子中,我们无论如何都要链接到一个虚拟的 libprimary
,我们会将其丢弃。我们不在乎最终用户是否拥有静态或动态的 libsecondary
,这不是我们关心的问题。使用静态 libsecondary
,当我们/需要/将 libprimary
链接到我们的可执行文件中时,无需担心依赖链,因为 libprimary
具有所有/符号。
构建目标:
要构建单个包(对于调试很有用),可以使用以下构建目标。
make ${package} make ${package}_fetched make ${package}_extracted make ${package}_preprocessed make ${package}_configured make ${package}_built make ${package}_staged make ${package}_postprocessed make ${package}_cached make ${package}_cached_checksum