Fix code asset copying logic in native asset code (#158984)
After the dart build is done, the flutter tool has to bundle the produced shared libraries, which it does that by copying them around. Though the code assumed that all code assets are shared libraries to be bundled, whereas in fact one can have code assets without any actual code (ones that are installed on the target system already or artificial code assets whose symbols get resolved from executable / process). => Using non-bundled code assets currently results in null pointer exceptions and/or cast errors. => We update the copy code to only operate on code assets that have a shared library to bundle. We also update the copy routines by removing copy&past'ed - but slightly different - printing code into the shared caller function.
This commit is contained in:
parent
256359194e
commit
1636fbd4cb
@ -10,7 +10,6 @@ import '../../../android/gradle_utils.dart';
|
||||
import '../../../base/common.dart';
|
||||
import '../../../base/file_system.dart';
|
||||
import '../../../build_info.dart' hide BuildMode;
|
||||
import '../../../globals.dart' as globals;
|
||||
|
||||
int targetAndroidNdkApi(Map<String, String> environmentDefines) {
|
||||
return int.parse(environmentDefines[kMinSdkVersion] ?? minSdkVersion);
|
||||
@ -21,30 +20,26 @@ Future<void> copyNativeCodeAssetsAndroid(
|
||||
Map<CodeAsset, KernelAsset> assetTargetLocations,
|
||||
FileSystem fileSystem,
|
||||
) async {
|
||||
if (assetTargetLocations.isNotEmpty) {
|
||||
globals.logger
|
||||
.printTrace('Copying native assets to ${buildUri.toFilePath()}.');
|
||||
final List<String> jniArchDirs = <String>[
|
||||
for (final AndroidArch androidArch in AndroidArch.values)
|
||||
androidArch.archName,
|
||||
];
|
||||
for (final String jniArchDir in jniArchDirs) {
|
||||
final Uri archUri = buildUri.resolve('jniLibs/lib/$jniArchDir/');
|
||||
await fileSystem.directory(archUri).create(recursive: true);
|
||||
}
|
||||
for (final MapEntry<CodeAsset, KernelAsset> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri source = assetMapping.key.file!;
|
||||
final Uri target = (assetMapping.value.path as KernelAssetAbsolutePath).uri;
|
||||
final AndroidArch androidArch =
|
||||
_getAndroidArch(assetMapping.value.target);
|
||||
final String jniArchDir = androidArch.archName;
|
||||
final Uri archUri = buildUri.resolve('jniLibs/lib/$jniArchDir/');
|
||||
final Uri targetUri = archUri.resolveUri(target);
|
||||
final String targetFullPath = targetUri.toFilePath();
|
||||
await fileSystem.file(source).copy(targetFullPath);
|
||||
}
|
||||
globals.logger.printTrace('Copying native assets done.');
|
||||
assert(assetTargetLocations.isNotEmpty);
|
||||
final List<String> jniArchDirs = <String>[
|
||||
for (final AndroidArch androidArch in AndroidArch.values)
|
||||
androidArch.archName,
|
||||
];
|
||||
for (final String jniArchDir in jniArchDirs) {
|
||||
final Uri archUri = buildUri.resolve('jniLibs/lib/$jniArchDir/');
|
||||
await fileSystem.directory(archUri).create(recursive: true);
|
||||
}
|
||||
for (final MapEntry<CodeAsset, KernelAsset> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri source = assetMapping.key.file!;
|
||||
final Uri target = (assetMapping.value.path as KernelAssetAbsolutePath).uri;
|
||||
final AndroidArch androidArch =
|
||||
_getAndroidArch(assetMapping.value.target);
|
||||
final String jniArchDir = androidArch.archName;
|
||||
final Uri archUri = buildUri.resolve('jniLibs/lib/$jniArchDir/');
|
||||
final Uri targetUri = archUri.resolveUri(target);
|
||||
final String targetFullPath = targetUri.toFilePath();
|
||||
await fileSystem.file(source).copy(targetFullPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import 'package:native_assets_cli/code_assets_builder.dart';
|
||||
import '../../../base/file_system.dart';
|
||||
import '../../../build_info.dart' hide BuildMode;
|
||||
import '../../../build_info.dart' as build_info;
|
||||
import '../../../globals.dart' as globals;
|
||||
import '../macos/native_assets_host.dart';
|
||||
|
||||
// TODO(dcharkes): Fetch minimum iOS version from somewhere. https://github.com/flutter/flutter/issues/145104
|
||||
@ -115,47 +114,41 @@ Future<void> copyNativeCodeAssetsIOS(
|
||||
build_info.BuildMode buildMode,
|
||||
FileSystem fileSystem,
|
||||
) async {
|
||||
if (assetTargetLocations.isNotEmpty) {
|
||||
globals.logger
|
||||
.printTrace('Copying native assets to ${buildUri.toFilePath()}.');
|
||||
assert(assetTargetLocations.isNotEmpty);
|
||||
final Map<String, String> oldToNewInstallNames = <String, String>{};
|
||||
final List<(File, String, Directory)> dylibs = <(File, String, Directory)>[];
|
||||
|
||||
final Map<String, String> oldToNewInstallNames = <String, String>{};
|
||||
final List<(File, String, Directory)> dylibs = <(File, String, Directory)>[];
|
||||
|
||||
for (final MapEntry<KernelAssetPath, List<CodeAsset>> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri target = (assetMapping.key as KernelAssetAbsolutePath).uri;
|
||||
final List<File> sources = <File>[
|
||||
for (final CodeAsset source in assetMapping.value)
|
||||
fileSystem.file(source.file)
|
||||
];
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final File dylibFile = fileSystem.file(targetUri);
|
||||
final Directory frameworkDir = dylibFile.parent;
|
||||
if (!await frameworkDir.exists()) {
|
||||
await frameworkDir.create(recursive: true);
|
||||
}
|
||||
await lipoDylibs(dylibFile, sources);
|
||||
|
||||
final String dylibFileName = dylibFile.basename;
|
||||
final String newInstallName =
|
||||
'@rpath/$dylibFileName.framework/$dylibFileName';
|
||||
final Set<String> oldInstallNames = await getInstallNamesDylib(dylibFile);
|
||||
for (final String oldInstallName in oldInstallNames) {
|
||||
oldToNewInstallNames[oldInstallName] = newInstallName;
|
||||
}
|
||||
dylibs.add((dylibFile, newInstallName, frameworkDir));
|
||||
|
||||
// TODO(knopp): Wire the value once there is a way to configure that in the hook.
|
||||
// https://github.com/dart-lang/native/issues/1133
|
||||
await createInfoPlist(targetUri.pathSegments.last, frameworkDir, minimumIOSVersion: '12.0');
|
||||
for (final MapEntry<KernelAssetPath, List<CodeAsset>> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri target = (assetMapping.key as KernelAssetAbsolutePath).uri;
|
||||
final List<File> sources = <File>[
|
||||
for (final CodeAsset source in assetMapping.value)
|
||||
fileSystem.file(source.file)
|
||||
];
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final File dylibFile = fileSystem.file(targetUri);
|
||||
final Directory frameworkDir = dylibFile.parent;
|
||||
if (!await frameworkDir.exists()) {
|
||||
await frameworkDir.create(recursive: true);
|
||||
}
|
||||
await lipoDylibs(dylibFile, sources);
|
||||
|
||||
for (final (File dylibFile, String newInstallName, Directory frameworkDir) in dylibs) {
|
||||
await setInstallNamesDylib(dylibFile, newInstallName, oldToNewInstallNames);
|
||||
await codesignDylib(codesignIdentity, buildMode, frameworkDir);
|
||||
final String dylibFileName = dylibFile.basename;
|
||||
final String newInstallName =
|
||||
'@rpath/$dylibFileName.framework/$dylibFileName';
|
||||
final Set<String> oldInstallNames = await getInstallNamesDylib(dylibFile);
|
||||
for (final String oldInstallName in oldInstallNames) {
|
||||
oldToNewInstallNames[oldInstallName] = newInstallName;
|
||||
}
|
||||
dylibs.add((dylibFile, newInstallName, frameworkDir));
|
||||
|
||||
globals.logger.printTrace('Copying native assets done.');
|
||||
// TODO(knopp): Wire the value once there is a way to configure that in the hook.
|
||||
// https://github.com/dart-lang/native/issues/1133
|
||||
await createInfoPlist(targetUri.pathSegments.last, frameworkDir, minimumIOSVersion: '12.0');
|
||||
}
|
||||
|
||||
for (final (File dylibFile, String newInstallName, Directory frameworkDir) in dylibs) {
|
||||
await setInstallNamesDylib(dylibFile, newInstallName, oldToNewInstallNames);
|
||||
await codesignDylib(codesignIdentity, buildMode, frameworkDir);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import 'package:native_assets_cli/code_assets_builder.dart';
|
||||
import '../../../base/file_system.dart';
|
||||
import '../../../build_info.dart' hide BuildMode;
|
||||
import '../../../build_info.dart' as build_info;
|
||||
import '../../../globals.dart' as globals;
|
||||
import 'native_assets_host.dart';
|
||||
|
||||
// TODO(dcharkes): Fetch minimum MacOS version from somewhere. https://github.com/flutter/flutter/issues/145104
|
||||
@ -127,79 +126,73 @@ Future<void> copyNativeCodeAssetsMacOS(
|
||||
build_info.BuildMode buildMode,
|
||||
FileSystem fileSystem,
|
||||
) async {
|
||||
if (assetTargetLocations.isNotEmpty) {
|
||||
globals.logger.printTrace(
|
||||
'Copying native assets to ${buildUri.toFilePath()}.',
|
||||
);
|
||||
assert(assetTargetLocations.isNotEmpty);
|
||||
|
||||
final Map<String, String> oldToNewInstallNames = <String, String>{};
|
||||
final List<(File, String, Directory)> dylibs = <(File, String, Directory)>[];
|
||||
final Map<String, String> oldToNewInstallNames = <String, String>{};
|
||||
final List<(File, String, Directory)> dylibs = <(File, String, Directory)>[];
|
||||
|
||||
for (final MapEntry<KernelAssetPath, List<CodeAsset>> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri target = (assetMapping.key as KernelAssetAbsolutePath).uri;
|
||||
final List<File> sources = <File>[
|
||||
for (final CodeAsset source in assetMapping.value) fileSystem.file(source.file),
|
||||
];
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final String name = targetUri.pathSegments.last;
|
||||
final Directory frameworkDir = fileSystem.file(targetUri).parent;
|
||||
if (await frameworkDir.exists()) {
|
||||
await frameworkDir.delete(recursive: true);
|
||||
}
|
||||
// MyFramework.framework/ frameworkDir
|
||||
// MyFramework -> Versions/Current/MyFramework dylibLink
|
||||
// Resources -> Versions/Current/Resources resourcesLink
|
||||
// Versions/ versionsDir
|
||||
// A/ versionADir
|
||||
// MyFramework dylibFile
|
||||
// Resources/ resourcesDir
|
||||
// Info.plist
|
||||
// Current -> A currentLink
|
||||
final Directory versionsDir = frameworkDir.childDirectory('Versions');
|
||||
final Directory versionADir = versionsDir.childDirectory('A');
|
||||
final Directory resourcesDir = versionADir.childDirectory('Resources');
|
||||
await resourcesDir.create(recursive: true);
|
||||
final File dylibFile = versionADir.childFile(name);
|
||||
final Link currentLink = versionsDir.childLink('Current');
|
||||
await currentLink.create(fileSystem.path.relative(
|
||||
versionADir.path,
|
||||
from: currentLink.parent.path,
|
||||
));
|
||||
final Link resourcesLink = frameworkDir.childLink('Resources');
|
||||
await resourcesLink.create(fileSystem.path.relative(
|
||||
resourcesDir.path,
|
||||
from: resourcesLink.parent.path,
|
||||
));
|
||||
await lipoDylibs(dylibFile, sources);
|
||||
final Link dylibLink = frameworkDir.childLink(name);
|
||||
await dylibLink.create(fileSystem.path.relative(
|
||||
versionsDir.childDirectory('Current').childFile(name).path,
|
||||
from: dylibLink.parent.path,
|
||||
));
|
||||
|
||||
final String dylibFileName = dylibFile.basename;
|
||||
final String newInstallName = '@rpath/$dylibFileName.framework/$dylibFileName';
|
||||
final Set<String> oldInstallNames = await getInstallNamesDylib(dylibFile);
|
||||
for (final String oldInstallName in oldInstallNames) {
|
||||
oldToNewInstallNames[oldInstallName] = newInstallName;
|
||||
}
|
||||
dylibs.add((dylibFile, newInstallName, frameworkDir));
|
||||
|
||||
await createInfoPlist(name, resourcesDir);
|
||||
for (final MapEntry<KernelAssetPath, List<CodeAsset>> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri target = (assetMapping.key as KernelAssetAbsolutePath).uri;
|
||||
final List<File> sources = <File>[
|
||||
for (final CodeAsset source in assetMapping.value) fileSystem.file(source.file),
|
||||
];
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final String name = targetUri.pathSegments.last;
|
||||
final Directory frameworkDir = fileSystem.file(targetUri).parent;
|
||||
if (await frameworkDir.exists()) {
|
||||
await frameworkDir.delete(recursive: true);
|
||||
}
|
||||
// MyFramework.framework/ frameworkDir
|
||||
// MyFramework -> Versions/Current/MyFramework dylibLink
|
||||
// Resources -> Versions/Current/Resources resourcesLink
|
||||
// Versions/ versionsDir
|
||||
// A/ versionADir
|
||||
// MyFramework dylibFile
|
||||
// Resources/ resourcesDir
|
||||
// Info.plist
|
||||
// Current -> A currentLink
|
||||
final Directory versionsDir = frameworkDir.childDirectory('Versions');
|
||||
final Directory versionADir = versionsDir.childDirectory('A');
|
||||
final Directory resourcesDir = versionADir.childDirectory('Resources');
|
||||
await resourcesDir.create(recursive: true);
|
||||
final File dylibFile = versionADir.childFile(name);
|
||||
final Link currentLink = versionsDir.childLink('Current');
|
||||
await currentLink.create(fileSystem.path.relative(
|
||||
versionADir.path,
|
||||
from: currentLink.parent.path,
|
||||
));
|
||||
final Link resourcesLink = frameworkDir.childLink('Resources');
|
||||
await resourcesLink.create(fileSystem.path.relative(
|
||||
resourcesDir.path,
|
||||
from: resourcesLink.parent.path,
|
||||
));
|
||||
await lipoDylibs(dylibFile, sources);
|
||||
final Link dylibLink = frameworkDir.childLink(name);
|
||||
await dylibLink.create(fileSystem.path.relative(
|
||||
versionsDir.childDirectory('Current').childFile(name).path,
|
||||
from: dylibLink.parent.path,
|
||||
));
|
||||
|
||||
for (final (File dylibFile, String newInstallName, Directory frameworkDir) in dylibs) {
|
||||
await setInstallNamesDylib(dylibFile, newInstallName, oldToNewInstallNames);
|
||||
// Do not code-sign the libraries here with identity. Code-signing
|
||||
// for bundled dylibs is done in `macos_assemble.sh embed` because the
|
||||
// "Flutter Assemble" target does not have access to the signing identity.
|
||||
if (codesignIdentity != null) {
|
||||
await codesignDylib(codesignIdentity, buildMode, frameworkDir);
|
||||
}
|
||||
final String dylibFileName = dylibFile.basename;
|
||||
final String newInstallName = '@rpath/$dylibFileName.framework/$dylibFileName';
|
||||
final Set<String> oldInstallNames = await getInstallNamesDylib(dylibFile);
|
||||
for (final String oldInstallName in oldInstallNames) {
|
||||
oldToNewInstallNames[oldInstallName] = newInstallName;
|
||||
}
|
||||
dylibs.add((dylibFile, newInstallName, frameworkDir));
|
||||
|
||||
globals.logger.printTrace('Copying native assets done.');
|
||||
await createInfoPlist(name, resourcesDir);
|
||||
}
|
||||
|
||||
for (final (File dylibFile, String newInstallName, Directory frameworkDir) in dylibs) {
|
||||
await setInstallNamesDylib(dylibFile, newInstallName, oldToNewInstallNames);
|
||||
// Do not code-sign the libraries here with identity. Code-signing
|
||||
// for bundled dylibs is done in `macos_assemble.sh embed` because the
|
||||
// "Flutter Assemble" target does not have access to the signing identity.
|
||||
if (codesignIdentity != null) {
|
||||
await codesignDylib(codesignIdentity, buildMode, frameworkDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,40 +214,34 @@ Future<void> copyNativeCodeAssetsMacOSFlutterTester(
|
||||
build_info.BuildMode buildMode,
|
||||
FileSystem fileSystem,
|
||||
) async {
|
||||
if (assetTargetLocations.isNotEmpty) {
|
||||
globals.logger.printTrace(
|
||||
'Copying native assets to ${buildUri.toFilePath()}.',
|
||||
);
|
||||
assert(assetTargetLocations.isNotEmpty);
|
||||
|
||||
final Map<String, String> oldToNewInstallNames = <String, String>{};
|
||||
final List<(File, String)> dylibs = <(File, String)>[];
|
||||
final Map<String, String> oldToNewInstallNames = <String, String>{};
|
||||
final List<(File, String)> dylibs = <(File, String)>[];
|
||||
|
||||
for (final MapEntry<KernelAssetPath, List<CodeAsset>> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri target = (assetMapping.key as KernelAssetAbsolutePath).uri;
|
||||
final List<File> sources = <File>[
|
||||
for (final CodeAsset source in assetMapping.value) fileSystem.file(source.file),
|
||||
];
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final File dylibFile = fileSystem.file(targetUri);
|
||||
final Directory targetParent = dylibFile.parent;
|
||||
if (!await targetParent.exists()) {
|
||||
await targetParent.create(recursive: true);
|
||||
}
|
||||
await lipoDylibs(dylibFile, sources);
|
||||
final String newInstallName = dylibFile.path;
|
||||
final Set<String> oldInstallNames = await getInstallNamesDylib(dylibFile);
|
||||
for (final String oldInstallName in oldInstallNames) {
|
||||
oldToNewInstallNames[oldInstallName] = newInstallName;
|
||||
}
|
||||
dylibs.add((dylibFile, newInstallName));
|
||||
for (final MapEntry<KernelAssetPath, List<CodeAsset>> assetMapping
|
||||
in assetTargetLocations.entries) {
|
||||
final Uri target = (assetMapping.key as KernelAssetAbsolutePath).uri;
|
||||
final List<File> sources = <File>[
|
||||
for (final CodeAsset source in assetMapping.value) fileSystem.file(source.file),
|
||||
];
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final File dylibFile = fileSystem.file(targetUri);
|
||||
final Directory targetParent = dylibFile.parent;
|
||||
if (!await targetParent.exists()) {
|
||||
await targetParent.create(recursive: true);
|
||||
}
|
||||
|
||||
for (final (File dylibFile, String newInstallName) in dylibs) {
|
||||
await setInstallNamesDylib(dylibFile, newInstallName, oldToNewInstallNames);
|
||||
await codesignDylib(codesignIdentity, buildMode, dylibFile);
|
||||
await lipoDylibs(dylibFile, sources);
|
||||
final String newInstallName = dylibFile.path;
|
||||
final Set<String> oldInstallNames = await getInstallNamesDylib(dylibFile);
|
||||
for (final String oldInstallName in oldInstallNames) {
|
||||
oldToNewInstallNames[oldInstallName] = newInstallName;
|
||||
}
|
||||
dylibs.add((dylibFile, newInstallName));
|
||||
}
|
||||
|
||||
globals.logger.printTrace('Copying native assets done.');
|
||||
for (final (File dylibFile, String newInstallName) in dylibs) {
|
||||
await setInstallNamesDylib(dylibFile, newInstallName, oldToNewInstallNames);
|
||||
await codesignDylib(codesignIdentity, buildMode, dylibFile);
|
||||
}
|
||||
}
|
||||
|
@ -629,6 +629,21 @@ Future<void> _copyNativeCodeAssetsForOS(
|
||||
Map<CodeAsset, KernelAsset> assetTargetLocations,
|
||||
String? codesignIdentity,
|
||||
bool flutterTester) async {
|
||||
// We only have to copy code assets that are bundled within the app.
|
||||
// If a code asset that use a linking mode of [LookupInProcess],
|
||||
// [LookupInExecutable] or [DynamicLoadingSystem] do not have anything to
|
||||
// bundle as part of the app.
|
||||
assetTargetLocations = <CodeAsset, KernelAsset>{
|
||||
for (final CodeAsset codeAsset in assetTargetLocations.keys)
|
||||
if (codeAsset.linkMode is DynamicLoadingBundled)
|
||||
codeAsset: assetTargetLocations[codeAsset]!,
|
||||
};
|
||||
|
||||
if (assetTargetLocations.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
globals.logger.printTrace('Copying native assets to ${buildUri.toFilePath()}.');
|
||||
final List<CodeAsset> codeAssets = assetTargetLocations.keys.toList();
|
||||
switch (targetOS) {
|
||||
case OS.windows:
|
||||
@ -673,6 +688,7 @@ Future<void> _copyNativeCodeAssetsForOS(
|
||||
default:
|
||||
throw StateError('This should be unreachable.');
|
||||
}
|
||||
globals.logger.printTrace('Copying native assets done.');
|
||||
}
|
||||
|
||||
/// Invokes the build of all transitive Dart packages.
|
||||
@ -908,22 +924,18 @@ Future<void> _copyNativeCodeAssetsToBundleOnWindowsLinux(
|
||||
build_info.BuildMode buildMode,
|
||||
FileSystem fileSystem,
|
||||
) async {
|
||||
globals.logger.printTrace('copyNativeCodeAssetsToBundleOnWindowsLinux()');
|
||||
if (assetTargetLocations.isNotEmpty) {
|
||||
globals.logger.printTrace('Copying native assets to ${buildUri.toFilePath()}.');
|
||||
final Directory buildDir = fileSystem.directory(buildUri.toFilePath());
|
||||
if (!buildDir.existsSync()) {
|
||||
buildDir.createSync(recursive: true);
|
||||
}
|
||||
for (final MapEntry<CodeAsset, KernelAsset> assetMapping in assetTargetLocations.entries) {
|
||||
final Uri source = assetMapping.key.file!;
|
||||
final Uri target = (assetMapping.value.path as KernelAssetAbsolutePath).uri;
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final String targetFullPath = targetUri.toFilePath();
|
||||
await fileSystem.file(source).copy(targetFullPath);
|
||||
globals.logger.printTrace('copyNativeCodeAssetsToBundleOnWindowsLinux(): copied $source to $targetFullPath');
|
||||
}
|
||||
globals.logger.printTrace('Copying native assets done.');
|
||||
assert(assetTargetLocations.isNotEmpty);
|
||||
|
||||
final Directory buildDir = fileSystem.directory(buildUri.toFilePath());
|
||||
if (!buildDir.existsSync()) {
|
||||
buildDir.createSync(recursive: true);
|
||||
}
|
||||
for (final MapEntry<CodeAsset, KernelAsset> assetMapping in assetTargetLocations.entries) {
|
||||
final Uri source = assetMapping.key.file!;
|
||||
final Uri target = (assetMapping.value.path as KernelAssetAbsolutePath).uri;
|
||||
final Uri targetUri = buildUri.resolveUri(target);
|
||||
final String targetFullPath = targetUri.toFilePath();
|
||||
await fileSystem.file(source).copy(targetFullPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,54 @@ void main() {
|
||||
expect(buildRunner.buildDryRunInvocations, 1);
|
||||
});
|
||||
|
||||
testUsingContext('Native assets: non-bundled libraries require no copying', overrides: <Type, Generator>{
|
||||
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
|
||||
ProcessManager: () => FakeProcessManager.empty(),
|
||||
}, () async {
|
||||
final File packageConfig =
|
||||
environment.projectDir.childFile('.dart_tool/package_config.json');
|
||||
final Uri nonFlutterTesterAssetUri = environment.buildDir.childFile('native_assets.yaml').uri;
|
||||
await packageConfig.parent.create();
|
||||
await packageConfig.create();
|
||||
|
||||
final File directSoFile = environment.projectDir.childFile('direct.so');
|
||||
directSoFile.writeAsBytesSync(<int>[]);
|
||||
|
||||
CodeAsset makeCodeAsset(String name, LinkMode linkMode, [Uri? file])
|
||||
=> CodeAsset(
|
||||
package: 'bar',
|
||||
name: name,
|
||||
linkMode: linkMode,
|
||||
os: OS.linux,
|
||||
architecture: Architecture.x64,
|
||||
file: file,
|
||||
);
|
||||
|
||||
final List<CodeAsset> codeAssets = <CodeAsset>[
|
||||
makeCodeAsset('malloc', LookupInProcess()),
|
||||
makeCodeAsset('free', LookupInExecutable()),
|
||||
makeCodeAsset('draw', DynamicLoadingSystem(Uri.file('/usr/lib/skia.so'))),
|
||||
];
|
||||
|
||||
await runFlutterSpecificDartBuild(
|
||||
environmentDefines: <String, String>{
|
||||
kBuildMode: BuildMode.release.cliName,
|
||||
},
|
||||
targetPlatform: TargetPlatform.linux_x64,
|
||||
projectUri: projectUri,
|
||||
nativeAssetsYamlUri: nonFlutterTesterAssetUri,
|
||||
fileSystem: fileSystem,
|
||||
buildRunner: FakeFlutterNativeAssetsBuildRunner(
|
||||
packagesWithNativeAssetsResult: <Package>[
|
||||
Package('bar', projectUri),
|
||||
],
|
||||
buildResult: FakeFlutterNativeAssetsBuilderResult.fromAssets(codeAssets: codeAssets),
|
||||
linkResult: FakeFlutterNativeAssetsBuilderResult.fromAssets(codeAssets: codeAssets),
|
||||
),
|
||||
);
|
||||
expect(testLogger.traceText, isNot(contains('Copying native assets to')));
|
||||
});
|
||||
|
||||
testUsingContext('build with assets but not enabled', overrides: <Type, Generator>{
|
||||
ProcessManager: () => FakeProcessManager.empty(),
|
||||
}, () async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user