@@ -274,8 +274,10 @@ KernelAsset _targetLocationMacOS(
274274/// For `flutter run -release` a multi-architecture solution is needed. So,
275275/// `lipo` is used to combine all target architectures into a single file.
276276///
277- /// The install name is set so that it matches what the place it will
278- /// be bundled in the final app.
277+ /// The install name is set so that it matches with the place it will
278+ /// be bundled in the final app. Install names that are referenced in dependent
279+ /// libraries are updated to match the new install name, so that the referenced
280+ /// library can be found the dynamic linker.
279281///
280282/// Code signing is also done here, so that it doesn't have to be done in
281283/// in macos_assemble.sh.
@@ -290,11 +292,15 @@ Future<void> _copyNativeAssetsMacOS(
290292 globals.logger.printTrace (
291293 'Copying native assets to ${buildUri .toFilePath ()}.' ,
292294 );
295+
296+ final Map <String , String > oldToNewInstallNames = < String , String > {};
297+ final List <(File , String , Directory )> dylibs = < (File , String , Directory )> [];
298+
293299 for (final MapEntry <KernelAssetPath , List <AssetImpl >> assetMapping
294300 in assetTargetLocations.entries) {
295301 final Uri target = (assetMapping.key as KernelAssetAbsolutePath ).uri;
296- final List <Uri > sources = < Uri > [
297- for (final AssetImpl source in assetMapping.value) source.file! ,
302+ final List <File > sources = < File > [
303+ for (final AssetImpl source in assetMapping.value) fileSystem. file ( source.file) ,
298304 ];
299305 final Uri targetUri = buildUri.resolveUri (target);
300306 final String name = targetUri.pathSegments.last;
@@ -332,15 +338,28 @@ Future<void> _copyNativeAssetsMacOS(
332338 versionsDir.childDirectory ('Current' ).childFile (name).path,
333339 from: dylibLink.parent.path,
334340 ));
335- await setInstallNameDylib (dylibFile);
341+
342+ final String dylibFileName = dylibFile.basename;
343+ final String newInstallName = '@rpath/$dylibFileName .framework/$dylibFileName ' ;
344+ final Set <String > oldInstallNames = await getInstallNamesDylib (dylibFile);
345+ for (final String oldInstallName in oldInstallNames) {
346+ oldToNewInstallNames[oldInstallName] = newInstallName;
347+ }
348+ dylibs.add ((dylibFile, newInstallName, frameworkDir));
349+
336350 await createInfoPlist (name, resourcesDir);
351+ }
352+
353+ for (final (File dylibFile, String newInstallName, Directory frameworkDir) in dylibs) {
354+ await setInstallNamesDylib (dylibFile, newInstallName, oldToNewInstallNames);
337355 // Do not code-sign the libraries here with identity. Code-signing
338356 // for bundled dylibs is done in `macos_assemble.sh embed` because the
339357 // "Flutter Assemble" target does not have access to the signing identity.
340358 if (codesignIdentity != null ) {
341359 await codesignDylib (codesignIdentity, buildMode, frameworkDir);
342360 }
343361 }
362+
344363 globals.logger.printTrace ('Copying native assets done.' );
345364 }
346365}
@@ -350,7 +369,10 @@ Future<void> _copyNativeAssetsMacOS(
350369/// For `flutter run -release` a multi-architecture solution is needed. So,
351370/// `lipo` is used to combine all target architectures into a single file.
352371///
353- /// In contrast to [_copyNativeAssetsMacOS] , it does not set the install name.
372+ /// The install names are set to the absolute paths from which the
373+ /// flutter_tester executable with load them. Install names that are
374+ /// referenced in dependent libraries are updated to match the new install name,
375+ /// so that the referenced library can be found the dynamic linker.
354376///
355377/// Code signing is also done here.
356378Future <void > _copyNativeAssetsMacOSFlutterTester (
@@ -364,11 +386,15 @@ Future<void> _copyNativeAssetsMacOSFlutterTester(
364386 globals.logger.printTrace (
365387 'Copying native assets to ${buildUri .toFilePath ()}.' ,
366388 );
389+
390+ final Map <String , String > oldToNewInstallNames = < String , String > {};
391+ final List <(File , String )> dylibs = < (File , String )> [];
392+
367393 for (final MapEntry <KernelAssetPath , List <AssetImpl >> assetMapping
368394 in assetTargetLocations.entries) {
369395 final Uri target = (assetMapping.key as KernelAssetAbsolutePath ).uri;
370- final List <Uri > sources = < Uri > [
371- for (final AssetImpl source in assetMapping.value) source.file! ,
396+ final List <File > sources = < File > [
397+ for (final AssetImpl source in assetMapping.value) fileSystem. file ( source.file) ,
372398 ];
373399 final Uri targetUri = buildUri.resolveUri (target);
374400 final File dylibFile = fileSystem.file (targetUri);
@@ -377,8 +403,19 @@ Future<void> _copyNativeAssetsMacOSFlutterTester(
377403 await targetParent.create (recursive: true );
378404 }
379405 await lipoDylibs (dylibFile, sources);
406+ final String newInstallName = dylibFile.path;
407+ final Set <String > oldInstallNames = await getInstallNamesDylib (dylibFile);
408+ for (final String oldInstallName in oldInstallNames) {
409+ oldToNewInstallNames[oldInstallName] = newInstallName;
410+ }
411+ dylibs.add ((dylibFile, newInstallName));
412+ }
413+
414+ for (final (File dylibFile, String newInstallName) in dylibs) {
415+ await setInstallNamesDylib (dylibFile, newInstallName, oldToNewInstallNames);
380416 await codesignDylib (codesignIdentity, buildMode, dylibFile);
381417 }
418+
382419 globals.logger.printTrace ('Copying native assets done.' );
383420 }
384421}
0 commit comments