blob: dfb4ed8954558606529e496a516d87066bdfdafe [file] [log] [blame]
Philipp Schrader0e19c602018-03-07 21:07:22 -08001load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
Austin Schuhf093fa52019-06-23 20:47:23 -07002load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
Philipp Schrader0e19c602018-03-07 21:07:22 -08003
4# In order to use deb packages in the build you have to follow these steps:
5#
6# 1. Create a "download_packages" build step in //debian/BUILD. List the
7# packages you care about and exclude the ones you don't care about.
Brian Silverman4b90dd02022-01-08 18:16:22 -08008# Invoke "bazel run" on the "download_packages" target you just created.
Philipp Schrader0e19c602018-03-07 21:07:22 -08009# Save the "_files" dictionary it prints into a .bzl file in the //debian
James Kuszmaul3ae42262019-11-08 12:33:41 -080010# folder. You will need to have the apt-rdepends package installed.
Brian Silverman4b90dd02022-01-08 18:16:22 -080011# If you want to get packages for a different architecture or distribution,
12# you can pass flags here to control those. See the --help for details.
Philipp Schrader0e19c602018-03-07 21:07:22 -080013# 2. The "download_packages" steps prints the location of the deb packages
14# after it prints the "_files" dictionary. Take the deb packages from there
Austin Schuha5778ae2020-10-21 21:15:35 -070015# and upload them to https://www.frc971.org/Build-Dependencies/.
Philipp Schrader0e19c602018-03-07 21:07:22 -080016# 3. Add the newly uploaded deb packages as WORKSPACE entries using the
17# "generate_repositories_for_debs" helper. Load the "_files" dictionary
18# created earlier and the "generate_repositories_for_debs" helper and call
19# them together in the WORKSPACE file.
20# 4. Add a "generate_deb_tarball" target to //debian/BUILD. Pass in the
21# "_files" dictionary created earlier by loading it from the .bzl file.
22# 5. Invoke "bazel build" on the "generate_deb_tarball" target you just created
Austin Schuha5778ae2020-10-21 21:15:35 -070023# and upload the resulting tarball to https://www.frc971.org/Build-Dependencies.
Philipp Schrader0e19c602018-03-07 21:07:22 -080024# 6. Add a new "new_http_archive" entry to the WORKSPACE file for the tarball
25# you just uploaded.
26
Philipp Schraderfd5489f2022-09-17 17:31:09 -070027def download_packages(name, packages, excludes = [], force_includes = [], force_excludes = [], target_compatible_with = None):
Austin Schuh8e17be92019-12-24 09:32:11 -080028 """Downloads a set of packages as well as their dependencies.
Philipp Schrader0e19c602018-03-07 21:07:22 -080029
Austin Schuh8e17be92019-12-24 09:32:11 -080030 You can also specify excludes in case some of the dependencies are meta
31 packages.
Philipp Schrader0e19c602018-03-07 21:07:22 -080032
Austin Schuh8e17be92019-12-24 09:32:11 -080033 Use "bazel run" on these targets to download the packages and generate the
34 list to use in a .bzl file. Once you have the packages on
Austin Schuha5778ae2020-10-21 21:15:35 -070035 https://www.frc971.org/Build-Dependencies/ you can add them to a to
Austin Schuh8e17be92019-12-24 09:32:11 -080036 combine_packages rule.
Philipp Schraderfd5489f2022-09-17 17:31:09 -070037
38 force_includes lets you include packages that are excluded by default. The
39 dependencies of these force-included packages are also force-included. To
40 counter-act that, you can use "force_excludes". The force-excluded packages
41 are excluded even if they're pulled in as a dependency from a
42 "force_includes" package.
Austin Schuh8e17be92019-12-24 09:32:11 -080043 """
44 package_list = " ".join(packages)
45 excludes_list = " ".join(["--exclude=%s" % e for e in excludes])
46 force_includes = " ".join(["--force-include=%s" % i for i in force_includes])
Philipp Schraderfd5489f2022-09-17 17:31:09 -070047 force_excludes = " ".join(["--force-exclude=%s" % e for e in force_excludes])
Austin Schuh8e17be92019-12-24 09:32:11 -080048 native.genrule(
Brian Silverman4b90dd02022-01-08 18:16:22 -080049 name = name + "_gen",
50 outs = ["%s.sh" % name],
51 executable = True,
52 cmd = """
53cat > $@ <<'END'
54#!/bin/bash
55
56# --- begin runfiles.bash initialization v2 ---
57# Copy-pasted from the Bazel Bash runfiles library v2.
58set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
59source "$${RUNFILES_DIR:-/dev/null}/$$f" 2>/dev/null || \\
60 source "$$(grep -sm1 "^$$f " "$${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \\
61 source "$$0.runfiles/$$f" 2>/dev/null || \\
62 source "$$(grep -sm1 "^$$f " "$$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \\
63 source "$$(grep -sm1 "^$$f " "$$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \\
64 { echo>&2 "ERROR: cannot find $$f"; exit 1; }; f=; set -e
65# --- end runfiles.bash initialization v2 ---
66
67
Philipp Schraderfd5489f2022-09-17 17:31:09 -070068exec "$$(rlocation org_frc971/debian/download_packages)" %s %s %s %s "$$@"
69END""" % (force_includes, force_excludes, excludes_list, package_list),
Brian Silverman4b90dd02022-01-08 18:16:22 -080070 target_compatible_with = target_compatible_with,
71 )
72 native.sh_binary(
Austin Schuh8e17be92019-12-24 09:32:11 -080073 name = name,
Brian Silverman4b90dd02022-01-08 18:16:22 -080074 srcs = ["%s.sh" % name],
75 deps = [
76 "@bazel_tools//tools/bash/runfiles",
Austin Schuh8e17be92019-12-24 09:32:11 -080077 ],
Brian Silverman4b90dd02022-01-08 18:16:22 -080078 data = [
Austin Schuh8e17be92019-12-24 09:32:11 -080079 "//debian:download_packages",
80 ],
Philipp Schraderdada1072020-11-24 11:34:46 -080081 target_compatible_with = target_compatible_with,
Austin Schuh8e17be92019-12-24 09:32:11 -080082 )
Philipp Schrader0e19c602018-03-07 21:07:22 -080083
84def _convert_deb_to_target(deb):
Brian Silvermandc7d8052020-01-31 17:44:30 -080085 """Converts a debian package filename to a valid bazel target name."""
86 target = deb
87 target = target.replace("-", "_")
88 target = target.replace(".", "_")
89 target = target.replace(":", "_")
90 target = target.replace("+", "x")
91 target = target.replace("~", "_")
92 return "deb_%s_repo" % target
Philipp Schrader0e19c602018-03-07 21:07:22 -080093
Austin Schuha5778ae2020-10-21 21:15:35 -070094def generate_repositories_for_debs(files, base_url = "https://www.frc971.org/Build-Dependencies"):
Austin Schuh8e17be92019-12-24 09:32:11 -080095 """A WORKSPACE helper to add all the deb packages in the dictionary as a repo.
Philipp Schrader0e19c602018-03-07 21:07:22 -080096
Austin Schuh8e17be92019-12-24 09:32:11 -080097 The files dictionary must be one generated with the "download_packages"
98 helper above.
99 """
100 for f in files.keys():
101 name = _convert_deb_to_target(f)
102 if name not in native.existing_rules():
103 http_file(
104 name = name,
105 urls = [base_url + "/" + f],
106 sha256 = files[f],
107 downloaded_file_path = f,
108 )
Philipp Schrader0e19c602018-03-07 21:07:22 -0800109
Philipp Schraderdada1072020-11-24 11:34:46 -0800110def generate_deb_tarball(name, files, target_compatible_with = None):
Austin Schuh8e17be92019-12-24 09:32:11 -0800111 """Takes all debs in the dictionary and generates one tarball from them.
Philipp Schrader0e19c602018-03-07 21:07:22 -0800112
Austin Schuh8e17be92019-12-24 09:32:11 -0800113 This can then be uploaded and used as another WORKSPACE entry.
114 """
115 deps = []
116 for f in files.keys():
117 dep = _convert_deb_to_target(f)
118 deps.append(dep)
119 if ("generate_%s_tarball" % dep) not in native.existing_rules():
120 native.genrule(
121 name = "generate_%s_tarball" % dep,
122 srcs = ["@%s//file" % dep],
123 outs = ["extracted_%s.tar" % dep],
124 cmd = "dpkg-deb --fsys-tarfile $(SRCS) > $@",
Philipp Schraderdada1072020-11-24 11:34:46 -0800125 target_compatible_with = target_compatible_with,
Austin Schuh8e17be92019-12-24 09:32:11 -0800126 )
Philipp Schrader0e19c602018-03-07 21:07:22 -0800127
Austin Schuh8e17be92019-12-24 09:32:11 -0800128 pkg_tar(
129 name = name,
130 extension = "tar.gz",
131 deps = ["extracted_%s.tar" % dep for dep in deps],
Philipp Schraderdada1072020-11-24 11:34:46 -0800132 target_compatible_with = target_compatible_with,
Austin Schuh8e17be92019-12-24 09:32:11 -0800133 )