Open cbracken opened 4 years ago
Yes, you have it here ;-) This is why started because I assumed that you would be open to contributions. Struggling but with the template scripts. Let's see how far I go
If it's useful, it looks like some work has been done on this fork: https://github.com/cbracken/rules_dart/compare/master...malkia:master
I'm not sure whether it works at all, and I believe it's probably pretty out-of-date, but could be useful to look over. I've recently acquired a Windows machine for development and testing; mostly for work on the win32/UWP Flutter desktop embedders, but I've got one less excuse not to get this working.
From a testing point of view, I've done some work with Appveyor in the past back when we had Flutter CI running there for Windows builds. If we get it to the point where the rules work, I should be able to get tests set up.
I've looked at this briefly. I think the main thing to do is replace layout_action with a rule which uses ctx.actions to do the symlinking? https://bazel.build/rules/lib/actions. I'm not entirely sure why layout_action exists in the first place though, I've not found other rules implementations (e.g. rust https://github.com/bazelbuild/rules_rust or dotnet https://github.com/bazelbuild/rules_dotnet) which seem to do this collect-all-files-in-one-directory? The rest of the rules look straightforward to change. Its possible the other .sh scripts could be replace with starlark calls, but they're also trivial to translate to .bat files (e.g. https://daniel-sc.github.io/bash-shell-to-bat-converter/) afaict?
OK, I was wrong. Here is the rust version: https://github.com/bazelbuild/rules_rust/blob/main/rust/private/rust.bzl#L128
It's been a while since I took a look at layout_action, but my recollection is that this was required because with Bazel, there are three places a tool might go looking for a file:
These form a sort of overlay filesystem where you may have file //foo/bar/a.dart
checked into the source tree. Let's say that file has a relative import like import 'b.dart';
, but let's imagine b.dart
is codegen'ed up using a genrule
. It'll be built to bazel-genfiles/foo/bar/b.dart
. Similarly, a Starlark action might build things to bazel-bin/foo/bar/c.dart
. The overlaid source tree you want the tool to see is something like:
//foo/
bar/
a.dart
b.dart
c.dart
However, most of our tools aren't clever enough to go poking in three places for each file, one after the other. Most C/C++ compilers have nice mechanisms for adding multiple include/library paths via -I or -L, etc. but most of the Dart tools don't. There used to be performance reasons for this in the VM -- resolving a URL purely in code vs actually having to probe the filesystem to see if a file is there; this may not be much of an issue now that everything is kernel/AOT.
TL;DR we create a flattened view of the tree so our tools don't have to, but maybe we should fix that now that we're not running from source!
Re: replacing it with something more Starlarky: I wonder if this has been solved by changes to Starlark in the years since that bit was hacked together. I also suspect we should be copying and not symlinking regardless - I may have made that change internally at some point but possibly forgot to make it here. IIRC, the performance was similar at least on ext4 and macOS and it would avoid the whole windows symlink issue. Will see if I can find some time some weekend to take a poke at it.
So its definitely possible to create what are called multi-root file systems in the Dart compilers now. That essentially gives you similar behavior to -I/-L . I'm not sure if these options are necessarily exposed by all of the Dart tools, but it is definitely used by the google3 rules. For example, if you were compiling an app and needed to handle source directories in foo/ and bar/, what you would do is:
--filesystem-root=foo/ --filesystem-root=bar/
So essentially you map package:whatever/whatever.dart to my-custom-scheme://whatever.dart to [foo/whatever.dart, bar/whatever.dart], and I believe the compiler will pick the first one that exists based on the order you specified.
On the batch/sh vs starlark, one thing to consider is that batch scripts are actually quite slow. And from my experience even with the small amount of batch in the flutter tool, very few people are actually interested in touching it.
This would require a lot of the same conditional work we do for macOS/Linux and the addition of batch scripts for Windows.