目录
概述
RPM宏定义是RPM打包系统中的变量替换机制,允许用户在构建过程中使用预定义或自定义的变量,使spec文件更具灵活性和可移植性。宏可以定义构建路径、体系结构、发行版信息等关键参数。
配置方法详解
1. 命令行实时定义(--define)
在构建时通过命令行参数临时定义宏,优先级最高。
bash
# 基本语法
rpmbuild --define="macro_name value" [options] spec_file
# 同时定义多个宏
rpmbuild --define="_topdir /opt/rpmbuild" --define="dist .el8" -ba package.spec
# 包含空格的宏值需要引号
rpmbuild --define="build_args '--disable-static --with-openssl'" -ba package.spec
2. 用户配置文件(~/.rpmmacros)
用户级宏配置文件,适用于特定用户的构建环境。
bash
# 创建或编辑用户宏配置文件
vim ~/.rpmmacros
# 常用配置示例
%_topdir %(echo $HOME)/rpmbuild
%_tmppath %{_topdir}/tmp
%dist .el8
%_arch x86_64
%_vendor mycompany
# 条件宏定义
%if 0%{?rhel} == 8
%dist .el8
%else
%dist .el7
%endif
3. 自定义宏配置文件(--macros)
使用外部文件定义宏集合,便于团队共享和管理。
bash
# 创建自定义宏文件
cat > /etc/rpm/macros.custom <<EOF
%_company_rpms /var/www/html/rpms
%_signature gpg
%_gpg_name packager@example.com
%_build_cflags -O2 -g -pipe -Wall -Werror=format-security
EOF
# 使用自定义宏文件构建
rpmbuild --macros=/etc/rpm/macros.custom:/usr/lib/rpm/macros -ba package.spec
# 加载多个宏文件
rpmbuild --macros="/etc/rpm/macros.d/*:/usr/lib/rpm/macros" -ba package.spec
常用宏定义说明
构建目录相关
bash
# 标准构建目录结构
%_topdir %{getenv:HOME}/rpmbuild # 顶级构建目录
%_builddir %{_topdir}/BUILD # 解压和编译目录
%_rpmdir %{_topdir}/RPMS # 二进制RPM输出目录
%_srcrpmdir %{_topdir}/SRPMS # 源码RPM输出目录
%_sourcedir %{_topdir}/SOURCES # 源码文件目录
%_specdir %{_topdir}/SPECS # spec文件目录
%_buildrootdir %{_topdir}/BUILDROOT # 安装根目录
发行版和架构
bash
# 发行版标识
%dist .el8 # 发行版后缀
%rhel 8 # RHEL主版本
%centos 8 # CentOS版本
# 架构相关
%_arch x86_64 # 目标架构
%_host_cpu x86_64 # 主机CPU类型
%_host x86_64-redhat-linux-gnu # 主机平台
构建参数
bash
# 编译器标志
%_optflags -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
%_build_cflags %{_optflags}
%_build_cxxflags %{_optflags}
# 打包选项
%_binary_payload w9.gzdio # 压缩算法
%_source_payload w9.gzdio
%_binary_filedigest_algorithm 8 # 文件校验算法
%_source_filedigest_algorithm 8
签名和验证
bash
# GPG签名配置
%_signature gpg
%_gpg_path /home/user/.gnupg
%_gpg_name Your Name <your.email@example.com>
%_gpgbin /usr/bin/gpg2
实战操作示例
示例1:完整构建环境配置
bash
# 1. 创建用户宏配置文件
cat > ~/.rpmmacros <<'EOF'
# 基础目录配置
%_topdir %{getenv:HOME}/rpmbuild
%_tmppath %{_topdir}/tmp
# 发行版特定配置
%if 0%{?rhel} >= 8
%dist .el8
%_systemd /usr/bin/systemctl
%elif 0%{?centos} >= 7
%dist .el7
%_systemd /bin/systemctl
%else
%dist .unknown
%endif
# 构建优化
%_smp_mflags -j$(nproc)
%_build_cflags -O2 -g -pipe -Wall -Werror=format-security
EOF
# 2. 创建目录结构
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
# 3. 使用配置构建
rpmbuild -ba --define="version 1.0.0" --define="release 1%{?dist}" mypackage.spec
示例2:企业级多环境配置
bash
# 创建环境特定的宏文件
# /etc/rpm/macros.d/development.macros
cat > /etc/rpm/macros.d/development.macros <<'EOF'
%_environment development
%_debug_package %{nil}
%_build_cflags -O0 -g -pipe
EOF
# /etc/rpm/macros.d/production.macros
cat > /etc/rpm/macros.d/production.macros <<'EOF'
%_environment production
%_strip /usr/bin/strip
%_build_cflags -O2 -s -pipe -fstack-protector-strong
EOF
# 构建时选择环境
# 开发构建
rpmbuild --macros="/etc/rpm/macros.d/development.macros:/usr/lib/rpm/macros" \
--define="_debug_package %{nil}" \
-ba app.spec
# 生产构建
rpmbuild --macros="/etc/rpm/macros.d/production.macros:/usr/lib/rpm/macros" \
--define="_strip /usr/bin/strip" \
-ba app.spec
示例3:跨发行版打包配置
bash
# ~/.rpmmacros 中的条件配置
%_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
%if 0%{?fedora}
%fedora 1
%dist .fc%{fedora}
%_vendor fedora
%endif
%if 0%{?rhel}
%rhel 1
%_vendor redhat
%if 0%{?rhel} == 8
%dist .el8
%_systemd 1
%elif 0%{?rhel} == 7
%dist .el7
%endif
%endif
%if 0%{?centos}
%centos 1
%_vendor centos
%dist .el%{centos}
%endif
# 在spec文件中使用条件逻辑
%if 0%{?rhel} >= 8
Requires: systemd
%endif
%if 0%{?fedora} >= 32
BuildRequires: gcc-c++
%else
BuildRequires: gcc-g++
%endif
宏定义调试技巧
查看宏定义
bash
# 查看所有宏定义
rpm --showrc | less
# 查看特定宏的值
rpm --eval '%{_topdir}'
rpm --eval '%{dist}'
rpm --eval '%{_arch}'
# 查看宏展开过程
rpmbuild --nobuild --define='version 1.0' -E package.spec
# 调试模式查看宏
rpmbuild --define='debug 1' --define='_verbose 5' -ba package.spec
宏调试脚本
bash
#!/bin/bash
# debug-macros.sh - 调试RPM宏定义
MACRO_FILE=${1:-~/.rpmmacros}
echo "=== Current Macro Values ==="
echo "_topdir: $(rpm --eval '%{_topdir}')"
echo "dist: $(rpm --eval '%{dist}')"
echo "_arch: $(rpm --eval '%{_arch}')"
echo "_vendor: $(rpm --eval '%{_vendor}')"
echo -e "\n=== Testing Macro File ==="
if [ -f "$MACRO_FILE" ]; then
echo "Using macro file: $MACRO_FILE"
rpm --macros="$MACRO_FILE:/usr/lib/rpm/macros" --showrc | grep -E "(dist|_topdir|_arch)"
else
echo "Macro file not found: $MACRO_FILE"
fi
echo -e "\n=== Conditional Macro Test ==="
for os in rhel centos fedora; do
value=$(rpm --eval "%{?$os}")
[ -n "$value" ] && echo "$os: $value" || echo "$os: not defined"
done
最佳实践建议
1. 组织宏定义
bash
# 推荐的文件结构
/etc/rpm/
├── macros # 系统全局宏
├── macros.d/ # 宏片段目录
│ ├── company.macros # 公司标准
│ ├── security.macros # 安全相关
│ └── build-opt.macros # 构建优化
└── platform.d/ # 平台相关
├── el8.macros
└── el7.macros
# 在~/.rpmmacros中加载
%include /etc/rpm/macros.d/company.macros
%include /etc/rpm/macros.d/security.macros
2. 版本控制
bash
# 在宏中定义版本策略
%_major_version 1
%_minor_version 0
%_patch_version 0
%version %{_major_version}.%{_minor_VERSION}.%{_patch_VERSION}
# 构建编号策略
%if 0%{?released}
%release 1%{?dist}
%else
%release 0.%(date +%Y%m%d%H%M%S).git%{shortcommit}
%endif
3. 安全配置
bash
# 安全相关宏
%_allow_deps_with_cycles 0
%_allow_undefined_version 0
%_allow_undefined_arch 0
%_allow_undefined_os 0
# 构建环境安全
%_buildhost build.example.com
%_builduser builder
%_buildshell /bin/bash
%_buildumask 022
4. 性能优化
bash
# 并行构建
%_smp_mflags -j%(nproc)
# 缓存优化
%_source_cache /var/cache/rpm/sources
%_binary_cache /var/cache/rpm/binaries
# 压缩设置
%_binary_payload w19.xzdio
%_source_payload w19.xzdio
5. 团队协作规范
bash
# 团队共享宏文件示例
# team-macros.macros
%_team_name "DevOps Team"
%_team_email devops@company.com
%_scm_type git
%_scm_url https://github.com/company/repo
%_reviewboard_url https://review.company.com
# 标准构建目标
%_build_targets all check test
# 代码质量标准
%_coverage_minimum 80
%_test_pass_rate 95
通过合理配置和使用RPM宏定义,可以显著提高打包效率,确保构建的一致性和可重复性,同时便于维护和团队协作。建议根据实际需求组合使用不同的配置方法,建立标准化的构建环境。