Skip to content

Commit

Permalink
Add support for cross-compiled rpms.
Browse files Browse the repository at this point in the history
This is enabled by a pending PR to the rules_pkg project:
bazelbuild/rules_pkg#729

I just added the patch to out build while we wait for the PR to get merged.
  • Loading branch information
jiceatscion committed Oct 31, 2024
1 parent bae8d39 commit ffd4dd3
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
2 changes: 2 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ install_python_doc_deps()
http_archive(
name = "rules_pkg",
sha256 = "8f9ee2dc10c1ae514ee599a8b42ed99fa262b757058f65ad3c384289ff70c4b8",
patch_args = ["-p1"],
patches = ["@//dist:rpm/rpm_rules.patch"],
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz",
"https://github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz",
Expand Down
3 changes: 3 additions & 0 deletions dist/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ DEB_PLATFORMS = [

RPM_PLATFORMS = [
"@io_bazel_rules_go//go/toolchain:linux_amd64",
"@io_bazel_rules_go//go/toolchain:linux_arm64",
"@io_bazel_rules_go//go/toolchain:linux_386",
"@io_bazel_rules_go//go/toolchain:linux_arm",
]

# TODO([email protected]):
Expand Down
5 changes: 5 additions & 0 deletions dist/package.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ def scion_pkg_rpm(name, package, executables = {}, systemds = [], configs = [],
else:
deps = []

tarch = kwargs.get("architecture")
if tarch:
kwargs.pop("architecture")

post = kwargs.get("postinst")
if post:
kwargs.pop("postinst")
Expand All @@ -122,6 +126,7 @@ def scion_pkg_rpm(name, package, executables = {}, systemds = [], configs = [],
summary = kwargs["description"],
srcs = ["%s_configs" % name, "%s_systemds" % name, "%s_execs" % name],
target_compatible_with = ["@platforms//os:linux"],
target_architecture = tarch,
package_file_name = "{package}_{file_name_version}_{architecture}.rpm",
package_variables = ":package_file_naming_" + name,
package_name = package,
Expand Down
139 changes: 139 additions & 0 deletions dist/rpm/rpm_rules.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
The following patch comes from:
https://github.com/bazelbuild/rules_pkg/pull/729
Ownership as per the github project's provisions.

I provide it here in advance of it being merged because it might take a while
to happen.

From 6c27a34cfe5a37901803ad8478f3b9ec668a3b69 Mon Sep 17 00:00:00 2001
From: Alex Blago <[email protected]>
Date: Sun, 13 Aug 2023 00:33:00 -0700
Subject: [PATCH] Support for cross-platform RPM package generation
diff --git a/pkg/make_rpm.py b/pkg/make_rpm.py
index e2ffca0a..76a2e51d 100644
--- a/pkg/make_rpm.py
+++ b/pkg/make_rpm.py
@@ -178,13 +178,14 @@ class RpmBuilder(object):
RPMS_DIR = 'RPMS'
DIRS = [SOURCE_DIR, BUILD_DIR, RPMS_DIR, TEMP_DIR]

- def __init__(self, name, version, release, arch, rpmbuild_path,
- source_date_epoch=None,
+ def __init__(self, name, version, release, arch, target_arch,
+ rpmbuild_path, source_date_epoch=None,
debug=False):
self.name = name
self.version = helpers.GetFlagValue(version)
self.release = helpers.GetFlagValue(release)
self.arch = arch
+ self.target_arch = target_arch
self.files = []
self.rpmbuild_path = FindRpmbuild(rpmbuild_path)
self.rpm_path = None
@@ -354,6 +355,10 @@ def CallRpmBuild(self, dirname, rpmbuild_args):
'--buildroot=%s' % buildroot,
] # yapf: disable

+ # Target platform
+ if self.target_arch:
+ args += ['--target=%s' % self.target_arch]
+
# Macro-based RPM parameter substitution, if necessary inputs provided.
if self.preamble_file:
args += ['--define', 'build_rpm_options %s' % self.preamble_file]
@@ -462,7 +467,10 @@ def main(argv):
help='The release of the software being packaged.')
parser.add_argument(
'--arch',
- help='The CPU architecture of the software being packaged.')
+ help='The CPU architecture of the machine on which it is built. '
+ 'If the package is not architecture dependent, set this to "noarch".')
+ parser.add_argument('--target_arch',
+ help='The CPU architecture of the target platform the software being packaged for.')
parser.add_argument('--spec_file', required=True,
help='The file containing the RPM specification.')
parser.add_argument('--out_file', required=True,
@@ -501,7 +509,7 @@ def main(argv):
try:
builder = RpmBuilder(options.name,
options.version, options.release,
- options.arch, options.rpmbuild,
+ options.arch, options.target_arch, options.rpmbuild,
source_date_epoch=options.source_date_epoch,
debug=options.debug)
builder.AddFiles(options.files)
diff --git a/pkg/rpm_pfg.bzl b/pkg/rpm_pfg.bzl
index 1e3450c1..596dc26d 100644
--- a/pkg/rpm_pfg.bzl
+++ b/pkg/rpm_pfg.bzl
@@ -142,7 +142,7 @@ def _make_absolute_if_not_already_or_is_macro(path):
# this can be inlined easily.
return path if path.startswith(("/", "%")) else "/" + path

-#### Input processing helper functons.
+#### Input processing helper functions.

# TODO(nacl, #459): These are redundant with functions and structures in
# pkg/private/pkg_files.bzl. We should really use the infrastructure provided
@@ -251,7 +251,7 @@ def _pkg_rpm_impl(ctx):
rpm_name,
ctx.attr.version,
ctx.attr.release,
- ctx.attr.architecture,
+ ctx.attr.architecture if ctx.attr.architecture else ctx.attr.target_architecture,
)

outputs, output_file, output_name = setup_output_files(
@@ -432,6 +432,9 @@ def _pkg_rpm_impl(ctx):

args.append("--out_file=" + output_file.path)

+ if ctx.attr.target_architecture:
+ args.append("--target_arch=" + ctx.attr.target_architecture)
+
# Add data files.
if ctx.file.changelog:
files.append(ctx.file.changelog)
@@ -666,7 +669,7 @@ def _pkg_rpm_impl(ctx):
output_groups = {
"out": [default_file],
"rpm": [output_file],
- "changes": changes
+ "changes": changes,
}
return [
OutputGroupInfo(**output_groups),
@@ -791,20 +794,29 @@ pkg_rpm = rule(
# funny if it's not provided. The contents of the RPM are believed to
# be set as expected, though.
"architecture": attr.string(
- doc = """Package architecture.
+ doc = """Host architecture.

This currently sets the `BuildArch` tag, which influences the output
architecture of the package.

Typically, `BuildArch` only needs to be set when the package is
- known to be cross-platform (e.g. written in an interpreted
- language), or, less common, when it is known that the application is
- only valid for specific architectures.
+ not architecture dependent (e.g. written in an interpreted
+ language).

When no attribute is provided, this will default to your host's
architecture. This is usually what you want.

""",
),
+ "target_architecture": attr.string(
+ doc = """Package architecture.
+
+ This currently sets the value for the "--target" argument to "rpmbuild"
+ to specify platform package is built for.
+
+ When no attribute is provided, this will default to your host's
+ architecture.
+ """,
+ ),
"license": attr.string(
doc = """RPM "License" tag.

0 comments on commit ffd4dd3

Please sign in to comment.