summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kelly <mkelly@arista.com>2024-04-24 13:03:11 -0700
committerGitHub <noreply@github.com>2024-04-24 16:03:11 -0400
commit581a86a29458b5f4fc580d7889f9bc3f591f25a2 (patch)
tree6ab2827ed5925f60de7edd7e13a695b45418e4f9
parenta811e7f44f09a2348735527fd999f04df8a7dbc7 (diff)
downloadbazelbuild-rules_pkg-581a86a29458b5f4fc580d7889f9bc3f591f25a2.tar.gz
Add support for generating debuginfo RPMs (#842)
* Enable creation and capture of debuginfo RPMs This change enables the creation and capture of debuginfo RPMs on Fedora40 and CentOS7. See: https://docs.fedoraproject.org/en-US/packaging-guidelines/Debuginfo/ Fedora 40 expects the RPM contents to be located in a subdirectory which is specified using the `buildsubdir` variable. In order to account for this, we need to tweak some of the location details if debuginfo is enabled. CentOS expects `buildsubdir` to have a value like `.` instead. In both cases, we disable debugsource packages by ensuring that we undefine `_debugsource_packages`, otherwise we'll try to generate them alongside the debuginfo packages and will fail. We only want this method of producing debuginfo to apply when we're using the system `rpmbuild` because the underlying behaviour is controlled by a combination of the rpmbuild version, macro definitions, find-debuginfo.sh, and debugedit. If we were to expand this to use a hermetic debuginfo then a different approach might be desirable. * Add an RPM example that generates debuginfo This provides a basic example that generates a debuginfo RPM configured to run on CentOS7. * Upgrade rules_python to 0.31.0 rules_python seems to fail us when we're generating debuginfo RPMs unless we upgrade to a version more recent than 0.24.0. * Only generate debuginfo RPM when pkg_rpm() asks for it In lieu of enabling this behaviour by default on the supported platforms, we add an additional argument to the pkg_rpm() rule that will allow us to enable it for pkg_rpm() targets. This prevents us from enabling it in cases where it's not desired. * Add test for building debuginfo RPM This test is modelled on the subrpm test. In lieu of using a simple text file as an input it instead generates a binary that includes debug symbosl from a C source file and includes that in the RPM. The baseline comparison strips out the `.build-id` paths because the hashes that are generated may not be stable.x * Remove architecture and size from debuginfo test output These values may vary depending on the platform that this is being run on and we don't really care about them. * Add period to docstring * Enable debuginfo support for CentOS Stream 9 CentOS Stream 9 appears to work more or less the same for debuginfo generation as CentOS 7. `os-release` describes it as os == `centos` and version == `9`. This change creates an extra token for `centos9` and sticks it in the places where we currently have controls for `centos7`.
-rw-r--r--MODULE.bazel2
-rw-r--r--examples/rpm/debuginfo/BUILD55
-rw-r--r--examples/rpm/debuginfo/MODULE.bazel32
-rw-r--r--examples/rpm/debuginfo/README.md17
-rw-r--r--examples/rpm/debuginfo/test.c3
-rw-r--r--pkg/make_rpm.py44
-rw-r--r--pkg/rpm_pfg.bzl64
-rw-r--r--tests/rpm/BUILD55
-rw-r--r--tests/rpm/test.c3
-rwxr-xr-xtests/rpm/test_debuginfo_rpm_contents.txt.golden29
-rw-r--r--toolchains/rpm/BUILD.tpl1
-rw-r--r--toolchains/rpm/rpmbuild.bzl10
-rw-r--r--toolchains/rpm/rpmbuild_configure.bzl60
13 files changed, 354 insertions, 21 deletions
diff --git a/MODULE.bazel b/MODULE.bazel
index 725f54e..ea29d95 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -7,7 +7,7 @@ module(
# Do not update to newer versions until you need a specific new feature.
bazel_dep(name = "rules_license", version = "0.0.4")
-bazel_dep(name = "rules_python", version = "0.24.0")
+bazel_dep(name = "rules_python", version = "0.31.0")
bazel_dep(name = "bazel_skylib", version = "1.2.0")
# Only for development
diff --git a/examples/rpm/debuginfo/BUILD b/examples/rpm/debuginfo/BUILD
new file mode 100644
index 0000000..72dc80f
--- /dev/null
+++ b/examples/rpm/debuginfo/BUILD
@@ -0,0 +1,55 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# -*- coding: utf-8 -*-
+
+
+load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
+load("@rules_pkg//pkg:rpm.bzl", "pkg_rpm")
+
+cc_binary(
+ name = "test",
+ copts = ["-g"],
+ srcs = [
+ "test.c",
+ ],
+)
+
+pkg_files(
+ name = "rpm_files",
+ srcs = [
+ ":test",
+ ],
+)
+
+pkg_rpm(
+ name = "test-rpm",
+ srcs = [
+ ":rpm_files",
+ ],
+ release = "0",
+ version = "1",
+ license = "Some license",
+ summary = "Summary",
+ description = "Description",
+ debuginfo = True,
+)
+
+# If you have rpmbuild, you probably have rpm2cpio too.
+# Feature idea: Add rpm2cpio and cpio to the rpmbuild toolchain
+genrule(
+ name = "inspect_content",
+ srcs = [":test-rpm"],
+ outs = ["content.txt"],
+ cmd = "rpm2cpio $(locations :test-rpm) | cpio -ivt >$@",
+)
diff --git a/examples/rpm/debuginfo/MODULE.bazel b/examples/rpm/debuginfo/MODULE.bazel
new file mode 100644
index 0000000..b2d8a8f
--- /dev/null
+++ b/examples/rpm/debuginfo/MODULE.bazel
@@ -0,0 +1,32 @@
+# Copyright 2024 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module(name = "rules_pkg_example_rpm_system_rpmbuild_bzlmod")
+
+bazel_dep(name = "rules_pkg")
+
+local_path_override(
+ module_name = "rules_pkg",
+ path = "../../..",
+)
+
+find_rpmbuild = use_extension(
+ "@rules_pkg//toolchains/rpm:rpmbuild_configure.bzl",
+ "find_system_rpmbuild_bzlmod",
+)
+use_repo(find_rpmbuild, "rules_pkg_rpmbuild")
+
+register_toolchains(
+ "@rules_pkg_rpmbuild//:all",
+)
diff --git a/examples/rpm/debuginfo/README.md b/examples/rpm/debuginfo/README.md
new file mode 100644
index 0000000..d42b117
--- /dev/null
+++ b/examples/rpm/debuginfo/README.md
@@ -0,0 +1,17 @@
+# Using system rpmbuild with bzlmod and generating debuginfo
+
+## Summary
+
+This example uses the `find_system_rpmbuild_bzlmod` module extension to help
+us register the system rpmbuild as a toolchain in a bzlmod environment.
+
+It configures the system toolchain to be aware of which debuginfo configuration
+to use (defaults to "none", the example uses "centos7").
+
+## To use
+
+```
+bazel build :*
+rpm2cpio bazel-bin/test-rpm.rpm | cpio -ivt
+cat bazel-bin/content.txt
+```
diff --git a/examples/rpm/debuginfo/test.c b/examples/rpm/debuginfo/test.c
new file mode 100644
index 0000000..4cce7f6
--- /dev/null
+++ b/examples/rpm/debuginfo/test.c
@@ -0,0 +1,3 @@
+int main() {
+ return 0;
+}
diff --git a/pkg/make_rpm.py b/pkg/make_rpm.py
index ded2832..6e5c581 100644
--- a/pkg/make_rpm.py
+++ b/pkg/make_rpm.py
@@ -172,6 +172,7 @@ class RpmBuilder(object):
SOURCE_DIR = 'SOURCES'
BUILD_DIR = 'BUILD'
+ BUILD_SUBDIR = 'BUILD_SUB'
BUILDROOT_DIR = 'BUILDROOT'
TEMP_DIR = 'TMP'
RPMS_DIR = 'RPMS'
@@ -345,7 +346,7 @@ class RpmBuilder(object):
shutil.copy(os.path.join(original_dir, file_list_path), RpmBuilder.BUILD_DIR)
self.file_list_path = os.path.join(RpmBuilder.BUILD_DIR, os.path.basename(file_list_path))
- def CallRpmBuild(self, dirname, rpmbuild_args):
+ def CallRpmBuild(self, dirname, rpmbuild_args, debuginfo_type):
"""Call rpmbuild with the correct arguments."""
buildroot = os.path.join(dirname, RpmBuilder.BUILDROOT_DIR)
@@ -361,16 +362,31 @@ class RpmBuilder(object):
if self.debug:
args.append('-vv')
+ if debuginfo_type == "fedora40":
+ os.makedirs(f'{dirname}/{RpmBuilder.BUILD_DIR}/{RpmBuilder.BUILD_SUBDIR}')
+
# Common options
# NOTE: There may be a need to add '--define', 'buildsubdir .' for some
# rpmbuild versions. But that breaks other rpmbuild versions, so before
# adding it back in, add extensive tests.
args += [
- '--define', '_topdir %s' % dirname,
- '--define', '_tmppath %s/TMP' % dirname,
- '--define', '_builddir %s/BUILD' % dirname,
- '--bb',
- '--buildroot=%s' % buildroot,
+ '--define', '_topdir %s' % dirname,
+ '--define', '_tmppath %s/TMP' % dirname,
+ '--define', '_builddir %s/BUILD' % dirname,
+ ]
+
+ if debuginfo_type in ["fedora40", "centos7", "centos9"]:
+ args += ['--undefine', '_debugsource_packages']
+
+ if debuginfo_type in ["centos7", "centos9"]:
+ args += ['--define', 'buildsubdir .']
+
+ if debuginfo_type == "fedora40":
+ args += ['--define', f'buildsubdir {RpmBuilder.BUILD_SUBDIR}']
+
+ args += [
+ '--bb',
+ '--buildroot=%s' % buildroot,
] # yapf: disable
# Macro-based RPM parameter substitution, if necessary inputs provided.
@@ -382,7 +398,11 @@ class RpmBuilder(object):
args += ['--define', 'build_rpm_install %s' % self.install_script_file]
if self.file_list_path:
# %files -f is taken relative to the package root
- args += ['--define', 'build_rpm_files %s' % os.path.basename(self.file_list_path)]
+ base_path = os.path.basename(self.file_list_path)
+ if debuginfo_type == "fedora40":
+ base_path = os.path.join("..", base_path)
+
+ args += ['--define', 'build_rpm_files %s' % base_path]
args.extend(rpmbuild_args)
@@ -459,7 +479,8 @@ class RpmBuilder(object):
posttrans_scriptlet_path=None,
file_list_path=None,
changelog_file=None,
- rpmbuild_args=None):
+ rpmbuild_args=None,
+ debuginfo_type=None):
"""Build the RPM described by the spec_file, with other metadata in keyword arguments"""
if self.debug:
@@ -490,7 +511,7 @@ class RpmBuilder(object):
postun_scriptlet_path=postun_scriptlet_path,
posttrans_scriptlet_path=posttrans_scriptlet_path,
changelog_file=changelog_file)
- status = self.CallRpmBuild(dirname, rpmbuild_args or [])
+ status = self.CallRpmBuild(dirname, rpmbuild_args or [], debuginfo_type)
self.SaveResult(out_file, subrpm_out_files)
return status
@@ -550,6 +571,8 @@ def main(argv):
parser.add_argument('--rpmbuild_arg', dest='rpmbuild_args', action='append',
help='Any additional arguments to pass to rpmbuild')
+ parser.add_argument('--debuginfo_type', dest='debuginfo_type', default='none',
+ help='debuginfo type to use (centos7, fedora40, or none)')
parser.add_argument('files', nargs='*')
options = parser.parse_args(argv or ())
@@ -574,7 +597,8 @@ def main(argv):
postun_scriptlet_path=options.postun_scriptlet,
posttrans_scriptlet_path=options.posttrans_scriptlet,
changelog_file=options.changelog,
- rpmbuild_args=options.rpmbuild_args)
+ rpmbuild_args=options.rpmbuild_args,
+ debuginfo_type=options.debuginfo_type)
except NoRpmbuildFoundError:
print('ERROR: rpmbuild is required but is not present in PATH')
return 1
diff --git a/pkg/rpm_pfg.bzl b/pkg/rpm_pfg.bzl
index c45c7dc..b3eac5c 100644
--- a/pkg/rpm_pfg.bzl
+++ b/pkg/rpm_pfg.bzl
@@ -67,6 +67,13 @@ DEFAULT_FILE_MODE = "%defattr(-,root,root)"
_INSTALL_FILE_STANZA_FMT = """
install -d "%{{buildroot}}/$(dirname '{1}')"
cp '{0}' '%{{buildroot}}/{1}'
+chmod +w '%{{buildroot}}/{1}'
+""".strip()
+
+_INSTALL_FILE_STANZA_FMT_FEDORA40_DEBUGINFO = """
+install -d "%{{buildroot}}/$(dirname '{1}')"
+cp '../{0}' '%{{buildroot}}/{1}'
+chmod +w '%{{buildroot}}/{1}'
""".strip()
# TODO(nacl): __install
@@ -172,7 +179,7 @@ def _make_absolute_if_not_already_or_is_macro(path):
# TODO(nacl, #459): These are redundant with functions and structures in
# pkg/private/pkg_files.bzl. We should really use the infrastructure provided
# there, but as of writing, it's not quite ready.
-def _process_files(pfi, origin_label, grouping_label, file_base, rpm_ctx):
+def _process_files(pfi, origin_label, grouping_label, file_base, rpm_ctx, debuginfo_type):
for dest, src in pfi.dest_src_map.items():
metadata = _package_contents_metadata(origin_label, grouping_label)
if dest in rpm_ctx.dest_check_map:
@@ -196,7 +203,12 @@ def _process_files(pfi, origin_label, grouping_label, file_base, rpm_ctx):
else:
# Files are well-known. Take care of them right here.
rpm_ctx.rpm_files_list.append(_FILE_MODE_STANZA_FMT.format(file_base, abs_dest))
- rpm_ctx.install_script_pieces.append(_INSTALL_FILE_STANZA_FMT.format(
+
+ install_stanza_fmt = _INSTALL_FILE_STANZA_FMT
+ if debuginfo_type == "fedora40":
+ install_stanza_fmt = _INSTALL_FILE_STANZA_FMT_FEDORA40_DEBUGINFO
+
+ rpm_ctx.install_script_pieces.append(install_stanza_fmt.format(
src.path,
abs_dest,
))
@@ -231,7 +243,7 @@ def _process_symlink(psi, origin_label, grouping_label, file_base, rpm_ctx):
psi.attributes["mode"],
))
-def _process_dep(dep, rpm_ctx):
+def _process_dep(dep, rpm_ctx, debuginfo_type):
# NOTE: This does not detect cases where directories are not named
# consistently. For example, all of these may collide in reality, but
# won't be detected by the below:
@@ -255,6 +267,7 @@ def _process_dep(dep, rpm_ctx):
None, # group label
_make_filetags(dep[PackageFilesInfo].attributes), # file_base
rpm_ctx,
+ debuginfo_type,
)
if PackageDirsInfo in dep:
@@ -285,6 +298,7 @@ def _process_dep(dep, rpm_ctx):
dep.label,
file_base,
rpm_ctx,
+ debuginfo_type
)
for entry, origin in pfg_info.pkg_dirs:
file_base = _make_filetags(entry.attributes, "%dir")
@@ -306,7 +320,7 @@ def _process_dep(dep, rpm_ctx):
rpm_ctx,
)
-def _process_subrpm(ctx, rpm_name, rpm_info, rpm_ctx):
+def _process_subrpm(ctx, rpm_name, rpm_info, rpm_ctx, debuginfo_type):
sub_rpm_ctx = struct(
dest_check_map = {},
install_script_pieces = [],
@@ -356,7 +370,7 @@ def _process_subrpm(ctx, rpm_name, rpm_info, rpm_ctx):
]
for dep in rpm_info.srcs:
- _process_dep(dep, sub_rpm_ctx)
+ _process_dep(dep, sub_rpm_ctx, debuginfo_type)
# rpmbuild will be unhappy if we have no files so we stick
# default file mode in for that scenario
@@ -424,6 +438,7 @@ def _pkg_rpm_impl(ctx):
files = []
tools = []
+ debuginfo_type = "none"
name = ctx.attr.package_name if ctx.attr.package_name else ctx.label.name
rpm_ctx.make_rpm_args.append("--name=" + name)
@@ -448,6 +463,10 @@ def _pkg_rpm_impl(ctx):
tools.append(executable_files)
rpm_ctx.make_rpm_args.append("--rpmbuild=%s" % executable_files.executable.path)
+ if ctx.attr.debuginfo:
+ debuginfo_type = toolchain.debuginfo_type
+ rpm_ctx.make_rpm_args.append("--debuginfo_type=%s" % debuginfo_type)
+
#### Calculate output file name
# rpm_name takes precedence over name if provided
if ctx.attr.package_name:
@@ -678,13 +697,14 @@ def _pkg_rpm_impl(ctx):
# they aren't unnecessarily recreated.
for dep in ctx.attr.srcs:
- _process_dep(dep, rpm_ctx)
+ _process_dep(dep, rpm_ctx, debuginfo_type)
#### subrpms
if ctx.attr.subrpms:
subrpm_lines = []
for s in ctx.attr.subrpms:
- subrpm_lines.extend(_process_subrpm(ctx, rpm_name, s[PackageSubRPMInfo], rpm_ctx))
+ subrpm_lines.extend(_process_subrpm(
+ ctx, rpm_name, s[PackageSubRPMInfo], rpm_ctx, debuginfo_type))
subrpm_file = ctx.actions.declare_file(
"{}.spec.subrpms".format(rpm_name),
@@ -696,6 +716,27 @@ def _pkg_rpm_impl(ctx):
files.append(subrpm_file)
rpm_ctx.make_rpm_args.append("--subrpms=" + subrpm_file.path)
+ if debuginfo_type != "none":
+ debuginfo_default_file = ctx.actions.declare_file(
+ "{}-debuginfo.rpm".format(rpm_name))
+ debuginfo_package_file_name = "%s-%s-%s-%s.%s.rpm" % (
+ rpm_name,
+ "debuginfo",
+ ctx.attr.version,
+ ctx.attr.release,
+ ctx.attr.architecture,
+ )
+
+ _, debuginfo_output_file, _ = setup_output_files(
+ ctx,
+ debuginfo_package_file_name,
+ default_output_file = debuginfo_default_file,
+ )
+
+ rpm_ctx.output_rpm_files.append(debuginfo_output_file)
+ rpm_ctx.make_rpm_args.append(
+ "--subrpm_out_file=debuginfo:%s" % debuginfo_output_file.path )
+
#### Procedurally-generated scripts/lists (%install, %files)
# We need to write these out regardless of whether we are using
@@ -1177,6 +1218,15 @@ pkg_rpm = rule(
[PackageSubRPMInfo],
],
),
+ "debuginfo": attr.bool(
+ doc = """Enable generation of debuginfo RPMs
+
+ For supported platforms this will enable the generation of debuginfo RPMs adjacent
+ to the regular RPMs. Currently this is supported by Fedora 40, CentOS7 and
+ CentOS Stream 9.
+ """,
+ default = False,
+ ),
"rpmbuild_path": attr.string(
doc = """Path to a `rpmbuild` binary. Deprecated in favor of the rpmbuild toolchain""",
),
diff --git a/tests/rpm/BUILD b/tests/rpm/BUILD
index 89b1e61..b35c1ed 100644
--- a/tests/rpm/BUILD
+++ b/tests/rpm/BUILD
@@ -531,7 +531,7 @@ genrule(
grep -v 'Build Date' | grep -v 'Build Host' | grep -v 'Relocations' >> $@
echo "===== sub RPM ======" >> $@
rpm -qpi --list $${RPMS[1]} | \
- grep -v 'Build Date' | grep -v 'Build Host' | grep -v 'Relocations'>> $@
+ grep -v 'Build Date' | grep -v 'Build Host' | grep -v 'Relocations' >> $@
""",
)
@@ -542,6 +542,59 @@ diff_test(
)
############################################################################
+# debuginfo tests
+############################################################################
+cc_binary(
+ name = "test_debuginfo",
+ copts = ["-g"],
+ srcs = [
+ "test.c",
+ ],
+)
+
+pkg_files(
+ name = "test_debuginfo_rpm_files",
+ srcs = [
+ ":test_debuginfo",
+ ],
+)
+
+pkg_rpm(
+ name = "test_debuginfo_rpm",
+ srcs = [
+ ":test_debuginfo_rpm_files",
+ ],
+ release = "0",
+ version = "1",
+ license = "Some license",
+ summary = "Summary",
+ description = "Description",
+ debuginfo = True,
+)
+
+genrule(
+ name = "test_debuginfo_rpm_contents",
+ srcs = [":test_debuginfo_rpm"],
+ outs = [":test_debuginfo_rpm_contents.txt"],
+ cmd = """
+ # pkg_rpm emits two outputs
+ RPMS=($(SRCS))
+ echo "===== main RPM =====" > $@
+ rpm -qpi --list $${RPMS[0]} | \
+ grep -v 'Build Date' | grep -v 'Build Host' | grep -v 'Relocations' | grep -v 'Architecture' | grep -v 'Size' | grep -v '.build-id' >> $@
+ echo "===== sub RPM ======" >> $@
+ rpm -qpi --list $${RPMS[1]} | \
+ grep -v 'Build Date' | grep -v 'Build Host' | grep -v 'Relocations' | grep -v 'Architecture' | grep -v 'Size' | grep -v '.build-id' >> $@
+ """,
+)
+
+diff_test(
+ name = "test_golden_debuginfo_rpm_contents",
+ file1 = ":test_debuginfo_rpm_contents",
+ file2 = "test_debuginfo_rpm_contents.txt.golden",
+)
+
+############################################################################
# Common tests
############################################################################
diff --git a/tests/rpm/test.c b/tests/rpm/test.c
new file mode 100644
index 0000000..4cce7f6
--- /dev/null
+++ b/tests/rpm/test.c
@@ -0,0 +1,3 @@
+int main() {
+ return 0;
+}
diff --git a/tests/rpm/test_debuginfo_rpm_contents.txt.golden b/tests/rpm/test_debuginfo_rpm_contents.txt.golden
new file mode 100755
index 0000000..0f65f11
--- /dev/null
+++ b/tests/rpm/test_debuginfo_rpm_contents.txt.golden
@@ -0,0 +1,29 @@
+===== main RPM =====
+Name : test_debuginfo_rpm
+Version : 1
+Release : 0
+Install Date: (not installed)
+Group : Unspecified
+License : Some license
+Signature : (none)
+Source RPM : test_debuginfo_rpm-1-0.src.rpm
+Summary : Summary
+Description :
+Description
+/test_debuginfo
+===== sub RPM ======
+Name : test_debuginfo_rpm-debuginfo
+Version : 1
+Release : 0
+Install Date: (not installed)
+Group : Development/Debug
+License : Some license
+Signature : (none)
+Source RPM : test_debuginfo_rpm-1-0.src.rpm
+Summary : Debug information for package test_debuginfo_rpm
+Description :
+This package provides debug information for package test_debuginfo_rpm.
+Debug information is useful when developing applications that use this
+package or when debugging this package.
+/usr/lib/debug
+/usr/lib/debug/test_debuginfo.debug
diff --git a/toolchains/rpm/BUILD.tpl b/toolchains/rpm/BUILD.tpl
index 8547062..5045bff 100644
--- a/toolchains/rpm/BUILD.tpl
+++ b/toolchains/rpm/BUILD.tpl
@@ -5,6 +5,7 @@ rpmbuild_toolchain(
name = "rpmbuild_auto",
path = "{RPMBUILD_PATH}",
version = "{RPMBUILD_VERSION}",
+ debuginfo_type = "{RPMBUILD_DEBUGINFO_TYPE}",
)
toolchain(
diff --git a/toolchains/rpm/rpmbuild.bzl b/toolchains/rpm/rpmbuild.bzl
index 7e22752..7cb4459 100644
--- a/toolchains/rpm/rpmbuild.bzl
+++ b/toolchains/rpm/rpmbuild.bzl
@@ -21,6 +21,7 @@ RpmbuildInfo = provider(
"label": "The path to a target I will build",
"path": "The path to a pre-built rpmbuild",
"version": "The version string of rpmbuild",
+ "debuginfo_type": "The variant of the underlying debuginfo config",
},
)
@@ -35,6 +36,7 @@ def _rpmbuild_toolchain_impl(ctx):
label = ctx.attr.label,
path = ctx.attr.path,
version = ctx.attr.version,
+ debuginfo_type = ctx.attr.debuginfo_type,
),
)
return [toolchain_info]
@@ -54,6 +56,14 @@ rpmbuild_toolchain = rule(
"version": attr.string(
doc = "The version string of the rpmbuild executable. This should be manually set.",
),
+ "debuginfo_type": attr.string(
+ doc = """
+ The underlying debuginfo configuration for the system rpmbuild.
+
+ One of centos7, fedora40, or none
+ """,
+ default = "none",
+ ),
},
)
diff --git a/toolchains/rpm/rpmbuild_configure.bzl b/toolchains/rpm/rpmbuild_configure.bzl
index a3cb83a..aa84ceb 100644
--- a/toolchains/rpm/rpmbuild_configure.bzl
+++ b/toolchains/rpm/rpmbuild_configure.bzl
@@ -17,8 +17,9 @@
# MODULE.bazel files. It seems like we should have a better interface that
# allows for this module name to be specified from a single point.
NAME = "rules_pkg_rpmbuild"
+RELEASE_PATH = "/etc/os-release"
-def _write_build(rctx, path, version):
+def _write_build(rctx, path, version, debuginfo_type):
if not path:
path = ""
rctx.template(
@@ -28,17 +29,58 @@ def _write_build(rctx, path, version):
"{GENERATOR}": "@rules_pkg//toolchains/rpm/rpmbuild_configure.bzl%find_system_rpmbuild",
"{RPMBUILD_PATH}": str(path),
"{RPMBUILD_VERSION}": version,
+ "{RPMBUILD_DEBUGINFO_TYPE}": debuginfo_type,
},
executable = False,
)
+def _strip_quote(s):
+ if s.startswith("\"") and s.endswith("\"") and len(s) > 1:
+ return s[1:-1]
+
+ return s
+
+def _parse_release_info(release_info):
+ os_name = "unknown"
+ os_version = "unknown"
+
+ for line in release_info.splitlines():
+ if "=" not in line:
+ continue
+
+ key, value = line.split("=")
+ if key == "ID":
+ os_name = _strip_quote(value)
+
+ if key == "VERSION_ID":
+ os_version = _strip_quote(value)
+
+ return os_name, os_version
+
def _build_repo_for_rpmbuild_toolchain_impl(rctx):
+ debuginfo_type = "none"
+ if rctx.path(RELEASE_PATH).exists:
+ os_name, os_version = _parse_release_info(rctx.read(RELEASE_PATH))
+
+ if os_name == "centos":
+ if os_version == "7":
+ debuginfo_type = "centos7"
+ elif os_version == "9":
+ debuginfo_type = "centos9"
+
+ if os_name == "fedora" and os_version == "40":
+ debuginfo_type = "fedora40"
+
rpmbuild_path = rctx.which("rpmbuild")
if rctx.attr.verbose:
if rpmbuild_path:
print("Found rpmbuild at '%s'" % rpmbuild_path) # buildifier: disable=print
else:
print("No system rpmbuild found.") # buildifier: disable=print
+
+ if rctx.attr.debuginfo_type not in ["centos7", "fedora40", "none"]:
+ fail("debuginfo_type must be one of centos7, fedora40, or none")
+
version = "unknown"
if rpmbuild_path:
res = rctx.execute([rpmbuild_path, "--version"])
@@ -47,7 +89,13 @@ def _build_repo_for_rpmbuild_toolchain_impl(rctx):
parts = res.stdout.strip().split(" ")
if parts[0] == "RPM" and parts[1] == "version":
version = parts[2]
- _write_build(rctx = rctx, path = rpmbuild_path, version = version)
+
+ _write_build(
+ rctx = rctx,
+ path = rpmbuild_path,
+ version = version,
+ debuginfo_type = debuginfo_type,
+ )
build_repo_for_rpmbuild_toolchain = repository_rule(
implementation = _build_repo_for_rpmbuild_toolchain_impl,
@@ -58,6 +106,14 @@ build_repo_for_rpmbuild_toolchain = repository_rule(
"verbose": attr.bool(
doc = "If true, print status messages.",
),
+ "debuginfo_type": attr.string(
+ doc = """
+ The underlying debuginfo configuration for the system rpmbuild.
+
+ One of centos7, fedora40, or none
+ """,
+ default = "none",
+ ),
},
)