33// found in the LICENSE file.
44
55import 'package:meta/meta.dart' ;
6- import 'package:native_assets_builder/native_assets_builder.dart' ;
76import 'package:package_config/package_config_types.dart' ;
87
98import '../../base/common.dart' ;
109import '../../base/file_system.dart' ;
1110import '../../build_info.dart' ;
11+ import '../../convert.dart' ;
1212import '../../dart/package_map.dart' ;
1313import '../../isolated/native_assets/native_assets.dart' ;
1414import '../build_system.dart' ;
1515import '../depfile.dart' ;
1616import '../exceptions.dart' ;
1717import 'common.dart' ;
1818
19- /// Builds the right native assets for a Flutter app.
20- ///
21- /// The build mode and target architecture can be changed from the
22- /// native build project (Xcode etc.), so only `flutter assemble` has the
23- /// information about build-mode and target architecture.
24- /// Invocations of flutter_tools other than `flutter assemble` are dry runs.
25- ///
26- /// This step needs to be consistent with the dry run invocations in `flutter
27- /// run`s so that the kernel mapping of asset id to dylib lines up after hot
28- /// restart.
29- ///
30- /// [KernelSnapshot] depends on this target. We produce a native_assets.yaml
31- /// here, and embed that mapping inside the kernel snapshot.
32- ///
33- /// The build always produces a valid native_assets.yaml and a native_assets.d
34- /// even if there are no native assets. This way the caching logic won't try to
35- /// rebuild.
36- class NativeAssets extends Target {
37- const NativeAssets ({
19+ /// Runs the dart build of the app.
20+ abstract class DartBuild extends Target {
21+ const DartBuild ({
3822 @visibleForTesting FlutterNativeAssetsBuildRunner ? buildRunner,
3923 }) : _buildRunner = buildRunner;
4024
4125 final FlutterNativeAssetsBuildRunner ? _buildRunner;
4226
4327 @override
4428 Future <void > build (Environment environment) async {
45- final String ? nativeAssetsEnvironment = environment.defines[kNativeAssets];
4629 final FileSystem fileSystem = environment.fileSystem;
47- final Uri nativeAssetsFileUri = environment.buildDir. childFile ( 'native_assets.yaml' ).uri ;
30+ final String ? nativeAssetsEnvironment = environment.defines[kNativeAssets] ;
4831
4932 final DartBuildResult result;
5033 if (nativeAssetsEnvironment == 'false' ) {
5134 result = const DartBuildResult .empty ();
52- await writeNativeAssetsYaml (KernelAssets (), nativeAssetsFileUri, fileSystem);
5335 } else {
54- final String ? targetPlatformEnvironment = environment.defines[kTargetPlatform];
55- if (targetPlatformEnvironment == null ) {
56- throw MissingDefineException (kTargetPlatform, name);
57- }
58- final TargetPlatform targetPlatform = getTargetPlatformForName (targetPlatformEnvironment);
59- final Uri projectUri = environment.projectDir.uri;
36+ final TargetPlatform targetPlatform = _getTargetPlatformFromEnvironment (environment, name);
6037
6138 final PackageConfig packageConfig = await loadPackageConfigWithLogging (
6239 fileSystem.file (environment.packageConfigPath),
6340 logger: environment.logger,
6441 );
42+ final Uri projectUri = environment.projectDir.uri;
6543 final FlutterNativeAssetsBuildRunner buildRunner = _buildRunner ??
6644 FlutterNativeAssetsBuildRunnerImpl (
6745 projectUri,
@@ -70,62 +48,154 @@ class NativeAssets extends Target {
7048 fileSystem,
7149 environment.logger,
7250 );
73-
74- (result, _) = await runFlutterSpecificDartBuild (
51+ result = await runFlutterSpecificDartBuild (
7552 environmentDefines: environment.defines,
7653 buildRunner: buildRunner,
7754 targetPlatform: targetPlatform,
7855 projectUri: projectUri,
79- nativeAssetsYamlUri : nativeAssetsFileUri,
8056 fileSystem: fileSystem,
8157 );
8258 }
8359
60+ final File dartBuildResultJsonFile = environment.buildDir.childFile (dartBuildResultFilename);
61+ if (! dartBuildResultJsonFile.parent.existsSync ()) {
62+ dartBuildResultJsonFile.parent.createSync (recursive: true );
63+ }
64+ dartBuildResultJsonFile.writeAsStringSync (json.encode (result.toJson ()));
65+
8466 final Depfile depfile = Depfile (
8567 < File > [
8668 for (final Uri dependency in result.dependencies) fileSystem.file (dependency),
8769 ],
8870 < File > [
89- fileSystem.file (nativeAssetsFileUri ),
71+ fileSystem.file (dartBuildResultJsonFile ),
9072 ],
9173 );
92- final File outputDepfile = environment.buildDir.childFile ('native_assets.d' );
74+ final File outputDepfile = environment.buildDir.childFile (depFilename );
9375 if (! outputDepfile.parent.existsSync ()) {
9476 outputDepfile.parent.createSync (recursive: true );
9577 }
9678 environment.depFileService.writeToFile (depfile, outputDepfile);
97- if (! await fileSystem.file (nativeAssetsFileUri).exists ()) {
98- throwToolExit ("${nativeAssetsFileUri .path } doesn't exist." );
99- }
10079 if (! await outputDepfile.exists ()) {
10180 throwToolExit ("${outputDepfile .path } doesn't exist." );
10281 }
10382 }
10483
10584 @override
106- List <String > get depfiles => < String > [
107- 'native_assets.d' ,
85+ List <String > get depfiles => const < String > [depFilename];
86+
87+ @override
88+ List <Source > get inputs => const < Source > [
89+ Source .pattern ('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart' ),
90+ // If different packages are resolved, different native assets might need to be built.
91+ Source .pattern ('{WORKSPACE_DIR}/.dart_tool/package_config_subset' ),
92+ // TODO(mosuem): Should consume resources.json. https://github.com/flutter/flutter/issues/146263
93+ ];
94+
95+ @override
96+ String get name => 'dart_build' ;
97+
98+ @override
99+ List <Source > get outputs => const < Source > [
100+ Source .pattern ('{BUILD_DIR}/$dartBuildResultFilename ' ),
108101 ];
109102
103+ /// Dependent build [Target] s can use this to consume the result of the
104+ /// [DartBuild] target.
105+ static Future <DartBuildResult > loadBuildResult (Environment environment) async {
106+ final File dartBuildResultJsonFile = environment.buildDir.childFile (DartBuild .dartBuildResultFilename);
107+ return DartBuildResult .fromJson (json.decode (dartBuildResultJsonFile.readAsStringSync ()) as Map <String , Object ?>);
108+ }
109+
110+ static const String dartBuildResultFilename = 'dart_build_result.json' ;
111+ static const String depFilename = 'dart_build.d' ;
112+ }
113+
114+ class DartBuildForNative extends DartBuild {
115+ const DartBuildForNative ({@visibleForTesting super .buildRunner});
116+
110117 @override
111118 List <Target > get dependencies => const < Target > [
112- // In AOT, depends on tree-shaking information (resources.json) from compiling dart.
113119 KernelSnapshotProgram (),
114120 ];
121+ }
122+
123+ /// Installs the code assets from a [DartBuild] Flutter app.
124+ ///
125+ /// The build mode and target architecture can be changed from the
126+ /// native build project (Xcode etc.), so only `flutter assemble` has the
127+ /// information about build-mode and target architecture.
128+ /// Invocations of flutter_tools other than `flutter assemble` are dry runs.
129+ ///
130+ /// This step needs to be consistent with the dry run invocations in `flutter
131+ /// run`s so that the kernel mapping of asset id to dylib lines up after hot
132+ /// restart.
133+ class InstallCodeAssets extends Target {
134+ const InstallCodeAssets ();
135+
136+ @override
137+ Future <void > build (Environment environment) async {
138+ final Uri projectUri = environment.projectDir.uri;
139+ final FileSystem fileSystem = environment.fileSystem;
140+ final TargetPlatform targetPlatform = _getTargetPlatformFromEnvironment (environment, name);
141+
142+ // We fetch the result from the [DartBuild].
143+ final DartBuildResult dartBuildResult = await DartBuild .loadBuildResult (environment);
144+
145+ // And install/copy the code assets to the right place and create a
146+ // native_asset.yaml that can be used by the final AOT compilation.
147+ final Uri nativeAssetsFileUri = environment.buildDir.childFile (nativeAssetsFilename).uri;
148+ await installCodeAssets (dartBuildResult: dartBuildResult, environmentDefines: environment.defines,
149+ targetPlatform: targetPlatform, projectUri: projectUri, fileSystem: fileSystem,
150+ nativeAssetsFileUri: nativeAssetsFileUri);
151+ assert (await fileSystem.file (nativeAssetsFileUri).exists ());
152+
153+ final Depfile depfile = Depfile (
154+ < File > [
155+ for (final Uri file in dartBuildResult.filesToBeBundled) fileSystem.file (file),
156+ ],
157+ < File > [
158+ fileSystem.file (nativeAssetsFileUri),
159+ ],
160+ );
161+ final File outputDepfile = environment.buildDir.childFile (depFilename);
162+ environment.depFileService.writeToFile (depfile, outputDepfile);
163+ if (! await outputDepfile.exists ()) {
164+ throwToolExit ("${outputDepfile .path } doesn't exist." );
165+ }
166+ }
167+
168+ @override
169+ List <String > get depfiles => < String > [depFilename];
170+
171+ @override
172+ List <Target > get dependencies => const < Target > [
173+ DartBuildForNative (),
174+ ];
115175
116176 @override
117177 List <Source > get inputs => const < Source > [
118178 Source .pattern ('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart' ),
119179 // If different packages are resolved, different native assets might need to be built.
120180 Source .pattern ('{WORKSPACE_DIR}/.dart_tool/package_config_subset' ),
121- // TODO(mosuem): Should consume resources.json. https://github.com/flutter/flutter/issues/146263
122181 ];
123182
124183 @override
125- String get name => 'native_assets ' ;
184+ String get name => 'install_code_assets ' ;
126185
127186 @override
128187 List <Source > get outputs => const < Source > [
129- Source .pattern ('{BUILD_DIR}/native_assets.yaml ' ),
188+ Source .pattern ('{BUILD_DIR}/$ nativeAssetsFilename ' ),
130189 ];
190+
191+ static const String nativeAssetsFilename = 'native_assets.yaml' ;
192+ static const String depFilename = 'install_code_assets.d' ;
193+ }
194+
195+ TargetPlatform _getTargetPlatformFromEnvironment (Environment environment, String name) {
196+ final String ? targetPlatformEnvironment = environment.defines[kTargetPlatform];
197+ if (targetPlatformEnvironment == null ) {
198+ throw MissingDefineException (kTargetPlatform, name);
199+ }
200+ return getTargetPlatformForName (targetPlatformEnvironment);
131201}
0 commit comments