blob: 8c4ab684e493c5641f6a50840135eb8608697f2f [file] [log] [blame]
Austin Schuhf093fa52019-06-23 20:47:23 -07001load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
Austin Schuh8f99c822024-05-05 22:43:40 -07002load("@rules_pkg//:pkg.bzl", "pkg_tar")
James Kuszmaulac0912d2024-05-21 15:56:59 -07003load("//tools/build_rules:clean_dep.bzl", "clean_dep")
Philipp Schrader0e19c602018-03-07 21:07:22 -08004
Stephan Pleines69a52cb2023-12-14 19:13:51 -08005# In order to use deb packages in the build you have to follow these steps.
Philipp Schrader0e19c602018-03-07 21:07:22 -08006#
Stephan Pleines69a52cb2023-12-14 19:13:51 -08007# Adding new packages:
Philipp Schrader0e19c602018-03-07 21:07:22 -08008# 1. Create a "download_packages" build step in //debian/BUILD. List the
9# packages you care about and exclude the ones you don't care about.
Brian Silverman4b90dd02022-01-08 18:16:22 -080010# Invoke "bazel run" on the "download_packages" target you just created.
Philipp Schrader0e19c602018-03-07 21:07:22 -080011# Save the "_files" dictionary it prints into a .bzl file in the //debian
James Kuszmaul3ae42262019-11-08 12:33:41 -080012# folder. You will need to have the apt-rdepends package installed.
Brian Silverman4b90dd02022-01-08 18:16:22 -080013# If you want to get packages for a different architecture or distribution,
14# you can pass flags here to control those. See the --help for details.
Philipp Schrader0e19c602018-03-07 21:07:22 -080015# 2. The "download_packages" steps prints the location of the deb packages
16# after it prints the "_files" dictionary. Take the deb packages from there
Maxwell Henderson7a93a652023-06-24 15:17:09 -070017# and upload them to https://software.frc971.org/Build-Dependencies/.
Philipp Schrader0e19c602018-03-07 21:07:22 -080018# 3. Add the newly uploaded deb packages as WORKSPACE entries using the
19# "generate_repositories_for_debs" helper. Load the "_files" dictionary
20# created earlier and the "generate_repositories_for_debs" helper and call
21# them together in the WORKSPACE file.
22# 4. Add a "generate_deb_tarball" target to //debian/BUILD. Pass in the
23# "_files" dictionary created earlier by loading it from the .bzl file.
24# 5. Invoke "bazel build" on the "generate_deb_tarball" target you just created
Maxwell Henderson7a93a652023-06-24 15:17:09 -070025# and upload the resulting tarball to https://software.frc971.org/Build-Dependencies.
Philipp Schrader0e19c602018-03-07 21:07:22 -080026# 6. Add a new "new_http_archive" entry to the WORKSPACE file for the tarball
27# you just uploaded.
Stephan Pleines69a52cb2023-12-14 19:13:51 -080028#
29# Updating existing packages:
30# 1. Read above instructions.
31# 2. The "download_packages" build step already exists, run it.
32# 3. The .bzl file with the file list already exists. Update it with the
33# output from the previous step.
34# 4. Follow steps 2., 5., and 6. from "adding new packages".
Philipp Schrader0e19c602018-03-07 21:07:22 -080035
Austin Schuh94dbdf32024-04-11 22:51:09 -070036def download_packages(name, packages, excludes = [], force_includes = [], force_excludes = [], target_compatible_with = None, release = "bookworm"):
Austin Schuh8e17be92019-12-24 09:32:11 -080037 """Downloads a set of packages as well as their dependencies.
Philipp Schrader0e19c602018-03-07 21:07:22 -080038
Austin Schuh8e17be92019-12-24 09:32:11 -080039 You can also specify excludes in case some of the dependencies are meta
40 packages.
Philipp Schrader0e19c602018-03-07 21:07:22 -080041
Austin Schuh8e17be92019-12-24 09:32:11 -080042 Use "bazel run" on these targets to download the packages and generate the
43 list to use in a .bzl file. Once you have the packages on
Maxwell Henderson7a93a652023-06-24 15:17:09 -070044 https://software.frc971.org/Build-Dependencies/ you can add them to a to
Austin Schuh8e17be92019-12-24 09:32:11 -080045 combine_packages rule.
Philipp Schraderfd5489f2022-09-17 17:31:09 -070046
47 force_includes lets you include packages that are excluded by default. The
48 dependencies of these force-included packages are also force-included. To
49 counter-act that, you can use "force_excludes". The force-excluded packages
50 are excluded even if they're pulled in as a dependency from a
51 "force_includes" package.
Austin Schuh8e17be92019-12-24 09:32:11 -080052 """
53 package_list = " ".join(packages)
54 excludes_list = " ".join(["--exclude=%s" % e for e in excludes])
55 force_includes = " ".join(["--force-include=%s" % i for i in force_includes])
Philipp Schraderfd5489f2022-09-17 17:31:09 -070056 force_excludes = " ".join(["--force-exclude=%s" % e for e in force_excludes])
Austin Schuh8e17be92019-12-24 09:32:11 -080057 native.genrule(
Brian Silverman4b90dd02022-01-08 18:16:22 -080058 name = name + "_gen",
59 outs = ["%s.sh" % name],
60 executable = True,
61 cmd = """
62cat > $@ <<'END'
63#!/bin/bash
64
65# --- begin runfiles.bash initialization v2 ---
66# Copy-pasted from the Bazel Bash runfiles library v2.
67set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
68source "$${RUNFILES_DIR:-/dev/null}/$$f" 2>/dev/null || \\
69 source "$$(grep -sm1 "^$$f " "$${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \\
70 source "$$0.runfiles/$$f" 2>/dev/null || \\
71 source "$$(grep -sm1 "^$$f " "$$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \\
72 source "$$(grep -sm1 "^$$f " "$$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \\
73 { echo>&2 "ERROR: cannot find $$f"; exit 1; }; f=; set -e
74# --- end runfiles.bash initialization v2 ---
75
76
Alexei Strotsf3b7e8d2023-08-16 21:35:13 -070077exec "$$(rlocation org_frc971/debian/download_packages)" %s %s %s %s --release=%s "$$@"
78END""" % (force_includes, force_excludes, excludes_list, package_list, release),
Brian Silverman4b90dd02022-01-08 18:16:22 -080079 target_compatible_with = target_compatible_with,
80 )
81 native.sh_binary(
Austin Schuh8e17be92019-12-24 09:32:11 -080082 name = name,
Brian Silverman4b90dd02022-01-08 18:16:22 -080083 srcs = ["%s.sh" % name],
84 deps = [
85 "@bazel_tools//tools/bash/runfiles",
Austin Schuh8e17be92019-12-24 09:32:11 -080086 ],
Brian Silverman4b90dd02022-01-08 18:16:22 -080087 data = [
James Kuszmaulac0912d2024-05-21 15:56:59 -070088 clean_dep("//debian:download_packages"),
Austin Schuh8e17be92019-12-24 09:32:11 -080089 ],
Philipp Schraderdada1072020-11-24 11:34:46 -080090 target_compatible_with = target_compatible_with,
Austin Schuh8e17be92019-12-24 09:32:11 -080091 )
Philipp Schrader0e19c602018-03-07 21:07:22 -080092
93def _convert_deb_to_target(deb):
Brian Silvermandc7d8052020-01-31 17:44:30 -080094 """Converts a debian package filename to a valid bazel target name."""
95 target = deb
96 target = target.replace("-", "_")
97 target = target.replace(".", "_")
98 target = target.replace(":", "_")
99 target = target.replace("+", "x")
100 target = target.replace("~", "_")
101 return "deb_%s_repo" % target
Philipp Schrader0e19c602018-03-07 21:07:22 -0800102
Maxwell Henderson7a93a652023-06-24 15:17:09 -0700103def generate_repositories_for_debs(files, base_url = "https://software.frc971.org/Build-Dependencies"):
Austin Schuh8e17be92019-12-24 09:32:11 -0800104 """A WORKSPACE helper to add all the deb packages in the dictionary as a repo.
Philipp Schrader0e19c602018-03-07 21:07:22 -0800105
Austin Schuh8e17be92019-12-24 09:32:11 -0800106 The files dictionary must be one generated with the "download_packages"
107 helper above.
108 """
109 for f in files.keys():
110 name = _convert_deb_to_target(f)
111 if name not in native.existing_rules():
112 http_file(
113 name = name,
114 urls = [base_url + "/" + f],
115 sha256 = files[f],
116 downloaded_file_path = f,
117 )
Philipp Schrader0e19c602018-03-07 21:07:22 -0800118
Philipp Schraderdada1072020-11-24 11:34:46 -0800119def generate_deb_tarball(name, files, target_compatible_with = None):
Austin Schuh8e17be92019-12-24 09:32:11 -0800120 """Takes all debs in the dictionary and generates one tarball from them.
Philipp Schrader0e19c602018-03-07 21:07:22 -0800121
Austin Schuh8e17be92019-12-24 09:32:11 -0800122 This can then be uploaded and used as another WORKSPACE entry.
123 """
124 deps = []
125 for f in files.keys():
126 dep = _convert_deb_to_target(f)
127 deps.append(dep)
128 if ("generate_%s_tarball" % dep) not in native.existing_rules():
129 native.genrule(
130 name = "generate_%s_tarball" % dep,
131 srcs = ["@%s//file" % dep],
132 outs = ["extracted_%s.tar" % dep],
133 cmd = "dpkg-deb --fsys-tarfile $(SRCS) > $@",
Philipp Schraderdada1072020-11-24 11:34:46 -0800134 target_compatible_with = target_compatible_with,
Austin Schuh8e17be92019-12-24 09:32:11 -0800135 )
Philipp Schrader0e19c602018-03-07 21:07:22 -0800136
Austin Schuh8e17be92019-12-24 09:32:11 -0800137 pkg_tar(
138 name = name,
139 extension = "tar.gz",
140 deps = ["extracted_%s.tar" % dep for dep in deps],
Philipp Schraderdada1072020-11-24 11:34:46 -0800141 target_compatible_with = target_compatible_with,
Austin Schuh8e17be92019-12-24 09:32:11 -0800142 )