Bazel和自动生成的cpp/hpp文件

8

我开始使用Bazel作为我的C++项目构建系统。

但是我遇到了以下问题:

我处于一个自动生成file.hpp和file.cpp文件(文学编程)的场景中。

要重现我的问题,可以简单地使用此最小生成器:

-- file.sh --
#!/bin/sh
echo "int foo();" >> file.hpp
echo "#include \"myLib/file.hpp\"\n\nint foo() { return 2017; }" >> file.cpp

我的项目仓库是:(WORKSPACE是一个空文件)

├── myLib
│   ├── BUILD
│   └── file.sh
└── WORKSPACE

BUILD 文件是指:
genrule(
  name = "tangle_file",
  srcs = ["file.sh"],
  outs = ["file.cpp","file.hpp"],
  cmd =  "./$(location file.sh);cp file.cpp $(@D);cp file.hpp $(@D);"
)

cc_library(
    name = "file",
    srcs = ["file.cpp"],
    hdrs = ["file.hpp"],
#    deps = [":tangle_file"],
    visibility = ["//bin:__pkg__"],
)

我是一个有用的助手,可以翻译文本。
我有两个问题:
问题(A),涉及genrule()部分:
我必须使用
cmd =  "./$(location file.sh);cp file.cpp $(@D);cp file.hpp $(@D);"

很神秘。

我的第一次尝试是:

cmd =  "./$(location file.sh)"

不过,在这种情况下,我会遇到以下错误:

声明的输出 'myLib/file.cpp' 不是由 genrule 创建的。这可能是因为 genrule 实际上没有创建此输出,或者是因为输出是一个目录并且在远程运行了 genrule(请注意,仅从在远程运行的 genrules 中复制声明文件输出的内容)

问题(B),处理 cc_library() 部分

我不知道如何让 Bazel 知道 :file 目标依赖于 :tangle_file 目标。

如果我取消注释:

deps = [":tangle_file"],

我遇到了以下错误:
在cc_library规则的deps属性中,//myLib:file中的genrule规则“//myLib:tangle_file”放错了位置(应该放在cc_inc_library、cc_library、objc_library、experimental_objc_library或cc_proto_library之中)。
1个回答

10

问题(A)

您看到的错误是由于genrule cmd未在其输出目录中运行。如果您在file.sh脚本中硬编码了bazel-out/local-fastbuild/genfiles/myLib/file.cpp而不是file.cpp,那么它将起作用。但是,建议的方法是让您的脚本将其输出目录作为参数。

例如,

genrule(
  name = "tangle_file",
  srcs = ["file.sh"],
  outs = ["file.cpp","file.hpp"],
  cmd =  "./$(location file.sh) $(@D)"
)

#!/bin/sh
echo "int foo();" >> $1/file.hpp
echo "#include \"myLib/file.hpp\"\n\nint foo() { return 2017; }" >> $1/file.cpp

问题(B)

你拥有的事实

srcs = ["file.cpp"],
hdrs = ["file.hpp"],

在你的 cc_library 中告诉 Bazel 它依赖于 genrule,因为 genrule 创建了这些文件。如果你想更明确地表达,可以使用标签语法,它也会做同样的事情:

srcs = ["//myLib:file.cpp"],
hdrs = ["//myLib:file.hpp"],

谢谢!我根据您的解释修补了我的文件,一切都像魔法般地运行良好! - Picaud Vincent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接