-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Windows: shell script cannot be used as an 'executable' for an action #3589
Comments
@laszlocsomor: can you take a look? Thanks! |
Ok, i'll take a look |
@davido : I dislike the idea to special-case shell scripts in Skylark actions on Windows. The rule had to "magically" depend on Bash if the executable looked like a shell script or war file. |
@laszlocsomor Thanks for the pointer, I wasn't aware of
But it does already, isn't? I can pass command line and it just works. Moreover I was wondering about inconsistency: Another option would be to expose I will replace the call and let you know if it fixed the problem. Thanks again. |
@davido : Thanks for trying it!
It works because Linux special-cases files that start with
Source: https://en.wikipedia.org/wiki/Shebang_(Unix)
Good point. The shell is the default executable of actions unless you set another one. As you said, executing a shell script just works on Linux, but it doesn't work on Windows because the I stand corrected though. We could set the actual executable to the shell if the action requested to use a shell script or war file. But then we must also rewrite the argument vector, and maybe quote the arguments as well. I'd rather not do that.
My previous paragraph explains this.
I think the cost of widening and maintaining the already large interface of
Thanks! |
Unfortunately, it doesn't work: http://paste.openstack.org/show/619248/ If I change ctx.actions.run_shell(
inputs = inputs,
outputs = [war],
mnemonic = 'WAR',
command = '\n'.join(cmd),
use_default_shell_env = True,
) I get:
And even if we sort out, why my current bazel version built from master is failing to correctly invoke
What I'm looking for, is the possibility to switch to using generated shell script file (25k size) in Skylark action on Windows. It seems that it's currently not supported. In which case this is a blocker to build Gerrit on Windows, because the generated script to package WAR file is too big, and cannot be passed as parameter to the shell without truncation. |
I think Let me look into that. |
But wait, if in some code paths shell script is automatically created if the command line is too long, then it raises the question why Is it a bug in ctx.action(
inputs = inputs,
outputs = [war],
mnemonic = 'WAR',
command = '\n'.join(cmd),
use_default_shell_env = True,
) ... on all platforms, and even on Windows, even if the script is longer then 8191 chars. |
Because Also earlier I confused two things:
Important: ~8K is cmd.exe's limit, but By the way
Yes, I think it's a bug. |
Thanks for the detailed explanation. I also missed the fact that So, am I getting it correctly, that the question boils down as for why |
I guess we could dump much more infos here, right? bazel/src/main/native/windows/processes-jni.cc Lines 306 to 309 in e88dfbe
|
Yes, but why? Btw I remembered one more thing:
|
...and that's why |
Sorry, I missed the question part from your previous comment.
Yes, you could patch it there, e.g. by dumping |
Have you done something similar in the past or could provide some code pointers where something similar is done already? |
Yes, for one-off debugging purposes I have. I'd simply append it to a hardcoded file; nothing fancy. Something like this (not tested):
|
Thanks, @laszlocsomor , will test it and let you know. Actually this JNI place or the code this JNI code is called from is always very interesting from debugging/dump perspective. So, I wonder why we can't easily instrument this native code and guard it with // Uncomment when needed
// #define DEBUG_ 42
[...]
#ifdef DEBUG_
<dump the whole truth>
#endif Looks like this is missing and such diagnostic code could be even committed there? |
You're welcome, and thanks!
I don't see the need for it. I believe adding debugging code wouldn't be any harder than discovering and understanding the existing ifdef'd code. However, I'm also not against it, so if you'd like to submit something, go ahead :) |
As for |
@laszlocsomor Wau, it just worked with your patch: https://bazel-review.googlesource.com/c/bazel/+/15850. I adjusted the
Applied gerrit patch, built Bazel from scratch, and now gerrit WAR creation just worked:
And testing it, reveals, that it even works ;-)
|
Whoa, nice! :) Thanks for trying it, I'm glad it works. |
I'm unlikely to get this change upstreamed this week because of other work I have to do. |
No problem. Hope to see this CL merged ASAP. WAR gathering is pretty much the last missing link in the chain to produce |
Ah, there's also #3636 . An MSYS bug is responsible for this issue and it prevents Bazel from running shell scripts with long chains of commands, i.e. write long extremely genrule commands to shell scripts and dispatch to Bash. |
David, snapshot 3 in https://bazel-review.googlesource.com/c/bazel/+/15850 contains the fix. I tested with the following bzl file:
And BUILD file:
|
@laszlocsomor Patch set 4 of your gerrit change just worked (I noticed, it needs a rebase, as it wasn't cleanly applied on recent master):
I checked the content of generated file: Thank you again for the quick fix! |
@damienmg @laszlocsomor Just in case you are curious, these are 4 diffs currently needed to patch gerrit master to build
Note, that I'm using Python 3 to make |
ctx.action() is deprecated in favor of ctx.actions.run() / ctx.actions.run_shell(): [1]. See discussion in [2], why we need this. [1] https://docs.bazel.build/versions/master/skylark/lib/ctx.html#action [2] bazelbuild/bazel#3589 Change-Id: I11af3afebc0d3c76bb8fb59a790db2e3f3ce982b
@laszlocsomor @meteorcloudy pointed out in bazelbuild/continuous-integration#126, that we cannot add Windows CI job for Gerrit project until this fix was released. Can't we accelerate it somehow? |
@davido : I don't know. I asked a related question on bazelbuild/continuous-integration#126. |
It will be pushed in a couple of hours. |
Replaced call to ctx.actions.run with ctx.actions.run_shell. Windows was trying to execute the script as a win32 binary, which was failing with the following error: ``` Action failed to execute: java.io.IOException: ERROR: src/main/native/windows/process.cc(199): CreateProcessW("C:\temp\7qgjmpto\execroot\__main__\bazel-out\x64_windows-fastbuild\bin\particles\Tutorial\Kotlin\3_JsonStore\JsonStore_genrule.sh"): %1 is not a valid Win32 application. ``` Advice from bazelbuild/bazel#3589 is to use ctx.actions.run_shell instead.
Replaced call to ctx.actions.run with ctx.actions.run_shell. Windows was trying to execute the script as a win32 binary, which was failing with the following error: ``` Action failed to execute: java.io.IOException: ERROR: src/main/native/windows/process.cc(199): CreateProcessW("C:\temp\7qgjmpto\execroot\__main__\bazel-out\x64_windows-fastbuild\bin\particles\Tutorial\Kotlin\3_JsonStore\JsonStore_genrule.sh"): %1 is not a valid Win32 application. ``` Advice from bazelbuild/bazel#3589 is to use ctx.actions.run_shell instead.
If the shell command in ctx.actions.run_shell.command is longer than the platform's shell's limit, Bazel will dump the command to a helper shell script and execute that script in the run_shell action. Genrules also write a helper script when genrule.cmd is longer than the shell's limit, and ctx.actions.run_shell now uses the same machinery. Fixes bazelbuild/bazel#3589 Change-Id: Ib24dce90182ef69552deb2d400e00ae061537309 PiperOrigin-RevId: 167126560
This is an attempt to fix command line limit problem reported in #3579. It's usual approach to work with a response file. So I adapted the code in question from passing the whole 25k command, that was truncated on 8191 character directly to
ctx.action()
, that was going through the shell:with an intermediate step, generated shell script and pass it as
executable
toctx.action()
instead:This works as expected on Linux, but is failing on Windows with:
I would expect that Bazel does some heuristic here and guess that the passed file is a shell script, for example, by trying to parse the first file line and see whether or not the first line is a shebang or something and shell out instead of trying to pass previously generated shell script directly to create process.
The text was updated successfully, but these errors were encountered: