Merge changes Ifa6d446d,Ife280464

* changes:
  Get all our k8 clang tools loading downloaded .sos
  Use a (mostly) hermetic Python interpreter
diff --git a/README.md b/README.md
index f8b2680..42faed2 100644
--- a/README.md
+++ b/README.md
@@ -17,21 +17,19 @@
 [git-review](http://manpages.debian.org/cgi-bin/man.cgi?query=git-review) can make the upload process simpler.
 
 ## Building the code
-The currently supported operating system for building the code is amd64 Debian Jessie. It is likely to work on any x86\_64 GNU/Linux system, but that's not at all well-tested.
+The currently supported operating system for building the code is amd64 Debian Stretch. It is likely to work on any x86\_64 GNU/Linux system, but that's not at all well-tested.
 
-We use [Bazel](http://bazel.io) to build the code. Bazel has [extensive](http://bazel.io/docs/build-ref.html) [docs](http://bazel.io/docs/build-encyclopedia.html) and does a nice job with fast, correct increment rebuilds.
+We use [Bazel](http://bazel.io) to build the code. Bazel has [extensive](https://docs.bazel.build/versions/master/build-ref.html) [docs](https://docs.bazel.build/versions/master/be/overview.html) and does a nice job with fast, correct increment rebuilds.
 
 ### Steps to set up a computer to build the code:
   0. Set up the required APT repositories:
      Download
 	 [frc971.list](http://robotics.mvla.net/files/frc971/packages/frc971.list)
-	 and
-	 [llvm.org.list](http://robotics.mvla.net/files/frc971/packages/llvm.org.list)
-	 and put them in `/etc/apt/sources.list.d/`.
+	 and put it in `/etc/apt/sources.list.d/`.
   1. Install the required packages:
 ```console
-apt-get install -t jessie-backports openjdk-8-jdk
-apt-get install python libpython-dev bazel ruby clang-format-3.5 clang-3.6 gfortran libblas-dev liblapack-dev python-scipy python-matplotlib
+apt-get update
+apt-get install bazel python ruby
 ```
   2. Allow Bazel's sandboxing to work:
      Follow the direction in `doc/frc971.conf`.
diff --git a/WORKSPACE b/WORKSPACE
index 6eab184..3921318 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -24,6 +24,14 @@
     "//debian:mingw_compiler.bzl",
     mingw_compiler_debs = "files",
 )
+load(
+    "//debian:patchelf.bzl",
+    patchelf_debs = "files",
+)
+load(
+    "//debian:matplotlib.bzl",
+    matplotlib_debs = "files",
+)
 load("//debian:packages.bzl", "generate_repositories_for_debs")
 
 generate_repositories_for_debs(python_debs)
@@ -38,11 +46,15 @@
 
 generate_repositories_for_debs(mingw_compiler_debs)
 
+generate_repositories_for_debs(patchelf_debs)
+
+generate_repositories_for_debs(matplotlib_debs)
+
 new_http_archive(
     name = "python_repo",
     build_file = "debian/python.BUILD",
-    sha256 = "21214b6386273698b6aa1b64bccf1bc8c5ef4ef44563871bac5cd85383575af5",
-    url = "http://frc971.org/Build-Dependencies/python.tar.gz",
+    sha256 = "4ff939f90cffd8c72f9992d7420481e361b6016b0ce5c6fa701be0691d4e20fa",
+    url = "http://frc971.org/Build-Dependencies/python-2.tar.gz",
 )
 
 new_http_archive(
@@ -208,3 +220,17 @@
     sha256 = "45e86a8460f2151a4f0306e7ae7b06761029d2412ee16f63d1e8d2d29354e378",
     url = "http://frc971.org/Build-Dependencies/mingw_compiler.tar.gz",
 )
+
+new_http_archive(
+    name = "matplotlib",
+    build_file = "debian/matplotlib.BUILD",
+    sha256 = "4aa1efb22f74859ab5c478ff743f2fd34291fc30635f4b7cf2d67550ed226117",
+    url = "http://frc971.org/Build-Dependencies/matplotlib.tar.gz",
+)
+
+new_http_archive(
+    name = "patchelf",
+    build_file = "debian/patchelf.BUILD",
+    sha256 = "bf8b709909d7d9e30815dd228eeded7dc282e3ce3919d0589ccbb56ac8632abc",
+    url = "http://frc971.org/Build-Dependencies/patchelf.tar.gz",
+)
diff --git a/aos/BUILD b/aos/BUILD
index 89948ab..2e73c51 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -1,62 +1,71 @@
 filegroup(
-  name = 'prime_binaries',
-  visibility = ['//visibility:public'],
-  srcs = [
-    '//aos/linux_code:core',
-    '//aos/common/logging:log_streamer',
-    '//aos/common/logging:log_displayer',
-    '//aos/linux_code/starter',
-  ],
-)
-filegroup(
-  name = 'prime_start_binaries',
-  visibility = ['//visibility:public'],
-  srcs = [
-    '//aos/common/logging:binary_log_writer',
-  ],
+    name = "prime_binaries",
+    srcs = [
+        "//aos/common/logging:log_displayer",
+        "//aos/common/logging:log_streamer",
+        "//aos/linux_code:core",
+        "//aos/linux_code/starter",
+    ],
+    visibility = ["//visibility:public"],
 )
 
 filegroup(
-  name = 'prime_binaries_stripped',
-  visibility = ['//visibility:public'],
-  srcs = [
-    # starter is hard coded to look for a non-stripped core...
-    '//aos/linux_code:core',
-    '//aos/common/logging:log_streamer.stripped',
-    '//aos/common/logging:log_displayer.stripped',
-    '//aos/linux_code/starter',
-  ],
+    name = "prime_start_binaries",
+    srcs = [
+        "//aos/common/logging:binary_log_writer",
+    ],
+    visibility = ["//visibility:public"],
 )
+
 filegroup(
-  name = 'prime_start_binaries_stripped',
-  visibility = ['//visibility:public'],
-  srcs = [
-    '//aos/common/logging:binary_log_writer.stripped',
-  ],
+    name = "prime_binaries_stripped",
+    srcs = [
+        # starter is hard coded to look for a non-stripped core...
+        "//aos/linux_code:core",
+        "//aos/common/logging:log_streamer.stripped",
+        "//aos/common/logging:log_displayer.stripped",
+        "//aos/linux_code/starter",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+filegroup(
+    name = "prime_start_binaries_stripped",
+    srcs = [
+        "//aos/common/logging:binary_log_writer.stripped",
+    ],
+    visibility = ["//visibility:public"],
 )
 
 cc_library(
-  name = 'once',
-  visibility = ['//visibility:public'],
-  hdrs = [
-    'once.h',
-  ],
-  srcs = [
-    'once-tmpl.h',
-  ],
-  deps = [
-    '//aos/common:gtest_prod',
-    '//aos/common:type_traits',
-  ],
+    name = "once",
+    srcs = [
+        "once-tmpl.h",
+    ],
+    hdrs = [
+        "once.h",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//aos/common:gtest_prod",
+        "//aos/common:type_traits",
+    ],
 )
+
 cc_test(
-  name = 'once_test',
-  visibility = ['//visibility:public'],
-  srcs = [
-    'once_test.cc',
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    '//aos:once',
-  ],
+    name = "once_test",
+    srcs = [
+        "once_test.cc",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//aos:once",
+        "//aos/testing:googletest",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
 )
diff --git a/aos/__init__.py b/aos/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/aos/__init__.py
diff --git a/aos/common/BUILD b/aos/common/BUILD
index 4de57b6..b1c5b3b 100644
--- a/aos/common/BUILD
+++ b/aos/common/BUILD
@@ -400,3 +400,10 @@
         "//aos/testing:googletest",
     ],
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//aos:python_init"],
+)
diff --git a/aos/common/__init__.py b/aos/common/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/aos/common/__init__.py
diff --git a/aos/common/util/BUILD b/aos/common/util/BUILD
index cd58bbf..8fcd2fe 100644
--- a/aos/common/util/BUILD
+++ b/aos/common/util/BUILD
@@ -1,268 +1,278 @@
-package(default_visibility = ['//visibility:public'])
+package(default_visibility = ["//visibility:public"])
 
 py_library(
-  name = 'py_trapezoid_profile',
-  srcs = [
-    'trapezoid_profile.py',
-  ],
+    name = "py_trapezoid_profile",
+    srcs = [
+        "trapezoid_profile.py",
+    ],
+    deps = [
+        ":python_init",
+    ],
 )
 
 cc_library(
-  name = 'run_command',
-  srcs = [
-    'run_command.cc',
-  ],
-  hdrs = [
-    'run_command.h',
-  ],
-  deps = [
-    '//aos/common/logging',
-  ],
+    name = "run_command",
+    srcs = [
+        "run_command.cc",
+    ],
+    hdrs = [
+        "run_command.h",
+    ],
+    deps = [
+        "//aos/common/logging",
+    ],
 )
 
 cc_test(
-  name = 'run_command_test',
-  srcs = [
-    'run_command_test.cc',
-  ],
-  deps = [
-    ':run_command',
-    '//aos/testing:googletest',
-    '//aos/common/logging',
-    ':thread',
-  ],
+    name = "run_command_test",
+    srcs = [
+        "run_command_test.cc",
+    ],
+    deps = [
+        ":run_command",
+        ":thread",
+        "//aos/common/logging",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'death_test_log_implementation',
-  hdrs = [
-    'death_test_log_implementation.h',
-  ],
-  deps = [
-    '//aos/common/logging:implementations',
-  ],
+    name = "death_test_log_implementation",
+    hdrs = [
+        "death_test_log_implementation.h",
+    ],
+    deps = [
+        "//aos/common/logging:implementations",
+    ],
 )
 
 cc_library(
-  name = 'inet_addr',
-  srcs = [
-    'inet_addr.cc',
-  ],
-  hdrs = [
-    'inet_addr.h',
-  ],
-  deps = [
-    '//aos/common:byteorder',
-    '//aos/common:network_port',
-  ],
+    name = "inet_addr",
+    srcs = [
+        "inet_addr.cc",
+    ],
+    hdrs = [
+        "inet_addr.h",
+    ],
+    deps = [
+        "//aos/common:byteorder",
+        "//aos/common:network_port",
+    ],
 )
 
 cc_library(
-  name = 'phased_loop',
-  srcs = [
-    'phased_loop.cc',
-  ],
-  hdrs = [
-    'phased_loop.h',
-  ],
-  deps = [
-    '//aos/common/logging',
-    '//aos/common:time',
-  ],
+    name = "phased_loop",
+    srcs = [
+        "phased_loop.cc",
+    ],
+    hdrs = [
+        "phased_loop.h",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/logging",
+    ],
 )
 
 cc_library(
-  name = 'log_interval',
-  hdrs = [
-    'log_interval.h',
-  ],
-  deps = [
-    '//aos/common:time',
-    '//aos/common/logging',
-  ],
+    name = "log_interval",
+    hdrs = [
+        "log_interval.h",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/logging",
+    ],
 )
 
 cc_library(
-  name = 'string_to_num',
-  hdrs = [
-    'string_to_num.h',
-  ],
+    name = "string_to_num",
+    hdrs = [
+        "string_to_num.h",
+    ],
 )
 
 cc_test(
-  name = 'string_to_num_test',
-  srcs = [
-    'string_to_num_test.cc',
-  ],
-  deps = [
-    ':string_to_num',
-    '//aos/testing:googletest',
-  ],
+    name = "string_to_num_test",
+    srcs = [
+        "string_to_num_test.cc",
+    ],
+    deps = [
+        ":string_to_num",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'thread',
-  srcs = [
-    'thread.cc',
-  ],
-  hdrs = [
-    'thread.h',
-  ],
-  deps = [
-    '//aos/common:macros',
-    '//aos/common/logging',
-  ],
+    name = "thread",
+    srcs = [
+        "thread.cc",
+    ],
+    hdrs = [
+        "thread.h",
+    ],
+    deps = [
+        "//aos/common:macros",
+        "//aos/common/logging",
+    ],
 )
 
 cc_library(
-  name = 'trapezoid_profile',
-  srcs = [
-    'trapezoid_profile.cc',
-  ],
-  hdrs = [
-    'trapezoid_profile.h',
-  ],
-  deps = [
-    '//third_party/eigen',
-    '//aos/common:time',
-    '//aos/common/logging',
-  ],
-  linkopts = [
-    '-lm',
-  ],
+    name = "trapezoid_profile",
+    srcs = [
+        "trapezoid_profile.cc",
+    ],
+    hdrs = [
+        "trapezoid_profile.h",
+    ],
+    linkopts = [
+        "-lm",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//third_party/eigen",
+    ],
 )
 
 cc_test(
-  name = 'trapezoid_profile_test',
-  srcs = [
-    'trapezoid_profile_test.cc',
-  ],
-  deps = [
-    ':trapezoid_profile',
-    '//aos/testing:googletest',
-  ],
+    name = "trapezoid_profile_test",
+    srcs = [
+        "trapezoid_profile_test.cc",
+    ],
+    deps = [
+        ":trapezoid_profile",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'wrapping_counter',
-  srcs = [
-    'wrapping_counter.cc',
-  ],
-  hdrs = [
-    'wrapping_counter.h',
-  ],
+    name = "wrapping_counter",
+    srcs = [
+        "wrapping_counter.cc",
+    ],
+    hdrs = [
+        "wrapping_counter.h",
+    ],
 )
 
 cc_test(
-  name = 'wrapping_counter_test',
-  srcs = [
-    'wrapping_counter_test.cc',
-  ],
-  deps = [
-    ':wrapping_counter',
-    '//aos/testing:googletest',
-  ],
+    name = "wrapping_counter_test",
+    srcs = [
+        "wrapping_counter_test.cc",
+    ],
+    deps = [
+        ":wrapping_counter",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'options',
-  hdrs = [
-    'options.h',
-  ],
+    name = "options",
+    hdrs = [
+        "options.h",
+    ],
 )
 
 cc_test(
-  name = 'options_test',
-  srcs = [
-    'options_test.cc',
-  ],
-  deps = [
-    ':options',
-    '//aos/testing:googletest',
-  ],
+    name = "options_test",
+    srcs = [
+        "options_test.cc",
+    ],
+    deps = [
+        ":options",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'compiler_memory_barrier',
-  hdrs = [
-    'compiler_memory_barrier.h',
-  ],
+    name = "compiler_memory_barrier",
+    hdrs = [
+        "compiler_memory_barrier.h",
+    ],
 )
 
 cc_library(
-  name = 'global_factory',
-  hdrs = [
-    'global_factory.h'
-  ],
+    name = "global_factory",
+    hdrs = [
+        "global_factory.h",
+    ],
 )
 
 cc_test(
-  name = 'global_factory_test',
-  srcs = [
-    'global_factory_test.cc'
-  ],
-  deps = [
-    '//aos/testing:googletest',
-    ':global_factory'
-  ],
+    name = "global_factory_test",
+    srcs = [
+        "global_factory_test.cc",
+    ],
+    deps = [
+        ":global_factory",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_library(
-  name = 'linked_list',
-  hdrs = [
-    'linked_list.h',
-  ],
-  deps = [
-    '//aos/common:transaction',
-  ],
+    name = "linked_list",
+    hdrs = [
+        "linked_list.h",
+    ],
+    deps = [
+        "//aos/common:transaction",
+    ],
 )
 
 cc_test(
-  name = 'linked_list_test',
-  srcs = [
-    'linked_list_test.cc',
-  ],
-  deps = [
-    ':linked_list',
-    '//aos/testing:googletest',
-    '//aos/common/logging',
-  ],
+    name = "linked_list_test",
+    srcs = [
+        "linked_list_test.cc",
+    ],
+    deps = [
+        ":linked_list",
+        "//aos/common/logging",
+        "//aos/testing:googletest",
+    ],
 )
 
 cc_test(
-  name = 'phased_loop_test',
-  srcs = [
-    'phased_loop_test.cc',
-  ],
-  deps = [
-    ':phased_loop',
-    '//aos/testing:googletest',
-    '//aos/testing:test_logging',
-  ],
+    name = "phased_loop_test",
+    srcs = [
+        "phased_loop_test.cc",
+    ],
+    deps = [
+        ":phased_loop",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+    ],
 )
 
 cc_library(
-  name = 'file',
-  hdrs = [
-    'file.h',
-  ],
-  srcs = [
-    'file.cc',
-  ],
-  deps = [
-    '//aos/common:scoped_fd',
-  ],
+    name = "file",
+    srcs = [
+        "file.cc",
+    ],
+    hdrs = [
+        "file.h",
+    ],
+    deps = [
+        "//aos/common:scoped_fd",
+    ],
 )
 
 cc_test(
-  name = 'file_test',
-  srcs = [
-    'file_test.cc',
-  ],
-  deps = [
-    ':file',
-    '//aos/testing:googletest',
-    '//aos/testing:test_logging',
-  ],
-  size = 'small',
+    name = "file_test",
+    size = "small",
+    srcs = [
+        "file_test.cc",
+    ],
+    deps = [
+        ":file",
+        "//aos/testing:googletest",
+        "//aos/testing:test_logging",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//aos/common:python_init"],
 )
diff --git a/aos/common/util/__init__.py b/aos/common/util/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/aos/common/util/__init__.py
diff --git a/aos/externals/seasocks/gen_embedded.py b/aos/externals/seasocks/gen_embedded.py
index 416e37b..fdcdfd9 100755
--- a/aos/externals/seasocks/gen_embedded.py
+++ b/aos/externals/seasocks/gen_embedded.py
@@ -39,7 +39,7 @@
     with open(f, 'rb') as file:
       bytes = file.read()
     o.write('{"/%s", {' % os.path.basename(f))
-    o.write('"' + "".join(['\\x%02x' % ord(x) for x in bytes]) + '"')
+    o.write('"' + "".join(['\\x%02x' % x for x in bytes]) + '"')
     o.write(',%d }},' % len(bytes))
 
   o.write("""
diff --git a/debian/BUILD b/debian/BUILD
index 957df39..aa1b85f 100644
--- a/debian/BUILD
+++ b/debian/BUILD
@@ -24,8 +24,24 @@
     ":mingw_compiler.bzl",
     mingw_compiler_debs = "files",
 )
+load(
+    ":patchelf.bzl",
+    patchelf_debs = "files",
+)
+load(
+    ":matplotlib.bzl",
+    matplotlib_debs = "files",
+)
 load("//debian:packages.bzl", "download_packages", "generate_deb_tarball")
 
+filegroup(
+    name = "matplotlib_patches",
+    srcs = [
+        "matplotlib_init.patch",
+    ],
+    visibility = ["@matplotlib//:__pkg__"],
+)
+
 py_binary(
     name = "download_packages",
     srcs = [
@@ -45,8 +61,10 @@
     packages = [
         "python-dev",
         "python-numpy",
+        "python-scipy",
         "python3-dev",
         "python3-numpy",
+        "python3-scipy",
     ],
 )
 
@@ -98,6 +116,33 @@
     ],
 )
 
+download_packages(
+    name = "download_patchelf_deps",
+    packages = [
+        "patchelf",
+    ],
+)
+
+download_packages(
+    name = "download_matplotlib_deps",
+    excludes = [
+        "python-dev",
+        "python-numpy",
+        "python-scipy",
+        "python3-dev",
+        "python3-numpy",
+        "python3-scipy",
+        "x11-common",
+        "fonts-freefont",
+        "python",
+        "libcups2",
+    ],
+    packages = [
+        "python-matplotlib",
+        "python3-matplotlib",
+    ],
+)
+
 generate_deb_tarball(
     name = "python",
     files = python_debs,
@@ -127,3 +172,13 @@
     name = "mingw_compiler",
     files = mingw_compiler_debs,
 )
+
+generate_deb_tarball(
+    name = "patchelf",
+    files = patchelf_debs,
+)
+
+generate_deb_tarball(
+    name = "matplotlib",
+    files = matplotlib_debs,
+)
diff --git a/debian/download_packages.py b/debian/download_packages.py
index ca36b4b..5ad46e1 100755
--- a/debian/download_packages.py
+++ b/debian/download_packages.py
@@ -19,13 +19,25 @@
     deps.update(get_deps(package))
   return deps
 
+def map_virtual_packages(packages):
+  '''Maps known virtual packages to the preferred concrete packages which
+  provide them.'''
+  for package in packages:
+    if package == b'python-numpy-abi9':
+      yield b'python-numpy'
+      continue
+    if package == b'python3-numpy-abi9':
+      yield b'python3-numpy'
+      continue
+    yield package
+
 def download_deps(packages, excludes, force_includes):
   deps = get_all_deps(packages)
   exclude_deps = get_all_deps(excludes)
   deps -= exclude_deps
   force_include_deps = get_all_deps(force_includes)
   deps |= force_include_deps
-  subprocess.check_call([b"apt-get", b"download"] + list(deps))
+  subprocess.check_call([b"apt-get", b"download"] + list(map_virtual_packages(deps)))
 
 def fixup_files():
   # Gotta remove those pesky epoch numbers in the file names. Bazel doesn't
diff --git a/debian/matplotlib.BUILD b/debian/matplotlib.BUILD
new file mode 100644
index 0000000..208761a
--- /dev/null
+++ b/debian/matplotlib.BUILD
@@ -0,0 +1,115 @@
+genrule(
+    name = "patch_init",
+    srcs = [
+        "usr/lib/python2.7/dist-packages/matplotlib/__init__.py",
+        "@//debian:matplotlib_patches",
+    ],
+    outs = ["matplotlib/__init__.py"],
+    cmd = " && ".join([
+        "cp $(location usr/lib/python2.7/dist-packages/matplotlib/__init__.py) $@",
+        "readonly PATCH=\"$$(readlink -f $(location @patch))\"",
+        "readonly FILE=\"$$(readlink -f $(location @//debian:matplotlib_patches))\"",
+        "(cd $(@D) && \"$${PATCH}\" -p1 < \"$${FILE}\") > /dev/null",
+    ]),
+    tools = [
+        "@patch",
+    ],
+)
+
+_src_files = glob(
+    include = ["usr/lib/python2.7/dist-packages/**/*.py"],
+    exclude = [
+        "usr/lib/python2.7/dist-packages/matplotlib/__init__.py",
+    ],
+)
+
+_data_files = glob([
+    "usr/share/matplotlib/mpl-data/**",
+])
+
+_src_copied = ["/".join(f.split("/")[4:]) for f in _src_files]
+
+_builtin_so_files = glob([
+    "usr/lib/python2.7/dist-packages/**/*.x86_64-linux-gnu.so",
+])
+
+_system_so_files = glob([
+    "usr/lib/x86_64-linux-gnu/**/*.so*",
+    "lib/x86_64-linux-gnu/**/*.so*",
+])
+
+_builtin_so_copied = ["/".join(f.split("/")[4:]) for f in _builtin_so_files]
+
+_system_so_copied = ["rpathed/" + f for f in _system_so_files]
+
+_builtin_rpaths = [":".join([
+    "\\$$ORIGIN/%s" % rel,
+    "\\$$ORIGIN/%s/rpathed/usr/lib/x86_64-linux-gnu" % rel,
+    "\\$$ORIGIN/%s/rpathed/lib/x86_64-linux-gnu" % rel,
+]) for rel in ["/".join([".." for _ in so.split("/")[1:]]) for so in _builtin_so_copied]]
+
+_system_rpaths = [":".join([
+    "\\$$ORIGIN/%s/rpathed/usr/lib/x86_64-linux-gnu" % rel,
+    "\\$$ORIGIN/%s/rpathed/lib/x86_64-linux-gnu" % rel,
+]) for rel in ["/".join([".." for _ in so.split("/")[1:]]) for so in _system_so_copied]]
+
+genrule(
+    name = "run_patchelf_builtin",
+    srcs = _builtin_so_files,
+    outs = _builtin_so_copied,
+    cmd = "\n".join(
+        [
+            "cp $(location %s) $(location %s)" % (src, dest)
+            for src, dest in zip(_builtin_so_files, _builtin_so_copied)
+        ] +
+        ["$(location @patchelf) --set-rpath %s $(location %s)" % (rpath, so) for rpath, so in zip(_builtin_rpaths, _builtin_so_copied)],
+    ),
+    tools = [
+        "@patchelf",
+    ],
+)
+
+genrule(
+    name = "run_patchelf_system",
+    srcs = _system_so_files,
+    outs = _system_so_copied,
+    cmd = "\n".join(
+        [
+            "cp $(location %s) $(location %s)" % (src, dest)
+            for src, dest in zip(_system_so_files, _system_so_copied)
+        ] +
+        ["$(location @patchelf) --set-rpath %s $(location %s)" % (rpath, so) for rpath, so in zip(_system_rpaths, _system_so_copied)],
+    ),
+    tools = [
+        "@patchelf",
+    ],
+)
+
+genrule(
+    name = "copy_files",
+    srcs = _src_files,
+    outs = _src_copied,
+    cmd = " && ".join(["cp $(location %s) $(location %s)" % (src, dest) for src, dest in zip(
+        _src_files,
+        _src_copied,
+    )]),
+)
+
+genrule(
+    name = "create_empty_rc",
+    outs = ["usr/share/matplotlib/mpl-data/matplotlibrc"],
+    cmd = "touch $@",
+)
+
+py_library(
+    name = "matplotlib",
+    srcs = _src_copied + [
+        "matplotlib/__init__.py",
+    ],
+    data = _data_files + _builtin_so_copied + _system_so_copied + [
+        ":usr/share/matplotlib/mpl-data/matplotlibrc",
+    ],
+    imports = ["usr/lib/python2.7/dist-packages"],
+    restricted_to = ["@//tools:k8"],
+    visibility = ["//visibility:public"],
+)
diff --git a/debian/matplotlib.bzl b/debian/matplotlib.bzl
new file mode 100644
index 0000000..d54ba56
--- /dev/null
+++ b/debian/matplotlib.bzl
@@ -0,0 +1,76 @@
+files = {
+    "coreutils_8.23-4_amd64.deb": "6d3764c746887015c88c684aecc14dd1317eefeb76ba2acdf59d9ad5e4d97236",
+    "fontconfig-config_2.11.0-6.3+deb8u1_all.deb": "f7963c0338fd031101f3f684a4e37306eefcd05094220947dd9cb7388a2fe85f",
+    "fontconfig_2.11.0-6.3+deb8u1_amd64.deb": "5383eabf18c4c3dc3d581d1efea0e6ccbfd2c08a6a98cd3e6c491b1a99759375",
+    "fonts-dejavu-core_2.34-1_all.deb": "002c9fa9445cfec4964637f22c73265d8a868f0810104452a6c906af52e43dab",
+    "fonts-liberation_1.07.4-1_all.deb": "5490dd0b745bae9aa0c9a31ab75597229042d8fb45910ebbc21fe04f0cb1b87b",
+    "fonts-lyx_2.1.2-2_all.deb": "81b282c02eeec70568ffc25ae385abe81fd133270fc110258b965692ec7e5f09",
+    "libatk1.0-0_2.14.0-1_amd64.deb": "3c09c360031a4d251b294557ac3dd4365150c1bffd522b4a78ba9d93f6d3ab26",
+    "libatk1.0-data_2.14.0-1_all.deb": "fd3d0906bdb08b9d8db9458f29b3c24640ca56669d30d82b9db7c9d1abaf2535",
+    "libcairo2_1.14.0-2.1+deb8u2_amd64.deb": "5bb8028434e2ecbc75734bb7bd8ebc1f2f4d824834820c09729fd713b67ca0fe",
+    "libdatrie1_0.2.8-1_amd64.deb": "8f1c9f4acaaa7cbe8b742c16d3b7c261c42193ceefef927cdefeccfc2b92348d",
+    "libfontconfig1_2.11.0-6.3+deb8u1_amd64.deb": "0bb54d61c13aa5b5253cb5e08aaca0dfc4c626a05ee30f51d0e3002cda166fec",
+    "libfreetype6_2.5.2-3+deb8u2_amd64.deb": "58e384796f31cd582e6da200fad74d09f5aad968eb7a45c5c2fa202675660b46",
+    "libgdk-pixbuf2.0-0_2.31.1-2+deb8u7_amd64.deb": "eba768ee4828f41df9eaae59fc90b72ad215497b0bb6b7618202e93a35a8aab8",
+    "libgdk-pixbuf2.0-common_2.31.1-2+deb8u7_all.deb": "04cf3a42d105483677363328d074c2a72bed3e782606e489d3b8b90723bedc47",
+    "libglib2.0-0_2.42.1-1+b1_amd64.deb": "a4b30c84c0c050f23a986fbc576daa04b246ab816ec0fcb0b471d19aa2689a97",
+    "libgraphite2-3_1.3.10-1~deb8u1_amd64.deb": "49e1434c15e17654714b7f158d75d8a8a2f0bef7c7d1f7eb9e6f1c55ec69c598",
+    "libgtk2.0-0_2.24.25-3+deb8u2_amd64.deb": "f3552042a360d44f8a7424a27f517efd755d665bc83d6fc99b55a19c942843bc",
+    "libgtk2.0-common_2.24.25-3+deb8u2_all.deb": "8288a823731cdd165bf6d04b6e047cb4b702f732738f652af365821957ac7c47",
+    "libharfbuzz0b_0.9.35-2_amd64.deb": "24cb370d0dab9769ab1cce6a8362e5a785152b253319789ac6d2420f1ce42185",
+    "libjasper1_1.900.1-debian1-2.4+deb8u3_amd64.deb": "a0887eb2f617ac0031ba195fd00119c85f3c20eb9d9670b2dc2d93e75faf1de9",
+    "libjbig0_2.1-3.1_amd64.deb": "d0b55e2da6648d6b91ced51e8c8ccfbe024283ffbbc1484f704ff7b0c97f8c51",
+    "libjpeg62-turbo_1.3.1-12_amd64.deb": "ac397a0c8d16891dbc0348a9ee30506b8b4cafe138a25b3af9e3cd0b417fab3d",
+    "libjs-jquery-ui_1.10.1+dfsg-1_all.deb": "4433e948caa120c7d92574b292491b3e1924d761d091f1144adda5cacacb012c",
+    "libjs-jquery_1.7.2+dfsg-3.2_all.deb": "e1a43ad00bc8b0d469544ddc2f11573fba9beda9d1b09c4ffd946fcdbf6cd1e4",
+    "libpango-1.0-0_1.36.8-3_amd64.deb": "54c29cbec70cc2dc45affb3cece358e6a8c57c0c4c4a1690f3adac472c8ee24c",
+    "libpangocairo-1.0-0_1.36.8-3_amd64.deb": "c088f8e9ce755eed168ff1e5be789252cadd4199070f2df703acb41742d90186",
+    "libpangoft2-1.0-0_1.36.8-3_amd64.deb": "30f34db7a73ac7e1b8f2945ac1b5d34e649beb2fa71b2232c0ccde0ca19e697d",
+    "libpixman-1-0_0.32.6-3_amd64.deb": "dfce4b6483c5704da051bc7da6aee76c025bf8a093212be122e956d7a8ea4c64",
+    "libpng12-0_1.2.50-2+deb8u3_amd64.deb": "fa86f58f9595392dc078abe3b446327089c47b5ed8632c19128a156a1ea68b96",
+    "libtcl8.6_8.6.2+dfsg-2_amd64.deb": "79124f4bde0867e63db1466d9ba9bbf7650f2e2f15c64e8bf1fe2dac42b98221",
+    "libthai-data_0.1.21-1_all.deb": "805c372a6f0da8e487933638cf74d969626175d2f77682691bd5c74b3bc02168",
+    "libthai0_0.1.21-1_amd64.deb": "992e35bf8c1685ba1cb439a99a78db72c7960075cb25cf3175d67f782cbb75c3",
+    "libtiff5_4.0.3-12.3+deb8u6_amd64.deb": "73f4e28cd270d59698feb45564fb73329eef645c645218420d600d7e13115b84",
+    "libtk8.6_8.6.2-1_amd64.deb": "c8bf4cffca2af331cd323c88e68ac1e90f48b08de24813f6b24308b18977d396",
+    "libx11-6_1.6.2-3+deb8u1_amd64.deb": "380aa38372e949f74b57e962146626aae847850ed4f1fcb83784086f239d50c3",
+    "libx11-data_1.6.2-3+deb8u1_all.deb": "4879a3054d6508e86f737bf668737c3fc64980c3512b2912f18bceea823e1899",
+    "libxau6_1.0.8-1_amd64.deb": "b03b2d0d400c2002a2d38300bd6630306abb0ff325c3d4a4447ecceb58335228",
+    "libxcb-render0_1.10-3+b1_amd64.deb": "1277261ed3b901d70b01901836b2f6d89235dd6777636f3f26b5d2979f1c7e22",
+    "libxcb-shm0_1.10-3+b1_amd64.deb": "724749f2ea6a471ba353f6a93585bf98577c2103648297fac40c46b9a08671b0",
+    "libxcb1_1.10-3+b1_amd64.deb": "07bf131f4f0f8a9f1a023ab88cce3a1d12cc7222d3c7f08f00b60a3699af5188",
+    "libxcomposite1_0.4.4-1_amd64.deb": "ff739711c5aa6df107fdfb6e13491e8317b2c45477d91a6b17da5660cd8ca8f4",
+    "libxcursor1_1.1.14-1+deb8u1_amd64.deb": "31c05ccd419d5c255643e3d21c871204e154a06af25300c2bd2b721989d038f0",
+    "libxdamage1_1.1.4-2+b1_amd64.deb": "c2b13deaa87dbad7d541e29755464f125409b9d4d038d6982bb9f8f35939b817",
+    "libxdmcp6_1.1.1-1+b1_amd64.deb": "6758bc820616254634fdd2354a2691e40d2973d6bf3a9c12417f02770f75081c",
+    "libxext6_1.3.3-1_amd64.deb": "5105f77289a7e08faaf3bb4c16c6945cafca65b9bdb4792fef820045ab43e568",
+    "libxfixes3_5.0.1-2+deb8u1_amd64.deb": "bc30bf139964c7505776374c7ba8a7f9bd7c6bd101823f3d6a1f3b0bf11e41ee",
+    "libxft2_2.3.2-1_amd64.deb": "38d6013c0b6305caf38932e6274108d81b2b2df0dd67f04987aa3f69c1e6677e",
+    "libxi6_1.7.4-1+deb8u1_amd64.deb": "a99de627a07f54bc40e5dc77e3ca7e9d9b5619e068f1bb303f86edd138d6d037",
+    "libxinerama1_1.1.3-1+b1_amd64.deb": "3668c1178ac649879338192759e79879e0f5797764b448dcac6aed4b24ef495b",
+    "libxml2_2.9.1+dfsg1-5+deb8u6_amd64.deb": "23c9e795d10443baf09fce7bcc007790f9c19597313fab3ff9691f7100fd0419",
+    "libxrandr2_1.4.2-1+deb8u1_amd64.deb": "e59996ac0e993331799aa7bc768f7edd7b0baec0fafdbeebeef658834ba96b63",
+    "libxrender1_0.9.8-1+b1_amd64.deb": "8980934c84c0ebbca4158023d91ced3ddbfa028a2be25959ff4566b37eceb8f4",
+    "libxss1_1.2.2-1_amd64.deb": "0f2fc4eff464b63a4fafed9ab2e499e1804dcee85c5d9a89e53c3ed6a2a06b88",
+    "python-dateutil_2.2-2_all.deb": "273f6761faa7ff230c20389df81d312aeeeafd3e02076587ebd5779279683b07",
+    "python-matplotlib-data_1.4.2-3.1_all.deb": "6312cca3ff7f26faa030807d051a807537df85ba7e4d24ec01eabd6e6344b842",
+    "python-matplotlib_1.4.2-3.1_amd64.deb": "27495f6ede9dc7ecbc2cbfabd15ec0013dcaf0a2bac48e809c8cfbd2baadd212",
+    "python-mock_1.0.1-3_all.deb": "c7b7c2c49645ba52b59c302148d9daf67f24183060eeb02c92d9618855641b2a",
+    "python-nose_1.3.4-1_all.deb": "832d36732f2dc645f53018343e8f97f8f00fd2e3c4a1f3a79efae7721e77ebeb",
+    "python-pkg-resources_5.5.1-1_all.deb": "a6d6963f9a1943aee463356e462f7f5283938da6e810940514c1b6c8b8496595",
+    "python-pyparsing_2.0.3+dfsg1-1_all.deb": "b8051ce4e3108f52c9ee6137ce5c2175ac64a81782a3249dbfe1f75e409e5978",
+    "python-six_1.8.0-1_all.deb": "15e635be0154af9232cb30b10df8c598a274a9b55bbe5c0355aff51cc1e63e88",
+    "python-tz_2012c+dfsg-0.1_all.deb": "cb240ad52f4f5e225b7366fab31257664a7b2a50d1bf339c3cd9fdcf0b9e34f6",
+    "python3-dateutil_2.2-2_all.deb": "f64d71bddfe4d8ee3ec602495605f79b36c217e61192a35fe2f168f63cea2006",
+    "python3-matplotlib_1.4.2-3.1_amd64.deb": "38314c38dcef9332b5b76b32f4207bb0e84188f21ca8e4df5cc2e7895e08b0c8",
+    "python3-nose_1.3.4-1_all.deb": "ea1fda128fc2eeaf8a80032afce6243417ef29f347121bf106ff3c92506e873b",
+    "python3-pkg-resources_5.5.1-1_all.deb": "f50c5bf7a75a5b563e1f1e9f96a386b1bed2fe5cae3f2d75eaf3541d9e4356e0",
+    "python3-pyparsing_2.0.3+dfsg1-1_all.deb": "52cc4f70a94f4a031dee68173dc246d2a373afd9a57a82b246412025eff32441",
+    "python3-six_1.8.0-1_all.deb": "33f8c63f7a50c2e002ed33d482dbadd7eebd24b02c7ef8e7aa56758394eac152",
+    "python3-tz_2012c+dfsg-0.1_all.deb": "add2d6e1afd92c106d61d09854316ccab73931442b54298df0269899ee9a834c",
+    "python_2.7.9-1_amd64.deb": "93dc9d03df366d658832fb238a6c1e6c57e5e57dd648145c2f57a8f3e2b419ed",
+    "shared-mime-info_1.3-1_amd64.deb": "50c122e36f96e5cc808c6b7528ebd27f8086783e2c5b7c39ac7f6da6f62b09c1",
+    "ttf-bitstream-vera_1.10-8_all.deb": "328def7f581bf94b3b06d21e641f3e5df9a9b2e84e93b4206bc952fe8e80f38a",
+    "tzdata_2018e-0+deb8u1_all.deb": "124fe7da8988d0779be3c1883e7de00742ed46464f5f94616d5222cd16f9537a",
+    "ucf_3.0030_all.deb": "1b93d9fc5930b9d8382705b71605e07fe11f4796db239b7ac2644bf4fbd7f6a2",
+}
diff --git a/debian/matplotlib_init.patch b/debian/matplotlib_init.patch
new file mode 100644
index 0000000..11a3ad8
--- /dev/null
+++ b/debian/matplotlib_init.patch
@@ -0,0 +1,32 @@
+--- a/__init__.py	2018-07-11 15:57:58.086509489 -0700
++++ b/__init__.py	2018-07-11 16:04:15.004795500 -0700
+@@ -102,6 +102,7 @@
+ from __future__ import (absolute_import, division, print_function,
+                         unicode_literals)
+ 
++import os
+ import six
+ import sys
+ import distutils.version
+@@ -110,6 +111,21 @@
+ __version__ = str('1.4.2')
+ __version__numpy__ = str('1.6')  # minimum required numpy version
+ 
++matplotlib_base = os.path.dirname(os.path.dirname(__file__))
++
++# Hack to point matplotlib at its data.
++os.environ['MATPLOTLIBDATA'] = \
++        os.path.join( \
++            matplotlib_base,
++            "usr", "share", "matplotlib", "mpl-data")
++# Avoid reading /etc/matplotlib in all cases. Matplotlib is pretty happy to
++# escape the sandbox by using absolute paths.
++os.environ['MATPLOTLIBRC'] = os.environ['MATPLOTLIBDATA']
++# There's a bug where the temp directory gets set if MATPLOTLIBRC isn't set.
++# That causes the directory to not be created in time. We set the variable
++# manually here to work around the bug.
++os.environ['MPLCONFIGDIR'] = '/tmp/matplotlib-nobody'
++
+ try:
+     import dateutil
+ except ImportError:
diff --git a/debian/patchelf.BUILD b/debian/patchelf.BUILD
new file mode 100644
index 0000000..423de57
--- /dev/null
+++ b/debian/patchelf.BUILD
@@ -0,0 +1,5 @@
+filegroup(
+    name = "patchelf",
+    srcs = ["usr/bin/patchelf"],
+    visibility = ["//visibility:public"],
+)
diff --git a/debian/patchelf.bzl b/debian/patchelf.bzl
new file mode 100644
index 0000000..d5cc127
--- /dev/null
+++ b/debian/patchelf.bzl
@@ -0,0 +1,4 @@
+files = {
+    "libstdc++6_4.9.2-10+deb8u1_amd64.deb": "a8f4ef6773b90bb39a8a8a0a5e3e20ca8501de6896204f665eb114d5b79f164f",
+    "patchelf_0.8-2_amd64.deb": "5d506507df7c02766ae6c3ca0d15b4234f4cb79a80799190ded9d3ca0ac28c0c",
+}
diff --git a/debian/python.BUILD b/debian/python.BUILD
index 084f198..666f2d8 100644
--- a/debian/python.BUILD
+++ b/debian/python.BUILD
@@ -1,66 +1,97 @@
-package(default_visibility = ['@//debian:__pkg__'])
+package(default_visibility = ["@//debian:__pkg__"])
 
 cc_library(
-  name = 'python3.4_lib',
-  hdrs = glob(['usr/include/python3.4m/**/*.h']),
-  includes = [
-    'usr/include/python3.4m/',
-  ],
-  visibility = ['//visibility:public'],
+    name = "python3.4_lib",
+    hdrs = glob(["usr/include/python3.4m/**/*.h"]),
+    includes = [
+        "usr/include/python3.4m/",
+    ],
+    visibility = ["//visibility:public"],
 )
 
 cc_library(
-  name = 'python3.4_f2py',
-  srcs = [
-    'usr/lib/python3/dist-packages/numpy/f2py/src/fortranobject.c',
-  ],
-  hdrs = [
-    'usr/lib/python3/dist-packages/numpy/f2py/src/fortranobject.h',
-  ],
-  copts = [
-    '-Wno-error',
-    '-Wno-parentheses-equality',
-  ],
-  includes = [
-    'usr/lib/python3/dist-packages/numpy/f2py/src/',
-  ],
-  deps = [
-    ':python3.4_lib',
-  ],
-  visibility = ['//visibility:public'],
+    name = "python3.4_f2py",
+    srcs = [
+        "usr/lib/python3/dist-packages/numpy/f2py/src/fortranobject.c",
+    ],
+    hdrs = [
+        "usr/lib/python3/dist-packages/numpy/f2py/src/fortranobject.h",
+    ],
+    copts = [
+        "-Wno-error",
+        "-Wno-parentheses-equality",
+    ],
+    includes = [
+        "usr/lib/python3/dist-packages/numpy/f2py/src/",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":python3.4_lib",
+    ],
 )
 
 cc_library(
-  name = 'python2.7_lib',
-  hdrs = glob([
-    'usr/include/**/*.h',
-  ]),
-  srcs = [
-    'usr/lib/x86_64-linux-gnu/libpython2.7.so',
-  ],
-  includes = [
-    'usr/include/',
-    'usr/include/python2.7/',
-  ],
-  visibility = ['//visibility:public'],
+    name = "python2.7_lib",
+    srcs = [
+        "usr/lib/x86_64-linux-gnu/libpython2.7.so",
+    ],
+    hdrs = glob([
+        "usr/include/**/*.h",
+    ]),
+    includes = [
+        "usr/include/",
+        "usr/include/python2.7/",
+    ],
+    visibility = ["//visibility:public"],
 )
 
 cc_library(
-  name = 'python2.7_f2py',
-  srcs = [
-    'usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.c',
-  ],
-  hdrs = [
-    'usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.h',
-  ],
-  copts = [
-    '-Wno-error',
-  ],
-  includes = [
-    'usr/lib/python2.7/dist-packages/numpy/f2py/src/',
-  ],
-  deps = [
-    ':python2.7_lib',
-  ],
-  visibility = ['//visibility:public'],
+    name = "python2.7_f2py",
+    srcs = [
+        "usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.c",
+    ],
+    hdrs = [
+        "usr/lib/python2.7/dist-packages/numpy/f2py/src/fortranobject.h",
+    ],
+    copts = [
+        "-Wno-error",
+    ],
+    includes = [
+        "usr/lib/python2.7/dist-packages/numpy/f2py/src/",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":python2.7_lib",
+    ],
+)
+
+filegroup(
+    name = "all_files",
+    srcs = glob(["**"]),
+    visibility = ["//visibility:public"],
+)
+
+genrule(
+    name = "copy_f2py",
+    srcs = ["usr/bin/f2py"],
+    outs = ["f2py.py"],
+    cmd = "cp $< $@",
+    executable = True,
+)
+
+py_binary(
+    name = "f2py",
+    srcs = ["f2py.py"],
+    visibility = ["//visibility:public"],
+)
+
+filegroup(
+    name = "scipy",
+    srcs = glob([
+        "usr/lib/python3/dist-packages/numpy",
+        "usr/lib/python3/dist-packages/scipy",
+        "usr/lib/python2.7/dist-packages/numpy",
+        "usr/lib/python2.7/dist-packages/scipy",
+    ]),
+    visibility = ["//visibility:public"],
 )
diff --git a/debian/python.bzl b/debian/python.bzl
index 2dc677f..ffecc8d 100644
--- a/debian/python.bzl
+++ b/debian/python.bzl
@@ -6,10 +6,10 @@
     "libexpat1-dev_2.1.0-6+deb8u4_amd64.deb": "6b4231b09a96933ff25aae9b68eaaa3b9252b82ca2fd37eccbe2a7823ea6d9ed",
     "libexpat1_2.1.0-6+deb8u4_amd64.deb": "de7979297d0298271d71b4554772ba4da60ba6895ed86ca8fc9c1159c58913e4",
     "libffi6_3.1-2+deb8u1_amd64.deb": "100343fca79ff265abc62467c7085fca68b8764e8c2551302ab741c771e7f0aa",
-    "libgfortran3_4.9.2-10_amd64.deb": "77798b64f1f042daca070e3edead2658ffed6a9dcf888ba8e22f6f140012510c",
+    "libgfortran3_4.9.2-10+deb8u1_amd64.deb": "05dc518146a4689e33d5f41c7b40a8861ad70b1ab6de018c48be6c929d0683d0",
     "liblapack3_3.5.0-4_amd64.deb": "d5b06e70f99ca0389b29b334a6d30d7ecddd08d2d11d0cb0b9bdcf7e230ce1f7",
     "libmpdec2_2.4.1-1_amd64.deb": "b61ae05899abfb6b82af1915e33ae72e0b7caf8035416fbbcb8128832fcb26d2",
-    "libncursesw5_5.9+20140913-1+deb8u2_amd64.deb": "9d8d80d077e0ca85ac4493173431df42fe8943a457bac35625433eb414d79eca",
+    "libncursesw5_5.9+20140913-1+deb8u3_amd64.deb": "7e2fe0b132724013c13751189338c22858f62db3c9f2268f03608ca7b01f3b8d",
     "libpython-dev_2.7.9-1_amd64.deb": "de5b306431959a50a8368f292157ee573aac86fa7e88cacd6b03983cf85570c4",
     "libpython-stdlib_2.7.9-1_amd64.deb": "5f9ffb96222498c764526a83cac48281a941ec6e8470db1a1f8e17e6236a5669",
     "libpython2.7-dev_2.7.9-2+deb8u1_amd64.deb": "af8754ad818d600d39cf6ab878f5afeb7265fa51da44487f21ab06e7df6462cd",
@@ -22,21 +22,26 @@
     "libpython3.4-minimal_3.4.2-1_amd64.deb": "d4c9fa2e127ca7799930152aedc37c3d891e0ee439e0595f0a654678570bfa34",
     "libpython3.4-stdlib_3.4.2-1_amd64.deb": "afa4d641e50b5671230f92f2a8bcf8ee961fbb54c9c3a9656a8ec9fd0391765b",
     "libpython3.4_3.4.2-1_amd64.deb": "089d804a6432d7a321cfd5a95d191251fa3a0d324451981e29ff695f765b5c06",
-    "libquadmath0_4.9.2-10_amd64.deb": "76b71fdb834434e7b6dde5ba343af9bacddb987ef8ad9c788442dbe4e236e78f",
+    "libquadmath0_4.9.2-10+deb8u1_amd64.deb": "7e3779d41a42a88621f93c47a77874547b266b7c8166c80e254721e8347c3355",
     "libreadline6_6.3-8+b3_amd64.deb": "647948737fcfea4749368aa233b2d8b89032546ba4db2f0338239e9a7f4bda3e",
     "libsqlite3-0_3.8.7.1-1+deb8u2_amd64.deb": "969b13188c642196def3846e1e44e7923bcf1fa07374b0fd7fe766ea2ba11bd0",
-    "libssl1.0.0_1.0.1t-1+deb8u7_amd64.deb": "d99de2cdca54484d23badc5683c7211b3a191977272d9e5281837af863dcdd56",
-    "libtinfo5_5.9+20140913-1+deb8u2_amd64.deb": "914cb3f1f52425ecd92c44aacdb3b1303b57db783ad53910c2bb1725a56ffbaf",
+    "libssl1.0.0_1.0.1t-1+deb8u8_amd64.deb": "3915d91e7f7d8c89360fd897d8bf0e2cf21d34f2b23edb97a7fa74d90fcf25b7",
+    "libstdc++6_4.9.2-10+deb8u1_amd64.deb": "a8f4ef6773b90bb39a8a8a0a5e3e20ca8501de6896204f665eb114d5b79f164f",
+    "libtinfo5_5.9+20140913-1+deb8u3_amd64.deb": "36a0f120da15f82c0c729535ac48d95e126c5d7fc2c4aceb94bf27ced5a4cecc",
     "mime-support_3.58_all.deb": "c05ebe8f38da4ff19d028c9f4680414149e5c7a746de13bc9db0a562796ed213",
+    "python-decorator_3.4.0-2_all.deb": "6ee71dc6bab959dab9ceb92a497256729c785606246e8cbc94b7a535fa56efca",
     "python-dev_2.7.9-1_amd64.deb": "402f2b3185fb83be92e9d13a08ed1f7678adf72c8bade7ccdec2d47d3321c5ae",
     "python-minimal_2.7.9-1_amd64.deb": "58649e19c19847e264b32ad8cb5a8f58477829e1afc2616c54cb0a1ef30496be",
     "python-numpy_1.8.2-2_amd64.deb": "598926db22f9f16a3f0597fdfcbdc3c271ef4991223ca3166bd5dbcb775a7831",
+    "python-scipy_0.14.0-2_amd64.deb": "6759ad925182c164a0474ecb189afdf6da2c1df4a158dabb7c8ebb075f5d0a40",
     "python2.7-dev_2.7.9-2+deb8u1_amd64.deb": "1d423c1f15f9ac0cf3d3c69958cc93cc7b673d39ac9200c1de84b82eb4be4a8d",
     "python2.7-minimal_2.7.9-2+deb8u1_amd64.deb": "c89199f908d5a508d8d404efc0e1aef3d9db59ea23bd4532df9e59941643fcfb",
     "python2.7_2.7.9-2+deb8u1_amd64.deb": "00c99c8dc1cda85053c8bfc7ea34ae5c40408c54b498ca22d0e2cb6b0acb796c",
+    "python3-decorator_3.4.0-2_all.deb": "7417249601d0c3a3961b27a1a054f407bd3a85019622b1ad112ea4f73d884fae",
     "python3-dev_3.4.2-2_amd64.deb": "c94a0b57c74e6158cde842e6376ee614fbefb380ab1e1bbed66b176b87090ed5",
     "python3-minimal_3.4.2-2_amd64.deb": "0a8f9f1e824929d6c7412538e1a7fa4f56c8d68565cf3aba3cbefe05a4187c8b",
     "python3-numpy_1.8.2-2_amd64.deb": "7e514578bee0eabee43915185d73526b0e28b912a31aa665920fbec16db380fc",
+    "python3-scipy_0.14.0-2_amd64.deb": "20677d39429321722c56b98e171c01c590f16f17ef5a6833ca0573fa5de045d2",
     "python3.4-dev_3.4.2-1_amd64.deb": "bc20dad65f0c37c712d612e247a8510888cbc97568659a00b45b2a0915e4e4b4",
     "python3.4-minimal_3.4.2-1_amd64.deb": "a2c868cd2deaa8467aa6fb4bfc2ff17001418de163195a86d02ae16c656ec373",
     "python3.4_3.4.2-1_amd64.deb": "398a1bf2c0c7c8f7271b9150b8db61f225c424b96fe2befcac9abea76a793d74",
diff --git a/debian/slycot.BUILD b/debian/slycot.BUILD
index 9853c40..368b87d 100644
--- a/debian/slycot.BUILD
+++ b/debian/slycot.BUILD
@@ -1,7 +1,7 @@
 # TODO(austin): I bet this is wrong.
-licenses(['restricted'])
+licenses(["restricted"])
 
-load('@//tools/build_rules:fortran.bzl', 'f2c_library')
+load("@//tools/build_rules:fortran.bzl", "f2c_library")
 
 # We can't create _wrapper.so in the slycot folder, and can't move it.
 # The best way I found to do this is to modify _wrapper.pyf to instead generate
@@ -9,17 +9,17 @@
 # which loads _fortranwrapper from the correct location.  This means that I
 # don't need to modify the repository.
 genrule(
-  name = '_fortranwrapper_pyf',
-  srcs = ['slycot/src/_wrapper.pyf'],
-  outs = ['slycot/src/_fortranwrapper.pyf'],
-  cmd = 'cat $(SRCS) | sed \'s/_wrapper/_fortranwrapper/\' > $(OUTS)',
-  restricted_to = ['@//tools:k8'],
+    name = "_fortranwrapper_pyf",
+    srcs = ["slycot/src/_wrapper.pyf"],
+    outs = ["slycot/src/_fortranwrapper.pyf"],
+    cmd = "cat $(SRCS) | sed 's/_wrapper/_fortranwrapper/' > $(OUTS)",
+    restricted_to = ["@//tools:k8"],
 )
 
 # The contents of the file telling f2py how to translate various types. The
 # format doesn't seem to be very well-documented, but this seems to make all the
 # argument types match up.
-_f2py_f2cmap_contents = '''{
+_f2py_f2cmap_contents = """{
 "integer": {
   "check m>=0": "long",
   "check n>=0": "long",
@@ -29,112 +29,115 @@
 "logical": {
   "": "long",
 },
-}'''
+}"""
 
 # Now generate the module wrapper.
 genrule(
-  name = '_fortranwrappermodule',
-  srcs = [
-    'slycot/src/analysis.pyf',
-    'slycot/src/synthesis.pyf',
-    'slycot/src/_fortranwrapper.pyf',
-    'slycot/src/math.pyf',
-    'slycot/src/transform.pyf',
-  ],
-  outs = ['_fortranwrappermodule.c'],
-  cmd = '\n'.join([
-    'cat > .f2py_f2cmap <<END',
-    _f2py_f2cmap_contents,
-    'END',
-    'readlink -f .f2py_f2cmap',
-    ' '.join([
-      '/usr/bin/python',
-      '/usr/bin/f2py',
-      '$(location :slycot/src/_fortranwrapper.pyf)',
-      '--include-paths external/slycot_repo/slycot/src/',
-      '--coutput $(OUTS)',
+    name = "_fortranwrappermodule",
+    srcs = [
+        "slycot/src/analysis.pyf",
+        "slycot/src/synthesis.pyf",
+        "slycot/src/_fortranwrapper.pyf",
+        "slycot/src/math.pyf",
+        "slycot/src/transform.pyf",
+    ],
+    outs = ["_fortranwrappermodule.c"],
+    cmd = "\n".join([
+        "cat > .f2py_f2cmap <<END",
+        _f2py_f2cmap_contents,
+        "END",
+        "readlink -f .f2py_f2cmap",
+        " ".join([
+            "$(location @python_repo//:f2py)",
+            "$(location :slycot/src/_fortranwrapper.pyf)",
+            "--include-paths external/slycot_repo/slycot/src/",
+            "--coutput $(OUTS)",
+        ]),
+        " ".join([
+            "sed",
+            "\"s/Generation date.*/Generation date: redacted/\"",
+            "-i $(OUTS)",
+        ]),
     ]),
-    ' '.join([
-      'sed',
-      '"s/Generation date.*/Generation date: redacted/"',
-      '-i $(OUTS)',
-    ]),
-  ]),
-  restricted_to = ['@//tools:k8'],
+    restricted_to = ["@//tools:k8"],
+    tools = [
+        "@python_repo//:f2py",
+    ],
 )
 
 # Build it.
 cc_library(
-  name = 'slycot_c',
-  srcs = [
-    ':_fortranwrappermodule',
-  ],
-  deps = [
-    ':slicot',
-    '@python_repo//:python2.7_lib',
-    '@python_repo//:python2.7_f2py',
-  ],
-  copts = [
-    '-Wno-error',
-    '-Wno-incompatible-pointer-types-discards-qualifiers',
-    '-Wno-cast-align',
-    '-Wno-unused-parameter',
-    '-Wno-missing-field-initializers',
-    '-Wno-unused-function',
-  ],
-  restricted_to = ['@//tools:k8'],
+    name = "slycot_c",
+    srcs = [
+        ":_fortranwrappermodule",
+    ],
+    copts = [
+        "-Wno-error",
+        "-Wno-incompatible-pointer-types-discards-qualifiers",
+        "-Wno-cast-align",
+        "-Wno-unused-parameter",
+        "-Wno-missing-field-initializers",
+        "-Wno-unused-function",
+    ],
+    restricted_to = ["@//tools:k8"],
+    deps = [
+        ":slicot",
+        "@python_repo//:python2.7_f2py",
+        "@python_repo//:python2.7_lib",
+    ],
 )
 
-# Link it all together.  Make sure it is dynamically linked so it can be
-# loaded by the Python interpreter.
+# Link it all together.  Make sure all the deps get static linked into a single
+# shared object, which will then be loaded by the Python interpreter.
 cc_binary(
-  name = '_fortranwrapper.so',
-  deps = [
-    ':slicot',
-    ':slycot_c',
-  ],
-  linkstatic = False,
-  linkshared = True,
-  restricted_to = ['@//tools:k8'],
+    name = "slycot/_fortranwrapper.so",
+    linkshared = True,
+    linkstatic = True,
+    restricted_to = ["@//tools:k8"],
+    deps = [
+        ":slicot",
+        ":slycot_c",
+    ],
 )
 
 # Generate the _wrapper file which loads _fortranwrapper and pretends.
 genrule(
-  name = '_wrapper',
-  outs = ['slycot/_wrapper.py'],
-  cmd = 'echo "from external.slycot_repo._fortranwrapper import *" > $(OUTS)',
-  output_to_bindir = True,
+    name = "_wrapper",
+    outs = ["slycot/_wrapper.py"],
+    cmd = "echo \"from slycot._fortranwrapper import *\" > $(OUTS)",
+    output_to_bindir = True,
 )
 
 # Now present a python library for slycot
 py_library(
-  name = 'slycot',
-  srcs = [
-    'slycot/analysis.py',
-    'slycot/examples.py',
-    'slycot/__init__.py',
-    'slycot/math.py',
-    'slycot/synthesis.py',
-    'slycot/transform.py',
-    ':_wrapper',
-  ],
-  data = [
-    ':_fortranwrapper.so',
-  ],
-  visibility = ['//visibility:public'],
-  restricted_to = ['@//tools:k8'],
+    name = "slycot",
+    srcs = [
+        "slycot/__init__.py",
+        "slycot/analysis.py",
+        "slycot/examples.py",
+        "slycot/math.py",
+        "slycot/synthesis.py",
+        "slycot/transform.py",
+        ":_wrapper",
+    ],
+    data = [
+        ":slycot/_fortranwrapper.so",
+    ],
+    imports = ["."],
+    restricted_to = ["@//tools:k8"],
+    visibility = ["//visibility:public"],
 )
 
 f2c_library(
-  name = 'slicot',
-  visibility = ['//visibility:public'],
-  srcs = glob(['slycot/src/*.f']),
-  copts = [
-    # This gets triggered because it doesn't realize xerbla doesn't return.
-    # TODO(Brian): Try and get __attribute__((noreturn)) on xerbla somehow.
-    '-Wno-uninitialized',
-  ],
-  deps = [
-    '@clapack',
-  ],
+    name = "slicot",
+    srcs = glob(["slycot/src/*.f"]),
+    copts = [
+        # This gets triggered because it doesn't realize xerbla doesn't return.
+        # TODO(Brian): Try and get __attribute__((noreturn)) on xerbla somehow.
+        "-Wno-uninitialized",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "@clapack",
+    ],
 )
diff --git a/frc971/BUILD b/frc971/BUILD
index 46317d3..563f05e 100644
--- a/frc971/BUILD
+++ b/frc971/BUILD
@@ -16,3 +16,9 @@
         "constants.h",
     ],
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+)
diff --git a/frc971/__init__.py b/frc971/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/frc971/__init__.py
diff --git a/frc971/control_loops/BUILD b/frc971/control_loops/BUILD
index 4951d86..7c39a85 100644
--- a/frc971/control_loops/BUILD
+++ b/frc971/control_loops/BUILD
@@ -68,14 +68,14 @@
     hdrs = [
         "position_sensor_sim.h",
     ],
+    linkopts = [
+        "-lm",
+    ],
     deps = [
         ":gaussian_noise",
         ":queues",
         "//aos/testing:random_seed",
     ],
-    linkopts = [
-        "-lm",
-    ],
 )
 
 cc_library(
@@ -114,13 +114,13 @@
     hdrs = [
         "coerce_goal.h",
     ],
+    linkopts = [
+        "-lm",
+    ],
     deps = [
         "//aos/common/controls:polytope",
         "//third_party/eigen",
     ],
-    linkopts = [
-        "-lm",
-    ],
 )
 
 # TODO(austin): Select isn't working right.  We should be able to remove
@@ -257,3 +257,10 @@
         "@slycot_repo//:slicot",
     ],
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//frc971:python_init"],
+)
diff --git a/frc971/control_loops/__init__.py b/frc971/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/frc971/control_loops/__init__.py
diff --git a/frc971/control_loops/python/BUILD b/frc971/control_loops/python/BUILD
index 64201c4..fb3e971 100644
--- a/frc971/control_loops/python/BUILD
+++ b/frc971/control_loops/python/BUILD
@@ -1,79 +1,98 @@
-package(default_visibility = ['//visibility:public'])
+package(default_visibility = ["//visibility:public"])
 
 py_binary(
-  name = 'haptic_wheel',
-  srcs = [
-    'haptic_wheel.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "haptic_wheel",
+    srcs = [
+        "haptic_wheel.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_library(
-  name = 'controls',
-  srcs = [
-    'cim.py',
-    'control_loop.py',
-    'controls.py',
-    'polytope.py',
-    'libcdd.py',
-  ],
-  deps = [
-    '//external:python-glog',
-    '@slycot_repo//:slycot',
-  ],
-  data = [
-    '//third_party/cddlib:_cddlib.so',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "controls",
+    srcs = [
+        "cim.py",
+        "control_loop.py",
+        "controls.py",
+        "libcdd.py",
+        "polytope.py",
+    ],
+    data = [
+        "//third_party/cddlib:_cddlib.so",
+        "@python_repo//:scipy",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-glog",
+        "@slycot_repo//:slycot",
+    ],
 )
 
 py_test(
-  name = 'polytope_test',
-  srcs = [
-    'polytope_test.py',
-  ],
-  deps = [
-    ':controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polytope_test",
+    srcs = [
+        "polytope_test.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":controls",
+        ":python_init",
+    ],
 )
 
 py_binary(
-  name = 'down_estimator',
-  srcs = [
-    'down_estimator.py',
-  ],
-  deps = [
-    ':controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "down_estimator",
+    srcs = [
+        "down_estimator.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":controls",
+        ":python_init",
+        "@matplotlib",
+    ],
 )
 
 py_library(
-  name = 'drivetrain',
-  srcs = [
-    'drivetrain.py',
-  ],
-  deps = [
-    ':controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "drivetrain",
+    srcs = [
+        "drivetrain.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":controls",
+        ":python_init",
+        "@matplotlib",
+    ],
 )
 
 py_library(
-  name = 'polydrivetrain',
-  srcs = [
-    'polydrivetrain.py',
-  ],
-  deps = [
-    ':controls',
-    ':drivetrain',
-    '//external:python-glog',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain",
+    srcs = [
+        "polydrivetrain.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":controls",
+        ":drivetrain",
+        ":python_init",
+        "//external:python-glog",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//frc971/control_loops:python_init"],
 )
diff --git a/frc971/control_loops/python/__init__.py b/frc971/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/frc971/control_loops/python/__init__.py
diff --git a/motors/BUILD b/motors/BUILD
index 395765e..a1375f4 100644
--- a/motors/BUILD
+++ b/motors/BUILD
@@ -148,3 +148,9 @@
     name = "simple_receiver",
     restricted_to = mcu_cpus,
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+)
diff --git a/motors/__init__.py b/motors/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/motors/__init__.py
diff --git a/motors/python/BUILD b/motors/python/BUILD
index 408f3cd..903b397 100644
--- a/motors/python/BUILD
+++ b/motors/python/BUILD
@@ -3,8 +3,10 @@
     srcs = [
         "big_phase_current.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:controls",
@@ -16,10 +18,19 @@
     srcs = [
         "haptic_phase_current.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:controls",
     ],
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//motors:python_init"],
+)
diff --git a/motors/python/__init__.py b/motors/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/motors/python/__init__.py
diff --git a/motors/seems_reasonable/BUILD b/motors/seems_reasonable/BUILD
index a1613eb..4b2919e 100644
--- a/motors/seems_reasonable/BUILD
+++ b/motors/seems_reasonable/BUILD
@@ -5,8 +5,10 @@
     srcs = [
         "drivetrain.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:drivetrain",
@@ -19,8 +21,10 @@
         "drivetrain.py",
         "polydrivetrain.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:polydrivetrain",
@@ -94,3 +98,10 @@
         "//aos/testing:googletest",
     ],
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//motors:python_init"],
+)
diff --git a/motors/seems_reasonable/__init__.py b/motors/seems_reasonable/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/motors/seems_reasonable/__init__.py
diff --git a/tools/bazel.rc b/tools/bazel.rc
index a0dd7a2..1dee9b5 100644
--- a/tools/bazel.rc
+++ b/tools/bazel.rc
@@ -9,6 +9,9 @@
 # Use the malloc we want.
 build --custom_malloc=//tools/cpp:malloc
 
+# Use our hermetic Python runtime.
+build --python_top=//tools/python:runtime
+
 build:asan --copt -fsanitize=address
 build:asan --linkopt -fsanitize=address --linkopt -ldl
 build:asan --platform_suffix=-asan
diff --git a/tools/cpp/BUILD b/tools/cpp/BUILD
index bc094aa..3bee68e 100644
--- a/tools/cpp/BUILD
+++ b/tools/cpp/BUILD
@@ -71,6 +71,14 @@
 )
 
 filegroup(
+    name = "clang_3p6_strip_files",
+    srcs = [
+        "//tools/cpp/clang_3p6:strip",
+        "@clang_3p6_repo//:compiler_pieces",
+    ],
+)
+
+filegroup(
     name = "clang_3p6_compiler_files",
     srcs = [
         "//tools/cpp/clang_3p6:clang",
@@ -90,7 +98,7 @@
     linker_files = ":clang_3p6_linker_files",
     objcopy_files = "//tools/cpp/clang_3p6:objcopy",
     static_runtime_libs = [":empty"],
-    strip_files = "//tools/cpp/clang_3p6:strip",
+    strip_files = ":clang_3p6_strip_files",
     supports_param_files = 1,
 )
 
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-as b/tools/cpp/clang_3p6/x86_64-linux-gnu-as
index f264544..461f584 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-as
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-as
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a as \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/as \
   "$@"
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-cpp b/tools/cpp/clang_3p6/x86_64-linux-gnu-cpp
index adf3869..5bc6499 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-cpp
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-cpp
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a cpp \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/cpp \
   "$@"
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-gcc b/tools/cpp/clang_3p6/x86_64-linux-gnu-gcc
index 4fe1d67..1d0e502 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-gcc
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-gcc
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/gcc/x86_64-linux-gnu/4.9:$PATH" \
   exec \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/gcc \
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-gcov b/tools/cpp/clang_3p6/x86_64-linux-gnu-gcov
index e71ab3e..58b621c 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-gcov
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-gcov
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a gcov \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/gcov \
   "$@"
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-ld b/tools/cpp/clang_3p6/x86_64-linux-gnu-ld
index 803a818..9f59f2e 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-ld
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-ld
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a ld \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/ld \
   "$@"
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-nm b/tools/cpp/clang_3p6/x86_64-linux-gnu-nm
index f8d1eb7..f0b12c8 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-nm
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-nm
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a nm \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/nm \
   "$@"
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-objcopy b/tools/cpp/clang_3p6/x86_64-linux-gnu-objcopy
index 2a49155..55b6b3d 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-objcopy
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-objcopy
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a objcopy \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/objcopy \
   "$@"
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-objdump b/tools/cpp/clang_3p6/x86_64-linux-gnu-objdump
index a549b29..194ffe9 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-objdump
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-objdump
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a objdump \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/objdump \
   "$@"
diff --git a/tools/cpp/clang_3p6/x86_64-linux-gnu-strip b/tools/cpp/clang_3p6/x86_64-linux-gnu-strip
index 0817069..c53f8dd 100755
--- a/tools/cpp/clang_3p6/x86_64-linux-gnu-strip
+++ b/tools/cpp/clang_3p6/x86_64-linux-gnu-strip
@@ -1,5 +1,9 @@
 #!/bin/bash --norc
 
+LD_LIBRARY_PATH="${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib/x86_64-linux-gnu"
+LD_LIBRARY_PATH+=":${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/lib"
+export LD_LIBRARY_PATH
+
 exec -a strip \
   ${BAZEL_OUTPUT_ROOT}external/clang_3p6_repo/usr/bin/strip \
   "$@"
diff --git a/tools/python/BUILD b/tools/python/BUILD
new file mode 100644
index 0000000..2181b31
--- /dev/null
+++ b/tools/python/BUILD
@@ -0,0 +1,9 @@
+py_runtime(
+    name = "runtime",
+    files = [
+        "runtime_binary.sh",
+        "@python_repo//:all_files",
+    ],
+    interpreter = "runtime_binary.sh",
+    visibility = ["//visibility:public"],
+)
diff --git a/tools/python/runtime_binary.sh b/tools/python/runtime_binary.sh
new file mode 100755
index 0000000..6c96fcb
--- /dev/null
+++ b/tools/python/runtime_binary.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+set -e
+set -u
+set -o pipefail
+
+# We disable writing .pyc files here so that the invocation is more
+# deterministic. If we get a corrupted .pyc file (for some reason) in the
+# .runfiles directory the corresponding Python invocation would crash with an
+# EOFError. You can try this by calling truncate(1) on a .pyc file and running
+# your Python script.
+# In the bazel sandbox none of the .pyc files are preserved anyway.
+# Sandboxing also means that Python's entire standard library got cached which
+# normally doesn't happen. That can lead to higher memory usage during the
+# individual build steps.
+export PYTHONDONTWRITEBYTECODE=1
+
+# Find the path that contains the Python runtime. It's not always obvious. For
+# example in a genrule the Python runtime is in the runfiles folder of the
+# tool, not of the genrule.
+# TODO(philipp): Is there a better way to do this?
+BASE_PATH=""
+for path in ${PYTHONPATH//:/ }; do
+  if [[ "$path" == *.runfiles/python_repo ]]; then
+    BASE_PATH="$path"
+    export LD_LIBRARY_PATH="$path"/lib/x86_64-linux-gnu:"$path"/usr/lib:"$path"/usr/lib/x86_64-linux-gnu
+    break
+  fi
+done
+
+if [[ -z "$BASE_PATH" ]]; then
+  echo "Could not find Python base path." >&2
+  echo "More sophisticated logic may be needed." >&2
+  exit 1
+fi
+
+export LD_LIBRARY_PATH="${BASE_PATH}/usr/lib/lapack:${BASE_PATH}/usr/lib/libblas:${BASE_PATH}/usr/lib/x86_64-linux-gnu"
+
+if head -n 1 "$1" | grep -q python3; then
+  exec "$BASE_PATH"/usr/bin/python3 "$@"
+else
+  exec "$BASE_PATH"/usr/bin/python2 "$@"
+fi
diff --git a/tools/ruby/BUILD b/tools/ruby/BUILD
index 426a9f1..b8b2543 100644
--- a/tools/ruby/BUILD
+++ b/tools/ruby/BUILD
@@ -1,5 +1,5 @@
 py_binary(
-  name = 'standalone_ruby',
-  srcs = ['standalone_ruby.py'],
-  visibility = ['//visibility:public'],
+    name = "standalone_ruby",
+    srcs = ["standalone_ruby.py"],
+    visibility = ["//visibility:public"],
 )
diff --git a/y2012/BUILD b/y2012/BUILD
index 27ea143..097ea57 100644
--- a/y2012/BUILD
+++ b/y2012/BUILD
@@ -1,70 +1,76 @@
-load('//aos/downloader:downloader.bzl', 'aos_downloader')
+load("//aos/downloader:downloader.bzl", "aos_downloader")
 
 cc_binary(
-  name = 'joystick_reader',
-  srcs = [
-    'joystick_reader.cc',
-  ],
-  deps = [
-    '//aos/input:joystick_input',
-    '//aos/linux_code:init',
-    '//aos/common/logging',
-    '//aos/common:time',
-    '//aos/common/util:log_interval',
-    '//aos/common/actions:action_lib',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//y2012/control_loops/accessories:accessories_queue',
-    '//frc971/queues:gyro',
-    '//frc971/autonomous:auto_queue',
-  ],
+    name = "joystick_reader",
+    srcs = [
+        "joystick_reader.cc",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/actions:action_lib",
+        "//aos/common/logging",
+        "//aos/common/util:log_interval",
+        "//aos/input:joystick_input",
+        "//aos/linux_code:init",
+        "//frc971/autonomous:auto_queue",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/queues:gyro",
+        "//y2012/control_loops/accessories:accessories_queue",
+    ],
 )
 
 aos_downloader(
-  name = 'download',
-  start_srcs = [
-    ':joystick_reader',
-    ':wpilib_interface',
-    '//y2012/control_loops/drivetrain',
-    '//y2012/control_loops/accessories',
-    '//aos:prime_start_binaries',
-  ],
-  srcs = [
-    '//aos:prime_binaries',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download",
+    srcs = [
+        "//aos:prime_binaries",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":joystick_reader",
+        ":wpilib_interface",
+        "//y2012/control_loops/drivetrain",
+        "//y2012/control_loops/accessories",
+        "//aos:prime_start_binaries",
+    ],
 )
 
 cc_binary(
-  name = 'wpilib_interface',
-  srcs = [
-    'wpilib_interface.cc',
-  ],
-  deps = [
-    '//aos/common/controls:control_loop',
-    '//aos/common/logging',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common/util:log_interval',
-    '//aos/common/util:phased_loop',
-    '//aos/common/util:wrapping_counter',
-    '//aos/common:stl_mutex',
-    '//aos/common:time',
-    '//aos/linux_code:init',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//frc971/control_loops:queues',
-    '//frc971/wpilib:buffered_pcm',
-    '//frc971/wpilib:dma',
-    '//frc971/wpilib:dma_edge_counting',
-    '//frc971/wpilib:encoder_and_potentiometer',
-    '//frc971/wpilib:gyro_sender',
-    '//frc971/wpilib:interrupt_edge_counting',
-    '//frc971/wpilib:joystick_sender',
-    '//frc971/wpilib:logging_queue',
-    '//frc971/wpilib:loop_output_handler',
-    '//frc971/wpilib:wpilib_interface',
-    '//frc971/wpilib:wpilib_robot_base',
-    '//third_party:wpilib',
-    '//y2012/control_loops/accessories:accessories_queue',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_interface",
+    srcs = [
+        "wpilib_interface.cc",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common:stl_mutex",
+        "//aos/common:time",
+        "//aos/common/controls:control_loop",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+        "//aos/common/util:phased_loop",
+        "//aos/common/util:wrapping_counter",
+        "//aos/linux_code:init",
+        "//frc971/control_loops:queues",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/wpilib:buffered_pcm",
+        "//frc971/wpilib:dma",
+        "//frc971/wpilib:dma_edge_counting",
+        "//frc971/wpilib:encoder_and_potentiometer",
+        "//frc971/wpilib:gyro_sender",
+        "//frc971/wpilib:interrupt_edge_counting",
+        "//frc971/wpilib:joystick_sender",
+        "//frc971/wpilib:logging_queue",
+        "//frc971/wpilib:loop_output_handler",
+        "//frc971/wpilib:wpilib_interface",
+        "//frc971/wpilib:wpilib_robot_base",
+        "//third_party:wpilib",
+        "//y2012/control_loops/accessories:accessories_queue",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
 )
diff --git a/y2012/__init__.py b/y2012/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2012/__init__.py
diff --git a/y2012/control_loops/BUILD b/y2012/control_loops/BUILD
new file mode 100644
index 0000000..613ddd4
--- /dev/null
+++ b/y2012/control_loops/BUILD
@@ -0,0 +1,6 @@
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2012:python_init"],
+)
diff --git a/y2012/control_loops/__init__.py b/y2012/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2012/control_loops/__init__.py
diff --git a/y2012/control_loops/python/BUILD b/y2012/control_loops/python/BUILD
index b29f7bd..f10d6fa 100644
--- a/y2012/control_loops/python/BUILD
+++ b/y2012/control_loops/python/BUILD
@@ -1,42 +1,53 @@
-package(default_visibility = ['//y2012:__subpackages__'])
+package(default_visibility = ["//y2012:__subpackages__"])
 
 py_binary(
-  name = 'drivetrain',
-  srcs = [
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:drivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "drivetrain",
+    srcs = [
+        "drivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:drivetrain",
+    ],
 )
 
 py_binary(
-  name = 'polydrivetrain',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:polydrivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:polydrivetrain",
+    ],
 )
 
 py_library(
-  name = 'polydrivetrain_lib',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain_lib",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2012/control_loops:python_init"],
 )
diff --git a/y2012/control_loops/python/__init__.py b/y2012/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2012/control_loops/python/__init__.py
diff --git a/y2014/BUILD b/y2014/BUILD
index 9b27015..a57bb72 100644
--- a/y2014/BUILD
+++ b/y2014/BUILD
@@ -1,115 +1,121 @@
-load('//aos/downloader:downloader.bzl', 'aos_downloader')
+load("//aos/downloader:downloader.bzl", "aos_downloader")
 
 cc_library(
-  name = 'constants',
-  visibility = ['//visibility:public'],
-  srcs = [
-    'constants.cc',
-  ],
-  hdrs = [
-    'constants.h',
-  ],
-  deps = [
-    '//aos/common/logging',
-    '//aos:once',
-    '//aos/common/network:team_number',
-    '//aos/common:mutex',
-    '//frc971/control_loops:state_feedback_loop',
-    '//y2014/control_loops/drivetrain:polydrivetrain_plants',
-    '//frc971:shifter_hall_effect',
-  ],
+    name = "constants",
+    srcs = [
+        "constants.cc",
+    ],
+    hdrs = [
+        "constants.h",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//aos:once",
+        "//aos/common:mutex",
+        "//aos/common/logging",
+        "//aos/common/network:team_number",
+        "//frc971:shifter_hall_effect",
+        "//frc971/control_loops:state_feedback_loop",
+        "//y2014/control_loops/drivetrain:polydrivetrain_plants",
+    ],
 )
 
 cc_binary(
-  name = 'joystick_reader',
-  srcs = [
-    'joystick_reader.cc',
-  ],
-  deps = [
-    ':constants',
-    '//aos/input:joystick_input',
-    '//aos/linux_code:init',
-    '//aos/common/logging',
-    '//aos/common:time',
-    '//aos/common/util:log_interval',
-    '//aos/common/actions:action_lib',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//frc971/queues:gyro',
-    '//frc971/autonomous:auto_queue',
-    '//y2014/control_loops/claw:claw_queue',
-    '//y2014/control_loops/shooter:shooter_queue',
-    '//y2014/actors:shoot_action_lib',
-  ],
+    name = "joystick_reader",
+    srcs = [
+        "joystick_reader.cc",
+    ],
+    deps = [
+        ":constants",
+        "//aos/common:time",
+        "//aos/common/actions:action_lib",
+        "//aos/common/logging",
+        "//aos/common/util:log_interval",
+        "//aos/input:joystick_input",
+        "//aos/linux_code:init",
+        "//frc971/autonomous:auto_queue",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/queues:gyro",
+        "//y2014/actors:shoot_action_lib",
+        "//y2014/control_loops/claw:claw_queue",
+        "//y2014/control_loops/shooter:shooter_queue",
+    ],
 )
 
 aos_downloader(
-  name = 'download',
-  start_srcs = [
-    ':hot_goal_reader',
-    ':joystick_reader',
-    ':wpilib_interface',
-    '//y2014/control_loops/drivetrain:drivetrain',
-    '//y2014/control_loops/claw:claw',
-    '//y2014/control_loops/shooter:shooter',
-    '//y2014/autonomous:auto',
-    '//y2014/actors:binaries',
-    '//aos:prime_start_binaries',
-  ],
-  srcs = [
-    '//aos:prime_binaries',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download",
+    srcs = [
+        "//aos:prime_binaries",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":hot_goal_reader",
+        ":joystick_reader",
+        ":wpilib_interface",
+        "//y2014/control_loops/drivetrain:drivetrain",
+        "//y2014/control_loops/claw:claw",
+        "//y2014/control_loops/shooter:shooter",
+        "//y2014/autonomous:auto",
+        "//y2014/actors:binaries",
+        "//aos:prime_start_binaries",
+    ],
 )
 
 cc_binary(
-  name = 'hot_goal_reader',
-  srcs = [
-    'hot_goal_reader.cc',
-  ],
-  deps = [
-    '//aos/common:time',
-    '//aos/common/logging',
-    '//aos/common/logging:queue_logging',
-    '//aos/linux_code:init',
-    '//y2014/queues:hot_goal',
-  ],
+    name = "hot_goal_reader",
+    srcs = [
+        "hot_goal_reader.cc",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/linux_code:init",
+        "//y2014/queues:hot_goal",
+    ],
 )
 
 cc_binary(
-  name = 'wpilib_interface',
-  srcs = [
-    'wpilib_interface.cc',
-  ],
-  deps = [
-    ':constants',
-    '//aos/linux_code:init',
-    '//aos/common:stl_mutex',
-    '//aos/common/logging',
-    '//third_party:wpilib',
-    '//y2014/queues:auto_mode',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//y2014/control_loops/shooter:shooter_queue',
-    '//y2014/control_loops/claw:claw_queue',
-    '//aos/common/controls:control_loop',
-    '//aos/common/util:log_interval',
-    '//aos/common:time',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common/util:phased_loop',
-    '//aos/common/util:wrapping_counter',
-    '//frc971/wpilib:joystick_sender',
-    '//frc971/wpilib:loop_output_handler',
-    '//frc971/wpilib:buffered_pcm',
-    '//frc971/wpilib:gyro_sender',
-    '//frc971/wpilib:dma_edge_counting',
-    '//frc971/wpilib:interrupt_edge_counting',
-    '//frc971/wpilib:wpilib_robot_base',
-    '//frc971/wpilib:encoder_and_potentiometer',
-    '//frc971/control_loops:queues',
-    '//frc971/wpilib:logging_queue',
-    '//frc971/wpilib:wpilib_interface',
-    '//frc971/wpilib:pdp_fetcher',
-    '//frc971/wpilib:dma',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_interface",
+    srcs = [
+        "wpilib_interface.cc",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":constants",
+        "//aos/common:stl_mutex",
+        "//aos/common:time",
+        "//aos/common/controls:control_loop",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+        "//aos/common/util:phased_loop",
+        "//aos/common/util:wrapping_counter",
+        "//aos/linux_code:init",
+        "//frc971/control_loops:queues",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/wpilib:buffered_pcm",
+        "//frc971/wpilib:dma",
+        "//frc971/wpilib:dma_edge_counting",
+        "//frc971/wpilib:encoder_and_potentiometer",
+        "//frc971/wpilib:gyro_sender",
+        "//frc971/wpilib:interrupt_edge_counting",
+        "//frc971/wpilib:joystick_sender",
+        "//frc971/wpilib:logging_queue",
+        "//frc971/wpilib:loop_output_handler",
+        "//frc971/wpilib:pdp_fetcher",
+        "//frc971/wpilib:wpilib_interface",
+        "//frc971/wpilib:wpilib_robot_base",
+        "//third_party:wpilib",
+        "//y2014/control_loops/claw:claw_queue",
+        "//y2014/control_loops/shooter:shooter_queue",
+        "//y2014/queues:auto_mode",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
 )
diff --git a/y2014/__init__.py b/y2014/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2014/__init__.py
diff --git a/y2014/control_loops/BUILD b/y2014/control_loops/BUILD
new file mode 100644
index 0000000..995a4c7
--- /dev/null
+++ b/y2014/control_loops/BUILD
@@ -0,0 +1,6 @@
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2014:python_init"],
+)
diff --git a/y2014/control_loops/__init__.py b/y2014/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2014/control_loops/__init__.py
diff --git a/y2014/control_loops/python/BUILD b/y2014/control_loops/python/BUILD
index 00dfda1..5216eb9 100644
--- a/y2014/control_loops/python/BUILD
+++ b/y2014/control_loops/python/BUILD
@@ -1,84 +1,104 @@
-package(default_visibility = ['//y2014:__subpackages__'])
+package(default_visibility = ["//y2014:__subpackages__"])
 
 py_binary(
-  name = 'drivetrain',
-  srcs = [
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:drivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "drivetrain",
+    srcs = [
+        "drivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:drivetrain",
+    ],
 )
 
 py_binary(
-  name = 'polydrivetrain',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:polydrivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:polydrivetrain",
+    ],
 )
 
 py_library(
-  name = 'polydrivetrain_lib',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-    '//frc971/control_loops/python:drivetrain',
-    '//frc971/control_loops/python:polydrivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain_lib",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "//frc971/control_loops/python:drivetrain",
+        "//frc971/control_loops/python:polydrivetrain",
+    ],
 )
 
 py_binary(
-  name = 'claw',
-  srcs = [
-    'claw.py',
-  ],
-  deps = [
-    ':polydrivetrain_lib',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "claw",
+    srcs = [
+        "claw.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":polydrivetrain_lib",
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'shooter',
-  srcs = [
-    'shooter.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "shooter",
+    srcs = [
+        "shooter.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'extended_lqr',
-  srcs = [
-    'extended_lqr.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "extended_lqr",
+    srcs = [
+        "extended_lqr.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2014/control_loops:python_init"],
 )
diff --git a/y2014/control_loops/python/__init__.py b/y2014/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2014/control_loops/python/__init__.py
diff --git a/y2014_bot3/BUILD b/y2014_bot3/BUILD
index 4065357..6f454ea 100644
--- a/y2014_bot3/BUILD
+++ b/y2014_bot3/BUILD
@@ -1,73 +1,77 @@
-load('//aos/downloader:downloader.bzl', 'aos_downloader')
+load("//aos/downloader:downloader.bzl", "aos_downloader")
 
 cc_binary(
-  name = 'joystick_reader',
-  srcs = [
-    'joystick_reader.cc',
-  ],
-  deps = [
-    '//aos/input:joystick_input',
-    '//aos/linux_code:init',
-    '//aos/common/logging',
-    '//aos/common:time',
-    '//aos/common/util:log_interval',
-    '//aos/common/actions:action_lib',
-
-    '//frc971/queues:gyro',
-    '//y2014_bot3/autonomous:auto_queue',
-    '//y2014_bot3/control_loops/rollers:rollers_queue',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-  ],
+    name = "joystick_reader",
+    srcs = [
+        "joystick_reader.cc",
+    ],
+    deps = [
+        "//aos/common:time",
+        "//aos/common/actions:action_lib",
+        "//aos/common/logging",
+        "//aos/common/util:log_interval",
+        "//aos/input:joystick_input",
+        "//aos/linux_code:init",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/queues:gyro",
+        "//y2014_bot3/autonomous:auto_queue",
+        "//y2014_bot3/control_loops/rollers:rollers_queue",
+    ],
 )
 
 aos_downloader(
-  name = 'download_stripped',
-  start_srcs = [
-    ':joystick_reader.stripped',
-    ':wpilib_interface.stripped',
-    '//aos:prime_start_binaries_stripped',
-    '//y2014_bot3/autonomous:auto.stripped',
-    '//y2014_bot3/control_loops/drivetrain:drivetrain.stripped',
-    '//y2014_bot3/control_loops/rollers:rollers.stripped',
-
-  ],
-  srcs = [
-    '//aos:prime_binaries_stripped',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download_stripped",
+    srcs = [
+        "//aos:prime_binaries_stripped",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":joystick_reader.stripped",
+        ":wpilib_interface.stripped",
+        "//aos:prime_start_binaries_stripped",
+        "//y2014_bot3/autonomous:auto.stripped",
+        "//y2014_bot3/control_loops/drivetrain:drivetrain.stripped",
+        "//y2014_bot3/control_loops/rollers:rollers.stripped",
+    ],
 )
 
 cc_binary(
-  name = 'wpilib_interface',
-  srcs = [
-    'wpilib_interface.cc',
-  ],
-  deps = [
-    '//aos/linux_code:init',
-    '//aos/common:stl_mutex',
-    '//aos/common/logging',
-    '//third_party:wpilib',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//aos/common/controls:control_loop',
-    '//aos/common/util:log_interval',
-    '//aos/common:time',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common/util:phased_loop',
-    '//aos/common/util:wrapping_counter',
-    '//frc971/wpilib:joystick_sender',
-    '//frc971/wpilib:loop_output_handler',
-    '//frc971/wpilib:buffered_pcm',
-    '//frc971/wpilib:gyro_sender',
-    '//frc971/control_loops:queues',
-    '//frc971/wpilib:logging_queue',
-    '//frc971/wpilib:wpilib_robot_base',
-    '//frc971/wpilib:wpilib_interface',
-    '//frc971/wpilib:pdp_fetcher',
-    '//frc971/wpilib:dma',
-    '//y2014_bot3/autonomous:auto_queue',
-    '//y2014_bot3/control_loops/rollers:rollers_lib',
-    '//y2014_bot3/control_loops/drivetrain:drivetrain_base',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_interface",
+    srcs = [
+        "wpilib_interface.cc",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        "//aos/common:stl_mutex",
+        "//aos/common:time",
+        "//aos/common/controls:control_loop",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+        "//aos/common/util:phased_loop",
+        "//aos/common/util:wrapping_counter",
+        "//aos/linux_code:init",
+        "//frc971/control_loops:queues",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/wpilib:buffered_pcm",
+        "//frc971/wpilib:dma",
+        "//frc971/wpilib:gyro_sender",
+        "//frc971/wpilib:joystick_sender",
+        "//frc971/wpilib:logging_queue",
+        "//frc971/wpilib:loop_output_handler",
+        "//frc971/wpilib:pdp_fetcher",
+        "//frc971/wpilib:wpilib_interface",
+        "//frc971/wpilib:wpilib_robot_base",
+        "//third_party:wpilib",
+        "//y2014_bot3/autonomous:auto_queue",
+        "//y2014_bot3/control_loops/drivetrain:drivetrain_base",
+        "//y2014_bot3/control_loops/rollers:rollers_lib",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
 )
diff --git a/y2014_bot3/__init__.py b/y2014_bot3/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2014_bot3/__init__.py
diff --git a/y2014_bot3/control_loops/BUILD b/y2014_bot3/control_loops/BUILD
new file mode 100644
index 0000000..8df2481
--- /dev/null
+++ b/y2014_bot3/control_loops/BUILD
@@ -0,0 +1,6 @@
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2014_bot3:python_init"],
+)
diff --git a/y2014_bot3/control_loops/__init__.py b/y2014_bot3/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2014_bot3/control_loops/__init__.py
diff --git a/y2014_bot3/control_loops/python/BUILD b/y2014_bot3/control_loops/python/BUILD
index 03dc97c..83e7bba 100644
--- a/y2014_bot3/control_loops/python/BUILD
+++ b/y2014_bot3/control_loops/python/BUILD
@@ -1,28 +1,39 @@
-package(default_visibility = ['//y2014_bot3:__subpackages__'])
+package(default_visibility = ["//y2014_bot3:__subpackages__"])
 
 py_binary(
-  name = 'drivetrain',
-  srcs = [
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:drivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "drivetrain",
+    srcs = [
+        "drivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:drivetrain",
+    ],
 )
 
 py_binary(
-  name = 'polydrivetrain',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:polydrivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:polydrivetrain",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2014_bot3/control_loops:python_init"],
 )
diff --git a/y2014_bot3/control_loops/python/__init__.py b/y2014_bot3/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2014_bot3/control_loops/python/__init__.py
diff --git a/y2016/BUILD b/y2016/BUILD
index aaab30b..e10be44 100644
--- a/y2016/BUILD
+++ b/y2016/BUILD
@@ -1,139 +1,145 @@
-load('//aos/downloader:downloader.bzl', 'aos_downloader')
+load("//aos/downloader:downloader.bzl", "aos_downloader")
 
 cc_library(
-  name = 'constants',
-  visibility = ['//visibility:public'],
-  srcs = [
-    'constants.cc',
-  ],
-  hdrs = [
-    'constants.h',
-  ],
-  deps = [
-    '//aos/common/logging',
-    '//aos:once',
-    '//aos/common/network:team_number',
-    '//aos/common:mutex',
-    '//frc971/control_loops:state_feedback_loop',
-    '//frc971:shifter_hall_effect',
-    '//frc971:constants',
-    '//y2016/control_loops/drivetrain:polydrivetrain_plants',
-  ],
+    name = "constants",
+    srcs = [
+        "constants.cc",
+    ],
+    hdrs = [
+        "constants.h",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//aos:once",
+        "//aos/common:mutex",
+        "//aos/common/logging",
+        "//aos/common/network:team_number",
+        "//frc971:constants",
+        "//frc971:shifter_hall_effect",
+        "//frc971/control_loops:state_feedback_loop",
+        "//y2016/control_loops/drivetrain:polydrivetrain_plants",
+    ],
 )
 
 cc_binary(
-  name = 'joystick_reader',
-  srcs = [
-    'joystick_reader.cc',
-  ],
-  deps = [
-    ':constants',
-    '//aos/common/actions:action_lib',
-    '//aos/common/logging',
-    '//aos/common/util:log_interval',
-    '//aos/common:time',
-    '//aos/input:joystick_input',
-    '//aos/linux_code:init',
-    '//frc971/autonomous:auto_queue',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//frc971/queues:gyro',
-    '//y2016/actors:autonomous_action_lib',
-    '//y2016/actors:superstructure_action_lib',
-    '//y2016/actors:vision_align_action_lib',
-    '//y2016/control_loops/shooter:shooter_queue',
-    '//y2016/control_loops/superstructure:superstructure_lib',
-    '//y2016/control_loops/superstructure:superstructure_queue',
-    '//y2016/queues:ball_detector',
-  ],
+    name = "joystick_reader",
+    srcs = [
+        "joystick_reader.cc",
+    ],
+    deps = [
+        ":constants",
+        "//aos/common:time",
+        "//aos/common/actions:action_lib",
+        "//aos/common/logging",
+        "//aos/common/util:log_interval",
+        "//aos/input:joystick_input",
+        "//aos/linux_code:init",
+        "//frc971/autonomous:auto_queue",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/queues:gyro",
+        "//y2016/actors:autonomous_action_lib",
+        "//y2016/actors:superstructure_action_lib",
+        "//y2016/actors:vision_align_action_lib",
+        "//y2016/control_loops/shooter:shooter_queue",
+        "//y2016/control_loops/superstructure:superstructure_lib",
+        "//y2016/control_loops/superstructure:superstructure_queue",
+        "//y2016/queues:ball_detector",
+    ],
 )
 
 aos_downloader(
-  name = 'download',
-  start_srcs = [
-    ':joystick_reader',
-    ':wpilib_interface',
-    '//aos:prime_start_binaries',
-    '//y2016/control_loops/drivetrain:drivetrain',
-    '//y2016/control_loops/superstructure:superstructure',
-    '//y2016/control_loops/shooter:shooter',
-    '//y2016/dashboard:dashboard',
-    '//y2016/actors:autonomous_action',
-    '//y2016/actors:superstructure_action',
-    '//y2016/actors:vision_align_action',
-    '//y2016/vision:target_receiver',
-  ],
-  srcs = [
-    '//aos:prime_binaries',
-  ],
-  dirs = [
-    '//y2016/dashboard:www_files',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download",
+    srcs = [
+        "//aos:prime_binaries",
+    ],
+    dirs = [
+        "//y2016/dashboard:www_files",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":joystick_reader",
+        ":wpilib_interface",
+        "//aos:prime_start_binaries",
+        "//y2016/control_loops/drivetrain:drivetrain",
+        "//y2016/control_loops/superstructure:superstructure",
+        "//y2016/control_loops/shooter:shooter",
+        "//y2016/dashboard:dashboard",
+        "//y2016/actors:autonomous_action",
+        "//y2016/actors:superstructure_action",
+        "//y2016/actors:vision_align_action",
+        "//y2016/vision:target_receiver",
+    ],
 )
 
 aos_downloader(
-  name = 'download_stripped',
-  start_srcs = [
-    ':joystick_reader.stripped',
-    ':wpilib_interface.stripped',
-    '//aos:prime_start_binaries_stripped',
-    '//y2016/control_loops/drivetrain:drivetrain.stripped',
-    '//y2016/control_loops/superstructure:superstructure.stripped',
-    '//y2016/control_loops/shooter:shooter.stripped',
-    '//y2016/dashboard:dashboard.stripped',
-    '//y2016/actors:autonomous_action.stripped',
-    '//y2016/actors:superstructure_action.stripped',
-    '//y2016/actors:vision_align_action.stripped',
-    '//y2016/vision:target_receiver.stripped',
-  ],
-  srcs = [
-    '//aos:prime_binaries_stripped',
-  ],
-  dirs = [
-    '//y2016/dashboard:www_files',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download_stripped",
+    srcs = [
+        "//aos:prime_binaries_stripped",
+    ],
+    dirs = [
+        "//y2016/dashboard:www_files",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":joystick_reader.stripped",
+        ":wpilib_interface.stripped",
+        "//aos:prime_start_binaries_stripped",
+        "//y2016/control_loops/drivetrain:drivetrain.stripped",
+        "//y2016/control_loops/superstructure:superstructure.stripped",
+        "//y2016/control_loops/shooter:shooter.stripped",
+        "//y2016/dashboard:dashboard.stripped",
+        "//y2016/actors:autonomous_action.stripped",
+        "//y2016/actors:superstructure_action.stripped",
+        "//y2016/actors:vision_align_action.stripped",
+        "//y2016/vision:target_receiver.stripped",
+    ],
 )
 
 cc_binary(
-  name = 'wpilib_interface',
-  srcs = [
-    'wpilib_interface.cc',
-  ],
-  deps = [
-    ':constants',
-    '//aos/common:stl_mutex',
-    '//aos/common/logging',
-    '//aos/common:math',
-    '//aos/common/controls:control_loop',
-    '//aos/common/util:log_interval',
-    '//aos/common:time',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common/util:phased_loop',
-    '//aos/common/util:wrapping_counter',
-    '//aos/linux_code:init',
-    '//third_party:wpilib',
-    '//frc971/autonomous:auto_queue',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//frc971/control_loops:queues',
-    '//frc971/wpilib:joystick_sender',
-    '//frc971/wpilib:loop_output_handler',
-    '//frc971/wpilib:buffered_pcm',
-    '//frc971/wpilib:gyro_sender',
-    '//frc971/wpilib:dma_edge_counting',
-    '//frc971/wpilib:interrupt_edge_counting',
-    '//frc971/wpilib:wpilib_robot_base',
-    '//frc971/wpilib:encoder_and_potentiometer',
-    '//frc971/wpilib:logging_queue',
-    '//frc971/wpilib:wpilib_interface',
-    '//frc971/wpilib:pdp_fetcher',
-    '//frc971/wpilib:ADIS16448',
-    '//frc971/wpilib:dma',
-    '//y2016/control_loops/drivetrain:polydrivetrain_plants',
-    '//y2016/control_loops/shooter:shooter_queue',
-    '//y2016/control_loops/superstructure:superstructure_queue',
-    '//y2016/queues:ball_detector',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_interface",
+    srcs = [
+        "wpilib_interface.cc",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":constants",
+        "//aos/common:math",
+        "//aos/common:stl_mutex",
+        "//aos/common:time",
+        "//aos/common/controls:control_loop",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+        "//aos/common/util:phased_loop",
+        "//aos/common/util:wrapping_counter",
+        "//aos/linux_code:init",
+        "//frc971/autonomous:auto_queue",
+        "//frc971/control_loops:queues",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/wpilib:ADIS16448",
+        "//frc971/wpilib:buffered_pcm",
+        "//frc971/wpilib:dma",
+        "//frc971/wpilib:dma_edge_counting",
+        "//frc971/wpilib:encoder_and_potentiometer",
+        "//frc971/wpilib:gyro_sender",
+        "//frc971/wpilib:interrupt_edge_counting",
+        "//frc971/wpilib:joystick_sender",
+        "//frc971/wpilib:logging_queue",
+        "//frc971/wpilib:loop_output_handler",
+        "//frc971/wpilib:pdp_fetcher",
+        "//frc971/wpilib:wpilib_interface",
+        "//frc971/wpilib:wpilib_robot_base",
+        "//third_party:wpilib",
+        "//y2016/control_loops/drivetrain:polydrivetrain_plants",
+        "//y2016/control_loops/shooter:shooter_queue",
+        "//y2016/control_loops/superstructure:superstructure_queue",
+        "//y2016/queues:ball_detector",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
 )
diff --git a/y2016/__init__.py b/y2016/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2016/__init__.py
diff --git a/y2016/control_loops/BUILD b/y2016/control_loops/BUILD
new file mode 100644
index 0000000..de3bfeb
--- /dev/null
+++ b/y2016/control_loops/BUILD
@@ -0,0 +1,6 @@
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2016:python_init"],
+)
diff --git a/y2016/control_loops/__init__.py b/y2016/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2016/control_loops/__init__.py
diff --git a/y2016/control_loops/python/BUILD b/y2016/control_loops/python/BUILD
index d2a5905..adb3150 100644
--- a/y2016/control_loops/python/BUILD
+++ b/y2016/control_loops/python/BUILD
@@ -1,156 +1,184 @@
-package(default_visibility = ['//y2016:__subpackages__'])
+package(default_visibility = ["//y2016:__subpackages__"])
 
 py_binary(
-  name = 'drivetrain',
-  srcs = [
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:drivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "drivetrain",
+    srcs = [
+        "drivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:drivetrain",
+    ],
 )
 
 py_binary(
-  name = 'polydrivetrain',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:polydrivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:polydrivetrain",
+    ],
 )
 
 py_library(
-  name = 'polydrivetrain_lib',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain_lib",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
 )
 
 py_binary(
-  name = 'shooter',
-  srcs = [
-    'shooter.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "shooter",
+    srcs = [
+        "shooter.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'intake',
-  srcs = [
-    'intake.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "intake",
+    srcs = [
+        "intake.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'shoulder',
-  srcs = [
-    'shoulder.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "shoulder",
+    srcs = [
+        "shoulder.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'wrist',
-  srcs = [
-    'wrist.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "wrist",
+    srcs = [
+        "wrist.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_library(
-  name = 'wrist_lib',
-  srcs = [
-    'wrist.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "wrist_lib",
+    srcs = [
+        "wrist.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
 )
 
 py_library(
-  name = 'shoulder_lib',
-  srcs = [
-    'shoulder.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "shoulder_lib",
+    srcs = [
+        "shoulder.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_library(
-  name = 'arm_lib',
-  srcs = [
-    'arm.py',
-  ],
-  deps = [
-    ':wrist_lib',
-    ':shoulder_lib',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-    '//aos/common/util:py_trapezoid_profile',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "arm_lib",
+    srcs = [
+        "arm.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":shoulder_lib",
+        ":wrist_lib",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
+
 py_binary(
-  name = 'arm',
-  srcs = [
-    'arm.py',
-  ],
-  deps = [
-    ':wrist_lib',
-    ':shoulder_lib',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-    '//aos/common/util:py_trapezoid_profile',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "arm",
+    srcs = [
+        "arm.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        ":shoulder_lib",
+        ":wrist_lib",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2016/control_loops:python_init"],
 )
diff --git a/y2016/control_loops/python/__init__.py b/y2016/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2016/control_loops/python/__init__.py
diff --git a/y2016/control_loops/python/intake.py b/y2016/control_loops/python/intake.py
index d99160d..02c1ada 100755
--- a/y2016/control_loops/python/intake.py
+++ b/y2016/control_loops/python/intake.py
@@ -5,7 +5,6 @@
 from frc971.control_loops.python import controls
 import numpy
 import sys
-import matplotlib
 from matplotlib import pylab
 import gflags
 import glog
diff --git a/y2016/control_loops/python/wrist.py b/y2016/control_loops/python/wrist.py
index f08f1a2..6de8551 100755
--- a/y2016/control_loops/python/wrist.py
+++ b/y2016/control_loops/python/wrist.py
@@ -4,7 +4,6 @@
 from frc971.control_loops.python import controls
 import numpy
 import sys
-import matplotlib
 from matplotlib import pylab
 import gflags
 import glog
diff --git a/y2017/BUILD b/y2017/BUILD
index d202064..f294aaa 100644
--- a/y2017/BUILD
+++ b/y2017/BUILD
@@ -1,120 +1,126 @@
-load('//aos/downloader:downloader.bzl', 'aos_downloader')
+load("//aos/downloader:downloader.bzl", "aos_downloader")
 
 cc_library(
-  name = 'constants',
-  visibility = ['//visibility:public'],
-  srcs = [
-    'constants.cc',
-  ],
-  hdrs = [
-    'constants.h',
-  ],
-  deps = [
-    '//aos/common/logging',
-    '//aos/common/network:team_number',
-    '//aos/common:mutex',
-    '//aos:once',
-    '//frc971:constants',
-    '//frc971/shooter_interpolation:interpolation',
-    '//y2017/control_loops/drivetrain:polydrivetrain_plants',
-    '//y2017/control_loops/superstructure/column:column_plants',
-    '//y2017/control_loops/superstructure/hood:hood_plants',
-    '//y2017/control_loops/superstructure/intake:intake_plants',
-    '//y2017/control_loops/superstructure/shooter:shooter_plants',
-  ],
+    name = "constants",
+    srcs = [
+        "constants.cc",
+    ],
+    hdrs = [
+        "constants.h",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//aos:once",
+        "//aos/common:mutex",
+        "//aos/common/logging",
+        "//aos/common/network:team_number",
+        "//frc971:constants",
+        "//frc971/shooter_interpolation:interpolation",
+        "//y2017/control_loops/drivetrain:polydrivetrain_plants",
+        "//y2017/control_loops/superstructure/column:column_plants",
+        "//y2017/control_loops/superstructure/hood:hood_plants",
+        "//y2017/control_loops/superstructure/intake:intake_plants",
+        "//y2017/control_loops/superstructure/shooter:shooter_plants",
+    ],
 )
 
 cc_binary(
-  name = 'joystick_reader',
-  srcs = [
-    'joystick_reader.cc',
-  ],
-  deps = [
-    ':constants',
-    '//aos/common/actions:action_lib',
-    '//aos/common/logging',
-    '//aos/common/util:log_interval',
-    '//aos/common:time',
-    '//aos/input:joystick_input',
-    '//aos/input:drivetrain_input',
-    '//aos/linux_code:init',
-    '//frc971/autonomous:auto_queue',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//y2017/actors:autonomous_action_lib',
-    '//y2017/control_loops/superstructure:superstructure_queue',
-    '//y2017/control_loops/drivetrain:drivetrain_base',
-  ],
+    name = "joystick_reader",
+    srcs = [
+        "joystick_reader.cc",
+    ],
+    deps = [
+        ":constants",
+        "//aos/common:time",
+        "//aos/common/actions:action_lib",
+        "//aos/common/logging",
+        "//aos/common/util:log_interval",
+        "//aos/input:drivetrain_input",
+        "//aos/input:joystick_input",
+        "//aos/linux_code:init",
+        "//frc971/autonomous:auto_queue",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//y2017/actors:autonomous_action_lib",
+        "//y2017/control_loops/drivetrain:drivetrain_base",
+        "//y2017/control_loops/superstructure:superstructure_queue",
+    ],
 )
 
 cc_binary(
-  name = 'wpilib_interface',
-  srcs = [
-    'wpilib_interface.cc',
-  ],
-  deps = [
-    ':constants',
-    '//aos/common:stl_mutex',
-    '//aos/common/logging',
-    '//aos/common:math',
-    '//aos/common/controls:control_loop',
-    '//aos/common/util:log_interval',
-    '//aos/common:time',
-    '//aos/common/logging:queue_logging',
-    '//aos/common/messages:robot_state',
-    '//aos/common/util:phased_loop',
-    '//aos/common/util:wrapping_counter',
-    '//aos/linux_code:init',
-    '//third_party:wpilib',
-    '//frc971/autonomous:auto_queue',
-    '//frc971/control_loops/drivetrain:drivetrain_queue',
-    '//frc971/control_loops:queues',
-    '//frc971/wpilib:joystick_sender',
-    '//frc971/wpilib:loop_output_handler',
-    '//frc971/wpilib:buffered_pcm',
-    '//frc971/wpilib:dma_edge_counting',
-    '//frc971/wpilib:interrupt_edge_counting',
-    '//frc971/wpilib:wpilib_robot_base',
-    '//frc971/wpilib:encoder_and_potentiometer',
-    '//frc971/wpilib:logging_queue',
-    '//frc971/wpilib:wpilib_interface',
-    '//frc971/wpilib:pdp_fetcher',
-    '//frc971/wpilib:ADIS16448',
-    '//frc971/wpilib:dma',
-    '//y2017/control_loops/superstructure:superstructure_queue',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "wpilib_interface",
+    srcs = [
+        "wpilib_interface.cc",
+    ],
+    restricted_to = ["//tools:roborio"],
+    deps = [
+        ":constants",
+        "//aos/common:math",
+        "//aos/common:stl_mutex",
+        "//aos/common:time",
+        "//aos/common/controls:control_loop",
+        "//aos/common/logging",
+        "//aos/common/logging:queue_logging",
+        "//aos/common/messages:robot_state",
+        "//aos/common/util:log_interval",
+        "//aos/common/util:phased_loop",
+        "//aos/common/util:wrapping_counter",
+        "//aos/linux_code:init",
+        "//frc971/autonomous:auto_queue",
+        "//frc971/control_loops:queues",
+        "//frc971/control_loops/drivetrain:drivetrain_queue",
+        "//frc971/wpilib:ADIS16448",
+        "//frc971/wpilib:buffered_pcm",
+        "//frc971/wpilib:dma",
+        "//frc971/wpilib:dma_edge_counting",
+        "//frc971/wpilib:encoder_and_potentiometer",
+        "//frc971/wpilib:interrupt_edge_counting",
+        "//frc971/wpilib:joystick_sender",
+        "//frc971/wpilib:logging_queue",
+        "//frc971/wpilib:loop_output_handler",
+        "//frc971/wpilib:pdp_fetcher",
+        "//frc971/wpilib:wpilib_interface",
+        "//frc971/wpilib:wpilib_robot_base",
+        "//third_party:wpilib",
+        "//y2017/control_loops/superstructure:superstructure_queue",
+    ],
 )
 
 aos_downloader(
-  name = 'download',
-  start_srcs = [
-    ':joystick_reader',
-    ':wpilib_interface',
-    '//aos:prime_start_binaries',
-    '//y2017/actors:autonomous_action',
-    '//y2017/control_loops/drivetrain:drivetrain',
-    '//y2017/control_loops/superstructure:superstructure',
-    '//y2017/vision:target_receiver',
-  ],
-  srcs = [
-    '//aos:prime_binaries',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download",
+    srcs = [
+        "//aos:prime_binaries",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":joystick_reader",
+        ":wpilib_interface",
+        "//aos:prime_start_binaries",
+        "//y2017/actors:autonomous_action",
+        "//y2017/control_loops/drivetrain:drivetrain",
+        "//y2017/control_loops/superstructure:superstructure",
+        "//y2017/vision:target_receiver",
+    ],
 )
 
 aos_downloader(
-  name = 'download_stripped',
-  start_srcs = [
-    ':joystick_reader.stripped',
-    ':wpilib_interface.stripped',
-    '//aos:prime_start_binaries_stripped',
-    '//y2017/actors:autonomous_action.stripped',
-    '//y2017/control_loops/drivetrain:drivetrain.stripped',
-    '//y2017/control_loops/superstructure:superstructure.stripped',
-    '//y2017/vision:target_receiver.stripped',
-  ],
-  srcs = [
-    '//aos:prime_binaries_stripped',
-  ],
-  restricted_to = ['//tools:roborio'],
+    name = "download_stripped",
+    srcs = [
+        "//aos:prime_binaries_stripped",
+    ],
+    restricted_to = ["//tools:roborio"],
+    start_srcs = [
+        ":joystick_reader.stripped",
+        ":wpilib_interface.stripped",
+        "//aos:prime_start_binaries_stripped",
+        "//y2017/actors:autonomous_action.stripped",
+        "//y2017/control_loops/drivetrain:drivetrain.stripped",
+        "//y2017/control_loops/superstructure:superstructure.stripped",
+        "//y2017/vision:target_receiver.stripped",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
 )
diff --git a/y2017/__init__.py b/y2017/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2017/__init__.py
diff --git a/y2017/control_loops/BUILD b/y2017/control_loops/BUILD
new file mode 100644
index 0000000..d34fcab
--- /dev/null
+++ b/y2017/control_loops/BUILD
@@ -0,0 +1,6 @@
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2017:python_init"],
+)
diff --git a/y2017/control_loops/__init__.py b/y2017/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2017/control_loops/__init__.py
diff --git a/y2017/control_loops/python/BUILD b/y2017/control_loops/python/BUILD
index 83473ae..47c24e8 100644
--- a/y2017/control_loops/python/BUILD
+++ b/y2017/control_loops/python/BUILD
@@ -1,153 +1,181 @@
-package(default_visibility = ['//y2017:__subpackages__'])
+package(default_visibility = ["//y2017:__subpackages__"])
 
 py_binary(
-  name = 'drivetrain',
-  srcs = [
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:drivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "drivetrain",
+    srcs = [
+        "drivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:drivetrain",
+    ],
 )
 
 py_binary(
-  name = 'polydrivetrain',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:polydrivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:polydrivetrain",
+    ],
 )
 
 py_library(
-  name = 'polydrivetrain_lib',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-    '//frc971/control_loops/python:drivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain_lib",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "//frc971/control_loops/python:drivetrain",
+    ],
 )
 
 py_binary(
-  name = 'shooter',
-  srcs = [
-    'shooter.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "shooter",
+    srcs = [
+        "shooter.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'indexer',
-  srcs = [
-    'indexer.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "indexer",
+    srcs = [
+        "indexer.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
 )
 
 py_binary(
-  name = 'intake',
-  srcs = [
-    'intake.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "intake",
+    srcs = [
+        "intake.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'turret',
-  srcs = [
-    'turret.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "turret",
+    srcs = [
+        "turret.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_binary(
-  name = 'hood',
-  srcs = [
-    'hood.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "hood",
+    srcs = [
+        "hood.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
 )
 
 py_library(
-  name = 'turret_lib',
-  srcs = [
-    'turret.py',
-  ],
-  deps = [
-    '//aos/common/util:py_trapezoid_profile',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "turret_lib",
+    srcs = [
+        "turret.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//aos/common/util:py_trapezoid_profile",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
 )
 
 py_library(
-  name = 'indexer_lib',
-  srcs = [
-    'indexer.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "indexer_lib",
+    srcs = [
+        "indexer.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
 )
 
 py_binary(
-  name = 'column',
-  srcs = [
-    'column.py',
-  ],
-  deps = [
-    ':turret_lib',
-    ':indexer_lib',
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "column",
+    srcs = [
+        "column.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":indexer_lib",
+        ":python_init",
+        ":turret_lib",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+        "@matplotlib",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2017/control_loops:python_init"],
 )
diff --git a/y2017/control_loops/python/__init__.py b/y2017/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2017/control_loops/python/__init__.py
diff --git a/y2017/control_loops/python/column.py b/y2017/control_loops/python/column.py
index d6043b3..4cbf4dd 100755
--- a/y2017/control_loops/python/column.py
+++ b/y2017/control_loops/python/column.py
@@ -7,7 +7,6 @@
 from y2017.control_loops.python import indexer
 import numpy
 import sys
-import matplotlib
 from matplotlib import pylab
 import gflags
 import glog
diff --git a/y2017/control_loops/python/hood.py b/y2017/control_loops/python/hood.py
index 6c7c2d0..2704216 100755
--- a/y2017/control_loops/python/hood.py
+++ b/y2017/control_loops/python/hood.py
@@ -5,7 +5,6 @@
 from frc971.control_loops.python import controls
 import numpy
 import sys
-import matplotlib
 from matplotlib import pylab
 import gflags
 import glog
diff --git a/y2017/control_loops/python/intake.py b/y2017/control_loops/python/intake.py
index ae209c3..5f557f1 100755
--- a/y2017/control_loops/python/intake.py
+++ b/y2017/control_loops/python/intake.py
@@ -5,7 +5,6 @@
 from frc971.control_loops.python import controls
 import numpy
 import sys
-import matplotlib
 from matplotlib import pylab
 import gflags
 import glog
diff --git a/y2017/control_loops/python/turret.py b/y2017/control_loops/python/turret.py
index d64fceb..f07e7a5 100755
--- a/y2017/control_loops/python/turret.py
+++ b/y2017/control_loops/python/turret.py
@@ -5,7 +5,6 @@
 from frc971.control_loops.python import controls
 import numpy
 import sys
-import matplotlib
 from matplotlib import pylab
 import gflags
 import glog
diff --git a/y2017_bot3/BUILD b/y2017_bot3/BUILD
index f2992cf..f07dcf6 100644
--- a/y2017_bot3/BUILD
+++ b/y2017_bot3/BUILD
@@ -88,3 +88,9 @@
         "//y2017_bot3/control_loops/superstructure:superstructure.stripped",
     ],
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+)
diff --git a/y2017_bot3/__init__.py b/y2017_bot3/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2017_bot3/__init__.py
diff --git a/y2017_bot3/control_loops/BUILD b/y2017_bot3/control_loops/BUILD
new file mode 100644
index 0000000..a98593b
--- /dev/null
+++ b/y2017_bot3/control_loops/BUILD
@@ -0,0 +1,6 @@
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2017_bot3:python_init"],
+)
diff --git a/y2017_bot3/control_loops/__init__.py b/y2017_bot3/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2017_bot3/control_loops/__init__.py
diff --git a/y2017_bot3/control_loops/python/BUILD b/y2017_bot3/control_loops/python/BUILD
index 0209757..ed5cc69 100644
--- a/y2017_bot3/control_loops/python/BUILD
+++ b/y2017_bot3/control_loops/python/BUILD
@@ -1,42 +1,53 @@
-package(default_visibility = ['//y2017_bot3:__subpackages__'])
+package(default_visibility = ["//y2017_bot3:__subpackages__"])
 
 py_binary(
-  name = 'drivetrain',
-  srcs = [
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:drivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "drivetrain",
+    srcs = [
+        "drivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:drivetrain",
+    ],
 )
 
 py_binary(
-  name = 'polydrivetrain',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:polydrivetrain',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    legacy_create_init = False,
+    restricted_to = ["//tools:k8"],
+    deps = [
+        ":python_init",
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:polydrivetrain",
+    ],
 )
 
 py_library(
-  name = 'polydrivetrain_lib',
-  srcs = [
-    'polydrivetrain.py',
-    'drivetrain.py',
-  ],
-  deps = [
-    '//external:python-gflags',
-    '//external:python-glog',
-    '//frc971/control_loops/python:controls',
-  ],
-  restricted_to = ['//tools:k8'],
+    name = "polydrivetrain_lib",
+    srcs = [
+        "drivetrain.py",
+        "polydrivetrain.py",
+    ],
+    restricted_to = ["//tools:k8"],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2017_bot3/control_loops:python_init"],
 )
diff --git a/y2017_bot3/control_loops/python/__init__.py b/y2017_bot3/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2017_bot3/control_loops/python/__init__.py
diff --git a/y2018/BUILD b/y2018/BUILD
index 4edb57e..e4c4128 100644
--- a/y2018/BUILD
+++ b/y2018/BUILD
@@ -138,3 +138,9 @@
     src = "vision.proto",
     visibility = ["//visibility:public"],
 )
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+)
diff --git a/y2018/__init__.py b/y2018/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2018/__init__.py
diff --git a/y2018/control_loops/BUILD b/y2018/control_loops/BUILD
new file mode 100644
index 0000000..57f2864
--- /dev/null
+++ b/y2018/control_loops/BUILD
@@ -0,0 +1,6 @@
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2018:python_init"],
+)
diff --git a/y2018/control_loops/__init__.py b/y2018/control_loops/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2018/control_loops/__init__.py
diff --git a/y2018/control_loops/python/BUILD b/y2018/control_loops/python/BUILD
index 89f8882..eebbfe2 100644
--- a/y2018/control_loops/python/BUILD
+++ b/y2018/control_loops/python/BUILD
@@ -5,8 +5,10 @@
     srcs = [
         "drivetrain.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:drivetrain",
@@ -19,8 +21,10 @@
         "drivetrain.py",
         "polydrivetrain.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:polydrivetrain",
@@ -47,9 +51,11 @@
     srcs = [
         "polydrivetrain_test.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
         ":polydrivetrain_lib",
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:controls",
@@ -63,8 +69,10 @@
         "arm_trajectory.py",
         "path_points.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:controls",
@@ -76,11 +84,14 @@
     srcs = [
         "intake.py",
     ],
+    legacy_create_init = False,
     restricted_to = ["//tools:k8"],
     deps = [
+        ":python_init",
         "//external:python-gflags",
         "//external:python-glog",
         "//frc971/control_loops/python:controls",
+        "@matplotlib",
     ],
 )
 
@@ -104,9 +115,12 @@
         "graph_edit.py",
         "graph_generate.py",
     ],
-    # Sigh, these aren't respected.
     default_python_version = "PY3",
+    legacy_create_init = False,
     srcs_version = "PY3",
+    deps = [
+        ":python_init",
+    ],
 )
 
 py_binary(
@@ -115,7 +129,17 @@
         "graph_codegen.py",
         "graph_generate.py",
     ],
-    # Sigh, these aren't respected.
     default_python_version = "PY2",
+    legacy_create_init = False,
     srcs_version = "PY2",
+    deps = [
+        ":python_init",
+    ],
+)
+
+py_library(
+    name = "python_init",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = ["//y2018/control_loops:python_init"],
 )
diff --git a/y2018/control_loops/python/__init__.py b/y2018/control_loops/python/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/y2018/control_loops/python/__init__.py
diff --git a/y2018/control_loops/python/intake.py b/y2018/control_loops/python/intake.py
index a9479e0..4fb4f1e 100755
--- a/y2018/control_loops/python/intake.py
+++ b/y2018/control_loops/python/intake.py
@@ -4,7 +4,6 @@
 from frc971.control_loops.python import controls
 import numpy
 import sys
-import matplotlib
 from matplotlib import pylab
 import gflags
 import glog