diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart index 29e374b416a..cf8ae2bc371 100644 --- a/packages/flutter_tools/lib/src/application_package.dart +++ b/packages/flutter_tools/lib/src/application_package.dart @@ -12,6 +12,7 @@ import 'base/process.dart'; import 'build_info.dart'; import 'globals.dart'; import 'ios/plist_utils.dart'; +import 'ios/xcodeproj.dart'; abstract class ApplicationPackage { /// Package ID from the Android Manifest or equivalent. @@ -137,6 +138,8 @@ class IOSApp extends ApplicationPackage { String value = getValueFromFile(plistPath, kCFBundleIdentifierKey); if (value == null) return null; + String projectPath = path.join('ios', 'Runner.xcodeproj'); + value = substituteXcodeVariables(value, projectPath, 'Runner'); return new IOSApp( appDirectory: path.join('ios'), diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 78df9a24bc0..d180827dd2f 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -15,7 +15,7 @@ import '../build_info.dart'; import '../flx.dart' as flx; import '../globals.dart'; import '../services.dart'; -import 'setup_xcodeproj.dart'; +import 'xcodeproj.dart'; String get homeDirectory => path.absolute(Platform.environment['HOME']); diff --git a/packages/flutter_tools/lib/src/ios/setup_xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart similarity index 62% rename from packages/flutter_tools/lib/src/ios/setup_xcodeproj.dart rename to packages/flutter_tools/lib/src/ios/xcodeproj.dart index 507b70c5197..6d1bc49bfd4 100644 --- a/packages/flutter_tools/lib/src/ios/setup_xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart @@ -6,10 +6,14 @@ import 'dart:io'; import 'package:path/path.dart' as path; +import '../base/process.dart'; import '../build_info.dart'; import '../cache.dart'; import '../globals.dart'; +final RegExp _settingExpr = new RegExp(r'(\w+)\s*=\s*(\S+)'); +final RegExp _varExpr = new RegExp(r'\$\((.*)\)'); + void updateXcodeGeneratedProperties(String projectPath, BuildMode mode, String target) { StringBuffer localsBuffer = new StringBuffer(); @@ -43,3 +47,28 @@ void updateXcodeGeneratedProperties(String projectPath, BuildMode mode, String t localsFile.createSync(recursive: true); localsFile.writeAsStringSync(localsBuffer.toString()); } + +Map getXcodeBuildSettings(String xcodeProjPath, String target) { + String absProjPath = path.absolute(xcodeProjPath); + String out = runCheckedSync([ + '/usr/bin/xcodebuild', '-project', absProjPath, '-target', target, '-showBuildSettings' + ]); + Map settings = {}; + for (String line in out.split('\n').where(_settingExpr.hasMatch)) { + Match match = _settingExpr.firstMatch(line); + settings[match[1]] = match[2]; + } + return settings; +} + + +/// Substitutes variables in [str] with their values from the specified Xcode +/// project and target. +String substituteXcodeVariables(String str, String xcodeProjPath, String target) { + Iterable matches = _varExpr.allMatches(str); + if (matches.isEmpty) + return str; + + Map settings = getXcodeBuildSettings(xcodeProjPath, target); + return str.replaceAllMapped(_varExpr, (Match m) => settings[m[1]] ?? m[0]); +}