2

I'm building ARM Cortex-M firmware from Bazel with a custom CROSSTOOL. I'm successfully building elf files and manually objcopying them to binary files with the usual:

path/to/my/objcopy -o binary hello.elf hello.bin

I want to make a Bazel macro or rule called cc_firmware that:

  • Adds the -Wl,-Map=hello.map flags to generate a mapfile
  • Changes the output elf name from hello to hello.elf
  • Invokes path/to/my/objcopy to convert the elf to a bin.

I don't know how to get the name of a CROSSTOOL tool (objcopy) to invoke it, and it feels wrong to have the rule know the path to the tool executable.

Is there a way to use the objcopy that I've already told Bazel about in my CROSSTOOL file?

4

1 回答 1

3

您实际上可以从自定义规则中访问它。基本上,您需要告诉 Bazel 您想要访问cpp配置信息 ( fragments = ["cpp"]),然后通过 访问其路径ctx.fragments.cpp.objcopy_executable,例如:

def _impl(ctx):
    print("path: {}".format(ctx.fragments.cpp.objcopy_executable))
    # TODO: actually do something with the path...

cc_firmware = rule(
    implementation = _impl,
    fragments = ["cpp"],
    attrs = {
         "src" : attr.label(allow_single_file = True),
         "map" : attr.label(allow_single_file = True),
    },
    outputs = {"elf" : "%{name}.elf"}
)

然后使用类似(未经测试)创建您想要的输出:

def _impl(ctx):
  src = ctx.attr.src.files.to_list()[0]
  m = ctx.attr.map.files.to_list()[0]

  ctx.action(
    command = "{objcopy} -Wl,-Map={map} -o binary {elf_out} {cc_bin}".format(
        objcopy=ctx.fragments.cpp.objcopy_executable,
        map=m,
        elf_out=ctx.outputs.elf.path,
        cc_bin=src,
    ),
    outputs = [ctx.outputs.elf],
    inputs = [src, m],
  )
于 2017-08-07T16:56:57.810 回答