-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Chicken and egg problem when evolving dart:_macros
library
#54976
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
Comments
I don't see where Aside from that, you might want to consider developing |
See the relation chain, it is added one CL earlier :). All the APIs are actually coming from |
One idea here, but it might be hard to implement, is to somehow extract out the support for running macros such that it can compile the platform without referencing any macro related types (no imports at all to I don't know how feasible that would be though. |
Ah, I missed that, sorry. I have to wonder whether it might be cause by the chaining. That is, I wonder whether the second CL would be having a problem if the first had landed so that the SDK being used to analyze the second CL already had the package defined (in |
|
Most of the package works fine - it is only the new APIs added to it which don't work. |
The error makes sense: currently when bootstrapping we will to run HEAD CFE on the prebuilt For Dart only code (i.e. things that don't require or depend on VM changes) we can probably make it work by having a special mode where we compile HEAD CFE using core library source rather than precompiled platform embedded into prebuilt |
It is, at least from my perspective, acceptable if we cannot use any macros in the CFE itself. |
We have discussed this problem with @johnniwinther a bit. @jakemac53 Before I jump into nitty gritty details of how we could change bootstrapping I want to ask metaquestion: are we sure we want to make Can we make it a builtin package instead (e.g. package the import of which is handled in a special way by the tooling)? e.g. if you have you have
Taking one step further: {
"name": "_macros",
"rootUri": "dart-builtin://_macros/",
"packageUri": "lib/",
"languageVersion": "3.2"
}, Then you don't need otherwise clause at all (but you would need Resolving bootstrapping problemFirst let me summarize the build process as we have it now:
I am gonna write The current bootstraping process goes like this: we want to produce Kernel binary from platform sources (compile Executing Attempt to compile The work around which I previously described would be to change this step to: That is instruct Currently prebuilt CFE is hidden inside the monolithic Here Footnotes
|
The important part, is that the version of the library is identical between the binaries shipped with the SDK and the users local version solve. You are correct in saying that if we supported SDK vendored packages in Dart (similar to Flutter), we could achieve this. I am trying to not invent more work than is necessary though, because the feature is already large enough, and every additional feature adds additional risk and complexity. We already have Note that I would also not want this to work how Flutter SDK packages work. They allow pub package dependencies, which is IMO a mistake (massive pain for both owners and users of those packages, they all become in effect SDK vendored due to pinning). Only other SDK vendored dependencies should be allowed. We also want proper versioning, that is the whole point of having the package as a layer on top of the My question would be, what advantage does being a package provide over a If it allowed us to use macros in the CFE or something I would possibly be in favor, but I don't believe it would, we still have the issue of the package being pre-compiled as a part of the CFE in the pre-built |
My point is that it does not have to be a real package - it just that I think what is more important here is that When compiling the compiler This made me think that another option is to simply redirect diff --git a/sdk/lib/_macros/api.dart b/sdk/lib/_macros/api.dart
new file mode 100644
index 00000000000..e9b4f9b2ac7
--- /dev/null
+++ b/sdk/lib/_macros/api.dart
@@ -0,0 +1 @@
+export 'macros.dart';
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 3f9a24207b0..9dee64683d1 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -148,6 +148,12 @@ Iterable<Package> makePackageConfigs(List<String> packageDirs) sync* {
var hasLibDirectory =
Directory(join(repoRoot, packageDir, 'lib')).existsSync();
+ // Hack: reroute macros package to point directly into SDK sources.
+ if (name == 'macros') {
+ packageDir = 'sdk/lib/_macros';
+ hasLibDirectory = false;
+ }
+
yield Package(
name: name,
rootUri: packageDir, And then your CL should build just fine. |
I don't know if we have anything written down for what a
That is almost crazy enough to work.... but it would be brittle. Package:macros will have two different libraries, one for users and one for implementations. Those each export only specific things from I might still try it anyways though. |
It's just a question of what is it coupled with. It seems that platform files are more coupled with the target platform than with the compiler. When we look at
Here is another concoction which removes the need to have a copy of diff --git a/pkg/macros/lib/api.dart b/pkg/macros/lib/api.dart
index 008a1da2b1d..293b61d1088 100644
--- a/pkg/macros/lib/api.dart
+++ b/pkg/macros/lib/api.dart
@@ -12,7 +12,9 @@
// only want to expose the public portions from this library, and use explicit
// shows to do that.
-export 'dart:_macros'
+// TODO: this should really be dart.library._macros, but there is no plumbing
+// in prebuilt SDK to do `--no-enable-macros`.
+export 'package:_macros/macros.dart' if (dart.library.mirrors) 'dart:_macros'
show
Annotatable,
Builder,
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index 3f9a24207b0..54c5acb8c74 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -85,6 +85,12 @@ void main(List<String> args) {
...makeFrontendServerPackageConfigs(frontendServerPackageDirs),
...makePkgVmPackageConfigs(pkgVmPackageDirs),
...makePackageConfigs(sampleDirs),
+ Package(
+ name: '_macros',
+ rootUri: 'sdk/lib/_macros',
+ packageUri: null,
+ languageVersion: '3.4',
+ ),
];
packages.sort((a, b) => a.name.compareTo(b.name));
diff --git a/utils/compile_platform.gni b/utils/compile_platform.gni
index 0523ac32039..ce0d26ab6f2 100644
--- a/utils/compile_platform.gni
+++ b/utils/compile_platform.gni
@@ -50,7 +50,12 @@ template("compile_platform") {
outputs = invoker.outputs
- vm_args = [ "-Dsdk_hash=$sdk_hash" ]
+ vm_args = [
+ "-Dsdk_hash=$sdk_hash",
+ # TODO: this should really be --no-enable-macros but we don't
+ # have plumbing for this.
+ "--no-enable-mirrors"
+ ]
inputs = []
deps = []
|
IMO it's a problem that environment:
# Restrict the upper bound to the next release, which allows us to do breaking
# changes if required, in minor SDK releases.
sdk: ">=3.4.0-0 <3.5.0" You see, when we want to bump the version number to e.g. Dart 3.5.0, we'll have to pub publish a new package:macros before we are able to even begin development of Dart 3.5.0. The moment anything serious starts to depend on package:macros, we will have to make the package:macros for the next release, before we even have begun making that release. It's already complicated enough to bump the Dart version number due to issues like this, and we've been working hard to untangle and reduce this class of issues. The 3.2.0 version bump was delayed a week and even reverted due to a similar issue. We don't have a good way to tightly couple package versions with dart sdk versions at this time and trying to do so will complicate release engineering and doesn't lead to a nice stable design for anyone. The good solution we have available to tightly version code with the Dart SDK is the It would be easier and simpler to accomplish the same thing by just having Is the concern with TLDR: macros being a tightly dart core library and a package complicates the design and release engineering and there are simpler options. |
Please read https://github.com/dart-lang/language/blob/main/working/macros/feature-specification.md#language-and-api-evolution for the justification of using a package and the tight constraints. I do believe that it has strong benefits over being a public
We are trying to be able to version separately from the SDK. This isn't about subverting the policy, but having our own versioning which is separate. It is very possible that this library would have breaking changes which are a result of changes to the language, not something we simply desired to do. They can essentially be forced upon us by changes that aren't otherwise breaking for the language. |
@mraleph I was able to get things building by just hacking the package config for package:macros (https://dart-review.googlesource.com/c/sdk/+/353561/6/tools/generate_package_config.dart). I am not sure how palatable that solution is though, cc @johnniwinther @scheglov |
Well, in effect this is giving the SDK multiple version numbers.
Which means you can do a major version bump on one without having to do it on the other. On topic, have you considered doing SDK packages, similar to how Flutter does it? So that users write:
That would solve any chicken egg problems. It's ugly, but there isn't really much of a reason to pretend that you can get a different version of |
What would it take to get support for this? We could do it that way, if we have versioning support. I probably would want to write a lint or something that tells users to actually use the version too. I would also want a lint to prohibit adding any package dependencies to this package. |
|
We have landed on using SDK packages as a fix for this, I am working on landing that in https://dart-review.googlesource.com/c/sdk/+/359040. |
add sdk_packages.yaml file (describes SDK vendored package locations) delete old macro code in _fe_analyzer_shared, move tests/benchmarks adds a top level `pkg` directory to the Dart SDK, which is where vendored packages live BUG: #54976 Change-Id: Ib3503a27fb5644fa8a39ab5a3e5b568df330cfd6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/359040 Auto-Submit: Jake Macdonald <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Jonas Termansen <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Bob Nystrom <[email protected]> Commit-Queue: Jake Macdonald <[email protected]> Reviewed-by: Devon Carew <[email protected]>
Even though this solution works, so I'll close the issue, we are looking at decoupling by introducing a stable serialization format dart-lang/language#3706 and dart-lang/language#3872 |
See https://dart-review.googlesource.com/c/sdk/+/353561, this exercises a pattern where we both add a new API to
dart:_macros
and expect to be able to use it in the compilers, atomically.In particular, I added the exception types to
dart:_macros
in this CL, and migrated analyzer/CFE to usepackage:macros
which exportsdart:_macros
at the same time. They expect these new exception APIs to exist, but they don't.Presumably this is related in some way to the pre-built SDK, but I don't fully understand all the context here.
I could likely avoid the issue in this case, but we will have this same pattern but not be able to avoid it in the future.
cc @johnniwinther @whesse
The text was updated successfully, but these errors were encountered: