Index: testing/iossim/iossim.mm |
=================================================================== |
--- testing/iossim/iossim.mm (revision 148955) |
+++ testing/iossim/iossim.mm (working copy) |
@@ -43,6 +43,12 @@ |
// is the PID of the process the message is about (as opposed to launchd's PID). |
#define ASL_KEY_REF_PID "RefPID" |
+// The path within the developer dir of the private Simulator frameworks. |
+#define kSimulatorFrameworkPathLeaf \ |
+ @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/iPhoneSimulatorRemoteClient.framework" |
+#define kDevToolsFoundationPathLeaf \ |
+ @"../OtherFrameworks/DevToolsFoundation.framework" |
+ |
namespace { |
// Name of environment variables that control the user's home directory in the |
@@ -248,26 +254,90 @@ |
namespace { |
+// Finds the developer dir via xcode-select or the DEVELOPER_DIR environment |
+// variable. |
+NSString* FindDeveloperDir() { |
+ // Check the env first. |
+ NSDictionary* env = [[NSProcessInfo processInfo] environment]; |
+ NSString* devDir = [env objectForKey:@"DEVELOPER_DIR"]; |
+ if ([devDir length] > 0) { |
+ return devDir; |
+ } |
+ |
+ // Go look for it via xcode-select. |
+ NSTask* task; |
+ task = [[[NSTask alloc] init] autorelease]; |
+ [task setLaunchPath:@"/usr/bin/xcode-select"]; |
+ [task setArguments:[NSArray arrayWithObject:@"-print-path"]]; |
+ |
+ NSPipe* pipe = [NSPipe pipe]; |
+ [task setStandardOutput: pipe]; |
+ NSFileHandle* file = [pipe fileHandleForReading]; |
+ |
+ [task launch]; |
+ NSData* output = [file readDataToEndOfFile]; |
+ [task terminate]; |
+ |
+ NSString* outputStr = |
+ [[[NSString alloc] initWithData:output |
lliabraa
2012/07/30 17:18:51
indent by 4
TVL
2012/07/30 17:23:05
Done.
|
+ encoding:NSUTF8StringEncoding] autorelease]; |
+ NSCharacterSet* wsNLSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; |
+ outputStr = [outputStr stringByTrimmingCharactersInSet:wsNLSet]; |
+ if ([outputStr length] == 0) { |
+ outputStr = nil; |
+ } |
+ return outputStr; |
+} |
+ |
+// Loads the Simulator framework from the given developer dir. |
+NSBundle* LoadSimulatorFramework(NSString* developerDir) { |
+ // The Simulator framework depends on some of the other Xcode private |
+ // frameworks, manually load them first so everything can be linked up. |
+ NSString* devToolsFoundationPath = |
lliabraa
2012/07/30 17:18:51
indent by 4
TVL
2012/07/30 17:23:05
Done.
|
+ [developerDir stringByAppendingPathComponent:kDevToolsFoundationPathLeaf]; |
+ NSBundle* devToolsFoundationBundle = |
+ [NSBundle bundleWithPath:devToolsFoundationPath]; |
lliabraa
2012/07/30 17:18:51
indent by 4
TVL
2012/07/30 17:23:05
Done.
|
+ if (![devToolsFoundationBundle load]) |
+ return nil; |
+ NSString* simBundlePath = |
+ [developerDir stringByAppendingPathComponent:kSimulatorFrameworkPathLeaf]; |
lliabraa
2012/07/30 17:18:51
indent by 4
TVL
2012/07/30 17:23:05
Done.
|
+ NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; |
+ if (![simBundle load]) |
+ return nil; |
+ return simBundle; |
+} |
+ |
+// Helper to find a class by name and die if it isn't found. |
+Class FindClassByName(NSString* clazzName) { |
+ Class theClass = NSClassFromString(clazzName); |
+ if (!theClass) { |
+ LogError(@"Failed to find class %@ at runtime.", clazzName); |
+ exit(EXIT_FAILURE); |
+ } |
+ return theClass; |
+} |
+ |
// Converts the given app path to an application spec, which requires an |
// absolute path. |
DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) { |
+ Class applicationSpecifierClass = |
+ FindClassByName(@"DTiPhoneSimulatorApplicationSpecifier"); |
lliabraa
2012/07/30 17:18:51
indent by 4
TVL
2012/07/30 17:23:05
Done.
|
if (![appPath isAbsolutePath]) { |
NSString* cwd = [[NSFileManager defaultManager] currentDirectoryPath]; |
appPath = [cwd stringByAppendingPathComponent:appPath]; |
} |
appPath = [appPath stringByStandardizingPath]; |
- return [DTiPhoneSimulatorApplicationSpecifier |
- specifierWithApplicationPath:appPath]; |
+ return [applicationSpecifierClass specifierWithApplicationPath:appPath]; |
} |
// Returns the system root for the given SDK version. If sdkVersion is nil, the |
// default system root is returned. Will return nil if the sdkVersion is not |
// valid. |
DTiPhoneSimulatorSystemRoot* BuildSystemRoot(NSString* sdkVersion) { |
- DTiPhoneSimulatorSystemRoot* systemRoot = |
- [DTiPhoneSimulatorSystemRoot defaultRoot]; |
+ Class systemRootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); |
+ DTiPhoneSimulatorSystemRoot* systemRoot = [systemRootClass defaultRoot]; |
if (sdkVersion) |
- systemRoot = [DTiPhoneSimulatorSystemRoot rootWithSDKVersion:sdkVersion]; |
+ systemRoot = [systemRootClass rootWithSDKVersion:sdkVersion]; |
return systemRoot; |
} |
@@ -281,8 +351,9 @@ |
NSArray* appArgs, |
NSDictionary* appEnv, |
NSNumber* deviceFamily) { |
+ Class sessionConfigClass = FindClassByName(@"DTiPhoneSimulatorSessionConfig"); |
DTiPhoneSimulatorSessionConfig* sessionConfig = |
- [[[DTiPhoneSimulatorSessionConfig alloc] init] autorelease]; |
+ [[[sessionConfigClass alloc] init] autorelease]; |
sessionConfig.applicationToSimulateOnStart = appSpec; |
sessionConfig.simulatedSystemRoot = systemRoot; |
sessionConfig.localizedClientName = @"chromium"; |
@@ -296,8 +367,9 @@ |
// Builds a simulator session that will use the given delegate. |
DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { |
+ Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); |
DTiPhoneSimulatorSession* session = |
- [[[DTiPhoneSimulatorSession alloc] init] autorelease]; |
+ [[[sessionClass alloc] init] autorelease]; |
session.delegate = delegate; |
return session; |
} |
@@ -456,6 +528,20 @@ |
exit(EXIT_FAILURE); |
} |
+ // Figure out the developer dir. |
+ NSString* developerDir = FindDeveloperDir(); |
+ if (!developerDir) { |
+ LogError(@"Unable to find developer directory."); |
+ exit(EXIT_FAILURE); |
+ } |
+ |
+ // Load the Simulator Client framework. |
+ NSBundle* simulatorFramework = LoadSimulatorFramework(developerDir); |
+ if (!simulatorFramework) { |
+ LogError(@"Failed to load the Simulator Framework."); |
+ exit(EXIT_FAILURE); |
+ } |
+ |
// Make sure the app path provided is legit. |
DTiPhoneSimulatorApplicationSpecifier* appSpec = BuildAppSpec(appPath); |
if (!appSpec) { |
@@ -513,7 +599,7 @@ |
appEnv, |
deviceFamily); |
SimulatorDelegate* delegate = |
- [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath] autorelease]; |
+ [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath] autorelease]; |
DTiPhoneSimulatorSession* session = BuildSession(delegate); |
// Start the simulator session. |