summaryrefslogtreecommitdiffstats
path: root/testing/iossim
diff options
context:
space:
mode:
authorthomasvl@chromium.org <thomasvl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-30 23:14:16 +0000
committerthomasvl@chromium.org <thomasvl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-30 23:14:16 +0000
commitaaba7448100c4d6536d265757d5680a8de9a7d61 (patch)
treeab762c9a454f2ae7432aa80fc9d9e67d233a614d /testing/iossim
parentf1d37b14081179ba16df8f556b9d4e7e48633606 (diff)
downloadchromium_src-aaba7448100c4d6536d265757d5680a8de9a7d61.zip
chromium_src-aaba7448100c4d6536d265757d5680a8de9a7d61.tar.gz
chromium_src-aaba7448100c4d6536d265757d5680a8de9a7d61.tar.bz2
- Don't directly link to the private Xcode framework, instead find it at runtime
and lookup the classes by name. This allows the binary to work with multiple versions of Xcode and doesn't tile the binary to an Xcode install location. - Fix problem where the tool could log the wrong thing since basename() returns an internal buffer. Review URL: https://chromiumcodereview.appspot.com/10828070 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149067 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'testing/iossim')
-rw-r--r--testing/iossim/iossim.gyp10
-rw-r--r--testing/iossim/iossim.mm112
2 files changed, 101 insertions, 21 deletions
diff --git a/testing/iossim/iossim.gyp b/testing/iossim/iossim.gyp
index b8dcf98..a2f559c 100644
--- a/testing/iossim/iossim.gyp
+++ b/testing/iossim/iossim.gyp
@@ -23,17 +23,7 @@
],
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
- '<(iphone_sim_path)/iPhoneSimulatorRemoteClient.framework',
],
- 'mac_framework_dirs': [
- '<(iphone_sim_path)',
- ],
- 'xcode_settings': {
- 'LD_RUNPATH_SEARCH_PATHS': [
- '<(iphone_sim_path)',
- '<(other_frameworks_path)',
- ]
- },
'actions': [
{
'action_name': 'generate_iphone_sim_header',
diff --git a/testing/iossim/iossim.mm b/testing/iossim/iossim.mm
index a02f0b9..19df378 100644
--- a/testing/iossim/iossim.mm
+++ b/testing/iossim/iossim.mm
@@ -70,6 +70,13 @@ const NSTimeInterval kSessionStartTimeoutSeconds = 30;
// polling interval.
const NSTimeInterval kOutputPollIntervalSeconds = 0.1;
+// The path within the developer dir of the private Simulator frameworks.
+NSString* const kSimulatorFrameworkRelativePath =
+ @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/"
+ @"iPhoneSimulatorRemoteClient.framework";
+NSString* const kDevToolsFoundationRelativePath =
+ @"../OtherFrameworks/DevToolsFoundation.framework";
+
const char* gToolName = "iossim";
void LogError(NSString* format, ...) {
@@ -248,26 +255,87 @@ void LogWarning(NSString* format, ...) {
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* developerDir = [env objectForKey:@"DEVELOPER_DIR"];
+ if ([developerDir length] > 0)
+ return developerDir;
+
+ // Go look for it via xcode-select.
+ NSTask* xcodeSelectTask = [[[NSTask alloc] init] autorelease];
+ [xcodeSelectTask setLaunchPath:@"/usr/bin/xcode-select"];
+ [xcodeSelectTask setArguments:[NSArray arrayWithObject:@"-print-path"]];
+
+ 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];
+ output = [output stringByTrimmingCharactersInSet:
+ [NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ if ([output length] == 0)
+ output = nil;
+ return output;
+}
+
+// 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 = [developerDir
+ stringByAppendingPathComponent:kDevToolsFoundationRelativePath];
+ NSBundle* devToolsFoundationBundle =
+ [NSBundle bundleWithPath:devToolsFoundationPath];
+ if (![devToolsFoundationBundle load])
+ return nil;
+ NSString* simBundlePath = [developerDir
+ stringByAppendingPathComponent:kSimulatorFrameworkRelativePath];
+ 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* nameOfClass) {
+ Class theClass = NSClassFromString(nameOfClass);
+ if (!theClass) {
+ LogError(@"Failed to find class %@ at runtime.", nameOfClass);
+ 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");
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 +349,9 @@ DTiPhoneSimulatorSessionConfig* BuildSessionConfig(
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 +365,9 @@ DTiPhoneSimulatorSessionConfig* BuildSessionConfig(
// 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;
}
@@ -392,9 +462,17 @@ void PrintUsage() {
int main(int argc, char* const argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- char* toolName = basename(argv[0]);
- if (toolName != NULL)
- gToolName = toolName;
+ // basename() may modify the passed in string and it returns a pointer to an
+ // internal buffer. Give it a copy to modify, and copy what it returns.
+ char* worker = strdup(argv[0]);
+ char* toolName = basename(worker);
+ if (toolName != NULL) {
+ toolName = strdup(toolName);
+ if (toolName != NULL)
+ gToolName = toolName;
+ }
+ if (worker != NULL)
+ free(worker);
NSString* appPath = nil;
NSString* appName = nil;
@@ -456,6 +534,18 @@ int main(int argc, char* const argv[]) {
exit(EXIT_FAILURE);
}
+ NSString* developerDir = FindDeveloperDir();
+ if (!developerDir) {
+ LogError(@"Unable to find developer directory.");
+ exit(EXIT_FAILURE);
+ }
+
+ 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 +603,7 @@ int main(int argc, char* const argv[]) {
appEnv,
deviceFamily);
SimulatorDelegate* delegate =
- [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath] autorelease];
+ [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath] autorelease];
DTiPhoneSimulatorSession* session = BuildSession(delegate);
// Start the simulator session.