title: Bazel: genrule that outputs a directory
body: <p>I'm just getting started working with Bazel. So, I apologize in advance that I haven't been able to figure this out.</p>
  
  <p>I'm trying to run a command that outputs a bunch of files to a directory and make this directory available for subsequent targets. I have two different attempts:</p>
  
  <ol>
  <li>Use genrule</li>
  <li>Write my own rule</li>
  </ol>
  
  <p>I was naively hoping to just do this with a <code>genrule</code>. But, it doesn't seem you can say "I don't know exactly what this command is going to output" and put a directory in <code>outs</code>. Now I'm trying to write a rule that can use <code>ctx.actions.declare_directory</code> but I haven't gotten it quite right. I can't seem to get the <code>tools</code> over from my workspace and into my rule.</p>
  
  <p>My genrule attempt looks something like this:</p>
  
  <pre><code>genrule(
      name = "doit",
      srcs = [
          "doitConfigA",
          "doitConfigB",
      ],
      cmd = 'HOME=. ./$(location path/to/doit) install',
  
      # Neither of the below outs work - seems like bazel wants to know
      # exactly this list of files. I don't know the files that
      # will be output ahead of time.
  
      # This one looks at the `out_dir` that I already have and
      # expects the files to be the same which they might not be
      outs = glob(["out_dir/**/*.*"]),
  
      # this fails with:
      # "declared output 'out_dir' was not 
      # created by genrule. This is probably because the genrule actually 
      # didn't create this output, or because the output was a directory 
      # and the genrule was run remotely (note that only the contents of 
      # declared file outputs are copied from genrules run remotely)"
      outs = ['out_dir'],
      tools = ['path/to/doit'],
  )
  </code></pre>
  
  <p>My custom rule attempt looks something like this:</p>
  
  <pre><code>def _impl(ctx):
    dir = ctx.actions.declare_directory("out_dir")
  
    ctx.actions.run_shell(
        outputs=[dir],
        progress_message="Running doit install ...",
        command="HOME=. ./path/to/doit install",
        tools=[ctx.attr.tools],
    )
  
  doit = rule(
      implementation=_impl,
      attrs={
        "tools": attr.label_list(allow_files=True),
      },
      outputs={"out": "out_dir"},
  )
  </code></pre>
  
  <p>Then, to run my <code>doit</code> rule, my BUILD file looks like this:</p>
  
  <pre><code>doit(
    name = 'doit',
    tools = ['path/to/doit'],
  )
  </code></pre>
  
  <p>In my genrule, the command runs but it doesn't like my trying to use a directory in <code>outs</code>, it seems. In my custom rule, I can't seem to tell Bazel that I want to use <code>./path/to/doit</code> as a tool from my workspace, eg <code>expected type 'File' for 'tools' element but got type 'list' instead</code> ...</p>
  
  <p>Seems like I must be missing something basic because surely this is a common situation to run a command and output a bunch of unknown stuff to a directory?</p>