Bazel 和自动生成的 cpp / hpp 文件
Bazel & automatically generated cpp / hpp files
我开始使用 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)"
但是在那种情况下我得到以下错误:
declared output 'myLib/file.cpp' was not created by genrule. This is probably because the genrule actually didn't create this output, or because the output was a directory and the genrule was run remotely (note that only the contents of declared file outputs are copied from genrules run remotely)
问题(B),处理cc_library()部分
我不知道如何让 Bazel 知道 :file 目标依赖于 :tangle_file 目标.
如果我取消注释:
deps = [":tangle_file"],
我收到以下错误:
in deps attribute of cc_library rule //myLib:file: genrule rule '//myLib:tangle_file' is misplaced here (expected cc_inc_library, cc_library, objc_library, experimental_objc_library or cc_proto_library).
问题 (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();" >> /file.hpp
echo "#include \"myLib/file.hpp\"\n\nint foo() { return 2017; }" >> /file.cpp
问题 (B)
你拥有的事实
srcs = ["file.cpp"],
hdrs = ["file.hpp"],
在你的 cc_library
中告诉 Bazel 它依赖于 genrule
,因为 genrule
创建了这些文件。如果你想让它更明确,你可以使用标签语法,它做同样的事情:
srcs = ["//myLib:file.cpp"],
hdrs = ["//myLib:file.hpp"],
我开始使用 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)"
但是在那种情况下我得到以下错误:
declared output 'myLib/file.cpp' was not created by genrule. This is probably because the genrule actually didn't create this output, or because the output was a directory and the genrule was run remotely (note that only the contents of declared file outputs are copied from genrules run remotely)
问题(B),处理cc_library()部分
我不知道如何让 Bazel 知道 :file 目标依赖于 :tangle_file 目标.
如果我取消注释:
deps = [":tangle_file"],
我收到以下错误:
in deps attribute of cc_library rule //myLib:file: genrule rule '//myLib:tangle_file' is misplaced here (expected cc_inc_library, cc_library, objc_library, experimental_objc_library or cc_proto_library).
问题 (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();" >> /file.hpp
echo "#include \"myLib/file.hpp\"\n\nint foo() { return 2017; }" >> /file.cpp
问题 (B)
你拥有的事实
srcs = ["file.cpp"],
hdrs = ["file.hpp"],
在你的 cc_library
中告诉 Bazel 它依赖于 genrule
,因为 genrule
创建了这些文件。如果你想让它更明确,你可以使用标签语法,它做同样的事情:
srcs = ["//myLib:file.cpp"],
hdrs = ["//myLib:file.hpp"],