blob: 59f993e4bff8eb53099868be1cefdd9fb57e0ee0 [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.
8# Invoke "bazel build" on the "download_packages" target you just created.
9# 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.
Philipp Schrader0e19c602018-03-07 21:07:22 -080011# 2. The "download_packages" steps prints the location of the deb packages
12# after it prints the "_files" dictionary. Take the deb packages from there
johnp8a384f92019-01-03 13:10:00 -080013# and upload them to http://www.frc971.org/Build-Dependencies/.
Philipp Schrader0e19c602018-03-07 21:07:22 -080014# 3. Add the newly uploaded deb packages as WORKSPACE entries using the
15# "generate_repositories_for_debs" helper. Load the "_files" dictionary
16# created earlier and the "generate_repositories_for_debs" helper and call
17# them together in the WORKSPACE file.
18# 4. Add a "generate_deb_tarball" target to //debian/BUILD. Pass in the
19# "_files" dictionary created earlier by loading it from the .bzl file.
20# 5. Invoke "bazel build" on the "generate_deb_tarball" target you just created
johnp8a384f92019-01-03 13:10:00 -080021# and upload the resulting tarball to http://www.frc971.org/Build-Dependencies.
Philipp Schrader0e19c602018-03-07 21:07:22 -080022# 6. Add a new "new_http_archive" entry to the WORKSPACE file for the tarball
23# you just uploaded.
24
25# TODO(phil): Deal with armhf packages. Right now only works for amd64.
26
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080027def download_packages(name, packages, excludes=[], force_includes=[]):
Philipp Schrader0e19c602018-03-07 21:07:22 -080028 """Downloads a set of packages as well as their dependencies.
29
30 You can also specify excludes in case some of the dependencies are meta
31 packages.
32
33 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
johnp8a384f92019-01-03 13:10:00 -080035 http://www.frc971.org/Build-Dependencies/ you can add them to a to
Philipp Schrader0e19c602018-03-07 21:07:22 -080036 combine_packages rule.
37 """
38 package_list = " ".join(packages)
39 excludes_list = " ".join(["--exclude=%s" % e for e in excludes])
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080040 force_includes = " ".join(["--force-include=%s" % i for i in force_includes])
Philipp Schrader0e19c602018-03-07 21:07:22 -080041 native.genrule(
42 name = name,
43 outs = ["%s_output.txt" % name],
44 tags = [
45 "local",
46 "manual",
47 ],
48 tools = [
49 "//debian:download_packages",
50 ],
51 # TODO(phil): Deal with stderr a bit better. It spews more stuff out than I
52 # would like it to.
Philipp Schraderaedfc5c2018-03-10 19:32:30 -080053 cmd = "$(location //debian:download_packages) %s %s %s | tee $@ >&2" \
54 % (force_includes, excludes_list, package_list),
Philipp Schrader0e19c602018-03-07 21:07:22 -080055 )
56
57def _convert_deb_to_target(deb):
58 """Converts a debian package filename to a valid bazel target name."""
59 target = deb.split('_')[0]
60 target = target.replace('-', '_')
61 target = target.replace('.', '_')
62 target = target.replace(':', '_')
63 target = target.replace('+', 'x')
64 return "deb_%s_repo" % target
65
James Kuszmaul3ae42262019-11-08 12:33:41 -080066def generate_repositories_for_debs(files, base_url = 'http://www.frc971.org/Build-Dependencies'):
Philipp Schrader0e19c602018-03-07 21:07:22 -080067 """A WORKSPACE helper to add all the deb packages in the dictionary as a repo.
68
69 The files dictionary must be one generated with the "download_packages"
70 helper above.
71 """
72 for f in files.keys():
73 name = _convert_deb_to_target(f)
74 if name not in native.existing_rules():
Austin Schuhf093fa52019-06-23 20:47:23 -070075 http_file(
Philipp Schrader0e19c602018-03-07 21:07:22 -080076 name = name,
James Kuszmaul3ae42262019-11-08 12:33:41 -080077 urls = [base_url + '/' + f],
Philipp Schrader0e19c602018-03-07 21:07:22 -080078 sha256 = files[f],
Austin Schuhf093fa52019-06-23 20:47:23 -070079 downloaded_file_path = f,
Philipp Schrader0e19c602018-03-07 21:07:22 -080080 )
81
82def generate_deb_tarball(name, files):
83 """Takes all debs in the dictionary and generates one tarball from them.
84
85 This can then be uploaded and used as another WORKSPACE entry.
86 """
87 deps = []
88 for f in files.keys():
89 dep = _convert_deb_to_target(f)
90 deps.append(dep)
91 if ('generate_%s_tarball' % dep) not in native.existing_rules():
92 native.genrule(
93 name = 'generate_%s_tarball' % dep,
94 srcs = ['@%s//file' % dep],
95 outs = ['extracted_%s.tar' % dep],
96 cmd = 'dpkg-deb --fsys-tarfile $(SRCS) > $@',
97 )
98
99 pkg_tar(
100 name = name,
101 extension = 'tar.gz',
102 deps = ['extracted_%s.tar' % dep for dep in deps],
103 )