Skip to content

Commit

Permalink
Add FlutterMacOS.xcframework artifact (flutter#143244)
Browse files Browse the repository at this point in the history
Replace `FlutterMacOS.framework` cached artifact with `FlutterMacOS.xcframework`. Also, update usage of `FlutterMacOS.framework` to use `FlutterMacOS.xcframework`.

Part of flutter#126016.
  • Loading branch information
vashworth authored Feb 27, 2024
1 parent b2a3075 commit 42252cd
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 83 deletions.
9 changes: 6 additions & 3 deletions dev/bots/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1728,9 +1728,9 @@ List<String> binariesWithEntitlements(String flutterRoot) {
/// cache.
List<String> binariesWithoutEntitlements(String flutterRoot) {
return <String>[
'artifacts/engine/darwin-x64-profile/FlutterMacOS.framework/Versions/A/FlutterMacOS',
'artifacts/engine/darwin-x64-release/FlutterMacOS.framework/Versions/A/FlutterMacOS',
'artifacts/engine/darwin-x64/FlutterMacOS.framework/Versions/A/FlutterMacOS',
'artifacts/engine/darwin-x64-profile/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS',
'artifacts/engine/darwin-x64-release/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS',
'artifacts/engine/darwin-x64/FlutterMacOS.xcframework/macos-arm64_x86_64/FlutterMacOS.framework/Versions/A/FlutterMacOS',
'artifacts/engine/darwin-x64/font-subset',
'artifacts/engine/darwin-x64/impellerc',
'artifacts/engine/darwin-x64/libpath_ops.dylib',
Expand Down Expand Up @@ -1764,6 +1764,9 @@ List<String> signedXcframeworks(String flutterRoot) {
'artifacts/engine/ios-release/extension_safe/Flutter.xcframework',
'artifacts/engine/ios/Flutter.xcframework',
'artifacts/engine/ios/extension_safe/Flutter.xcframework',
'artifacts/engine/darwin-x64-profile/FlutterMacOS.xcframework',
'artifacts/engine/darwin-x64-release/FlutterMacOS.xcframework',
'artifacts/engine/darwin-x64/FlutterMacOS.xcframework',
]
.map((String relativePath) => path.join(flutterRoot, 'bin', 'cache', relativePath)).toList();
}
Expand Down
6 changes: 6 additions & 0 deletions dev/devicelab/lib/tasks/plugin_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ class PluginTest {
// Currently this test is only implemented for macOS; it can be extended to
// others as needed.
if (buildTarget == 'macos') {
// When using a local engine, podhelper.rb will search for a "macos-"
// directory within the FlutterMacOS.xcframework, so create a dummy one.
Directory(
path.join(buildDir.path, 'FlutterMacOS.xcframework/macos-arm64_x86_64'),
).createSync(recursive: true);

// Clean before regenerating the config to ensure that the pod steps run.
await inDirectory(Directory(app.rootPath), () async {
await evalFlutter('clean');
Expand Down
18 changes: 13 additions & 5 deletions packages/flutter_tools/bin/podhelper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ def flutter_additional_macos_build_settings(target)
# This podhelper script is at $FLUTTER_ROOT/packages/flutter_tools/bin.
# Add search paths from $FLUTTER_ROOT/bin/cache/artifacts/engine.
artifacts_dir = File.join('..', '..', '..', '..', 'bin', 'cache', 'artifacts', 'engine')
debug_framework_dir = File.expand_path(File.join(artifacts_dir, 'darwin-x64'), __FILE__)
release_framework_dir = File.expand_path(File.join(artifacts_dir, 'darwin-x64-release'), __FILE__)
debug_framework_dir = File.expand_path(File.join(artifacts_dir, 'darwin-x64', 'FlutterMacOS.xcframework'), __FILE__)
release_framework_dir = File.expand_path(File.join(artifacts_dir, 'darwin-x64-release', 'FlutterMacOS.xcframework'), __FILE__)
application_path = File.dirname(defined_in_file.realpath) if respond_to?(:defined_in_file)
# Find the local engine path, if any.
local_engine = application_path.nil? ?
Expand All @@ -156,9 +156,17 @@ def flutter_additional_macos_build_settings(target)
# Skip other updates if it does not depend on Flutter (including transitive dependency)
next unless depends_on_flutter(target, 'FlutterMacOS')

# Profile can't be derived from the CocoaPods build configuration. Use release framework (for linking only).
configuration_engine_dir = local_engine || (build_configuration.type == :debug ? debug_framework_dir : release_framework_dir)
build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] = "\"#{configuration_engine_dir}\" $(inherited)"
if local_engine
configuration_engine_dir = File.expand_path(File.join(local_engine, 'FlutterMacOS.xcframework'), __FILE__)
else
# Profile can't be derived from the CocoaPods build configuration. Use release framework (for linking only).
configuration_engine_dir = (build_configuration.type == :debug ? debug_framework_dir : release_framework_dir)
end
Dir.new(configuration_engine_dir).each_child do |xcframework_file|
if xcframework_file.start_with?('macos-') # Could be macos-arm64_x86_64, macos-arm64, macos-x86_64
build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] = "\"#{configuration_engine_dir}/#{xcframework_file}\" $(inherited)"
end
end

# When deleted, the deployment version will inherit from the higher version derived from the 'Runner' target.
# If the pod only supports a higher version, do not delete to correctly produce an error.
Expand Down
50 changes: 49 additions & 1 deletion packages/flutter_tools/lib/src/artifacts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum Artifact {
flutterXcframework,
/// The framework directory of the macOS desktop.
flutterMacOSFramework,
flutterMacOSXcframework,
vmSnapshotData,
isolateSnapshotData,
icuData,
Expand Down Expand Up @@ -184,6 +185,8 @@ String? _artifactToFileName(Artifact artifact, Platform hostPlatform, [ BuildMod
return 'Flutter.xcframework';
case Artifact.flutterMacOSFramework:
return 'FlutterMacOS.framework';
case Artifact.flutterMacOSXcframework:
return 'FlutterMacOS.xcframework';
case Artifact.vmSnapshotData:
return 'vm_isolate_snapshot.bin';
case Artifact.isolateSnapshotData:
Expand Down Expand Up @@ -598,6 +601,10 @@ class CachedArtifacts implements Artifacts {
final String engineDir = _getEngineArtifactsPath(platform, mode)!;
return _fileSystem.path.join(engineDir, _artifactToFileName(artifact, _platform));
}
if (platform != null && artifact == Artifact.flutterMacOSFramework) {
final String engineDir = _getEngineArtifactsPath(platform, mode)!;
return _getMacOSEngineArtifactPath(engineDir, _fileSystem, _platform);
}
return _getHostArtifactPath(artifact, platform ?? _currentHostPlatform(_platform, _operatingSystemUtils), mode);
}

Expand All @@ -617,6 +624,7 @@ class CachedArtifacts implements Artifacts {
case Artifact.constFinder:
case Artifact.flutterFramework:
case Artifact.flutterMacOSFramework:
case Artifact.flutterMacOSXcframework:
case Artifact.flutterPatchedSdkPath:
case Artifact.flutterTester:
case Artifact.flutterXcframework:
Expand Down Expand Up @@ -657,6 +665,7 @@ class CachedArtifacts implements Artifacts {
case Artifact.frontendServerSnapshotForEngineDartSdk:
case Artifact.constFinder:
case Artifact.flutterMacOSFramework:
case Artifact.flutterMacOSXcframework:
case Artifact.flutterPatchedSdkPath:
case Artifact.flutterTester:
case Artifact.fontSubset:
Expand Down Expand Up @@ -705,6 +714,7 @@ class CachedArtifacts implements Artifacts {
case Artifact.constFinder:
case Artifact.flutterFramework:
case Artifact.flutterMacOSFramework:
case Artifact.flutterMacOSXcframework:
case Artifact.flutterTester:
case Artifact.flutterXcframework:
case Artifact.fontSubset:
Expand Down Expand Up @@ -771,6 +781,13 @@ class CachedArtifacts implements Artifacts {
case Artifact.engineDartAotRuntime:
return _fileSystem.path.join(_dartSdkPath(_cache), 'bin', _artifactToFileName(artifact, _platform));
case Artifact.flutterMacOSFramework:
String platformDirName = _enginePlatformDirectoryName(platform);
if (mode == BuildMode.profile || mode == BuildMode.release) {
platformDirName = '$platformDirName-${mode!.cliName}';
}
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _getMacOSEngineArtifactPath(_fileSystem.path.join(engineArtifactsPath, platformDirName), _fileSystem, _platform);
case Artifact.flutterMacOSXcframework:
case Artifact.linuxDesktopPath:
case Artifact.windowsDesktopPath:
case Artifact.linuxHeaders:
Expand Down Expand Up @@ -896,6 +913,33 @@ String _getIosEngineArtifactPath(String engineDirectory,
.path;
}

String _getMacOSEngineArtifactPath(
String engineDirectory,
FileSystem fileSystem,
Platform hostPlatform,
) {
final Directory xcframeworkDirectory = fileSystem
.directory(engineDirectory)
.childDirectory(_artifactToFileName(Artifact.flutterMacOSXcframework, hostPlatform)!);

if (!xcframeworkDirectory.existsSync()) {
throwToolExit('No xcframework found at ${xcframeworkDirectory.path}. Try running "flutter precache --macos".');
}
final Directory? flutterFrameworkSource = xcframeworkDirectory
.listSync()
.whereType<Directory>()
.where((Directory platformDirectory) =>
platformDirectory.basename.startsWith('macos-'))
.firstOrNull;
if (flutterFrameworkSource == null) {
throwToolExit('No macOS frameworks found in ${xcframeworkDirectory.path}');
}

return flutterFrameworkSource
.childDirectory(_artifactToFileName(Artifact.flutterMacOSFramework, hostPlatform)!)
.path;
}

/// Manages the artifacts of a locally built engine.
class CachedLocalEngineArtifacts implements Artifacts {
CachedLocalEngineArtifacts(
Expand Down Expand Up @@ -1054,7 +1098,7 @@ class CachedLocalEngineArtifacts implements Artifacts {
return _fileSystem.path.join(localEngineInfo.targetOutPath, 'gen', 'flutter', 'lib', 'snapshot', artifactFileName);
case Artifact.icuData:
case Artifact.flutterXcframework:
case Artifact.flutterMacOSFramework:
case Artifact.flutterMacOSXcframework:
return _fileSystem.path.join(localEngineInfo.targetOutPath, artifactFileName);
case Artifact.platformKernelDill:
if (platform == TargetPlatform.fuchsia_x64 || platform == TargetPlatform.fuchsia_arm64) {
Expand All @@ -1066,6 +1110,9 @@ class CachedLocalEngineArtifacts implements Artifacts {
case Artifact.flutterFramework:
return _getIosEngineArtifactPath(
localEngineInfo.targetOutPath, environmentType, _fileSystem, _platform);
case Artifact.flutterMacOSFramework:
return _getMacOSEngineArtifactPath(
localEngineInfo.targetOutPath, _fileSystem, _platform);
case Artifact.flutterPatchedSdkPath:
// When using local engine always use [BuildMode.debug] regardless of
// what was specified in [mode] argument because local engine will
Expand Down Expand Up @@ -1246,6 +1293,7 @@ class CachedLocalWebSdkArtifacts implements Artifacts {
case Artifact.flutterFramework:
case Artifact.flutterXcframework:
case Artifact.flutterMacOSFramework:
case Artifact.flutterMacOSXcframework:
case Artifact.vmSnapshotData:
case Artifact.isolateSnapshotData:
case Artifact.icuData:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class ReleaseUnpackMacOS extends UnpackMacOS {
@override
List<Source> get inputs => <Source>[
...super.inputs,
const Source.artifact(Artifact.flutterMacOSFramework, mode: BuildMode.release),
const Source.artifact(Artifact.flutterMacOSXcframework, mode: BuildMode.release),
];
}

Expand All @@ -171,7 +171,7 @@ class ProfileUnpackMacOS extends UnpackMacOS {
@override
List<Source> get inputs => <Source>[
...super.inputs,
const Source.artifact(Artifact.flutterMacOSFramework, mode: BuildMode.profile),
const Source.artifact(Artifact.flutterMacOSXcframework, mode: BuildMode.profile),
];
}

Expand All @@ -185,7 +185,7 @@ class DebugUnpackMacOS extends UnpackMacOS {
@override
List<Source> get inputs => <Source>[
...super.inputs,
const Source.artifact(Artifact.flutterMacOSFramework, mode: BuildMode.debug),
const Source.artifact(Artifact.flutterMacOSXcframework, mode: BuildMode.debug),
];
}

Expand Down
8 changes: 0 additions & 8 deletions packages/flutter_tools/lib/src/cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -944,14 +944,6 @@ abstract class EngineCachedArtifact extends CachedArtifact {
await artifactUpdater.downloadZipArchive('Downloading $friendlyName tools...', Uri.parse(url + urlPath), dir);

_makeFilesExecutable(dir, operatingSystemUtils);

final File frameworkZip = fileSystem.file(fileSystem.path.join(dir.path, 'FlutterMacOS.framework.zip'));
if (frameworkZip.existsSync()) {
final Directory framework = fileSystem.directory(fileSystem.path.join(dir.path, 'FlutterMacOS.framework'));
ErrorHandlingFileSystem.deleteIfExists(framework, recursive: true);
framework.createSync();
operatingSystemUtils.unzip(frameworkZip, framework);
}
}

final File licenseSource = cache.getLicenseFile();
Expand Down
57 changes: 40 additions & 17 deletions packages/flutter_tools/lib/src/commands/build_macos_framework.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'package:meta/meta.dart';

import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
Expand Down Expand Up @@ -83,13 +84,16 @@ class BuildMacOSFrameworkCommand extends BuildFrameworkCommand {

if (boolArg('cocoapods')) {
produceFlutterPodspec(buildInfo.mode, modeDirectory, force: boolArg('force'));
} else {
await _produceFlutterFramework(buildInfo, modeDirectory);
}

// Build aot, create App.framework and copy FlutterMacOS.framework. Make XCFrameworks.
await _produceAppFramework(buildInfo, modeDirectory);
final Directory buildOutput = modeDirectory.childDirectory('macos');

// Build aot, create App.framework. Make XCFrameworks.
await _produceAppFramework(buildInfo, modeDirectory, buildOutput);

// Build and copy plugins.
final Directory buildOutput = modeDirectory.childDirectory('macos');
await processPodsIfNeeded(project.macos, getMacOSBuildDirectory(), buildInfo.mode);
if (boolArg('plugins') && hasPlugins(project)) {
await _producePlugins(xcodeBuildConfiguration, buildOutput, modeDirectory);
Expand Down Expand Up @@ -200,15 +204,15 @@ end
Future<void> _produceAppFramework(
BuildInfo buildInfo,
Directory outputBuildDirectory,
Directory macosBuildOutput,
) async {
final Status status = globals.logger.startProgress(
' ├─Building App.xcframework and FlutterMacOS.xcframework...',
' ├─Building App.xcframework...',
);

try {
final Environment environment = Environment(
projectDir: globals.fs.currentDirectory,
outputDir: outputBuildDirectory,
outputDir: macosBuildOutput,
buildDir: project.dartTool.childDirectory('flutter_build'),
cacheDir: globals.cache.getRoot(),
flutterRootDir: globals.fs.directory(Cache.flutterRoot),
Expand Down Expand Up @@ -251,26 +255,45 @@ end
status.stop();
}

final Directory appFramework = outputBuildDirectory.childDirectory('App.framework');
final Directory appFramework = macosBuildOutput.childDirectory('App.framework');
await BuildFrameworkCommand.produceXCFramework(
<Directory>[appFramework],
'App',
outputBuildDirectory,
globals.processManager,
);
appFramework.deleteSync(recursive: true);
final Directory flutterFramework = outputBuildDirectory.childDirectory('FlutterMacOS.framework');

// If FlutterMacOS.podspec was generated, do not generate XCFramework.
if (!boolArg('cocoapods')) {
await BuildFrameworkCommand.produceXCFramework(
<Directory>[flutterFramework],
'FlutterMacOS',
outputBuildDirectory,
globals.processManager,
}

Future<void> _produceFlutterFramework(
BuildInfo buildInfo,
Directory modeDirectory,
) async {
final Status status = globals.logger.startProgress(
' ├─Copying FlutterMacOS.xcframework...',
);
final String engineCacheFlutterFrameworkDirectory = globals.artifacts!.getArtifactPath(
Artifact.flutterMacOSXcframework,
platform: TargetPlatform.darwin,
mode: buildInfo.mode,
);
final String flutterFrameworkFileName = globals.fs.path.basename(
engineCacheFlutterFrameworkDirectory,
);
final Directory flutterFrameworkCopy = modeDirectory.childDirectory(
flutterFrameworkFileName,
);

try {
// Copy xcframework engine cache framework to mode directory.
copyDirectory(
globals.fs.directory(engineCacheFlutterFrameworkDirectory),
flutterFrameworkCopy,
followLinks: false,
);
} finally {
status.stop();
}
flutterFramework.deleteSync(recursive: true);
}

Future<void> _producePlugins(
Expand Down
6 changes: 3 additions & 3 deletions packages/flutter_tools/lib/src/flutter_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -858,12 +858,12 @@ List<List<String>> _getWindowsDesktopBinaryDirs(String arch) {
}

const List<List<String>> _macOSDesktopBinaryDirs = <List<String>>[
<String>['darwin-x64', 'darwin-x64/FlutterMacOS.framework.zip'],
<String>['darwin-x64', 'darwin-x64/framework.zip'],
<String>['darwin-x64', 'darwin-x64/gen_snapshot.zip'],
<String>['darwin-x64-profile', 'darwin-x64-profile/FlutterMacOS.framework.zip'],
<String>['darwin-x64-profile', 'darwin-x64-profile/framework.zip'],
<String>['darwin-x64-profile', 'darwin-x64-profile/artifacts.zip'],
<String>['darwin-x64-profile', 'darwin-x64-profile/gen_snapshot.zip'],
<String>['darwin-x64-release', 'darwin-x64-release/FlutterMacOS.framework.zip'],
<String>['darwin-x64-release', 'darwin-x64-release/framework.zip'],
<String>['darwin-x64-release', 'darwin-x64-release/artifacts.zip'],
<String>['darwin-x64-release', 'darwin-x64-release/gen_snapshot.zip'],
];
Expand Down
Loading

0 comments on commit 42252cd

Please sign in to comment.