
Spack SConsPackage 构建系统完全指南从scons --help到编译器包装器的实战解析【免费下载链接】spackA flexible package manager that supports multiple versions, configurations, platforms, and compilers.项目地址: https://gitcode.com/GitHub_Trending/sp/spackSCons 是 Spack 支持的一种通用构建系统它不依赖 Makefile而是使用 Python 编写构建脚本并自行完成编译与链接。本文以 Spack 官方文档 sconspackage.rst 为主线系统讲解 SCons 构建脚本的非统一性、SConsBuilder/SConsPackage的构建与安装阶段、build_test测试覆盖、依赖声明、scons --help选项探测、build_args传参以及最易踩坑的编译器包装器兼容性问题。读完本文你将掌握如何在 Spack 包中正确封装任意 SCons 项目并能在遇到 Spack compiler must be run from Spack! 这类报错时快速定位根因。SCons 构建系统在 Spack 中的定位SCons 是一种通用构建系统不依赖 Makefile来构建软件。它本身用 Python 编写所有构建与链接工作都由 SCons 自己完成sconspackage.rst。就构建系统而言SCons 的风格非常不统一non-uniform它只给开发者提供一套通用的框架来编写构建脚本但不同项目写出的构建脚本可能差异极大。例如有些开发者会添加子命令subcommands如clean、build、test、install$ scons clean $ scons build $ scons test $ scons install有些开发者则完全不添加任何子命令有些项目支持通过命令行变量variables传入配置选项有些项目则不支持。这种高度自由的构建脚本风格意味着 Spack 无法用一套固定模式去适配所有 SCons 项目这也是后面需要手动探测选项、覆盖build_args的根本原因。PhasesSConsBuilder 与 SConsPackage 提供的构建阶段虽然 SCons 允许开发者自定义build、install等子命令但默认情况下SCons 项目的安装流程通常是$ scons $ scons install为了适配这一通用流程SConsBuilder与SConsPackage两个基类提供了以下两个阶段phasesbuild—— 构建软件包install—— 安装软件包在 Spack 中SConsPackage对应spack_repo.builtin.build_systems.scons模块。这一点可以从源码迁移映射表中得到印证repo_migrate.pySConsPackage: spack_repo.builtin.build_systems.scons,而当你使用spack create创建基于 SCons 的包时create命令会通过SconsPackageTemplate生成以SConsPackage为基类、默认覆盖build_args的包骨架create.pyclass SconsPackageTemplate(PackageTemplate): Provides appropriate overrides for SCons-based packages base_class_name SConsPackage package_class_import from spack_repo.builtin.build_systems.scons import SConsPackage body_def \ def build_args(self, spec, prefix): # FIXME: Add arguments to pass to build. # FIXME: If not needed delete this function args [] return args这也印证了build_args是 SCons 包中最常需要定制的入口点。测试阶段覆盖 build_test 方法很多包开发者会添加可通过scons test或scons check调用的单元测试。Spack 为此提供了build_test方法来处理测试。由于我们无法预知包开发者究竟选择了test还是check因此build_test方法默认什么都不做但可以很容易地覆盖它例如def build_test(self): scons(check)关于这一点Spack 的打包测试指南中也明确把SConsPackage列为支持测试的构建系统packaging_guide_testing.rst说明 SCons 包可以通过覆盖测试方法来接入 Spack 的spack test体系。识别 SCons 包SConstruct 文件与 EnsureSConsVersionSCons 包可以通过它们的SConstruct文件来识别。这些文件负责从子命令设置、命令行选项到链接与编译的全部工作。其中值得特别留意的是EnsureSConsVersion函数EnsureSConsVersion(2, 3, 0)这表示SCons 2.3.0 是最早可用的版本。你应当在包中用depends_on语句声明这一版本约束详见下一节。构建系统依赖scons 的 depends_on 声明使用 SCons 构建系统的包至少需要一个scons依赖。由于这一点恒定成立SConsPackage基类已经内置了depends_on(scons, typebuild)如果你需要指定特定的版本要求可以在自己的包中覆盖该声明例如depends_on(scons2.3.0:, typebuild)这与前面EnsureSConsVersion(2, 3, 0)的要求一一对应当SConstruct中声明了最低 SCons 版本时务必在depends_on中同步声明否则可能使用过旧版本的 SCons 导致构建失败。探测可用选项scons --help 的正确用法寻找构建包时第一步是运行scons --help查看有效选项列表。有些包例如 kahip没有覆盖 SCons 默认的帮助信息因此scons --help的参考价值不大但另一些包例如 serf会打印一组有效的命令行变量输出类似$ scons --help scons: Reading SConscript files ... Checking for GNU-compatible C compiler...yes scons: done reading SConscript files. PREFIX: Directory to install under ( /path/to/PREFIX ) default: /usr/local actual: /usr/local LIBDIR: Directory to install architecture dependent libraries under ( /path/to/LIBDIR ) default: $PREFIX/lib actual: /usr/local/lib APR: Path to apr-1-config, or to APRs install area ( /path/to/APR ) default: /usr actual: /usr APU: Path to apu-1-config, or to APRs install area ( /path/to/APU ) default: /usr actual: /usr OPENSSL: Path to OpenSSLs install area ( /path/to/OPENSSL ) default: /usr actual: /usr ZLIB: Path to zlibs install area ( /path/to/ZLIB ) default: /usr actual: /usr GSSAPI: Path to GSSAPIs install area ( /path/to/GSSAPI ) default: None actual: None DEBUG: Enable debugging info and strict compile warnings (yes|no) default: False actual: False APR_STATIC: Enable using a static compiled APR (yes|no) default: False actual: False CC: Command name or path of the C compiler default: None actual: gcc CFLAGS: Extra flags for the C compiler (space-separated) default: None actual: LIBS: Extra libraries passed to the linker, e.g. -llibrary1 -llibrary2 (space separated) default: None actual: None LINKFLAGS: Extra flags for the linker (space-separated) default: None actual: CPPFLAGS: Extra flags for the C preprocessor (space separated) default: None actual: None Use scons -H for help about command-line options.从这个例子可以看出 SCons 命令行变量的通用形态每个变量都带有描述、默认值default和当前实际值actual。像PREFIX、ZLIB、OPENSSL这类指向安装路径或依赖位置的变量正是 Spack 打包时需要重点注入的。更高级的包例如 cantera则用scons --help打印一组子命令列表$ scons --help scons: Reading SConscript files ... SCons build script for Cantera Basic usage: scons help - print a description of user-specifiable options. scons build - Compile Cantera and the language interfaces using default options. scons clean - Delete files created while building Cantera. [sudo] scons install - Install Cantera. [sudo] scons uninstall - Uninstall Cantera. scons test - Run all tests which did not previously pass or for which the results may have changed. scons test-reset - Reset the passing status of all tests. scons test-clean - Delete files created while running the tests. scons test-help - List available tests. scons test-NAME - Run the test named NAME. scons command dump - Dump the state of the SCons environment to the screen instead of doing command, e.g. scons build dump. For debugging purposes. scons samples - Compile the C and Fortran samples. scons msi - Build a Windows installer (.msi) for Cantera. scons sphinx - Build the Sphinx documentation scons doxygen - Build the Doxygen documentation注意 cantera 额外提供了scons help子命令。运行scons help会打印有效的命令行变量列表与scons --help配合使用可以更完整地掌握一个项目的可配置面。向 SCons 传递参数覆盖 build_args 与 install_args在确定项目接受的参数后就可以把它们加入包的构建阶段。方法是通过覆盖build_argsdef build_args(self, spec, prefix): args [ fPREFIX{prefix}, fZLIB{spec[zlib].prefix}, ] if spec.satisfies(debug): args.append(DEBUGyes) else: args.append(DEBUGno) return args这个示例展示了两个关键技巧注入安装前缀通过PREFIX{prefix}把 Spack 计算出的安装前缀传给 SCons避免软件默认安装到/usr/local传递依赖路径通过ZLIB{spec[zlib].prefix}把依赖包的安装路径作为命令行变量传入这相当于 SCons 世界里告知依赖位置的标准做法根据变体variant条件传参spec.satisfies(debug)判断用户是否启用了debug变体进而追加DEBUGyes或DEBUGno实现变体到 SCons 变量的映射。此外SConsPackage还提供了install_args函数你可以覆盖它来向scons install传递额外的参数。从源码结构看create.pyspack create生成的 SCons 包模板默认就覆盖了build_args并返回空列表说明这是包作者最常打交道的扩展点对应地Spack 的create测试也会断言生成的包包含TestScons(SConsPackage)与def build_args(self两个特征create.py 测试。编译器包装器SCons 包最易踩的坑默认情况下SCons在独立的执行环境中构建所有包不会传递用户环境中的任何环境变量。即使是PATH的改动也不会传播除非包开发者显式处理。这一点对 Spack 的**编译器包装器compiler wrappers**尤其麻烦——因为编译器包装器正是依赖环境变量来管理依赖和链接标志的。在很多情况下SCons 包与 Spack 的编译器包装器不兼容链接必须手动完成。处理步骤可以概括为三条优先查找环境变量相关的选项。先检查scons --help/scons help的选项列表里有没有与环境变量传播相关的项。例如 cantera 就提供了这样的选项* env_vars: [ string ] Environment variables to propagate through to SCons. Either the string all or a comma separated list of variable names, e.g. LD_LIBRARY_PATH,HOME. - default: LD_LIBRARY_PATH,PYTHONPATH在 cantera 的例子中使用env_varsall就可以让 Spack 的编译器包装器正常工作。尝试直接传编译器包装器。如果项目没有提供环境变量相关选项可以尝试把spack_cc、spack_cxx、spack_fc分别通过CC、CXX、FC参数传给构建CCspack_cc CXXspack_cxx FCspack_fc scons ...识别失败信号并回退到真实编译器。如果在构建时看到如下报错Spack compiler must be run from Spack! Input SPACK_PREFIX is missing.就说明该包不兼容Spack 的编译器包装器。此时只能改用真实编译器的路径它们存放在self.compiler.cc及其相关属性中。注意回退到真实编译器时可能还需要额外传入若干标志来定位依赖而这通常是由编译器包装器自动完成的。serf 就是存在这种限制的包的例子。总结与最佳实践清单围绕 Spack 中封装 SCons 项目可以沉淀出如下可操作的检查清单识别构建系统查找包根目录的SConstruct文件确认其为 SCons 项目检查版本要求看SConstruct中是否有EnsureSConsVersion并同步到depends_on(sconsX.Y.Z:, typebuild)探测选项运行scons --help必要时运行scons help确认项目支持的命令行变量与子命令定制构建覆盖build_args必要时覆盖install_args注入PREFIX、依赖路径与变体映射参数接入测试覆盖build_test调用scons test或scons check处理编译器优先寻找env_vars类选项否则尝试直接传spack_cc/spack_cxx/spack_fc若出现 Spack compiler must be run from Spack! 报错则改用self.compiler.cc等真实编译器并手动补齐依赖定位参数。SCons 构建脚本的高度自由性决定了它没有一刀切的适配方案但借助SConsPackage基类提供的build/install阶段、可覆盖的build_args/install_args/build_test钩子以及scons --help的探测手段任何 SCons 项目都能被可靠地封装进 Spack 的依赖管理与构建流程中。【免费下载链接】spackA flexible package manager that supports multiple versions, configurations, platforms, and compilers.项目地址: https://gitcode.com/GitHub_Trending/sp/spack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考