Add --target support to flutter build ios (#4318)

Fixes #4298
diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart
index 3385b75..741d26b 100644
--- a/packages/flutter_tools/lib/src/commands/build_ios.dart
+++ b/packages/flutter_tools/lib/src/commands/build_ios.dart
@@ -15,6 +15,7 @@
 
 class BuildIOSCommand extends FlutterCommand {
   BuildIOSCommand() {
+    usesTargetOption();
     addBuildModeFlags();
     argParser.addFlag('simulator', help: 'Build for the iOS simulator instead of the device.');
     argParser.addFlag('codesign', negatable: true, defaultsTo: true,
@@ -53,9 +54,13 @@
 
     String typeName = path.basename(tools.getEngineArtifactsDirectory(TargetPlatform.ios, getBuildMode()).path);
     Status status = logger.startProgress('Building $app for $logTarget ($typeName)...');
-    XcodeBuildResult result = await buildXcodeProject(app, getBuildMode(),
-        buildForDevice: !forSimulator,
-        codesign: shouldCodesign);
+    XcodeBuildResult result = await buildXcodeProject(
+      app: app,
+      mode: getBuildMode(),
+      target: argResults['target'],
+      buildForDevice: !forSimulator,
+      codesign: shouldCodesign
+    );
     status.stop(showElapsedTime: true);
 
     if (!result.success) {
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart
index 4a1e72d..df8d16b 100644
--- a/packages/flutter_tools/lib/src/ios/devices.dart
+++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -180,7 +180,7 @@
     printTrace('Building ${app.name} for $id');
 
     // Step 1: Install the precompiled/DBC application if necessary.
-    XcodeBuildResult buildResult = await buildXcodeProject(app, mode, buildForDevice: true);
+    XcodeBuildResult buildResult = await buildXcodeProject(app: app, mode: mode, buildForDevice: true);
     if (!buildResult.success) {
       printError('Could not build the precompiled application for the device.');
       return new LaunchResult.failed();
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 154621b..7854097 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -13,6 +13,7 @@
 import '../base/process.dart';
 import '../build_info.dart';
 import '../cache.dart';
+import '../flx.dart' as flx;
 import '../globals.dart';
 import '../services.dart';
 import 'setup_xcodeproj.dart';
@@ -97,18 +98,23 @@
   return false;
 }
 
-Future<XcodeBuildResult> buildXcodeProject(ApplicationPackage app, BuildMode mode,
-    { bool buildForDevice, bool codesign: true }) async {
+Future<XcodeBuildResult> buildXcodeProject({
+  ApplicationPackage app,
+  BuildMode mode,
+  String target: flx.defaultMainPath,
+  bool buildForDevice,
+  bool codesign: true
+}) async {
   String flutterProjectPath = Directory.current.path;
 
   if (xcodeProjectRequiresUpdate(mode)) {
     printTrace('Initializing the Xcode project.');
-    if ((await setupXcodeProjectHarness(flutterProjectPath, mode)) != 0) {
+    if ((await setupXcodeProjectHarness(flutterProjectPath, mode, target)) != 0) {
       printError('Could not initialize the Xcode project.');
       return new XcodeBuildResult(false);
     }
   } else {
-   updateXcodeGeneratedProperties(flutterProjectPath, mode);
+   updateXcodeGeneratedProperties(flutterProjectPath, mode, target);
   }
 
   if (!_validateEngineRevision(app))
diff --git a/packages/flutter_tools/lib/src/ios/setup_xcodeproj.dart b/packages/flutter_tools/lib/src/ios/setup_xcodeproj.dart
index 2ad557c..29bd790 100644
--- a/packages/flutter_tools/lib/src/ios/setup_xcodeproj.dart
+++ b/packages/flutter_tools/lib/src/ios/setup_xcodeproj.dart
@@ -54,7 +54,7 @@
   return true;
 }
 
-void updateXcodeGeneratedProperties(String projectPath, BuildMode mode) {
+void updateXcodeGeneratedProperties(String projectPath, BuildMode mode, String target) {
   StringBuffer localsBuffer = new StringBuffer();
 
   localsBuffer.writeln('// This is a generated file; do not edit or check into version control.');
@@ -66,6 +66,9 @@
   String applicationRoot = path.normalize(Directory.current.path);
   localsBuffer.writeln('FLUTTER_APPLICATION_PATH=$applicationRoot');
 
+  // Relative to FLUTTER_APPLICATION_PATH, which is [Directory.current].
+  localsBuffer.writeln('FLUTTER_TARGET=$target');
+
   String flutterFrameworkDir = path.normalize(tools.getEngineArtifactsDirectory(TargetPlatform.ios, mode).path);
   localsBuffer.writeln('FLUTTER_FRAMEWORK_DIR=$flutterFrameworkDir');
 
@@ -97,7 +100,7 @@
   return false;
 }
 
-Future<int> setupXcodeProjectHarness(String flutterProjectPath, BuildMode mode) async {
+Future<int> setupXcodeProjectHarness(String flutterProjectPath, BuildMode mode, String target) async {
   // Step 1: Fetch the archive from the cloud
   String iosFilesPath = path.join(flutterProjectPath, 'ios');
   String xcodeprojPath = path.join(iosFilesPath, '.generated');
@@ -119,7 +122,7 @@
   }
 
   // Step 3: Populate the Generated.xcconfig with project specific paths
-  updateXcodeGeneratedProperties(flutterProjectPath, mode);
+  updateXcodeGeneratedProperties(flutterProjectPath, mode, target);
 
   // Step 4: Write the REVISION file
   File revisionFile = new File(path.join(xcodeprojPath, 'REVISION'));
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart
index 6409396..eafdf5f 100644
--- a/packages/flutter_tools/lib/src/ios/simulators.dart
+++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -548,7 +548,7 @@
   Future<bool> _buildAndInstallApplicationBundle(ApplicationPackage app) async {
     // Step 1: Build the Xcode project.
     // The build mode for the simulator is always debug.
-    XcodeBuildResult buildResult = await buildXcodeProject(app, BuildMode.debug, buildForDevice: false);
+    XcodeBuildResult buildResult = await buildXcodeProject(app: app, mode: BuildMode.debug, buildForDevice: false);
     if (!buildResult.success) {
       printError('Could not build the application for the simulator.');
       return false;