blob: a72a8b8838c8d3e8238fbd1ca9c32bcf58487e76 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/process_manager.dart';
import '../build_info.dart';
import '../build_system/build_system.dart';
import '../build_system/targets/dart.dart';
import '../convert.dart';
import '../globals.dart';
import '../ios/xcodeproj.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import 'application_package.dart';
/// Builds the macOS project through xcodebuild and returns the app bundle.
Future<PrebuiltMacOSApp> buildMacOS({
FlutterProject flutterProject,
BuildInfo buildInfo,
String targetOverride = 'lib/main.dart',
}) async {
// Create the environment used to process the build. This needs to match what
// is provided in bin/macos_build_flutter_assets.sh otherwise the directories
// will be different.
final Environment environment = Environment(
projectDir: flutterProject.directory,
buildDir: flutterProject.dartTool.childDirectory('flutter_build'),
defines: <String, String>{
kBuildMode: buildInfo.isDebug == true ? 'debug' : 'release',
kTargetPlatform: 'darwin-x64',
kTargetFile: fs.file(targetOverride).absolute.path
},
);
// Write configuration to an xconfig file in a standard location.
await updateGeneratedXcodeProperties(
project: flutterProject,
buildInfo: buildInfo,
targetOverride: targetOverride,
useMacOSConfig: true,
setSymroot: false,
buildDirOverride: environment.buildDir.path,
);
// If the xcfilelists do not exist, create empty version.
if (!flutterProject.macos.inputFileList.existsSync()) {
flutterProject.macos.inputFileList.createSync(recursive: true);
}
if (!flutterProject.macos.outputFileList.existsSync()) {
flutterProject.macos.outputFileList.createSync(recursive: true);
}
// Set debug or release mode.
String config = 'Debug';
if (buildInfo.isRelease ?? false) {
config = 'Release';
}
// Invoke Xcode with correct configuration.
final Stopwatch sw = Stopwatch()..start();
final List<String> command = <String>[
'/usr/bin/env',
'xcrun',
'xcodebuild',
'-workspace', flutterProject.macos.xcodeWorkspace.path,
'-configuration', config,
'-scheme', 'Runner',
'-derivedDataPath', environment.buildDir.path,
'OBJROOT=${fs.path.join(environment.buildDir.path, 'Build', 'Intermediates.noindex')}',
'SYMROOT=${fs.path.join(environment.buildDir.path, 'Build', 'Products')}',
];
final Process process = await processManager.start(command);
final Status status = logger.startProgress(
'Building macOS application...',
timeout: null,
);
int result;
try {
process.stderr
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen(printError);
process.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen(printTrace);
result = await process.exitCode;
} finally {
status.cancel();
}
if (result != 0) {
throwToolExit('Build process failed');
}
flutterUsage.sendTiming('build', 'xcode-macos', Duration(milliseconds: sw.elapsedMilliseconds));
final File appBundleNameFile = flutterProject.macos.nameFile;
final Directory bundleDir = fs.directory(fs.path.join(
environment.buildDir.path,
'Build',
'Products',
buildInfo.mode == BuildMode.debug ? 'Debug' : 'Release',
appBundleNameFile.readAsStringSync().trim(),
));
return MacOSApp.fromPrebuiltApp(bundleDir);
}