是否可以为exec平台构建部分可执行文件并将其用作目标平台的工具链?

问题描述 投票:0回答:1

我有一些关于 bazel 平台和工具链的问题。我目前正在尝试做以下几件事:

  • 通过 Bazel 规则构建 clang
  • 使用此 clang 作为 cc_toolchain 的一部分
  • 通过这个新工具链构建与 llvm 工具链无关的其他规则。
  • 通过一个“build bazel ...:*”命令完成上述所有 3 个步骤。

那么,可能吗?要为 exec 平台构建可执行文件的一部分(cc_binary、cc_library),然后将它们用作工具链的一部分,通过使用一个“bazel build”调用为目标平台构建其他可执行文件?或者只能通过几次 bazel 调用才能完成这样的事情?

我试图通过平台和平台转换来做这样的事情,但不知道如何做到这一点。 你有什么想法吗?

谢谢

bazel bazel-rules
1个回答
2
投票

完全可以在一次 Bazel 调用中编译要在另一个工具链中使用的工具。我有一个工具链+平台玩具,我粘贴在该演示下面。

更棘手的事情是如何让它与 cc_toolchain 一起工作。联系 [电子邮件受保护] 告知您目前所掌握的内容和不起作用的内容可能会有所帮助。

另请参阅
https://docs.bazel.build/versions/main/tutorial/cc-toolchain-config.html
https://docs.bazel.build/versions/main/cc-toolchain-config-reference.html


BUILD

load(":printself.bzl", "printself_toolchain", "printself_binary")

cc_binary(
  name = "printself_compiler_dos",
  srcs = ["printself_compiler_dos.c"],
)

constraint_setting(name = "os")
constraint_setting(name = "cpu")

constraint_value(
  name = "dos",
  constraint_setting = ":os",
)

constraint_value(
  name = "8086",
  constraint_setting = ":cpu",
)

platform(
  name = "dos_8086",
  constraint_values = [
    ":dos",
    ":8086"
  ],
)

toolchain_type(name = "printself_toolchain_type")

printself_toolchain(
  name = "printself_toolchain",
  compiler = ":printself_compiler_dos",
)

toolchain(
    name = "printself_toolchain_dos_8086",
    target_compatible_with = [
        ":dos",
        ":8086",
    ],
    toolchain = ":printself_toolchain",
    toolchain_type = ":printself_toolchain_type",
)

printself_binary(
  name = "hello",
  src = "input.txt",
)

printself.bzl


def _printself_impl(ctx):
  compiler = ctx.toolchains["//:printself_toolchain_type"].compiler
  out = ctx.actions.declare_file(ctx.label.name + ".com")
  ctx.actions.run(
      outputs = [out],
      inputs = [ctx.files.src[0]],
      arguments = [ctx.files.src[0].path, out.path],
      executable = compiler.files_to_run,
  )

  return DefaultInfo(files = depset([out]))

printself_binary = rule(
  implementation = _printself_impl,
  attrs = {
    "src": attr.label(mandatory = True, allow_single_file = True),
  },
  toolchains = ["//:printself_toolchain_type"]
)

def _printself_toolchain_impl(ctx):
    toolchain_info = platform_common.ToolchainInfo(
        compiler = ctx.attr.compiler,
    )
    return [toolchain_info]

printself_toolchain = rule(
    implementation = _printself_toolchain_impl,
    attrs = {
        "compiler": attr.label(mandatory = True, executable = True, cfg = "exec"),
    },
)

printself_compiler_dos.c

#include <stdio.h>

// "compiles" a txt file to a "self printing" text file
int main(int argc, char *argv[]) {
  if (argc != 3) {
    printf("input and output filenames needed\n");
    return 1;
  }
  printf("compiling %s\n", argv[1]);

  FILE* src = fopen(argv[1], "r");
  if (src == NULL) {
    printf("could not open input file");
    return 1;
  }
  char srcbuff[255];
  if (fgets(srcbuff, 255, src) == NULL) {
    printf("could not read input file");
    fclose(src);
    return 1;
  }
  fclose(src);

  char prog[] = {
    /* mov ax, 9   */ 0xB4, 0x09,
    /* mov dx, msg */ 0xBA, 0x08, 0x01, // 0x0108 is byte after ret
    /* int 21h     */ 0xCD, 0x21,
    /* ret         */ 0xC3,
    /* msg: db "$" */ 
  };
  
  FILE* out = fopen(argv[2], "w");
  fwrite(prog, 1, 8, out);
  fputs(srcbuff, out);
  fputc('$', out); // $ terminated string
  fclose(out);

  printf("wrote %s\n", argv[2]);
  printf("done\n");
  return 0;
}

WORKSPACE

register_toolchains("//:printself_toolchain_dos_8086")

input.txt

hello world!

用途:

bazel build hello --platforms=//:dos_8086
dosbox bazel-bin/hello.com
© www.soinside.com 2019 - 2024. All rights reserved.