是否可以为 exec 平台构建部分可执行文件并将它们用作目标平台的工具链?
Posted
技术标签:
【中文标题】是否可以为 exec 平台构建部分可执行文件并将它们用作目标平台的工具链?【英文标题】:Is it possible to build part of executables for exec platform and use them as toolchain for target platform? 【发布时间】:2021-11-24 09:58:03 【问题描述】:我有一些关于 bazel 平台和工具链的问题。我目前正在尝试做以下事情:
通过 Bazel 规则构建 clang 将此 clang 用作 cc_toolchain 的一部分 通过这个新工具链构建与 llvm 工具链无关的其他规则。 通过一个“build bazel ...:*”命令完成上述所有这 3 个步骤。那么,有可能吗?要为 exec 平台构建可执行文件的某些部分(cc_binary、cc_library),然后使用它们作为工具链的一部分,通过使用一个“bazel build”调用为目标平台构建其他可执行文件?还是只能通过几个 bazel 调用来做这样的事情?
我试图用平台和平台转换来做这样的事情,但不知道该怎么做。 你有什么想法吗?
谢谢
【问题讨论】:
【参考方案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 工具链构建的目标使用平台转换,这似乎是工作,但你的解决方案似乎很简单,我也会试试这个,谢谢!以上是关于是否可以为 exec 平台构建部分可执行文件并将它们用作目标平台的工具链?的主要内容,如果未能解决你的问题,请参考以下文章
是否有 Eclipse 插件来构建用于分发的 python 可执行文件?
exec:“powershell”:在 Terraform 中运行 local-exec 时在 $PATH 中找不到可执行文件