3
3
// found in the LICENSE file.
4
4
5
5
import 'package:meta/meta.dart' ;
6
- import 'package:native_assets_builder/native_assets_builder.dart' ;
7
6
import 'package:package_config/package_config_types.dart' ;
8
7
9
8
import '../../base/common.dart' ;
10
9
import '../../base/file_system.dart' ;
11
10
import '../../build_info.dart' ;
11
+ import '../../convert.dart' ;
12
12
import '../../dart/package_map.dart' ;
13
13
import '../../isolated/native_assets/native_assets.dart' ;
14
14
import '../build_system.dart' ;
15
15
import '../depfile.dart' ;
16
16
import '../exceptions.dart' ;
17
17
import 'common.dart' ;
18
18
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 ({
38
22
@visibleForTesting FlutterNativeAssetsBuildRunner ? buildRunner,
39
23
}) : _buildRunner = buildRunner;
40
24
41
25
final FlutterNativeAssetsBuildRunner ? _buildRunner;
42
26
43
27
@override
44
28
Future <void > build (Environment environment) async {
45
- final String ? nativeAssetsEnvironment = environment.defines[kNativeAssets];
46
29
final FileSystem fileSystem = environment.fileSystem;
47
- final Uri nativeAssetsFileUri = environment.buildDir. childFile ( 'native_assets.yaml' ).uri ;
30
+ final String ? nativeAssetsEnvironment = environment.defines[kNativeAssets] ;
48
31
49
32
final DartBuildResult result;
50
33
if (nativeAssetsEnvironment == 'false' ) {
51
34
result = const DartBuildResult .empty ();
52
- await writeNativeAssetsYaml (KernelAssets (), nativeAssetsFileUri, fileSystem);
53
35
} 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);
60
37
61
38
final PackageConfig packageConfig = await loadPackageConfigWithLogging (
62
39
fileSystem.file (environment.packageConfigPath),
63
40
logger: environment.logger,
64
41
);
42
+ final Uri projectUri = environment.projectDir.uri;
65
43
final FlutterNativeAssetsBuildRunner buildRunner = _buildRunner ??
66
44
FlutterNativeAssetsBuildRunnerImpl (
67
45
projectUri,
@@ -70,62 +48,154 @@ class NativeAssets extends Target {
70
48
fileSystem,
71
49
environment.logger,
72
50
);
73
-
74
- (result, _) = await runFlutterSpecificDartBuild (
51
+ result = await runFlutterSpecificDartBuild (
75
52
environmentDefines: environment.defines,
76
53
buildRunner: buildRunner,
77
54
targetPlatform: targetPlatform,
78
55
projectUri: projectUri,
79
- nativeAssetsYamlUri : nativeAssetsFileUri,
80
56
fileSystem: fileSystem,
81
57
);
82
58
}
83
59
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
+
84
66
final Depfile depfile = Depfile (
85
67
< File > [
86
68
for (final Uri dependency in result.dependencies) fileSystem.file (dependency),
87
69
],
88
70
< File > [
89
- fileSystem.file (nativeAssetsFileUri ),
71
+ fileSystem.file (dartBuildResultJsonFile ),
90
72
],
91
73
);
92
- final File outputDepfile = environment.buildDir.childFile ('native_assets.d' );
74
+ final File outputDepfile = environment.buildDir.childFile (depFilename );
93
75
if (! outputDepfile.parent.existsSync ()) {
94
76
outputDepfile.parent.createSync (recursive: true );
95
77
}
96
78
environment.depFileService.writeToFile (depfile, outputDepfile);
97
- if (! await fileSystem.file (nativeAssetsFileUri).exists ()) {
98
- throwToolExit ("${nativeAssetsFileUri .path } doesn't exist." );
99
- }
100
79
if (! await outputDepfile.exists ()) {
101
80
throwToolExit ("${outputDepfile .path } doesn't exist." );
102
81
}
103
82
}
104
83
105
84
@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 ' ),
108
101
];
109
102
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
+
110
117
@override
111
118
List <Target > get dependencies => const < Target > [
112
- // In AOT, depends on tree-shaking information (resources.json) from compiling dart.
113
119
KernelSnapshotProgram (),
114
120
];
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
+ ];
115
175
116
176
@override
117
177
List <Source > get inputs => const < Source > [
118
178
Source .pattern ('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart' ),
119
179
// If different packages are resolved, different native assets might need to be built.
120
180
Source .pattern ('{WORKSPACE_DIR}/.dart_tool/package_config_subset' ),
121
- // TODO(mosuem): Should consume resources.json. https://github.com/flutter/flutter/issues/146263
122
181
];
123
182
124
183
@override
125
- String get name => 'native_assets ' ;
184
+ String get name => 'install_code_assets ' ;
126
185
127
186
@override
128
187
List <Source > get outputs => const < Source > [
129
- Source .pattern ('{BUILD_DIR}/native_assets.yaml ' ),
188
+ Source .pattern ('{BUILD_DIR}/$ nativeAssetsFilename ' ),
130
189
];
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);
131
201
}
0 commit comments