由于新的工作区模式,Bazel无法构建go目标(版本1.21)

frebpwbc  于 2023-11-14  发布在  Go
关注(0)|答案(1)|浏览(135)

您使用的是哪个版本的rules_go?

0.42.0

您使用的是哪个版本的gazelle?

0.33.0

您使用的是哪个版本的Bazel?

6.4.0

此问题是否会在上述所有最新版本中重现?

是的

您使用的是什么操作系统和处理器架构?

MacOS索诺马/苹果M2 Pro
你做了什么
升级到go 1.21,现在当我运行bazel build //...时,我的程序使用的所有外部go模块都会抛出与1.18 https://go.dev/doc/tutorial/workspaces中引入的新工作区模式相关的错误:
x1c 0d1x的数据
我该如何解决这个问题?没有可行的方法将该目录中使用的所有模块添加到go.work文件中。2有没有方法关闭这个新的工作区模式?

9jyewag0

9jyewag01#

在我看来,错误消息是:

ERROR: /private/var/tmp/_bazel_ - /9b1e5e83eabb1d6e19b3164cad07defe/external/com_github_klosmo_atlas_app_toolkit_v2/rpc/errfields/BUILD.bazel:18:11: GoCompilePkg external/com github_klosmo_atlas_app_toolkit_v2/rpc/errfields/errfields.a failed: (Exit 1): builder failed: error executing command (from target @com_github_klosmo_atlas_app_toolkit_v2//rpc/errfields:errfields) bazel-out/d&rwin_arm64-opt=exec-2B5CBBC6/bin/external/go_sdk/builder_reset/builder compilepkg -sdk external/go_sdk -installsuffix darwin_arm64 -src (remaining 21 arguments skipped)
Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
external/com_github_klosmo_atlas_app_toolkit v2/rpc/errfields/error_fields.go:7:10: undefined: FieldInfo
external/com_github_klosmo_atlas.app_toolkit_v2/rpc/errfields/error.fields.go:9:26; undefined: StringListValue
external/com_github_klosmo_atlas_app_toolkit_v2/rpc/errfields/error_fields.go:13:23: undefined: StringListValue
external/com_github_klosmo_atlas app_toolkit_v2/rpc/errfields/error_fields.go:20:11: undefined: FieldInfo
external/com_github_klosmo_atlas_app_toolkit_v2/rpc/errfields/error_fields.go:39:11: undefined: FieldInfo
compilepkg: error running subcommand external/go sdk/pkg/tool/darwin_arm64/compile: exit status 2
INFO: Elapsed time: 31.451s, Critical

字符串
这表明Bazel构建中针对来自com_github_klosmo_atlas_app_toolkit_v2存储库的Go包的编译失败。
错误消息特别提到了errfields包中未定义的标识符,如FieldInfoStringListValue。这表明代码中可能缺少依赖项或导入路径不正确。
不,问题不是拉入目标仓库,问题是Bazel将仓库符号链接到/private/var/tmp/_bazel_/external/目录,并从那里构建所有目标-随着go xml 4的出现,这些被认为是我项目的外部模块;因此抛出错误,因为我没有使用go.work文件来引用这些“外部”模块。
我不可能以这种方式手动引用每一个go模块,所以我想知道是否有一个解决方案。
因此,问题来自Go的新工作区模式与Bazel处理外部依赖项的方式之间的交互,Bazel通过将它们符号链接到单独的目录(outputRoot directory)中来处理外部依赖项。这种行为导致Go将这些依赖项视为外部模块,这反过来会在go.work文件未用于引用这些模块时触发错误。
作为一种解决方法,您可以考虑创建一个脚本,设置从Bazel构建目录到Go工作区的必要符号链接,模仿Go工作区模式所期望的布局。
这个脚本可以作为预构建步骤运行(有点像in this question,关于bazel预构建步骤)。

#!/bin/bash
ln -s /private/var/tmp/_bazel_/external/ /path/to/your/go/workspace
bazel build //...


或者,您可以根据go.mod文件或Bazel构建文件中指定的依赖项自动生成go.work文件。此脚本可以扫描项目的依赖项,并自动生成引用所有必需模块的go.work文件。

#!/bin/bash
# Script to generate go.work file based on dependencies
# for instance, using go list -m all

# Define the output go.work file
gowork_file="./go.work"

# Create or clear the output go.work file
echo "go 1.18" > $gowork_file

# Get the list of module dependencies from the current project
deps=$(go list -m all | tail -n +2)

# Write the module dependencies to the go.work file
echo "" >> $gowork_file
echo "require (" >> $gowork_file
for dep in $deps; do
    echo "    $dep" >> $gowork_file
done
echo ")" >> $gowork_file

# Output the generated go.work file to the console
cat $gowork_file


由于bazelbuild/bazel-gazelle有一个“非常简约的支持go example”(PR 1250),这可能会有所帮助。

相关问题