title: Zipping Bazel-generated files for deployment
body: <p>I have a Bazel project that contains a <code>python/</code> folder in the root. This folder contains two files:</p>
  
  <pre><code># BUILD
  py_binary(
      name = "foo",
      srcs = ["foo.py"],
      deps = ["//cc:bar"],
  )
  </code></pre>
  
  <p>and</p>
  
  <pre><code># foo.py
  import cc.bar as bar
  
  # This is a SWIG-wrapped C++ function that prints "hello world"
  print(bar.hello_world())
  </code></pre>
  
  <p>The <code>cc/</code> folder, which is also in the root, contains (among other things) the following rule:</p>
  
  <pre><code># Expose the shared object library to Python.
  py_library(
      name = "bar",
      srcs = [":bar_swig.py"], # Generated by SWIG.
      data = [":_bar.so"], # Generated by SWIG.
      visibility = ["//python:__pkg__"],
  )
  </code></pre>
  
  <p>Running <code>bazel build //python:foo</code> generates <code>bazel-bin/python/foo.runfiles/</code> and <code>bazel-bin/python/foo</code>. I would like to write a rule in Bazel that gathers this directory and binary and zips them in <code>foo.zip</code>.</p>
  
  <p>This is what I came up with:</p>
  
  <pre><code>genrule(
      name = "zip_foo",
      srcs = ["//python:foo"],
      outs = ["foo.zip"],
      cmd = "zip $@ $(locations //python:foo)",
  )
  </code></pre>
  
  <p>However, the generated zip does not include <code>foo.runfiles/</code>. How do I write a rule that zips all of a target's runtime dependencies? I would like this rule to be as generic as possible, by which I mean it should handle zipping any target's runtime, even if the target has complex dependencies.</p>