-
Notifications
You must be signed in to change notification settings - Fork 52
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
[native_assets_cli] Move BuildConfig.targetOS
to BuildConfig.codeConfig.targetOS
, remove it entirely or extend to cover web
#1738
Comments
This is not an option right?
That would be If users have data assets that are OS dependent, they might start misusing |
Again, the concept of "operating system" does not make sense in general, because for web builds there's no operating system. The more general concept of "target platform" is a superset, it gives the same information as OS but also allows expressing we compile for the web. So that would allow removing We could structure it slightly differently and have
In any case I believe for web builds it doesn't make sense to have I think we should reduce the top-level scope on |
👍 |
I would never introduce |
This should probably be addressed together with restructuring the JSON: |
BuildConfig.targetOS
to BuildConfig.codeConfig.targetOS
, remove it entirely or extend to cover webBuildConfig.targetOS
to BuildConfig.codeConfig.targetOS
, remove it entirely or extend to cover web
Thinking a bit further along these lines. Once we add support for We might as well adopt the convention that we have toplevel configs for
BuildConfig
// 0. shared
.outputDirectory
.outputDirectoryShared
.packageName
.packageRoot
// 1. per target platform
.targetPlatform // if it's native, .nativeConfig will be set, if it's web .webConfig will be set
.nativeConfig
.targetOS
.webConfig
.compiler // JS or Wasm
.crossOriginIsolated // or whatever web specific options
// 2. per asset
.buildAssetTypes // every asset type has it's own config, optionally
.codeConfig
.targetArchitecture
.buildMode // This is `config.buildMode` currently, but shouldn't this be for code assets only?
.linkModePreference
.targetIOSVersion
.targetMacOSVersion
.targetAndroidNdkApi
.targetIOSSdk
.cCompiler
.archiver
.compiler
.linker
...
.dataConfig // we haven't found a need yet, so doesn't exist currently
.wasmConfig
.abi // emscripten
.wasiVersion // 'Preview 1' currently
.javaConfig // or named differently if we'd include Kotlin things?
.gradlePath // would something like this be useful?
.iconConfig // in Flutter only, for IconAsset
.resolution // xxx dpi
.fontConfig // in Flutter only, for FontAsset
... // Maybe no need for this either
// 3. per embedder
.flutterConfig
.buildMode // release, debug, profile (different from codeConfig.buildMode) Current target platforms: (Side note: Using nesting to detail whether things are available is nice. However it doesn't always work. @HosseinYousefi For We could consider whether asset types should be nested under @mkustermann Do you have any need for (Edit: Maybe we should even leave |
I think we should remove it entirely.
I prefer us having if (config.buildCodeAssets) {
print(config.codeAsset.abi); // <- can access as non-nullable, no need for `!` operator
}
I do find it slightly confusing to have Yes, theoretically one could have an arm32 interpreter running in the browser and one could theoretically then say a flutter web build should therefore set a C compiler configuration and ask packages to build arm32 C code which it will run in it's arm32 interpreter in the browser. But this is super contrived. I'm not sure we should be considering that use case. Similarly, yes, theoretically one could have a wasm interpreter in an AOT-compiled android app. Therefore android What we should remember is that an asset type is usually coupled with a runtime API on how to access those asset. For example a hook emitting code assets is 1 <-> 1 coupled with dart code using
The place where this would not be ideal if there was a need for a I'll think a bit more about this. Maybe we can discuss this in the next meeting. |
👍 As discussed offline, this brings it in line with our reasoning for not having optimization levels in the protocol as discussed in #1267.
👍
Agreed. Confusing and not pretty! I think it's likely that we want to use the targetOS for icons/images etc. Maybe
That's an interesting point. Because we could potentially share the We might have use cases where we three ways adding an asset. Where two share a runtime API and the third does not: // package:mysql hook/build.dart
if(config.nativeConfig.targetOS == OS.Android) {
output.java.addJarAsset(...);
// use dart:ffi via JNIgen generated code
} else if(config.buildCodeAssets) {
CBuilder(...).build();
} else if(config.buildWasmAssets) {
WasmBuilder(...).build(); // or maybe it should be called EmscriptenBuilder
} But it would be nice if we can abstract the shared things using the same FFI code away as you suggest: // package:mysql hook/build.dart
if(config.nativeConfig.targetOS == OS.Android) {
output.java.addJarAsset(...);
// use dart:ffi via JNIgen generated code
} else if(FfiBuilder.canBuild(config)) {
FfiBuilder(...).build(); // delegates to CBuilder and WasmBuilder.
} I'm not fully happy with // package:mysql hook/build.dart
if(config.nativeConfig.targetOS == OS.Android) {
output.java.addJarAsset(...);
// use dart:ffi via JNIgen generated code
} else if(CWasmBuilder.canBuild(config)) {
CWasmBuilder(...).build(); // delegates to CBuilder and WasmBuilder.
} I am not entirely sure if we need a shared config for the
I can't think of a use case either. |
The first in a series of refactorings to address: * #1738 We align `BuildMode` with `OptimizationLevel`, it's configured by the hook author in the build hook. Likely, every package should ship with max optimization level and build mode set to release. Only while developing a package (when it is the root package or path-depsed in) would the build mode be set to debug. This will require a manual roll into dartdev and flutter tools due to the removal of `BuildMode` from the `native_assets_builder` API. The native assets builder will still emit the field in the JSON, until we can bump the `native_assets_cli` SDK constraint to 3.7 stable. Then only people with older versions of the `native_assets_cli` package but a newer SDK break.
Notes from discussion with @mkustermann:
|
(Maybe an additional thing: I don't like that |
We should also consider if we want to run the |
Yes we may also want to do that as part of CLI cleanup: #1606 |
Next refactoring in: * #1738 We move `config.targetOS` to `config.codeConfig.targetOS`. Other asset types might not get access on the target OS. This will require a manual roll into dartdev and flutter tools due to the targetOS now having to be passed in via `setupCodeConfig` instead of the base config. The native assets builder will still emit the same JSON if code assets are supported. Since both Dart and Flutter support code assets currently, this will not break anything. Once data assets for web in Flutter are added, all existing build hooks that assume code assets are always supported will break.
Addressing: * #1738 (comment) Currently on Flutter and the Dart CI provide this information, and they always provide all 3. So this should not be a breaking change on the protocol level. It is a breaking change on the API level.
Dart and Flutter have been passing the minimum OS SDK versions for a while (in non-dry-run), which means we can mark these fields non-optional if the target OS is used. This PR changes the `CodeConfig` to nest the OS versions (and iOS target SDK: device or simulator) to be nested under the OS and required. Other side effects of this PR: * Many unit tests where missing these (now) mandatory fields * `native_toolchain_c` can no longer test without the minimum OS versions, which changed the iOS test `otool` output. Addressing: * #1738 (comment)
I think I like
@mkustermann Let me know what you think. |
Moving the discussion back to here: Based on recent discussions with @mosuem @liamappelbe about what is used to hash the build directory and this PR restructuring, we may want to consider rename a few things and do the following // build hook
main(...) asyc {
await build((BuildInput input, BuildOutputBuilder output) {
input.outputDirectory;
input.config.{code,...} // <-- only this goes into hashing
input.metadata.* // <-- metadata emitted from package deps we can utilize
output.assets.code.add();
});
}
// link hook
main(...) asyc {
await link((LinkInput input, LinkOutputBuilder output) {
input.outputDirectory
input.config.{code,...}. // <-- only this goes into hashing
input.assets.{code,data,...} // <-- symmetric to `hook/build.dart`'s `output.assets.{code,data,...}`
output.assets.code.add();
});
} That would achieve
Originally posted by @mkustermann in #1830 (comment) I like the idea of I like the idea of having very clear what leads to directory sharing and not. Any input or dependencies changing means being reinvoked. That's also easy to understand. I'm not entirely sure about "config". #startBrainDump It feels more like a "target" e.g. how build systems can target multiple target tripples. And some build systems use target for the asset being built rather than the target tripple, which corresponds more closely to our And then we have to decide where
With Holistic overview of the JSON BuildInput // all influence whether the hook is reinvoked
// a. shared
.packageName
.packageRoot
.outputDirectory
.outputDirectoryShared
.outputJson // instead of a predefined filename in outputDirectory
// b. hook specific
.assetsForLinking // link only
.metaData // build only
// c. target config - all influence whether the output dir is shared
.target // TargetConfig - shared for both link and build
// 1. per target platform
.platform // if it's native, .native will be set, if it's web .web will be set
.native // we have no current need for this, everything lives in input.target.code
.web
.compiler // JS or Wasm
.crossOriginIsolated // or whatever web specific options
// 2. per asset
.assetTypes // every asset type has it's own config, optionally
.code
.linkModePreference
.targetArchitecture
.targetOS
.iOS
.targetVersion
.targetIOSSdk
.macOS
.targetVersion
.android
.targetNdkApi
.cCompiler
.archiver
.compiler
.linker
.dartCApi // Dynamically linked via VM, so available in every embedder
.data // we haven't found a need yet, so doesn't exist currently
.wasm
.abi // emscripten
.wasiVersion // 'Preview 1' currently
.java // or named differently if we'd include Kotlin things?
.gradlePath // would something like this be useful?
.icon // in Flutter only, for IconAsset
.resolution // xxx dpi
.font // in Flutter only, for FontAsset
... // Maybe no need for this either
// 3. per embedder
.flutter
.buildMode // release, debug, profile
.code
.cApi Re Dart API:
That's more in line with the v1 prototype. With the explicit split between Sorry for the very long write up. 😄 PTAL @liamappelbe @mosuem @mkustermann (Optional @HosseinYousefi) if anything looks weird before I start a big refactoring! 🚧 |
Currently the CLI protocol mandates
BuildConfig.targetOS
. Though making builds for the web platform wouldn't have any operating system. So we could either move this toBuildConfig.codeConfig.targetOS
or remove it entirely.We may decide that we introduce a
BuildConfig.targetPlatform
which is the platform we're going to run Dart code on - but this is different from an operating system concept ("web" is a target platform, but not an operating system)./cc @dcharkes
The text was updated successfully, but these errors were encountered: