【发布时间】:2020-06-25 03:58:00
【问题描述】:
我被难住了:(
我正在将一些用于非常复杂的嵌入式系统的 Makefile 移植到 Bazel,但我遇到了一些问题,我有一些奇怪的依赖项。
一些背景知识,所以你知道我为什么要做这些奇怪的事情:我正在使用我开发的交叉编译器工具链为 TI C6000 系列处理器构建。 TI 为您使用他们提供的 java 工具配置的处理器提供了可配置的 BIOS。这会创建一堆文件,包括链接器命令文件和编译器命令文件。它们有一个非标准的扩展名,而 Bazel 对扩展名很挑剔,所以我将扩展名为 .lds 的命令文件复制到我的 genrule 中。
我可以直接构建它,但是当我尝试构建依赖于正在构建的 BIOS(因此命令文件可用)的cc_library 时,它不会首先构建 BIOS。
这里是相关的genrule。我将逐字包含代码,因为我想知道是否有一些导致问题的细微语法错误。当我尝试调试时,shell 部分变得越来越复杂。一旦一切正常,我可能会将它变成一个单独的 shell 脚本。
genrule(
name = "libs",
srcs = [
":deps",
"ti_bios_without_edma3.cfg",
],
outs = [
"compiler.opt",
"compiler.opt.lds",
"linker.cmd",
"linker.cmd.lds",
"package/package.defs.h",
"package/cfg/ti_bios_without_edma3_pe66.h",
"package/cfg/ti_bios_without_edma3_pe66.oe66",
"package/cfg/ti_bios_without_edma3_pe66.src/utils/utils.ae66",
"package/cfg/ti_bios_without_edma3_pe66.src/sysbios/sysbios.ae66",
"package/cfg/ti_bios_without_edma3_pe66.src/ipc/ipc.ae66",
],
cmd = """
rm -rf "$(@D)" \
&& $(location //phy/platform/ti_bios_common:xdc_parser.sh) \
$(location ti_bios_without_edma3.cfg) \
"/workspace/output/bazel_output_base/execroot/cap/$(location linker.cmd)" \
"$(@D)" > /dev/null \
&& cp $(location linker.cmd) $(location linker.cmd).lds \
&& cp $(location compiler.opt) $(location compiler.opt).lds
""",
tools = ["//phy/platform/ti_bios_common:xdc_parser.sh"],
visibility = ["//visibility:public"],
)
这是依赖于它的规则
# TI optimized math library
cc_library(
name = "math_ti",
srcs = [
"src/ti_c66x/multiply_cmplx_mat_vec.c",
"src/ti_c66x/add_cmplx_vec.c",
"src/ti_c66x/add_real_vec.c",
"src/ti_c66x/calc_abs_val_vec.c",
"src/ti_c66x/calc_positive_real_vec_log.c",
"src/ti_c66x/calc_positive_real_vec_sqrt.c",
"src/ti_c66x/calc_vec_cos.c",
"src/ti_c66x/calc_real_vec_exp.c",
"src/ti_c66x/calc_real_vec_alog.c",
"src/ti_c66x/div_real_vec.c",
"src/ti_c66x/multiply_cmplx_mat.c",
"src/ti_c66x/multiply_real_mat.c",
"src/ti_c66x/multiply_real_vec.c",
"src/ti_c66x/multiply_cmplx_vec.c",
"src/ti_c66x/tw_alog.c",
"src/ti_c66x/tw_log.c",
],
hdrs = [
"math_generic.h",
],
copts = [
"--cmd_file=$(location //phy/platform/ti_bios_without_edma3:compiler.opt.lds)"
],
linkopts = [
"-@$(location //phy/platform/ti_bios_without_edma3:linker.cmd.lds)"
],
visibility = [
"//visibility:private",
],
deps = [
":math_generic",
":math_generic_novla",
"//phy/include:common",
"//phy/platform/ti_bios_without_edma3:compiler.opt.lds",
"//phy/platform/ti_bios_without_edma3:linker.cmd.lds",
],
data = [
"//phy/platform/ti_bios_without_edma3:libs",
]
)
在我的一生中,我无法在构建 math 库之前构建 BIOS。如果我先手动构建 BIOS,然后构建 math 库,那么我的构建成功,但在干净构建中,math 库构建失败,因为尚未构建 BIOS。
我在 x86 上的 Ubuntu 16.04 Docker 中使用 Bazel 1.1.0
很抱歉写小说。非常感谢任何帮助!
编辑:
$ bazel query "deps(//phy/lib/math:math_ti)" 给我的查询
...
//phy/platform/ti_bios_without_edma3:linker.cmd.lds
//phy/platform/ti_bios_without_edma3:compiler.opt.lds
//phy/platform/ti_bios_without_edma3:libs
//phy/platform/ti_bios_without_edma3:ti_bios_without_edma3.cfg
//phy/platform/ti_bios_without_edma3:deps
...
所以它确实将//phy/platform/ti_bios_without_edma3:libs 识别为依赖项,但在构建我的库之前它不会构建它:
SUBCOMMAND: # //phy/lib/math:math_ti [action 'Compiling phy/lib/math/src/ti_c66x/multiply_cmplx_mat_vec.c', configuration: 04904b24bebbf24a56366c3e37012771]
...
ERROR: /twbuild/rj/2work/tarana3/cpu/applications/src/phy/lib/math/BUILD:192:1: C++ compilation of rule '//phy/lib/math:math_ti' failed (Exit 1)
>> ERROR: Cannot open command file 'bazel-out/ti_c6000-opt-bn_c10/bin/phy/platform/ti_bios_without_edma3/compiler.opt.lds': No such file or directory
...
没有子命令显示它试图构建//phy/platform/ti_bios_without_edma3:libs
在这些命令之后,我可以运行查找并且看不到任何生成的文件:
$ find -L . -name compiler.opt.lds
$
如果我直接构建//phy/platform/ti_bios_without_edma3:libs,那么我确实会看到生成的文件:
$ find -L . -name compiler.opt.lds
./bazel-src/bazel-out/ti_c6000-opt-bn_c10/bin/phy/platform/ti_bios_without_edma3/compiler.opt.lds
./bazel-bin/phy/platform/ti_bios_without_edma3/compiler.opt.lds
./bazel-out/ti_c6000-opt-null for //phy/lib/math:math_ti
Mnemonic: Middleman
Target: //phy/lib/math:math_ti
Configuration: ti_c6000-opt-bn_c10
ActionKey: 5c25f976e1ff1473093bcd3508178109
Inputs: [bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Sinclude_Ccommon-null, bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Ugeneric-null, bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Ugeneric_Unovla-null, phy/lib/math/math_generic.h]
Outputs: [bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Uti-null]
action 'Compiling phy/lib/math/src/ti_c66x/multiply_cmplx_mat_vec.c'
Mnemonic: CppCompile
Target: //phy/lib/math:math_ti
Configuration: ti_c6000-opt-bn_c10
ActionKey: 92f17fb0219b9758ba79e3c77721e5c7
Inputs: [bazel-out/host/internal/_middlemen/tools_Sti_Ucompiler_Cempty, bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Uti-null, external/bazel_tools/tools/cpp/grep-includes.sh, phy/lib/math/src/ti_c66x/multiply_cmplx_mat_vec.c]
Outputs: [bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.d, bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.o]
Command Line: (exec tools/ti_compiler/wrapper_scripts/cl6x \
-ppa \
-k \
-pden \
-pdv \
-pdew \
-c \
--c99 \
'--diag_error=225' \
-O3 \
phy/lib/math/src/ti_c66x/multiply_cmplx_mat_vec.c \
--output_file \
bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.o \
'-ppd=bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.d' \
-I. \
-Ibazel-out/ti_c6000-opt-bn_c10/bin \
-Iexternal/ti_toolchain/include \
-Ithird_party/ti/dsplib_c66x/packages \
-Ithird_party/ti/mathlib_c66x/packages \
-DPLATFORM_C10 \
-DROLE_BN \
'-DPLATFORM=B10' \
'-DROLE=BN' \
--verbose \
'--cmd_file=bazel-out/ti_c6000-opt-bn_c10/bin/phy/platform/ti_bios_without_edma3/compiler.opt.lds')
bn_c10/bin/phy/platform/ti_bios_without_edma3/compiler.opt.lds
编辑:
我没有意识到bazel aquery 是一个东西。我看到了这条线
action 'Executing genrule //phy/platform/ti_bios_without_edma3:libs'
在aquery 输出的底部,我认为这意味着 Bazel 想要在我所有的编译之后执行它,而不是之前。
这是aquery的结果顶部:
null for //phy/lib/math:math_ti
Mnemonic: Middleman
Target: //phy/lib/math:math_ti
Configuration: ti_c6000-opt-bn_c10
ActionKey: 5c25f976e1ff1473093bcd3508178109
Inputs: [bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Sinclude_Ccommon-null, bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Ugeneric-null, bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Ugeneric_Unovla-null, phy/lib/math/math_generic.h]
Outputs: [bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Uti-null]
action 'Compiling phy/lib/math/src/ti_c66x/multiply_cmplx_mat_vec.c'
Mnemonic: CppCompile
Target: //phy/lib/math:math_ti
Configuration: ti_c6000-opt-bn_c10
ActionKey: 92f17fb0219b9758ba79e3c77721e5c7
Inputs: [bazel-out/host/internal/_middlemen/tools_Sti_Ucompiler_Cempty, bazel-out/ti_c6000-opt-bn_c10/internal/_middlemen/_S_Sphy_Slib_Smath_Cmath_Uti-null, external/bazel_tools/tools/cpp/grep-includes.sh, phy/lib/math/src/ti_c66x/multiply_cmplx_mat_vec.c]
Outputs: [bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.d, bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.o]
Command Line: (exec tools/ti_compiler/wrapper_scripts/cl6x \
-ppa \
-k \
-pden \
-pdv \
-pdew \
-c \
--c99 \
'--diag_error=225' \
-O3 \
phy/lib/math/src/ti_c66x/multiply_cmplx_mat_vec.c \
--output_file \
bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.o \
'-ppd=bazel-out/ti_c6000-opt-bn_c10/bin/phy/lib/math/_objs/math_ti/multiply_cmplx_mat_vec.d' \
-I. \
-Ibazel-out/ti_c6000-opt-bn_c10/bin \
-Iexternal/ti_toolchain/include \
-Ithird_party/ti/dsplib_c66x/packages \
-Ithird_party/ti/mathlib_c66x/packages \
-DPLATFORM_C10 \
-DROLE_BN \
'-DPLATFORM=B10' \
'-DROLE=BN' \
--verbose \
'--cmd_file=bazel-out/ti_c6000-opt-bn_c10/bin/phy/platform/ti_bios_without_edma3/compiler.opt.lds')
所以它确实没有将compiler.opt.lds 或linker.cmd.lds 视为输入。
【问题讨论】:
-
您遇到什么错误?
.lds文件中的一个或两个“找不到文件”?您可以做几件事来帮助诊断:清理后,使用--subcommands构建库以确认libsgenrule 正在运行。然后在math_ti上执行bazel aquery,并确认.lds文件实际上已添加到相关操作的输入中(不仅仅是命令行)。我猜虽然在 deps 中有.lds文件会导致它们被构建,但$(location)不会导致它们被添加到输入中,所以它们不在沙箱中 -
我将您问题的答案放入问题中,以便进行格式化。我不认为问题在于找不到它们,因为它从不尝试构建库,但是如果我先手动构建它,那么构建就会成功。
-
所以
query将返回目标级别的依赖关系,看起来不错,这只是告诉您.lds文件确实在deps 中列出。bazel aquery //phy/lib/math:math_ti会告诉你你需要的输入是否真的被添加到动作中。将.lds文件移动到data而不是deps可能会起作用。aquery会告诉你发生了什么 -
“如果我先手动构建它,那么构建成功” - 你的意思是如果你先构建
libs,然后构建math_ti,它可以工作吗?您是否在没有沙盒的情况下运行? -
我不确定我是否使用沙盒。阅读它,我认为答案可能是肯定的。但我不确定,因为我们从 v0.11 开始就一直在使用 Bazel,大约 6 个月前我们进行了复杂的迁移到 v1.1.0。我怎么知道?关于您的第一个问题:是的,如果我先构建
libs然后构建math_ti,则构建工作。如果我将.lds文件放在数据部分中,我会看到会发生什么
标签: cross-compiling bazel