-
Notifications
You must be signed in to change notification settings - Fork 653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Repeated issues with unable to create directory for _empty.go on Windows #3558
Comments
I have just done a complete clean build with "--jobs=1" and it ran through successfully without intervention, so this would appear to be a concurrency issue of some kind. Note that I'm not using the experimental "sandboxing" feature on Windows. As I say, the curiosity I have is why it's even attempting to create an "_empty.go" file. |
cc @sluongng as you worked on this in the past I could see this happening if a build action is interrupted before performing the cleanup that deletes the directory, but that should be rare. @tomqwpl Does the directory exist after every build? Are there two targets with importpaths that become identical after being converted to directory names (e.g. slashes replaced with underscores)? |
Yeah, I ran into this in the past. See #3145 for a detailed explanation. If you could help provide how you configured your tests in the same package, it would be tremendously helpful for us to troubleshoot this. Part of the rules_go test suite configuration also "demonstrates" this well: there is no sandboxing on Windows. Bazel's experimental sandboxing for Windows is actually a no-op without a So long story short, when working with Bazel on Windows, expect no sandbox available. |
@fmeum In response to "Does the directory exist after every build?". So I believe that when it fails with the "can't create directory for "_empty.go", the directory it's trying to create exists, and already contains _empty.go. If I delete that directory and rerun, then the directory is created, and at the end of the build is actually empty. Hopefully that makes sense |
@sluongng Here is an example that's just failed:
None of the source files have any build conditions in them. Note that the BUILD.bazel file has only one go_test in. BUILD.bazel is generated from gazelle. |
As far as I can tell, not. All of the BUILD.bazel build files are generated by gazelle. The one that just failed (golang\pkg\migrations\rbac\go_altair_com_slchub_pkg_migrations_rbac) I'm sure that there's not another package with the same name if you convert slashes to underscores. And anyway, it would have to exist in the same "golang\pkg\migrations\rbac\BUILD.bazel" build file for it to be trying to create a directory under the same "golang\pkg\migrations\rbac" directory. That file is exhibited above. It's as simple as it can be. |
Rewrite the error above a bit for easier reading.
This is happening on rules_go/go/tools/builders/compilepkg.go Lines 223 to 227 in 4660427
It seems like the directory In https://github.com/bazelbuild/rules_go/pull/3145/files#diff-f5ba5554688cd727c306fb33aa10f80e92fd27201da575159972b133f7c6916cR105, when there is no implicit Since I don't have a way to reproduce this on my end, @tomqwpl is it possible for you to setup a small example git repo that we could use to reproduce and fix the problem? |
The bit I'm suspicious about is the "if len(srcs.goSrcs) == 0 {" line. Given the BUILD.bazel file above, why is that condition true? Or am I misunderstanding something? I can have a go at setting something up, but as you can see from my example above, it's a pretty simple example. This has the feel of something that will only occur in a large example though. It doesn't always happen in the same place, though it always happens somewhere for me at the moment. |
You would need to understand how Go (and rules_go) compiles tests in a package. I would recommend reading #3145 as I tried explaining it there in detail. But when there is a go_test target being compiled, rules_go will actually split that into 2 libraries underneath, 1 internal and 1 external. rules_go/go/private/rules/test.bzl Lines 64 to 84 in c403db6
It's possible that you use external tests or internal tests exclusively in that package though. In that case, one of the 2 packages will be empty without any source files to compile. And because Bazel expects deterministic outputs, we would still need to provide it with something... which is why we would create |
It feels to me like there are two complete copies of bazel running at the same time both trying to do the same build, thus conflicting with each other. The things it is complaining about aren't duplicated as far as I can see. There is only one "go_test" in each BUILD.bazel file that it complaint at. At the beginning of the build log I get:
I can only see one place in the BUILB.bazel files where the code to generate that is being referenced, yet it's being output twice. I have only one java.exe process running. If I I will try rebooting and see whether that makes any difference. |
Rebooting makes no difference. |
Possibly spoke too soon on that front.
That is, it complained twice on subsequent runs about the same directory, despite the fact that I erased it in between (and I have checked the directories against each other, they are the same and I deleted the same one). So second time the directory didn't exist before bazel started, it must have been created by bazel. |
Yeah that's because you have multiple actions under
That would let you build all targets under the same package and check if there is any duplication within that package. |
|
@fmeum I know it's unlikely due to |
Different configurations should result in different output paths and the directory we create @tomqwpl I have access to Windows - it would be very helpful if you could provide me with a reproducer. |
So far I'm been unable to reproduce on a small example. If I just take the one BUILD.bazel file that fails for example and try and put that in a separate directory, it then succeeds. But equally, it seems that just running the one single build target seems to work. The BUILD.bazel files are nothing complicated though, see example above. Now, the interesting thing is that I don't seem to be able to reproduce this any more. I've just done a "clean --expunge" and then a "build //..." and it worked without issue. Previously this would have given me an issue. I'm fairly sure nothing in the code has changed, and that I'm using the same directory as I was before. |
This is happening in Bazel CI (https://buildkite.com/bazel/bazel-at-head-plus-downstream/builds/3035#0188343c-c91d-4305-866f-aabf6f5e5a9d):
It's possible that file deletion sometimes just fails and that leaves behind |
Turns out that every test triggers this logic since there is a separate compile action for the external test package |
Duplicated `go_tests` can result in compilation actions failing due to bazelbuild/rules_go#3558.
Duplicated `go_tests` can result in compilation actions failing due to bazelbuild/rules_go#3558.
What version of rules_go are you using?
v0.39.0
What version of gazelle are you using?
v0.29.0
What version of Bazel are you using?
bazel 6.1.0
Does this issue reproduce with the latest releases of all the above?
Yes. tried 0.39.1 of rules, bazel 6.2.0, 0.30.0 of gazelle.
What operating system and processor architecture are you using?
Windows x64
Any other potentially useful information about your toolchain?
What did you do?
Just trying to build golang
What did you expect to see?
That it works
What did you see instead?
Many golang targets (almost always tests, don't know whether that is significant) fail with errors like:
There is an issue elsewhere that reports that this only happens when there are multiple
go_test
targets in the BUILD.bazel file. That isn't the case here, or at least not in all cases (it is in a couple).It also happens when running with
--jobs=1
, though I haven't run a completely clean build like that. I ran bazel with--keep_going
to try and run all targets that would succeed and then tried running with--jobs=1
to see whether the rest would succeed.I could get it to run using
--jobs=1
and then each time it failed, deleting the directory it was trying to create. After a few rounds of that the build succeeded.I have repeated the test by first manually deleting the "execroot" output directory to force a completely clean build and I get the same thing.
The curious thing is that looking at the source code for the rules, I don't really understand why it's even trying to make an
_empty.go
file. The appears to be that it is only created iflen(srcs.goSrcs) == 0
. But all of my rules have lists of go files, and none of the files have golang build conditions in them, so it ought to have real code to build.The text was updated successfully, but these errors were encountered: