Bazel:输出目录的风格

时间:2018-06-28 00:29:51

标签: bazel skylark starlark

我刚刚开始使用Bazel。因此,我预先向您致歉,直到无法解决。

我正在尝试运行一个命令,该命令将一堆文件输出到一个目录,并使该目录可用于后续目标。我有两种不同的尝试:

  1. 使用genrule
  2. 写下我自己的规则

我很天真地希望用<?xml version="1.0"?> <menu> <header> <listname>Files list</listname> <lastlistupdate>02/08/2018</lastlistupdate> </header> <project name="file001" index="true" image="'"> <description>ABC Project</description> <month>January</month> </project> <project name="file002" index="true" image="'"> <description>DEF Project</description> <month>February</month> </project> <project name="file003" index="true" image="'"> <description>Not really important project</description> <month>March</month> </project> </menu> 来做到这一点。但是,您似乎无法说“我不知道此命令将要输出什么”,而是将目录放在Dim xmlfile As String = "" Dim filename As String = "" Dim title As String = "" ListViewFiles.Items.Clear() xmlfile = Application.StartupPath & "\projectlist.xml" Dim xr As XmlReader = XmlReader.Create(xmlfile) While xr.Read() If xr.NodeType = XmlNodeType.Element AndAlso xr.Name = "project" Then filename = xr.GetAttribute(0) 'Gets "name" correctly (ex: file001) title = Trim(xr.ReadString()) '<<<<-- will not work WriteLog("xr.name: " & xr.Name.ToString) <-shows the tag "description"??? ListViewFiles.Items.Add(New ListViewItem(New String() {filename, title})) End If End While xr.Close() 中。现在,我正在尝试编写一个可以使用genrule的规则,但是我还没有完全正确。我似乎无法将outs从工作区转移到规则中。

我的绅士尝试看起来像这样:

ctx.actions.declare_directory

我的自定义规则尝试看起来像这样:

tools

然后,要运行我的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'], ) 规则,我的BUILD文件如下所示:

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"},
)

在我看来,该命令可以运行,但似乎不像我尝试在doit中使用目录。在我的自定义规则中,我似乎无法告诉Bazel我想使用doit( name = 'doit', tools = ['path/to/doit'], ) 作为工作区中的工具,例如outs ...

似乎我必须缺少一些基本知识,因为肯定是运行命令并将一堆未知内容输出到目录中的常见情况吗?

2 个答案:

答案 0 :(得分:4)

genrule must be a fixed list of files的输出。解决方法是,可以从输出目录创建一个zip。

我使用这种方法来操纵yarn install的输出,而通常的方法不可行:

genrule(
  name = "node_modules",
  srcs = [
    "package.json",
    "yarn.lock",
  ],
  cmd = " && ".join([
    "yarn install --pure-lockfile",
    "zip -r $@ node_modules",
  ]),
  outs = [
    "node_modules.zip",
  ],
)

然后是一个使用zip的规则:

# Rule that generates a list of the folders in node_modules
genrule(
  name = "node_modules_ls",
  srcs = [
    ":node_modules",
  ],
  cmd = " && ".join([
    "unzip $(location :node_modules) -d . ",
    "ls > $@",
  ]),
  outs = [
    "out.txt",
  ],
)

答案 1 :(得分:2)

前一段时间,我创建了一个示例,展示了如何使用云雀动作How to build static library from the Generated source files using Bazel Build使用目录。也许它仍然有效:)

Genrule不起作用,这是太高级的用例。