[native_assets] Stop running link hooks in JIT mode (#151534)

Stop running link hooks in debug mode.

Rationale: link hooks only get access to tree-shaking info in release builds, so they can't do anything meaningful in debug builds. Debug builds should be fast as development cycle, so running less is better.

More details:

* https://github.com/dart-lang/native/issues/1252

Also: rolls packages to latest versions.

## Implementation details

The decision whether linking is enabled is made as follows:

* For normal builds `build_info.dart::BuildMode` is used to determine whether Dart is compiled in JIT or AOT mode.
* Testers always run in JIT, so no linking.
* Native asset dry runs only run for JIT builds (e.g only when hot reload and hot restart are enabled).

## Testing

The integration test is updated to output an asset for linking if `BuildConfig.linkingEnabled` is true, and to output an asset for bundling directly if linking is not enabled.
This commit is contained in:
Daco Harkes 2024-07-12 08:44:23 +02:00 committed by GitHub
parent dddea4d155
commit cec2400658
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 637 additions and 632 deletions

View File

@ -9,10 +9,22 @@ import 'package:native_toolchain_c/native_toolchain_c.dart';
void main(List<String> args) async {
await build(args, (BuildConfig config, BuildOutput output) async {
final String assetName;
if (config.linkingEnabled) {
// The link hook will be run. So emit an asset with a name that is
// not used, so that the link hook can rename it.
// This will ensure the test fails if the link-hooks are not run
// while being reported that linking is enabled.
assetName = 'some_asset_name_that_is_not_used';
} else {
// The link hook will not be run, so immediately emit an asset for
// bundling.
assetName = '${config.packageName}_bindings_generated.dart';
}
final String packageName = config.packageName;
final CBuilder cbuilder = CBuilder.library(
name: packageName,
assetName: 'some_asset_name_that_is_not_used',
assetName: assetName,
sources: <String>[
'src/$packageName.c',
],
@ -27,10 +39,10 @@ void main(List<String> args) async {
..onRecord.listen((LogRecord record) => print(record.message)),
);
output.addDependencies(outputCatcher.dependencies);
// Send the asset to hook/link.dart.
// Send the asset to hook/link.dart or immediately for bundling.
output.addAsset(
outputCatcher.assets.single,
linkInPackage: 'link_hook',
linkInPackage: config.linkingEnabled ? 'link_hook' : null,
);
});
}

View File

@ -8,8 +8,8 @@ environment:
dependencies:
cli_config: 0.2.0
logging: 1.2.0
native_assets_cli: 0.6.1
native_toolchain_c: 0.5.0
native_assets_cli: 0.7.0
native_toolchain_c: 0.5.1
args: 2.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@ -67,4 +67,4 @@ dev_dependencies:
webkit_inspection_protocol: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml_edit: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: fe47
# PUBSPEC CHECKSUM: 0248

View File

@ -57,18 +57,8 @@ Future<Iterable<KernelAsset>> dryRunNativeAssetsAndroidInternal(
includeParentEnvironment: true,
);
ensureNativeAssetsBuildDryRunSucceed(buildDryRunResult);
final LinkDryRunResult linkDryRunResult = await buildRunner.linkDryRun(
linkModePreference: LinkModePreferenceImpl.dynamic,
targetOS: targetOS,
workingDirectory: projectUri,
includeParentEnvironment: true,
buildDryRunResult: buildDryRunResult,
);
ensureNativeAssetsLinkDryRunSucceed(linkDryRunResult);
final List<AssetImpl> nativeAssets = <AssetImpl>[
...buildDryRunResult.assets,
...linkDryRunResult.assets,
];
// No link hooks in JIT mode.
final List<AssetImpl> nativeAssets = buildDryRunResult.assets;
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Dry running native assets for $targetOS done.');
final Map<AssetImpl, KernelAsset> assetTargetLocations =
@ -102,6 +92,7 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)>
final List<Target> targets = androidArchs.map(_getNativeTarget).toList();
final BuildModeImpl buildModeCli =
nativeAssetsBuildMode(buildMode);
final bool linkingEnabled = buildModeCli == BuildModeImpl.release;
globals.logger
.printTrace('Building native assets for $targets $buildModeCli.');
@ -116,23 +107,26 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)>
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.ndkCCompilerConfigImpl,
targetAndroidNdkApi: targetAndroidNdkApi,
linkingEnabled: linkingEnabled,
);
ensureNativeAssetsBuildSucceed(buildResult);
nativeAssets.addAll(buildResult.assets);
dependencies.addAll(buildResult.dependencies);
final LinkResult linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.ndkCCompilerConfigImpl,
targetAndroidNdkApi: targetAndroidNdkApi,
buildResult: buildResult,
);
ensureNativeAssetsLinkSucceed(linkResult);
nativeAssets.addAll(linkResult.assets);
dependencies.addAll(linkResult.dependencies);
if (linkingEnabled) {
final LinkResult linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.ndkCCompilerConfigImpl,
targetAndroidNdkApi: targetAndroidNdkApi,
buildResult: buildResult,
);
ensureNativeAssetsLinkSucceed(linkResult);
nativeAssets.addAll(linkResult.assets);
dependencies.addAll(linkResult.dependencies);
}
}
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Building native assets for $targets done.');

View File

@ -55,18 +55,8 @@ Future<Iterable<KernelAsset>> dryRunNativeAssetsIOSInternal(
includeParentEnvironment: true,
);
ensureNativeAssetsBuildDryRunSucceed(buildDryRunResult);
final LinkDryRunResult linkDryRunResult = await buildRunner.linkDryRun(
linkModePreference: LinkModePreferenceImpl.dynamic,
targetOS: targetOS,
workingDirectory: projectUri,
includeParentEnvironment: true,
buildDryRunResult: buildDryRunResult,
);
ensureNativeAssetsLinkDryRunSucceed(linkDryRunResult);
final List<AssetImpl> nativeAssets = <AssetImpl>[
...buildDryRunResult.assets,
...linkDryRunResult.assets,
];
// No link hooks in JIT.
final List<AssetImpl> nativeAssets = buildDryRunResult.assets;
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Dry running native assets for $targetOS done.');
return _assetTargetLocations(nativeAssets).values;
@ -90,6 +80,7 @@ Future<List<Uri>> buildNativeAssetsIOS({
final List<Target> targets = darwinArchs.map(_getNativeTarget).toList();
final BuildModeImpl buildModeCli = nativeAssetsBuildMode(buildMode);
final bool linkingEnabled = buildModeCli == BuildModeImpl.release;
const OSImpl targetOS = OSImpl.iOS;
final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS);
@ -109,25 +100,28 @@ Future<List<Uri>> buildNativeAssetsIOS({
cCompilerConfig: await buildRunner.cCompilerConfig,
// TODO(dcharkes): Fetch minimum iOS version from somewhere. https://github.com/flutter/flutter/issues/145104
targetIOSVersion: 12,
linkingEnabled: linkingEnabled,
);
ensureNativeAssetsBuildSucceed(buildResult);
nativeAssets.addAll(buildResult.assets);
dependencies.addAll(buildResult.dependencies);
final LinkResult linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
targetIOSSdkImpl: iosSdk,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig,
buildResult: buildResult,
// TODO(dcharkes): Fetch minimum iOS version from somewhere. https://github.com/flutter/flutter/issues/145104
targetIOSVersion: 12,
);
ensureNativeAssetsLinkSucceed(linkResult);
nativeAssets.addAll(linkResult.assets);
dependencies.addAll(linkResult.dependencies);
if (linkingEnabled) {
final LinkResult linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
targetIOSSdkImpl: iosSdk,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig,
buildResult: buildResult,
// TODO(dcharkes): Fetch minimum iOS version from somewhere. https://github.com/flutter/flutter/issues/145104
targetIOSVersion: 12,
);
ensureNativeAssetsLinkSucceed(linkResult);
nativeAssets.addAll(linkResult.assets);
dependencies.addAll(linkResult.dependencies);
}
}
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Building native assets for $targets done.');

View File

@ -59,18 +59,8 @@ Future<Iterable<KernelAsset>> dryRunNativeAssetsMacOSInternal(
includeParentEnvironment: true,
);
ensureNativeAssetsBuildDryRunSucceed(buildDryRunResult);
final LinkDryRunResult linkDryRunResult = await buildRunner.linkDryRun(
linkModePreference: LinkModePreferenceImpl.dynamic,
targetOS: targetOS,
workingDirectory: projectUri,
includeParentEnvironment: true,
buildDryRunResult: buildDryRunResult,
);
ensureNativeAssetsLinkDryRunSucceed(linkDryRunResult);
final List<AssetImpl> nativeAssets = <AssetImpl>[
...buildDryRunResult.assets,
...linkDryRunResult.assets,
];
// No link hooks in JIT mode.
final List<AssetImpl> nativeAssets = buildDryRunResult.assets;
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Dry running native assets for $targetOS done.');
final Uri? absolutePath = flutterTester ? buildUri : null;
@ -115,6 +105,7 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsMacOS({
: <Target>[Target.current];
final BuildModeImpl buildModeCli =
nativeAssetsBuildMode(buildMode);
final bool linkingEnabled = buildModeCli == BuildModeImpl.release;
globals.logger
.printTrace('Building native assets for $targets $buildModeCli.');
@ -130,24 +121,27 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsMacOS({
cCompilerConfig: await buildRunner.cCompilerConfig,
// TODO(dcharkes): Fetch minimum MacOS version from somewhere. https://github.com/flutter/flutter/issues/145104
targetMacOSVersion: 13,
linkingEnabled: linkingEnabled,
);
ensureNativeAssetsBuildSucceed(buildResult);
nativeAssets.addAll(buildResult.assets);
dependencies.addAll(buildResult.dependencies);
final LinkResult linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig,
buildResult: buildResult,
// TODO(dcharkes): Fetch minimum MacOS version from somewhere. https://github.com/flutter/flutter/issues/145104
targetMacOSVersion: 13,
);
ensureNativeAssetsLinkSucceed(linkResult);
nativeAssets.addAll(linkResult.assets);
dependencies.addAll(linkResult.dependencies);
if (linkingEnabled) {
final LinkResult linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig,
buildResult: buildResult,
// TODO(dcharkes): Fetch minimum MacOS version from somewhere. https://github.com/flutter/flutter/issues/145104
targetMacOSVersion: 13,
);
ensureNativeAssetsLinkSucceed(linkResult);
nativeAssets.addAll(linkResult.assets);
dependencies.addAll(linkResult.dependencies);
}
}
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Building native assets for $targets done.');

View File

@ -64,6 +64,7 @@ abstract class NativeAssetsBuildRunner {
int? targetIOSVersion,
int? targetMacOSVersion,
IOSSdkImpl? targetIOSSdkImpl,
required bool linkingEnabled,
});
/// Runs all [packagesWithNativeAssets] `link.dart` in dry run.
@ -169,6 +170,7 @@ class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner {
targetOS: targetOS,
workingDirectory: workingDirectory,
packageLayout: packageLayout,
linkingEnabled: false, // Dry run is only used in JIT mode.
);
}
@ -184,6 +186,7 @@ class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner {
int? targetMacOSVersion,
int? targetAndroidNdkApi,
IOSSdkImpl? targetIOSSdkImpl,
required bool linkingEnabled,
}) {
final PackageLayout packageLayout = PackageLayout.fromPackageConfig(
packageConfig,
@ -201,6 +204,7 @@ class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner {
packageLayout: packageLayout,
targetIOSVersion: targetIOSVersion,
targetMacOSVersion: targetMacOSVersion,
linkingEnabled: linkingEnabled,
);
}
@ -657,18 +661,8 @@ Future<Iterable<KernelAsset>> dryRunNativeAssetsSingleArchitectureInternal(
includeParentEnvironment: true,
);
ensureNativeAssetsBuildDryRunSucceed(buildDryRunResult);
final LinkDryRunResult linkDryRunResult = await buildRunner.linkDryRun(
linkModePreference: LinkModePreferenceImpl.dynamic,
targetOS: targetOS,
workingDirectory: projectUri,
includeParentEnvironment: true,
buildDryRunResult: buildDryRunResult,
);
ensureNativeAssetsLinkDryRunSucceed(linkDryRunResult);
final List<AssetImpl> nativeAssets = <AssetImpl>[
...buildDryRunResult.assets,
...linkDryRunResult.assets,
];
// No link hooks in JIT mode.
final List<AssetImpl> nativeAssets = buildDryRunResult.assets;
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Dry running native assets for $targetOS done.');
final Uri? absolutePath = flutterTester ? buildUri : null;
@ -714,6 +708,7 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsSingleA
}
final BuildModeImpl buildModeCli = nativeAssetsBuildMode(buildMode);
final bool linkingEnabled = buildModeCli == BuildModeImpl.release;
globals.logger.printTrace('Building native assets for $target $buildModeCli.');
final BuildResult buildResult = await buildRunner.build(
@ -723,25 +718,29 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsSingleA
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig,
linkingEnabled: linkingEnabled,
);
ensureNativeAssetsBuildSucceed(buildResult);
final LinkResult linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig,
buildResult: buildResult,
);
ensureNativeAssetsLinkSucceed(linkResult);
late final LinkResult linkResult;
if (linkingEnabled) {
linkResult = await buildRunner.link(
linkModePreference: LinkModePreferenceImpl.dynamic,
target: target,
buildMode: buildModeCli,
workingDirectory: projectUri,
includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig,
buildResult: buildResult,
);
ensureNativeAssetsLinkSucceed(linkResult);
}
final List<AssetImpl> nativeAssets = <AssetImpl>[
...buildResult.assets,
...linkResult.assets,
if (linkingEnabled) ...linkResult.assets,
];
final Set<Uri> dependencies = <Uri>{
...buildResult.dependencies,
...linkResult.dependencies,
if (linkingEnabled) ...linkResult.dependencies,
};
ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Building native assets for $target done.');

View File

@ -56,8 +56,8 @@ dependencies:
cli_config: 0.2.0
graphs: 2.3.1
native_assets_builder: 0.7.1
native_assets_cli: 0.6.1
native_assets_builder: 0.8.0
native_assets_cli: 0.7.0
# We depend on very specific internal implementation details of the
# 'test' package, which change between versions, so when upgrading
@ -120,4 +120,4 @@ dartdoc:
# Exclude this package from the hosted API docs.
nodoc: true
# PUBSPEC CHECKSUM: 52ae
# PUBSPEC CHECKSUM: 5aae

View File

@ -9,8 +9,8 @@ environment:
dependencies:
cli_config: ^0.2.0
logging: ^1.2.0
native_assets_cli: ^0.6.1
native_toolchain_c: ^0.5.0
native_assets_cli: ^0.7.0
native_toolchain_c: ^0.5.1
dev_dependencies:
ffi: ^2.1.2

View File

@ -161,7 +161,7 @@ void main() {
contains('package:bar/bar.dart'),
);
expect(buildRunner.buildDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 0);
});
testUsingContext('build with assets but not enabled', () async {
@ -215,57 +215,67 @@ void main() {
);
});
testUsingContext('build with assets',
skip: const LocalPlatform().isWindows, // [intended] Backslashes in commands, but we will never run these commands on Windows.
overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final File dylibAfterCompiling = fileSystem.file('libbar.so');
// The mock doesn't create the file, so create it here.
await dylibAfterCompiling.create();
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: OSImpl.android,
architecture: ArchitectureImpl.arm64,
file: Uri.file('libbar.so'),
),
for (final BuildMode buildMode in <BuildMode>[
BuildMode.debug,
BuildMode.release,
]) {
testUsingContext('build with assets $buildMode',
skip: const LocalPlatform().isWindows, // [intended] Backslashes in commands, but we will never run these commands on Windows.
overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final File dylibAfterCompiling = fileSystem.file('libbar.so');
// The mock doesn't create the file, so create it here.
await dylibAfterCompiling.create();
final FakeNativeAssetsBuildRunner buildRunner =
FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
),
);
await buildNativeAssetsAndroid(
androidArchs: <AndroidArch>[AndroidArch.arm64_v8a],
targetAndroidNdkApi: 21,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for [android_arm64] debug.',
'Building native assets for [android_arm64] done.',
]),
);
expect(
environment.buildDir.childFile('native_assets.yaml'),
exists,
);
expect(buildRunner.buildInvocations, 1);
expect(buildRunner.linkInvocations, 1);
});
buildResult: FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: OSImpl.android,
architecture: ArchitectureImpl.arm64,
file: Uri.file('libbar.so'),
),
],
),
);
await buildNativeAssetsAndroid(
androidArchs: <AndroidArch>[AndroidArch.arm64_v8a],
targetAndroidNdkApi: 21,
projectUri: projectUri,
buildMode: buildMode,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for [android_arm64] $buildMode.',
'Building native assets for [android_arm64] done.',
]),
);
expect(
environment.buildDir.childFile('native_assets.yaml'),
exists,
);
expect(buildRunner.buildInvocations, 1);
expect(
buildRunner.linkInvocations,
buildMode == BuildMode.release ? 1 : 0,
);
});
}
// Ensure no exceptions for a non installed NDK are thrown if no native
// assets have to be build.
@ -328,29 +338,24 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => dryRunNativeAssetsAndroid(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => dryRunNativeAssetsAndroid(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook (dry run) native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building (dry run) native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
@ -367,7 +372,7 @@ void main() {
androidArchs: <AndroidArch>[AndroidArch.arm64_v8a],
targetAndroidNdkApi: 21,
projectUri: projectUri,
buildMode: BuildMode.debug,
buildMode: BuildMode.release,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(

View File

@ -59,6 +59,7 @@ class FakeNativeAssetsBuildRunner implements NativeAssetsBuildRunner {
int? targetIOSVersion,
int? targetMacOSVersion,
IOSSdkImpl? targetIOSSdkImpl,
required bool linkingEnabled,
}) async {
buildInvocations++;
lastBuildMode = buildMode;

View File

@ -163,7 +163,7 @@ void main() {
contains('package:bar/bar.dart'),
);
expect(buildRunner.buildDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 0);
});
testUsingContext('build with assets but not enabled', () async {
@ -217,88 +217,101 @@ void main() {
);
});
testUsingContext('build with assets', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <Pattern>[
'lipo',
'-create',
'-output',
'/build/native_assets/ios/bar.framework/bar',
'arm64/libbar.dylib',
'x64/libbar.dylib',
],
),
const FakeCommand(
command: <Pattern>[
'install_name_tool',
'-id',
'@rpath/bar.framework/bar',
'/build/native_assets/ios/bar.framework/bar'
],
),
const FakeCommand(
command: <Pattern>[
'codesign',
'--force',
'--sign',
'-',
'--timestamp=none',
'/build/native_assets/ios/bar.framework',
],
),
],
),
}, () async {
if (const LocalPlatform().isWindows) {
return; // Backslashes in commands, but we will never run these commands on Windows.
}
final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
onBuild: (native_assets_cli.Target target) =>
FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: target.os,
architecture: target.architecture,
file: Uri.file('${target.architecture}/libbar.dylib'),
),
for (final BuildMode buildMode in <BuildMode>[
BuildMode.debug,
BuildMode.release,
]) {
testUsingContext('build with assets $buildMode',
overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <Pattern>[
'lipo',
'-create',
'-output',
'/build/native_assets/ios/bar.framework/bar',
'arm64/libbar.dylib',
'x64/libbar.dylib',
],
),
const FakeCommand(
command: <Pattern>[
'install_name_tool',
'-id',
'@rpath/bar.framework/bar',
'/build/native_assets/ios/bar.framework/bar'
],
),
FakeCommand(
command: <Pattern>[
'codesign',
'--force',
'--sign',
'-',
if (buildMode == BuildMode.debug)
'--timestamp=none',
'/build/native_assets/ios/bar.framework',
],
),
],
),
}, () async {
if (const LocalPlatform().isWindows) {
return; // Backslashes in commands, but we will never run these commands on Windows.
}
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final FakeNativeAssetsBuildRunner buildRunner =
FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
),
);
await buildNativeAssetsIOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64, DarwinArch.x86_64],
environmentType: EnvironmentType.simulator,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for [ios_arm64, ios_x64] debug.',
'Building native assets for [ios_arm64, ios_x64] done.',
]),
);
expect(
environment.buildDir.childFile('native_assets.yaml'),
exists,
);
// Two archs.
expect(buildRunner.buildInvocations, 2);
expect(buildRunner.linkInvocations, 2);
});
onBuild: (native_assets_cli.Target target) =>
FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: target.os,
architecture: target.architecture,
file: Uri.file('${target.architecture}/libbar.dylib'),
),
],
),
);
await buildNativeAssetsIOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64, DarwinArch.x86_64],
environmentType: EnvironmentType.simulator,
projectUri: projectUri,
buildMode: buildMode,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for [ios_arm64, ios_x64] $buildMode.',
'Building native assets for [ios_arm64, ios_x64] done.',
]),
);
expect(
environment.buildDir.childFile('native_assets.yaml'),
exists,
);
// Two archs.
expect(buildRunner.buildInvocations, 2);
expect(
buildRunner.linkInvocations,
buildMode == BuildMode.release ? 2 : 0,
);
});
}
testUsingContext('Native assets dry run error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
@ -308,29 +321,24 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => dryRunNativeAssetsIOS(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => dryRunNativeAssetsIOS(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook (dry run) native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building (dry run) native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
@ -347,7 +355,7 @@ void main() {
darwinArchs: <DarwinArch>[DarwinArch.arm64],
environmentType: EnvironmentType.simulator,
projectUri: projectUri,
buildMode: BuildMode.debug,
buildMode: BuildMode.release,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(

View File

@ -199,7 +199,7 @@ void main() {
contains('package:bar/bar.dart'),
);
expect(buildRunner.buildDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 0);
});
testUsingContext('build with assets but not enabled', overrides: <Type, Generator>{
@ -266,66 +266,78 @@ void main() {
if (flutterTester) {
testName += ' flutter tester';
}
testUsingContext('build with assets$testName', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig = environment.projectDir.childDirectory('.dart_tool').childFile('package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final File dylibAfterCompiling = fileSystem.file('libbar.so');
// The mock doesn't create the file, so create it here.
await dylibAfterCompiling.create();
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: OSImpl.linux,
architecture: ArchitectureImpl.x64,
file: dylibAfterCompiling.uri,
),
for (final BuildMode buildMode in <BuildMode>[
BuildMode.debug,
BuildMode.release,
]) {
testUsingContext('build with assets $buildMode$testName',
overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig = environment.projectDir
.childDirectory('.dart_tool')
.childFile('package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final File dylibAfterCompiling = fileSystem.file('libbar.so');
// The mock doesn't create the file, so create it here.
await dylibAfterCompiling.create();
final FakeNativeAssetsBuildRunner buildRunner =
FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
),
);
final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsLinux(
targetPlatform: TargetPlatform.linux_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
flutterTester: flutterTester,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for linux_x64 debug.',
'Building native assets for linux_x64 done.',
]),
);
expect(
nativeAssetsYaml,
projectUri.resolve('build/native_assets/linux/native_assets.yaml'),
);
expect(
await fileSystem.file(nativeAssetsYaml).readAsString(),
stringContainsInOrder(<String>[
'package:bar/bar.dart',
if (flutterTester)
// Tests run on host system, so the have the full path on the system.
'- ${projectUri.resolve('build/native_assets/linux/libbar.so').toFilePath()}'
else
// Apps are a bundle with the dylibs on their dlopen path.
'- libbar.so',
]),
);
expect(buildRunner.buildInvocations, 1);
expect(buildRunner.linkInvocations, 1);
});
buildResult: FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: OSImpl.linux,
architecture: ArchitectureImpl.x64,
file: dylibAfterCompiling.uri,
),
],
),
);
final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsLinux(
targetPlatform: TargetPlatform.linux_x64,
projectUri: projectUri,
buildMode: buildMode,
fileSystem: fileSystem,
flutterTester: flutterTester,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for linux_x64 $buildMode.',
'Building native assets for linux_x64 done.',
]),
);
expect(
nativeAssetsYaml,
projectUri.resolve('build/native_assets/linux/native_assets.yaml'),
);
expect(
await fileSystem.file(nativeAssetsYaml).readAsString(),
stringContainsInOrder(<String>[
'package:bar/bar.dart',
if (flutterTester)
// Tests run on host system, so the have the full path on the system.
'- ${projectUri.resolve('build/native_assets/linux/libbar.so').toFilePath()}'
else
// Apps are a bundle with the dylibs on their dlopen path.
'- libbar.so',
]),
);
expect(buildRunner.buildInvocations, 1);
expect(
buildRunner.linkInvocations,
buildMode == BuildMode.release ? 1 : 0,
);
});
}
}
testUsingContext('static libs not supported', overrides: <Type, Generator>{
@ -379,29 +391,24 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => dryRunNativeAssetsLinux(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => dryRunNativeAssetsLinux(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook (dry run) native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building (dry run) native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
@ -412,32 +419,27 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => buildNativeAssetsLinux(
targetPlatform: TargetPlatform.linux_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => buildNativeAssetsLinux(
targetPlatform: TargetPlatform.linux_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
// This logic is mocked in the other tests to avoid having test order

View File

@ -184,7 +184,7 @@ void main() {
contains('package:bar/bar.dart'),
);
expect(buildRunner.buildDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 0);
// Check that the framework uri is identical for both archs.
final String pathSeparator = const LocalPlatform().pathSeparator;
expect(
@ -267,100 +267,108 @@ void main() {
dylibPath = '/build/native_assets/macos/bar.framework/Versions/A/bar';
signPath = '/build/native_assets/macos/bar.framework';
}
testUsingContext('build with assets$testName', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.list(
<FakeCommand>[
FakeCommand(
command: <Pattern>[
'lipo',
'-create',
'-output',
dylibPath,
'arm64/libbar.dylib',
'x64/libbar.dylib',
],
),
if (!flutterTester)
for (final BuildMode buildMode in <BuildMode>[
BuildMode.debug,
BuildMode.release,
]) {
testUsingContext('build with assets $buildMode$testName', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.list(
<FakeCommand>[
FakeCommand(
command: <Pattern>[
'install_name_tool',
'-id',
'@rpath/bar.framework/bar',
'lipo',
'-create',
'-output',
dylibPath,
'arm64/libbar.dylib',
'x64/libbar.dylib',
],
),
FakeCommand(
command: <Pattern>[
'codesign',
'--force',
'--sign',
'-',
'--timestamp=none',
signPath,
],
),
],
),
}, () async {
if (const LocalPlatform().isWindows) {
return; // Backslashes in commands, but we will never run these commands on Windows.
}
final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
onBuild: (native_assets_cli.Target target) =>
FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: target.os,
architecture: target.architecture,
file: Uri.file('${target.architecture}/libbar.dylib'),
if (!flutterTester)
FakeCommand(
command: <Pattern>[
'install_name_tool',
'-id',
'@rpath/bar.framework/bar',
dylibPath,
],
),
FakeCommand(
command: <Pattern>[
'codesign',
'--force',
'--sign',
'-',
if (buildMode == BuildMode.debug) '--timestamp=none',
signPath,
],
),
],
),
);
final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsMacOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64, DarwinArch.x86_64],
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
flutterTester: flutterTester,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for [macos_arm64, macos_x64] debug.',
'Building native assets for [macos_arm64, macos_x64] done.',
]),
);
expect(
nativeAssetsYaml,
projectUri.resolve('build/native_assets/macos/native_assets.yaml'),
);
expect(
await fileSystem.file(nativeAssetsYaml).readAsString(),
stringContainsInOrder(<String>[
'package:bar/bar.dart',
if (flutterTester)
// Tests run on host system, so the have the full path on the system.
'- ${projectUri.resolve('build/native_assets/macos/libbar.dylib').toFilePath()}'
else
// Apps are a bundle with the dylibs on their dlopen path.
'- bar.framework/bar',
]),
);
// Multi arch.
expect(buildRunner.buildInvocations, 2);
expect(buildRunner.linkInvocations, 2);
});
}, () async {
if (const LocalPlatform().isWindows) {
return; // Backslashes in commands, but we will never run these commands on Windows.
}
final File packageConfig = environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
onBuild: (native_assets_cli.Target target) =>
FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: target.os,
architecture: target.architecture,
file: Uri.file('${target.architecture}/libbar.dylib'),
),
],
),
);
final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsMacOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64, DarwinArch.x86_64],
projectUri: projectUri,
buildMode: buildMode,
fileSystem: fileSystem,
flutterTester: flutterTester,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for [macos_arm64, macos_x64] $buildMode.',
'Building native assets for [macos_arm64, macos_x64] done.',
]),
);
expect(
nativeAssetsYaml,
projectUri.resolve('build/native_assets/macos/native_assets.yaml'),
);
expect(
await fileSystem.file(nativeAssetsYaml).readAsString(),
stringContainsInOrder(<String>[
'package:bar/bar.dart',
if (flutterTester)
// Tests run on host system, so the have the full path on the system.
'- ${projectUri.resolve('build/native_assets/macos/libbar.dylib').toFilePath()}'
else
// Apps are a bundle with the dylibs on their dlopen path.
'- bar.framework/bar',
]),
);
// Multi arch.
expect(buildRunner.buildInvocations, 2);
expect(
buildRunner.linkInvocations,
buildMode == BuildMode.release ? 2 : 0,
);
});
}
}
testUsingContext('static libs not supported', overrides: <Type, Generator>{
@ -416,29 +424,24 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => dryRunNativeAssetsMacOS(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => dryRunNativeAssetsMacOS(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook (dry run) native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building (dry run) native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
@ -449,32 +452,27 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => buildNativeAssetsMacOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64],
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => buildNativeAssetsMacOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64],
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
// This logic is mocked in the other tests to avoid having test order

View File

@ -172,7 +172,7 @@ void main() {
contains('package:bar/bar.dart'),
);
expect(buildRunner.buildDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 1);
expect(buildRunner.linkDryRunInvocations, 0);
});
testUsingContext('build with assets but not enabled', overrides: <Type, Generator>{
@ -236,66 +236,74 @@ void main() {
if (flutterTester) {
testName += ' flutter tester';
}
testUsingContext('build with assets$testName', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig = environment.projectDir.childDirectory('.dart_tool').childFile('package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final File dylibAfterCompiling = fileSystem.file('bar.dll');
// The mock doesn't create the file, so create it here.
await dylibAfterCompiling.create();
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: OSImpl.windows,
architecture: ArchitectureImpl.x64,
file: dylibAfterCompiling.uri,
),
for (final BuildMode buildMode in <BuildMode>[
BuildMode.debug,
BuildMode.release,
]) {
testUsingContext('build with assets $buildMode$testName', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig = environment.projectDir.childDirectory('.dart_tool').childFile('package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
final File dylibAfterCompiling = fileSystem.file('bar.dll');
// The mock doesn't create the file, so create it here.
await dylibAfterCompiling.create();
final FakeNativeAssetsBuildRunner buildRunner = FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
),
);
final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsWindows(
targetPlatform: TargetPlatform.windows_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
flutterTester: flutterTester,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for windows_x64 debug.',
'Building native assets for windows_x64 done.',
]),
);
expect(
nativeAssetsYaml,
projectUri.resolve('build/native_assets/windows/native_assets.yaml'),
);
expect(
await fileSystem.file(nativeAssetsYaml).readAsString(),
stringContainsInOrder(<String>[
'package:bar/bar.dart',
if (flutterTester)
// Tests run on host system, so the have the full path on the system.
'- ${projectUri.resolve('build/native_assets/windows/bar.dll').toFilePath()}'
else
// Apps are a bundle with the dylibs on their dlopen path.
'- bar.dll',
]),
);
expect(buildRunner.buildInvocations, 1);
expect(buildRunner.linkInvocations, 1);
});
buildResult: FakeNativeAssetsBuilderResult(
assets: <AssetImpl>[
NativeCodeAssetImpl(
id: 'package:bar/bar.dart',
linkMode: DynamicLoadingBundledImpl(),
os: OSImpl.windows,
architecture: ArchitectureImpl.x64,
file: dylibAfterCompiling.uri,
),
],
),
);
final (Uri? nativeAssetsYaml, _) = await buildNativeAssetsWindows(
targetPlatform: TargetPlatform.windows_x64,
projectUri: projectUri,
buildMode: buildMode,
fileSystem: fileSystem,
flutterTester: flutterTester,
buildRunner: buildRunner,
);
expect(
(globals.logger as BufferLogger).traceText,
stringContainsInOrder(<String>[
'Building native assets for windows_x64 $buildMode.',
'Building native assets for windows_x64 done.',
]),
);
expect(
nativeAssetsYaml,
projectUri.resolve('build/native_assets/windows/native_assets.yaml'),
);
expect(
await fileSystem.file(nativeAssetsYaml).readAsString(),
stringContainsInOrder(<String>[
'package:bar/bar.dart',
if (flutterTester)
// Tests run on host system, so the have the full path on the system.
'- ${projectUri.resolve('build/native_assets/windows/bar.dll').toFilePath()}'
else
// Apps are a bundle with the dylibs on their dlopen path.
'- bar.dll',
]),
);
expect(buildRunner.buildInvocations, 1);
expect(
buildRunner.linkInvocations,
buildMode == BuildMode.release ? 1 :0,
);
});
}
}
testUsingContext('static libs not supported', overrides: <Type, Generator>{
@ -344,29 +352,24 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => dryRunNativeAssetsWindows(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkDryRunResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => dryRunNativeAssetsWindows(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildDryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook (dry run) native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building (dry run) native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
@ -377,32 +380,27 @@ void main() {
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
for (final String hook in <String>['Building', 'Linking']) {
expect(
() => buildNativeAssetsWindows(
targetPlatform: TargetPlatform.windows_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: FakeNativeAssetsBuilderResult(
success: hook != 'Building',
),
linkResult: FakeNativeAssetsBuilderResult(
success: hook != 'Linking',
),
expect(
() => buildNativeAssetsWindows(
targetPlatform: TargetPlatform.windows_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
throwsToolExit(
message:
'$hook native assets failed. See the logs for more details.',
),
);
}
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
// This logic is mocked in the other tests to avoid having test order