You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Ensure the output directory is left untouched by the native assets builder.
Make native_toolchain_c use a subdirectory for each builder. Not needed. With the current compilers wrapped, doing it in the same outputDirectory works fine.
Add documentation.
==================
How does a hook writer producing many assets, reuse their previous build in a next run? E.g. How do they cache assets?
For example: If we have 1000 3d models in source files, and they need to be compiled to some binary format, and we change one. Then the next cold start of the flutter app will rerun the hook, and if the hook writer does not get access to their previously built binary files, they will need to rerun the "compilation" step for all 1000 assets.
This is a simpler variant than thinking about caching with hot restart in mind, but both will need similar infrastructure.
We have two possible approaches here: (1) hook writers can check the timestamps of their own dependencies and the build outputs and on rebuild the ones which need rebuilding, or (2) the protocol reports changed dependencies and asset IDs that need rebuilding.
1. Hooks do caching internally
If the native assets builder promises to not modify the output directory in between runs, then hook writers can internally.
The hooks always output the full list of assets, and all the asset files exist after a hook run.
import'dart:io';
import'package:native_assets_cli/native_assets_cli.dart';
voidmain(List<String> args) async {
awaitbuild(args, (config, output) async {
final packageName = config.packageName;
final sourceDirectory =Directory.fromUri(config.packageRoot.resolve('models/'));
// If assets are added, rerun hook.
output.addDependency(sourceDirectory.uri);
awaitfor (final sourceFile in assetDirectory.list()) {
if (sourceFile is!File) {
continue;
}
final targetFile =File.fromUri(output.outputDirectory.resolve(sourceFile.replaceLast('.model', '.binary'));
if (!await targetFile.exists() ||await sourceFile.lastModified() >await targetFile.lastModified()){
compile(sourceFile, targetFile)
}
// The file path relative to the package root, with forward slashes.final name = targetFile
.toFilePath(windows:false)
.substring(config.packageRoot.toFilePath(windows:false).length);
output.addAsset(
DataAsset(
package: packageName,
name: name,
file: targetFile.uri,
),
linkInPackage: config.linkingEnabled ? packageName :null,
dependencies: [dataAsset.uri],
);
output.addDependency(
sourceFile,
);
}
});
}
For example wrapping a CMake build already works this way by default, as CMake caches stuff internally in its build folder.
On thing to consider is if a hook has multiple builders adding assets. Then those builders should likely have their own subdirectory in the output directory.
TODO:
Ensure the output directory is left untouched by the native assets builder.
Make native_toolchain_c use a subdirectory for each builder.
2. BuildConfig reports changed dependencies and assets which need to be rebuilt
An alternative design is to have hooks get a list of changed global dependencies and a map with changed asset ids as keys and which of the dependencies for each asset changed as values in the map.
Then the hook would only run the build for the changed assets and only report the changed assets.
An open question is whether this should be done inside the same directory as the initial build or not. If no, then no intermediate build artifacts can be used (CMake). If yes, we have to worry about combining all the build outputs from various runs.
It's not clear that this is beneficial for hook writers over using dart:io. But it does add a lot of extra book keeping to the native_assets_builder to combine the build outputs of various subsequent runs.
If we're not doing 2, then "dependency" is simply thing that if changed, will trigger a build hook run on cold/hot restart. However if the user really wants to exploit this system, they can split up their package into several packages, each with a different build hook and a different set of dependencies, so that they can get a more fine grained rebuild.
TODO
MakeNot needed. With the current compilers wrapped, doing it in the same outputDirectory works fine.native_toolchain_c
use a subdirectory for each builder.==================
How does a hook writer producing many assets, reuse their previous build in a next run? E.g. How do they cache assets?
For example: If we have 1000 3d models in source files, and they need to be compiled to some binary format, and we change one. Then the next cold start of the flutter app will rerun the hook, and if the hook writer does not get access to their previously built binary files, they will need to rerun the "compilation" step for all 1000 assets.
This is a simpler variant than thinking about caching with hot restart in mind, but both will need similar infrastructure.
We have two possible approaches here: (1) hook writers can check the timestamps of their own dependencies and the build outputs and on rebuild the ones which need rebuilding, or (2) the protocol reports changed dependencies and asset IDs that need rebuilding.
1. Hooks do caching internally
If the native assets builder promises to not modify the output directory in between runs, then hook writers can internally.
The hooks always output the full list of assets, and all the asset files exist after a hook run.
For example wrapping a CMake build already works this way by default, as CMake caches stuff internally in its build folder.
On thing to consider is if a hook has multiple builders adding assets. Then those builders should likely have their own subdirectory in the output directory.
TODO:
native_toolchain_c
use a subdirectory for each builder.2. BuildConfig reports changed dependencies and assets which need to be rebuilt
An alternative design is to have hooks get a list of changed global dependencies and a map with changed asset ids as keys and which of the dependencies for each asset changed as values in the map.
Then the hook would only run the build for the changed assets and only report the changed assets.
An open question is whether this should be done inside the same directory as the initial build or not. If no, then no intermediate build artifacts can be used (CMake). If yes, we have to worry about combining all the build outputs from various runs.
It's not clear that this is beneficial for hook writers over using
dart:io
. But it does add a lot of extra book keeping to thenative_assets_builder
to combine the build outputs of various subsequent runs.Hence, we suggest going with option 1.
Thanks @HosseinYousefi for triggering this discussion!
Background, only accessible for Googlers: http://go/dart-native-asset-caching
Somewhat related:
The text was updated successfully, but these errors were encountered: