Skip to content

Reland "Add FlutterMacOS.xcframework artifact (#143244)" #144275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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