diff --git a/packages/flutter_tools/lib/src/commands/build.dart b/packages/flutter_tools/lib/src/commands/build.dart index c3c78bc6a2a..bd88f4ad6ba 100644 --- a/packages/flutter_tools/lib/src/commands/build.dart +++ b/packages/flutter_tools/lib/src/commands/build.dart @@ -8,12 +8,14 @@ import 'dart:io'; import '../globals.dart'; import '../runner/flutter_command.dart'; import 'build_apk.dart'; +import 'build_ios.dart'; import 'build_flx.dart'; class BuildCommand extends FlutterCommand { BuildCommand() { addSubcommand(new BuildApkCommand()); addSubcommand(new BuildCleanCommand()); + addSubcommand(new BuildIOSCommand()); addSubcommand(new BuildFlxCommand()); } diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart new file mode 100644 index 00000000000..6db8a43fc8f --- /dev/null +++ b/packages/flutter_tools/lib/src/commands/build_ios.dart @@ -0,0 +1,71 @@ +// Copyright 2016 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 'dart:async'; +import 'dart:io'; + +import '../application_package.dart'; +import '../build_configuration.dart'; +import '../globals.dart'; +import '../ios/mac.dart'; +import '../runner/flutter_command.dart'; + +import 'package:path/path.dart' as path; + +class BuildIOSCommand extends FlutterCommand { + BuildIOSCommand() { + argParser.addFlag('simulator', help: 'Build for the iOS simulator instead of the device'); + } + + @override + final String name = 'ios'; + + @override + final String description = 'Build an iOS application bundle (Mac OSX host only).'; + + @override + Future runInProject() async { + if (getCurrentHostPlatform() != HostPlatform.mac) { + printError('Building for iOS is only supported on the Mac.'); + return 1; + } + + printTrace('Ensuring toolchains are up to date.'); + + await Future.wait([ + downloadToolchain(), + downloadApplicationPackages(), + ], eagerError: true); + + IOSApp app = applicationPackages.iOS; + + if (app == null) { + printError('Application not configured for iOS'); + return 1; + } + + bool forSimulator = argResults['simulator']; + + String logTarget = forSimulator ? "simulator" : "device"; + + printStatus('Building the application for $logTarget.'); + + Directory buildDir = new Directory(path.join('build', 'ios_$logTarget')); + + if (!buildDir.existsSync()) + await buildDir.create(); + + bool result = await buildIOSXcodeProject(app, + buildForDevice: !forSimulator, buildDirectory: buildDir); + + if (!result) { + printError('Encountered error while building for $logTarget.'); + return 1; + } + + printStatus('Built in ${buildDir.path}.'); + + return 0; + } +} diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index fd1db37d45e..3745bc52ba7 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -89,7 +89,8 @@ bool _xcodeVersionCheckValid(int major, int minor) { return false; } -Future buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice }) async { +Future buildIOSXcodeProject(ApplicationPackage app, + { bool buildForDevice, Directory buildDirectory }) async { String flutterProjectPath = Directory.current.path; if (xcodeProjectRequiresUpdate()) { @@ -114,9 +115,23 @@ Future buildIOSXcodeProject(ApplicationPackage app, { bool buildForDevice await _addServicesToBundle(new Directory(app.localPath)); List commands = [ - '/usr/bin/env', 'xcrun', 'xcodebuild', '-target', 'Runner', '-configuration', 'Release' + '/usr/bin/env', + 'xcrun', + 'xcodebuild', + '-target', 'Runner', + '-configuration', 'Release', + 'ONLY_ACTIVE_ARCH=YES', ]; + if (buildDirectory != null) { + if (!buildDirectory.existsSync()) { + printError('The specified build directory ${buildDirectory.path} does not exist'); + return false; + } + + commands.add('TARGET_BUILD_DIR=${buildDirectory.absolute.path}'); + } + if (buildForDevice) { commands.addAll(['-sdk', 'iphoneos', '-arch', 'arm64']); } else {