Use a (mostly) hermetic Python interpreter

It still requires python to be installed on the host to run the wrapper
scripts, but it's close to being fully hermetic.

This also requires/enables the following changes, unfortunately all at
the same time:
 * Use a downloaded f2py
 * Use a downloaded scipy/numpy/matplotlib
 * Fix a few things that don't run with the python version in their #!
 * Stop using bazel-generated __init__.py files, because those interfere
   with importing matplotlib nicely

Change-Id: Ife280464613d67cece9587b7d947f0b1d5466d7e
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",
+    ],
 )