【问题标题】:Is it possible to build part of executables for exec platform and use them as toolchain for target platform?是否可以为 exec 平台构建部分可执行文件并将它们用作目标平台的工具链?
【发布时间】:2021-11-24 09:58:03
【问题描述】:

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

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

那么,有可能吗?要为 exec 平台构建可执行文件的某些部分(cc_binary、cc_library),然后使用它们作为工具链的一部分,通过使用一个“bazel build”调用为目标平台构建其他可执行文件?还是只能通过几个 bazel 调用来做这样的事情?

我试图用平台和平台转换来做这样的事情,但不知道该怎么做。 你有什么想法吗?

谢谢

【问题讨论】:

    标签: bazel bazel-rules


    【解决方案1】:

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

    更棘手的是如何让它与 cc_toolchain 一起工作。与 bazel-discuss@googlegroups.com 联系可能会有所帮助,以了解您目前所拥有的以及无法正常工作的内容。

    另请参阅
    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"],
    )
    
    py_binary(
      name = "printself_compiler_dos_py",
      srcs = ["printself_compiler_dos.py"],
      main = "printself_compiler_dos.py",
    )
    
    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 intput 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
    

    【讨论】:

    • 感谢您的回答!在我提出问题之后,我尝试使用两个显式 cc 工具链(第一个用于主机工具链,第二个用于自定义 clang 工具链)以及两个具有不同约束的不同平台,并为应该通过 clang 工具链构建的目标使用平台转换,这似乎是工作,但你的解决方案似乎很简单,我也会试试这个,谢谢!
    猜你喜欢
    • 2015-06-21
    • 2016-09-09
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多