Index: testing/iossim/iossim.mm |
diff --git a/testing/iossim/iossim.mm b/testing/iossim/iossim.mm |
index 48482e81ef2b69b68dd7a0b5de2dde36b7d1d502..7a3ffebbdc32598ec5a520c576b8ea7045ea18c2 100644 |
--- a/testing/iossim/iossim.mm |
+++ b/testing/iossim/iossim.mm |
@@ -101,19 +101,6 @@ const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30; |
// polling interval. |
const NSTimeInterval kOutputPollIntervalSeconds = 0.1; |
-// The path within the developer dir of the private Simulator frameworks. |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
-NSString* const kSimulatorFrameworkRelativePath = |
- @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; |
-NSString* const kCoreSimulatorRelativePath = |
- @"Library/PrivateFrameworks/CoreSimulator.framework"; |
-#else |
-NSString* const kSimulatorFrameworkRelativePath = |
- @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" |
- @"DVTiPhoneSimulatorRemoteClient.framework"; |
-#endif // IOSSIM_USE_XCODE_6 |
NSString* const kDVTFoundationRelativePath = |
@"../SharedFrameworks/DVTFoundation.framework"; |
NSString* const kDevToolsFoundationRelativePath = |
@@ -172,36 +159,80 @@ Class FindClassByName(NSString* nameOfClass) { |
return theClass; |
} |
+// Finds the Xcode version via xcodebuild -version. Output from xcodebuild is |
+// expected to look like: |
+// Xcode <version> |
+// Build version 5B130a |
+// where <version> is the string returned by this function (e.g. 6.0). |
+NSString* FindXcodeVersion() { |
+ NSTask* xcodeSelectTask = [[[NSTask alloc] init] autorelease]; |
TVL
2014/08/21 19:41:50
fyi - you could probably make a common method with
|
+ [xcodeSelectTask setLaunchPath:@"/usr/bin/xcodebuild"]; |
+ [xcodeSelectTask setArguments:[NSArray arrayWithObject:@"-version"]]; |
+ |
+ NSPipe* outputPipe = [NSPipe pipe]; |
+ [xcodeSelectTask setStandardOutput:outputPipe]; |
+ NSFileHandle* outputFile = [outputPipe fileHandleForReading]; |
+ |
+ [xcodeSelectTask launch]; |
+ NSData* outputData = [outputFile readDataToEndOfFile]; |
+ [xcodeSelectTask terminate]; |
+ |
+ NSString* output = |
+ [[[NSString alloc] initWithData:outputData |
+ encoding:NSUTF8StringEncoding] autorelease]; |
TVL
2014/08/21 19:41:50
fyi - another options is NSScanner, can the "Xcode
lliabraa
2014/08/22 17:50:56
Done.
|
+ NSArray* tokens = [output componentsSeparatedByCharactersInSet: |
+ [NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
+ if ([tokens count] != 6) { |
+ LogError(@"Unable to find Xcode version. 'xcodebuild -version' " |
+ @"returned \n%@", output); |
+ return nil; |
+ } |
+ return tokens[1]; |
+} |
+ |
+// Returns true if iossim is running with Xcode 6 or later installed on the |
+// host. |
+BOOL IsRunningWithXcode6OrLater() { |
+ static NSString* xcodeVersion = FindXcodeVersion(); |
+ if (!xcodeVersion) { |
+ return false; |
+ } |
+ NSArray* components = [xcodeVersion componentsSeparatedByString:@"."]; |
+ if ([components count] < 1) { |
+ return false; |
+ } |
+ NSInteger majorVersion = [components[0] integerValue]; |
+ return majorVersion >= 6; |
+} |
+ |
// Prints supported devices and SDKs. |
void PrintSupportedDevices() { |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
- printf("Supported device/SDK combinations:\n"); |
- Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
- id deviceSet = |
- [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
- for (id simDevice in [deviceSet availableDevices]) { |
- NSString* deviceInfo = |
- [NSString stringWithFormat:@" -d '%@' -s '%@'\n", |
- [simDevice name], [[simDevice runtime] versionString]]; |
- printf("%s", [deviceInfo UTF8String]); |
- } |
-#else |
- printf("Supported SDK versions:\n"); |
- Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); |
- for (id root in [rootClass knownRoots]) { |
- printf(" '%s'\n", [[root sdkVersion] UTF8String]); |
+ if (IsRunningWithXcode6OrLater()) { |
+ printf("Supported device/SDK combinations:\n"); |
+ Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
+ id deviceSet = |
+ [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
+ for (id simDevice in [deviceSet availableDevices]) { |
+ NSString* deviceInfo = |
+ [NSString stringWithFormat:@" -d '%@' -s '%@'\n", |
+ [simDevice name], [[simDevice runtime] versionString]]; |
+ printf("%s", [deviceInfo UTF8String]); |
+ } |
+ } else { |
+ printf("Supported SDK versions:\n"); |
TVL
2014/08/21 19:41:50
maybe a comment that this the the list from Xcode
lliabraa
2014/08/22 17:50:56
Makes sense for the hard-coded list of devices, bu
|
+ Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); |
+ for (id root in [rootClass knownRoots]) { |
+ printf(" '%s'\n", [[root sdkVersion] UTF8String]); |
+ } |
+ printf("Supported devices:\n"); |
TVL
2014/08/21 19:41:50
maybe a comment that this the the list from Xcode
lliabraa
2014/08/22 17:50:56
Done.
|
+ printf(" 'iPhone'\n"); |
+ printf(" 'iPhone Retina (3.5-inch)'\n"); |
+ printf(" 'iPhone Retina (4-inch)'\n"); |
+ printf(" 'iPhone Retina (4-inch 64-bit)'\n"); |
+ printf(" 'iPad'\n"); |
+ printf(" 'iPad Retina'\n"); |
+ printf(" 'iPad Retina (64-bit)'\n"); |
} |
- printf("Supported devices:\n"); |
- printf(" 'iPhone'\n"); |
- printf(" 'iPhone Retina (3.5-inch)'\n"); |
- printf(" 'iPhone Retina (4-inch)'\n"); |
- printf(" 'iPhone Retina (4-inch 64-bit)'\n"); |
- printf(" 'iPad'\n"); |
- printf(" 'iPad Retina'\n"); |
- printf(" 'iPad Retina (64-bit)'\n"); |
-#endif // defined(IOSSIM_USE_XCODE_6) |
} |
} // namespace |
@@ -260,17 +291,16 @@ void PrintSupportedDevices() { |
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_]; |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
- // With iOS 8 simulators on Xcode 6, the app output is relative to the |
- // simulator's data directory. |
- if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { |
- NSString* dataPath = session.sessionConfig.device.dataPath; |
- NSString* appOutput = [dataPath stringByAppendingPathComponent:stdioPath_]; |
- simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; |
+ if (IsRunningWithXcode6OrLater()) { |
+ // With iOS 8 simulators on Xcode 6, the app output is relative to the |
+ // simulator's data directory. |
+ if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { |
+ NSString* dataPath = session.sessionConfig.device.dataPath; |
+ NSString* appOutput = |
+ [dataPath stringByAppendingPathComponent:stdioPath_]; |
+ simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; |
+ } |
} |
-#endif |
NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput]; |
// Copy data to stdout/stderr while the app is running. |
while (appRunning_) { |
@@ -419,19 +449,18 @@ void PrintSupportedDevices() { |
} else { |
// Otherwise, the iOS Simulator's system logging is sandboxed, so parse the |
// sandboxed system.log file for known errors. |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
- NSString* dataPath = session.sessionConfig.device.dataPath; |
- NSString* path = |
- [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; |
-#else |
- NSString* relativePathToSystemLog = |
- [NSString stringWithFormat: |
- @"Library/Logs/iOS Simulator/%@/system.log", versionString]; |
- NSString* path = |
- [simulatorHome_ stringByAppendingPathComponent:relativePathToSystemLog]; |
-#endif // defined(IOSSIM_USE_XCODE_6) |
+ NSString* path; |
+ if (IsRunningWithXcode6OrLater()) { |
+ NSString* dataPath = session.sessionConfig.device.dataPath; |
+ path = |
+ [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; |
+ } else { |
+ NSString* relativePathToSystemLog = |
+ [NSString stringWithFormat: |
+ @"Library/Logs/iOS Simulator/%@/system.log", versionString]; |
+ path = [simulatorHome_ |
+ stringByAppendingPathComponent:relativePathToSystemLog]; |
+ } |
NSFileManager* fileManager = [NSFileManager defaultManager]; |
if ([fileManager fileExistsAtPath:path]) { |
NSString* content = |
@@ -530,19 +559,26 @@ NSBundle* LoadSimulatorFramework(NSString* developerDir) { |
return nil; |
} |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
- NSString* coreSimulatorPath = [developerDir |
- stringByAppendingPathComponent:kCoreSimulatorRelativePath]; |
- NSBundle* coreSimulatorBundle = |
- [NSBundle bundleWithPath:coreSimulatorPath]; |
- if (![coreSimulatorBundle load]) |
- return nil; |
-#endif // defined(IOSSIM_USE_XCODE_6) |
- |
+ // The path within the developer dir of the private Simulator frameworks. |
+ NSString* simulatorFrameworkRelativePath; |
+ if (IsRunningWithXcode6OrLater()) { |
+ simulatorFrameworkRelativePath = |
+ @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; |
+ NSString* const kCoreSimulatorRelativePath = |
+ @"Library/PrivateFrameworks/CoreSimulator.framework"; |
+ NSString* coreSimulatorPath = [developerDir |
+ stringByAppendingPathComponent:kCoreSimulatorRelativePath]; |
+ NSBundle* coreSimulatorBundle = |
+ [NSBundle bundleWithPath:coreSimulatorPath]; |
+ if (![coreSimulatorBundle load]) |
+ return nil; |
+ } else { |
+ simulatorFrameworkRelativePath = |
+ @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" |
+ @"DVTiPhoneSimulatorRemoteClient.framework"; |
+ } |
NSString* simBundlePath = [developerDir |
- stringByAppendingPathComponent:kSimulatorFrameworkRelativePath]; |
+ stringByAppendingPathComponent:simulatorFrameworkRelativePath]; |
NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; |
if (![simBundle load]) |
return nil; |
@@ -602,47 +638,45 @@ DTiPhoneSimulatorSessionConfig* BuildSessionConfig( |
sessionConfig.simulatedDeviceInfoName = deviceName; |
sessionConfig.simulatedDeviceFamily = deviceFamily; |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
- Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
- id simDeviceType = |
- [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; |
- Class simRuntimeClass = FindClassByName(@"SimRuntime"); |
- NSString* identifier = systemRoot.runtime.identifier; |
- id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; |
- |
- // Attempt to use an existing device, but create one if a suitable match can't |
- // be found. For example, if the simulator is running with a non-default home |
- // directory (e.g. via iossim's -u command line arg) then there won't be any |
- // devices so one will have to be created. |
- Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
- id deviceSet = |
- [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
- id simDevice = nil; |
- for (id device in [deviceSet availableDevices]) { |
- if ([device runtime] == simRuntime && |
- [device deviceType] == simDeviceType) { |
- simDevice = device; |
- break; |
+ if (IsRunningWithXcode6OrLater()) { |
+ Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
+ id simDeviceType = |
+ [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; |
+ Class simRuntimeClass = FindClassByName(@"SimRuntime"); |
+ NSString* identifier = systemRoot.runtime.identifier; |
+ id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; |
+ |
+ // Attempt to use an existing device, but create one if a suitable match |
+ // can't be found. For example, if the simulator is running with a |
+ // non-default home directory (e.g. via iossim's -u command line arg) then |
+ // there won't be any devices so one will have to be created. |
+ Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
+ id deviceSet = |
+ [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
+ id simDevice = nil; |
+ for (id device in [deviceSet availableDevices]) { |
+ if ([device runtime] == simRuntime && |
+ [device deviceType] == simDeviceType) { |
+ simDevice = device; |
+ break; |
+ } |
} |
- } |
- if (!simDevice) { |
- NSError* error = nil; |
- // n.b. only the device name is necessary because the iOS Simulator menu |
- // already splits devices by runtime version. |
- NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; |
- simDevice = [deviceSet createDeviceWithType:simDeviceType |
- runtime:simRuntime |
- name:name |
- error:&error]; |
- if (error) { |
- LogError(@"Failed to create device: %@", error); |
- exit(kExitInitializationFailure); |
+ if (!simDevice) { |
+ NSError* error = nil; |
+ // n.b. only the device name is necessary because the iOS Simulator menu |
+ // already splits devices by runtime version. |
+ NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; |
+ simDevice = [deviceSet createDeviceWithType:simDeviceType |
+ runtime:simRuntime |
+ name:name |
+ error:&error]; |
+ if (error) { |
+ LogError(@"Failed to create device: %@", error); |
+ exit(kExitInitializationFailure); |
+ } |
} |
+ sessionConfig.device = simDevice; |
} |
- sessionConfig.device = simDevice; |
-#endif |
return sessionConfig; |
} |
@@ -774,13 +808,7 @@ int main(int argc, char* const argv[]) { |
NSString* appPath = nil; |
NSString* appName = nil; |
NSString* sdkVersion = nil; |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
- NSString* deviceName = @"iPhone 5"; |
-#else |
- NSString* deviceName = @"iPhone"; |
-#endif |
+ NSString* deviceName = IsRunningWithXcode6OrLater() ? @"iPhone 5" : @"iPhone"; |
NSString* simHomePath = nil; |
NSMutableArray* appArgs = [NSMutableArray array]; |
NSMutableDictionary* appEnv = [NSMutableDictionary dictionary]; |
@@ -887,27 +915,25 @@ int main(int argc, char* const argv[]) { |
// Determine the deviceFamily based on the deviceName |
NSNumber* deviceFamily = nil; |
-// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
-// (crbug.com/385030). |
-#if defined(IOSSIM_USE_XCODE_6) |
- Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
- if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { |
- LogError(@"Invalid device name: %@.", deviceName); |
- PrintSupportedDevices(); |
- exit(kExitInvalidArguments); |
- } |
-#else |
- if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { |
- deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; |
- } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { |
- deviceFamily = [NSNumber numberWithInt:kIPadFamily]; |
- } |
- else { |
- LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", |
- deviceName); |
- exit(kExitInvalidArguments); |
+ if (IsRunningWithXcode6OrLater()) { |
+ Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
+ if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { |
+ LogError(@"Invalid device name: %@.", deviceName); |
+ PrintSupportedDevices(); |
+ exit(kExitInvalidArguments); |
+ } |
+ } else { |
+ if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { |
+ deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; |
+ } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { |
+ deviceFamily = [NSNumber numberWithInt:kIPadFamily]; |
+ } |
+ else { |
+ LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", |
+ deviceName); |
+ exit(kExitInvalidArguments); |
+ } |
} |
-#endif // !defined(IOSSIM_USE_XCODE_6) |
// Set up the user home directory for the simulator only if a non-default |
// value was specified. |