Write a guide on how to write portable Skylark rules.
Bumping to P1 -- we committed to doing this work in Q4'2017.
I plan to work on this next week.
Some things I've hit:
ctx.Args) directly (example PR: https://github.com/bazelbuild/rules_dotnet/pull/47/files )ctx.actions.run should be used when possible (vs. the deprecated ctx.action) to avoid bash--output_user_root to C:\tmp to generally mitigate this.) Something that would be interesting is any advice for making the best of unsandboxed execution. For example, we're able to vendor the C# compiler via an external package, but we rely on the system-wide .NET framework installation. My assumption (we haven't got to the point of cache sharing yet) is that these unsandboxed/unvendored resources won't contribute to the digests used in caching. This could lead (naturally) to non-repeatable builds in a way that could be dangerous with cache-sharing.
My guess at what I'll have to do is find some proxy to include as an input from outside the sandbox (e.g. there are files/registry keys that indicate the specific .NET framework release number) and "hope for the best". Any kind of insight here would be really helpful. If there's specific things we should document as rule authors on this topic that'd be good to know.
I'd like to see a section on dealing with runfiles:
On Thu, Dec 14, 2017 at 7:57 AM Jacob Parker notifications@github.com
wrote:
Some things I've hit:
- Windows command line length limits. Many(?) tools use the "response
file" idiom which (usually?) maps to Bazel's param files (via ctx.Args)
directly (example PR:
https://github.com/bazelbuild/rules_dotnet/pull/47/files )- ctx.actions.run should be used when possible (vs. the deprecated
ctx.action) to avoid bash- Bash/etc. on windows should be avoided if possible (general perf,
difficulty with consistent environment, weird edge cases like #4013
https://github.com/bazelbuild/bazel/issues/4013)- Path length limits: a lot of tools (e.g. the C# compiler IIRC) are
still very limited. I don't think this has come up yet for me in
rule-writing specifically but maybe it could be a factor (we do set
--output_user_root to C:tmp to generally mitigate this.)Something that would be interesting is any advice for making the best of
unsandboxed execution. For example, we're able to vendor the C# compiler
via an external package, but we rely on the system-wide .NET framework
installation. My assumption (we haven't got to the point of cache sharing
yet) is that these unsandboxed/unvendored resources won't contribute to the
digests used in caching. This could lead (naturally) to non-repeatable
builds in a way that could be dangerous with cache-sharing.My guess at what I'll have to do is find some proxy to include as an input
from outside the sandbox (e.g. there are files/registry keys that indicate
the specific .NET framework release number) and "hope for the best". Any
kind of insight here would be really helpful. If there's specific things we
should document as rule authors on this topic that'd be good to know.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/bazelbuild/bazel/issues/3889#issuecomment-351752057,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAC5IzY-v-vk9WqIJAwP9wd9nh9VVlEEks5tAUVNgaJpZM4P1DsG
.
Thank you @j3parker and @alexeagle , these are insightful and valuable ideas and questions. I'll incorporate them / their answers in the doc.
@j3parker :
Something that would be interesting is any advice for making the best of unsandboxed execution. For example, we're able to vendor the C# compiler via an external package, but we rely on the system-wide .NET framework installation. My assumption (we haven't got to the point of cache sharing yet) is that these unsandboxed/unvendored resources won't contribute to the digests used in caching. This could lead (naturally) to non-repeatable builds in a way that could be dangerous with cache-sharing.
Frankly I have no good answer at the moment. (For the record, we don't know about the feasibility of sandboxing on Windows.)
My guess at what I'll have to do is find some proxy to include as an input from outside the sandbox (e.g. there are files/registry keys that indicate the specific .NET framework release number) and "hope for the best".
That'd be one option. Another is to create a local repository for the .NET framework and write the .NET rules such that their actions depend on that local repository.
@alexeagle :
Thanks for mentioning runfiles, I'll write a section on that. There's also https://github.com/bazelbuild/bazel/issues/4279.
Update: sorry for having dropped the ball on this issue. I never submitted any docs. @j3parker and @alexeagle , do you think it's still worthwhile to publish best practices for writing platform-aware Skylark rules?
Yes, absolutely worthwhile.
On Wed, May 16, 2018 at 1:59 AM László Csomor notifications@github.com
wrote:
Update: sorry for having dropped the ball on this issue. I never submitted
any docs. @j3parker https://github.com/j3parker and @alexeagle
https://github.com/alexeagle , do you think it's still worthwhile to
publish best practices for writing platform-aware Skylark rules?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/bazelbuild/bazel/issues/3889#issuecomment-389447426,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAC5I6Igt2sARiAg4vtVb--HNfseErXfks5ty-qMgaJpZM4P1DsG
.
Thanks for the feedback. I'll try to get something done before the end of this quarter.
@filipesilva suggested (https://github.com/bazelbuild/bazel/issues/6764#issuecomment-447773095) (in response to my question: "Where would you look for [this guide]?"):
I would look for it in https://bazel.build/ ->
Documentation->Rules->Developing your own rules(a new section.I'd expect to find a small tutorial on how to make my own language rule and how to ensure windows compatibility, and some resources for further reading.
Is there any preliminary version of this guide somewhere? Would be very useful for porting rules_haskell to Windows.
Sorry, there isn't yet.
Here are some tips that will go into that doc:
ctx.actions.run_shell when you need to run Bash command(s).ctx.actions.run if you have to run a native binary or a xx_binary target. Don't use ctx.actimons.run_shell for that, and also don't run Bash commands in ctx.actions.run.ctx.resolve_command (and soon ctx.resolve_tools, which is better because it doesn't require Bash) if you need to run xx_binary targets in your action. Example that works with Bazel 0.21 (though still needs Bash): https://github.com/bazelbuild/bazel-skylib/blob/8d4f7612b264849b4b0d7961ab5532f6879d9239/rules/maprule_private.bzl#L397ctx.action -- it's deprecated and Bazel cannot correctly execute it on Windows when the command is e.g. cat <path>/ separator, so when creating an action that will run on Windows, you have to replace these with \.ctx.actions.run(..., executable=["cmd.exe"], arguments=["/C", cmd], ...) -- cmd should be a cmd.exe command.echo "hello" will retain the quotes.maprule from Skylib.data dependencies), Bazel provides built-in libraries for C++, Java, Python, and Bash.Some more:
cmd.exe semantics are different from Bash, and often surprising. AFAIK there's no equivalent of Bash's &&. The equivalent of Bash's || operator in cmd.exe is &: echo hello & echo world.c1 && c2 && ... && cN) that short-circuit upon failure is to OR them together and error-check after each one: c1 & if "%errorlevel%" neq "0" (exit 1) & c2 & if "%errorlevel%" neq "0" (exit 1) & ... & cNQuestion: do genrules on Windows use Bash? Does Bazel ship with a Bash layer for Windows?
Yes, genrule uses Bash even on Windows. Bazel does not ship bash in the binary, it must be installed from Git (Git bash) or Msys2.
So if I run Bazel in PowerShell, genrules will not work?
Is it recommended to run Bazel in Git Bash / Msys2?
Bazel works in any Windows shell (cmd, powershell and bash). It is just that Bazel will internally call bash for genrule, sh_test, sh_binary etc.
OK, that sounds like what I was hoping for! :slightly_smiling_face:
Just to clarify, if I run Bazel in PowerShell, and then build a genrule, Bazel will automatically find my Git Bash (or similar) installation and run that to build the target?
It is better to set BAZEL_SH env var to absolute path of bash.exe that you want to use (regardless of what shell you use).
@njlr :
Just to clarify, if I run Bazel in PowerShell, and then build a genrule, Bazel will automatically find my Git Bash (or similar) installation and run that to build the target?
Correct. As @rongjiecomputer says, better to set BAZEL_SH.
I advise against using Git Bash as BAZEL_SH. See https://github.com/bazelbuild/bazel/issues/5751
I'm closing this one because @laszlocsomor has done an excellent job in https://docs.bazel.build/versions/master/skylark/windows_tips.html
Please file new issue or PR if you think anything else should be added in that guide.