完全可以在一次 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