当前位置: 首页 > news >正文

RPM Spec 文件中的 %bcond_with和 %bcond_without条件宏

RPM Spec 文件中的 %bcond_with%bcond_without这两个非常有用的条件宏。

核心概念:什么是 bcond?

bcond是 "build condition" 的缩写,即“构建条件”。它允许软件包维护者在构建(build)RPM 包时,通过命令行参数来启用或禁用某些功能、依赖项或代码路径。这极大地增强了 Spec 文件的灵活性和可配置性。

%bcond_with%bcond_without是定义这些构建条件的两种主要方式,它们互为镜像。


1. %bcond_with

这个宏用于定义一个默认关闭的选项。用户需要显式地使用 --with <option>来开启它。

语法和工作原理

在 Spec 文件中,你这样定义:

%bcond_with option_name
  • 默认状态option_name未定义的(%{with_option_name}会展开为空)。
  • 检查方式:在 Spec 中,使用 %{with option_name}来判断该选项是否被启用。如果启用了,这个宏会展开为 1,否则为空。
  • 启用方法:在构建时,使用 --with option_name参数。 rpmbuild -ba --with option_name mypackage.spec # 或者在 mock, koji 等工具中设置

典型使用场景

当你要添加的是一个非必需、可能带来额外依赖或仅部分用户需要的功能时,使用 %bcond_with。例如,一个程序有图形界面和纯文本模式,而图形界面需要安装 X11 库。

示例:构建一个带 GUI 功能的包

# 1. 定义条件:默认不构建 GUI
%bcond_with guiName:           myapp
Version:        1.0
Release:        1%{?dist}
Summary:        A useful application# 2. 根据条件处理依赖
# 如果启用了 GUI,则添加图形相关的依赖
%if %{with gui}
BuildRequires:  libX11-devel, libXtst-devel
Requires:       libX11, libXtst
%endif%description
A useful application with optional GUI.%prep
%autosetup%build
# 3. 将条件传递给 configure 脚本
%configure %{?_with_gui:--enable-gui} # 注意:这里传递的是 _with_gui
# 或者更常见的写法是直接让 configure 自己检测,但有时需要强制
./configure --prefix=%{_prefix} %{!?_without_gui:--enable-gui} # 另一种写法,与 bcond_without 配合%install
%make_install%files
%{_bindir}/myapp
%{_mandir}/man1/myapp.1.gz
# 4. 根据条件安装文件
%if %{with gui}
%{_datadir}/applications/myapp.desktop
%{_datadir}/icons/hicolor/...
%endif

构建命令:

  • 构建无 GUI 版本(默认)rpmbuild -ba myapp.spec
  • 构建有 GUI 版本rpmbuild -ba --with gui myapp.spec

2. %bcond_without

这个宏用于定义一个默认开启的选项。用户需要显式地使用 --without <option>来关闭它。

语法和工作原理

在 Spec 文件中,你这样定义:

%bcond_without option_name
  • 默认状态option_name已定义的(%{with_option_name}会展开为 1)。
  • 检查方式:同样使用 %{with option_name}来判断。如果没有--without关闭,则展开为 1;如果使用了 --without,则展开为空。
  • 禁用方法:在构建时,使用 --without option_name参数。 rpmbuild -ba --without option_name mypackage.spec

典型使用场景

当你要添加的是一个核心、常用、但少数用户可能想排除的功能时,使用 %bcond_without。最常见的例子是 Python 模块文档。大多数用户需要 Python 绑定,但有些最小化安装的环境可能不需要。

示例:构建一个可选的 Python 模块

# 1. 定义条件:默认构建 Python 模块
%bcond_without pythonName:           mylib
Version:        1.0
Release:        1%{?dist}
Summary:        A core library# 2. 根据条件处理依赖
# 如果 *不* 禁用 Python (即默认或 --with python),则添加 Python 依赖
%if %{with python}
BuildRequires:  python3-devel
%py3_build
%endif%description
A core library with an optional Python module.%package -n python3-mylib
Summary:        Python bindings for %{name}
Requires:       %{name} = %{version}-%{release}
%description -n python3-mylib
This package provides the Python bindings for %{name}.%prep
%autosetup%build
%configure
%make_build
# 3. 根据条件构建 Python 模块
%if %{with python}
%py3_build
%endif%install
%make_install
# 4. 根据条件安装和创建子包
%if %{with python}
%py3_install
%files -n python3-mylib
%license LICENSE
%{python3_sitelib}/mylib/
%{python3_sitelib}/mylib-*.egg-info/
%endif%files
%{_libdir}/libmylib.so*
%{_includedir}/mylib.h

构建命令:

  • 构建包含 Python 模块的版本(默认)rpmbuild -ba mylib.spec
  • 构建不包含 Python 模块的版本(例如,为了最小化依赖): rpmbuild -ba --without python mylib.spec

关键区别与使用指南

特性 %bcond_with <option> %bcond_without <option>
默认状态 关闭 (%{with ...}为空) 开启 (%{with ...}为 1)
如何启用 --with <option> (默认即启用,无需操作)
如何禁用 (默认即禁用,无需操作) --without <option>
设计哲学 “默认精简,按需添加” “默认完整,按需移除”
适用场景 附加功能、可选依赖、实验性特性 核心功能、常见依赖、文档、Python/Perl 模块

高级技巧和注意事项

  1. rpmmacros中设置默认值 你可以修改用户的 ~/.rpmmacros或系统的 /etc/rpm/macros文件来永久改变某个条件的默认行为,而无需每次都在命令行指定。 # 在 ~/.rpmmacros 中 %_with_gui 1 # 将 %bcond_with gui 的默认行为改为开启 %_without_python 1 # 将 %bcond_without python 的默认行为改为关闭
  2. %{?_with_foo:...}%{!?_without_bar:...}配合使用./configure行或其他地方,你经常看到这种简写: %{?_with_foo:--enable-foo}:如果 _with_foo被定义(即用户用了 --with foo),则展开为 --enable-foo,否则为空。 %{!?_without_bar:--enable-bar}:如果 _without_bar没有被定义(即用户没有--without bar,也就是默认或用了 --with bar),则展开为 --enable-bar,否则为空。这在使用 %bcond_without时非常方便。
  3. 检查条件是否定义 你可以用 %{defined with_...}来检查一个 with_变量是否被定义,这比检查它是否为空更明确。 %if %{defined with_gui} echo "GUI is defined, but is it enabled?" %if %{with_gui} echo "Yes, GUI is enabled." %else echo "No, GUI is defined but disabled (this shouldn't happen with bcond_with)." %endif %endif

总结

  • %bcond_with:为默认不构建的功能提供开关。用 --with打开。
  • %bcond_without:为默认构建的功能提供开关。用 --without关闭。

选择哪一个取决于你对“正常”或“默认”构建的理解。对于 Fedora/RHEL 官方源中的软件包,%bcond_without在需要处理 Python/Perl 模块和文档时更为常见,因为确保这些组件可用是默认预期。而对于用户自己的或第三方仓库的包,如果功能很专业且非必需,%bcond_with是更好的选择。

熟练掌握这两个宏是编写专业、灵活、可维护的 RPM Spec 文件的关键一步。

http://www.gsyq.cn/news/179987.html

相关文章:

  • ownCloud集群部署终极指南:构建高可用企业级文件同步平台
  • [Linux]学习笔记系列 -- [fs]mnt_idmapping
  • Apache ShenYu深度重构:Redis集群缓存架构设计完全指南
  • 21天精通量化投资:日历效应检测工具的实战应用宝典
  • 从星空菜鸟到深空大师:DeepSkyStacker让你的天文摄影梦想照进现实
  • 2025 年总结盘点:成长、突破与平衡
  • Pyenv与Miniconda对比:哪种更适合管理Python AI环境?
  • 如何快速配置Chuck:Android网络请求调试的完整指南
  • Waymo数据集完整实践指南:从零开始快速掌握自动驾驶数据
  • GitHub托管PyTorch项目时忽略.pycache/和__pycache__/目录
  • Transformer模型训练提速秘诀:PyTorch + CUDA多卡并行实战
  • 逻辑门组合逻辑设计:多层感知机实战案例详解
  • AutoAgent零代码AI代理框架:5分钟快速上手指南
  • Go 语言 2025 年度深度研究报告:架构演进、生态格局与未来展望
  • PyTorch v2.9新特性解读:性能优化与CUDA兼容性增强
  • OpenHantek开源示波器软件:专业信号分析的理想选择
  • Conda与Pip共用时的PyTorch环境管理注意事项
  • PyTorch-CUDA-v2.9镜像Product Hunt发布准备清单
  • NodePPT Mermaid插件终极指南:如何用代码创建专业级演示图表
  • 心理咨询预约|基于springboot + vue心理咨询预约系统(源码+数据库+文档)
  • PyTorch-CUDA-v2.9镜像小红书种草文案写作要点
  • OpenHantek 开源示波器软件终极指南:从入门到精通
  • FFUF终极指南:快速掌握高效Web安全测试工具
  • Pyomo:Python生态系统中的专业优化建模框架
  • SwiftShield终极指南:5步保护你的iOS应用安全
  • 如何快速测量CPU核心间延迟:提升多核性能的关键工具
  • PyTorch-CUDA-v2.9镜像专利申请中的技术创新点描述
  • Sketch Palettes完整指南:如何快速管理你的设计色彩方案
  • SweetAlert2 深度解析:重新定义现代Web应用交互体验
  • 使用Markdown制作PyTorch学习路线图文档