ios: simulator support for Xcode 5.1

update iossim to be based on version 1.9.0, so that we can support
the new Xcode 5.1. Keep the old version around and use it
with older Xcode.
All the logic has been moved into iossim which does an exec of the
older binary if needed (so that creator itself remains untouched)

Task-number: QTCREATORBUG-11714
Change-Id: I4ad9f922f22367c8371b3be68eae5b6dfdf4df5c
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
This commit is contained in:
Fawzi Mohamed
2014-03-14 00:07:35 +01:00
parent e8d4349c37
commit 470f7973d2
22 changed files with 1417 additions and 180 deletions

View File

@@ -1,5 +1,7 @@
TEMPLATE = subdirs TEMPLATE = subdirs
mac { mac {
SUBDIRS += iossim SUBDIRS += \
iossim \
iossim_1_8_2
} }

View File

@@ -0,0 +1,290 @@
//
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
#pragma mark Blocks
typedef void (^CDUnknownBlockType)(void); // return type and parameters are unknown
#pragma mark -
//
// File: $(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTiPhoneSimulatorRemoteClient.framework/Versions/A/DVTiPhoneSimulatorRemoteClient
//
// Arch: x86_64
// Current version: 12.0.0
// Compatibility version: 1.0.0
// Source version: 5037.3.0.0.0
// Minimum Mac OS X version: 10.8.0
// SDK version: 10.9.0
//
// Objective-C Garbage Collection: Unsupported
//
// Run path: @loader_path/../../../../PrivateFrameworks/
// = $(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks
//
@class DTiPhoneSimulatorApplicationSpecifier;
@class DTiPhoneSimulatorSession;
@class DTiPhoneSimulatorSessionConfig;
@class DTiPhoneSimulatorSystemRoot;
@class DVTiPhoneSimulatorMessenger;
@protocol DTiPhoneSimulatorSessionDelegate
- (void) session: (DTiPhoneSimulatorSession *) session didEndWithError: (NSError *) error;
- (void) session: (DTiPhoneSimulatorSession *) session didStart: (BOOL) started withError: (NSError *) error;
@end
@protocol OS_dispatch_source
@end
@protocol OS_dispatch_queue
@end
@class DVTDispatchLock;
@class DVTConfinementServiceConnection;
@class DVTTask;
@interface DVTiPhoneSimulatorMessenger : NSObject
{
DTiPhoneSimulatorSession *_session;
CDUnknownBlockType _readyMessageHandler;
CDUnknownBlockType _runningMessageHandler;
CDUnknownBlockType _appDidLaunchMessageHandler;
CDUnknownBlockType _appDidQuitMessageHandler;
CDUnknownBlockType _appPIDExitedMessageHandler;
CDUnknownBlockType _toolDidLaunchMessageHandler;
}
+ (id)messengerForSession:(id)arg1 withConnection:(id)arg2;
+ (id)messengerForSession:(id)arg1;
@property(copy, nonatomic) CDUnknownBlockType toolDidLaunchMessageHandler; // @synthesize toolDidLaunchMessageHandler=_toolDidLaunchMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType appPIDExitedMessageHandler; // @synthesize appPIDExitedMessageHandler=_appPIDExitedMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType appDidQuitMessageHandler; // @synthesize appDidQuitMessageHandler=_appDidQuitMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType appDidLaunchMessageHandler; // @synthesize appDidLaunchMessageHandler=_appDidLaunchMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType runningMessageHandler; // @synthesize runningMessageHandler=_runningMessageHandler;
@property(copy, nonatomic) CDUnknownBlockType readyMessageHandler; // @synthesize readyMessageHandler=_readyMessageHandler;
@property(readonly) DTiPhoneSimulatorSession *session; // @synthesize session=_session;
- (void)doUbiquityFetchEvent;
- (void)doFetchEventForPID:(int)arg1;
- (void)backgroundAllApps:(int)arg1;
- (void)startSimulatorToolSessionWithParameters:(id)arg1;
- (void)stopSimulatingLocation;
- (void)startSimulatingLocationWithLatitude:(id)arg1 longitute:(id)arg2;
- (void)endSimulatorSessionWithPID:(int)arg1;
- (void)startSimulatorSessionWithRequestInfo:(id)arg1;
- (void)clearAllMessageHandlers;
- (void)waitPID:(int)arg1 withAppPIDExitedMessagedHandler:(CDUnknownBlockType)arg2;
- (void)disconnectFromService;
- (BOOL)connectToServiceWithSessionOnLaunch:(BOOL)arg1 simulatorPID:(int *)arg2 error:(id *)arg3;
- (id)initWithSession:(id)arg1;
@end
@interface DVTiPhoneSimulatorLocalMessenger : DVTiPhoneSimulatorMessenger
{
BOOL _appTerminationMessageSent;
NSObject<OS_dispatch_source> *_pidDispatchSource;
DVTTask *_simTask;
}
- (void)doUbiquityFetchEvent;
- (void)doFetchEventForPID:(int)arg1;
- (void)backgroundAllApps:(int)arg1;
- (void)_handleSimulatorToolDidLaunchMessage:(id)arg1;
- (void)setToolDidLaunchMessageHandler:(CDUnknownBlockType)arg1;
- (void)waitPID:(int)arg1 withAppPIDExitedMessagedHandler:(CDUnknownBlockType)arg2;
- (void)_handleSimulatorAppDidQuitMessage:(id)arg1;
- (void)setAppDidQuitMessageHandler:(CDUnknownBlockType)arg1;
- (void)_handleSimulatorAppDidLaunchMessage:(id)arg1;
- (void)setAppDidLaunchMessageHandler:(CDUnknownBlockType)arg1;
- (void)_handleSimulatorRunningMessage:(id)arg1;
- (void)setRunningMessageHandler:(CDUnknownBlockType)arg1;
- (void)_handleSimulatorReadyMessage:(id)arg1;
- (void)setReadyMessageHandler:(CDUnknownBlockType)arg1;
- (void)startSimulatorToolSessionWithParameters:(id)arg1;
- (void)stopSimulatingLocation;
- (void)startSimulatingLocationWithLatitude:(id)arg1 longitute:(id)arg2;
- (void)endSimulatorSessionWithPID:(int)arg1;
- (void)startSimulatorSessionWithRequestInfo:(id)arg1;
- (void)clearAllMessageHandlers;
- (void)disconnectFromService;
- (BOOL)connectToServiceWithSessionOnLaunch:(BOOL)arg1 simulatorPID:(int *)arg2 error:(id *)arg3;
- (void)_enableObserver:(BOOL)arg1 forName:(id)arg2 selector:(SEL)arg3;
@end
@interface DVTiPhoneSimulatorRemoteMessenger : DVTiPhoneSimulatorMessenger
{
unsigned long long _commandTag;
NSObject<OS_dispatch_queue> *_responseQueue;
DVTDispatchLock *_awaitingLock;
NSMutableDictionary *_awaitingSemaphores;
NSMutableDictionary *_awaitingResponses;
NSMutableSet *_waitingAppPIDs;
DVTConfinementServiceConnection *_connection;
}
@property(readonly) DVTConfinementServiceConnection *connection; // @synthesize connection=_connection;
- (void)handleNotificationResponse:(id)arg1;
- (void)waitPID:(int)arg1 withAppPIDExitedMessagedHandler:(CDUnknownBlockType)arg2;
- (void)startSimulatorToolSessionWithParameters:(id)arg1;
- (void)stopSimulatingLocation;
- (void)startSimulatingLocationWithLatitude:(id)arg1 longitute:(id)arg2;
- (void)endSimulatorSessionWithPID:(int)arg1;
- (void)startSimulatorSessionWithRequestInfo:(id)arg1;
- (void)disconnectFromService;
- (BOOL)connectToServiceWithSessionOnLaunch:(BOOL)arg1 simulatorPID:(int *)arg2 error:(id *)arg3;
- (BOOL)sendTaggedRequest:(id)arg1 awaitingResponse:(id *)arg2 error:(id *)arg3;
- (id)nextCommandTag;
- (id)awaitResponseWithTag:(id)arg1 error:(id *)arg2;
- (void)enqueueResponse:(id)arg1 withTag:(id)arg2 error:(id)arg3;
- (BOOL)sendRequest:(id)arg1 withTag:(id)arg2 error:(id *)arg3;
- (id)initWithSession:(id)arg1 connection:(id)arg2;
@end
@interface DTiPhoneSimulatorSession : NSObject
{
int _simulatedApplicationPID;
int _simulatorPID;
NSString *_uuid;
id <DTiPhoneSimulatorSessionDelegate> _delegate;
NSString *_simulatedAppPath;
long long _sessionLifecycleProgress;
NSTimer *_timeoutTimer;
DTiPhoneSimulatorSessionConfig *_sessionConfig;
DVTiPhoneSimulatorMessenger *_messenger;
}
@property(retain) DVTiPhoneSimulatorMessenger *messenger; // @synthesize messenger=_messenger;
@property(copy, nonatomic) DTiPhoneSimulatorSessionConfig *sessionConfig; // @synthesize sessionConfig=_sessionConfig;
@property(retain, nonatomic) NSTimer *timeoutTimer; // @synthesize timeoutTimer=_timeoutTimer;
@property(nonatomic) long long sessionLifecycleProgress; // @synthesize sessionLifecycleProgress=_sessionLifecycleProgress;
@property int simulatorPID; // @synthesize simulatorPID=_simulatorPID;
@property(copy) NSString *simulatedAppPath; // @synthesize simulatedAppPath=_simulatedAppPath;
@property int simulatedApplicationPID; // @synthesize simulatedApplicationPID=_simulatedApplicationPID;
@property(retain, nonatomic) id <DTiPhoneSimulatorSessionDelegate> delegate; // @synthesize delegate=_delegate;
@property(copy, nonatomic) NSString *uuid; // @synthesize uuid=_uuid;
- (void)doUbiquityFetchEvent;
- (void)doFetchEventForPID:(int)arg1;
- (void)backgroundAllApps:(int)arg1;
- (id)_invalidConfigError;
- (void)_endSimulatorSession;
- (void)_callDelegateResponseFromSessionEndedInfo:(id)arg1;
- (void)_callDelegateResponseFromSessionStartedInfo:(id)arg1;
- (id)_sessionStartRequestInfoFromConfig:(id)arg1 withError:(id *)arg2;
- (BOOL)_startToolSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_startApplicationSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_startBasicSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_startSessionInSimulatorWithError:(id *)arg1;
- (BOOL)_handleSessionEndedInSimulator:(id)arg1 notification:(id)arg2;
- (void)_handleSessionStartedWithSim:(id)arg1;
- (void)_handleSessionStartedInSimulator:(id)arg1;
- (void)_handleSimulatorReadyMessage:(id)arg1;
- (void)_timeoutElapsed:(id)arg1;
- (BOOL)attachedToTargetWithConfig:(id)arg1 error:(id *)arg2;
- (void)stopLocationSimulation;
- (void)simulateLocationWithLatitude:(id)arg1 longitude:(id)arg2;
- (void)requestEndWithTimeout:(double)arg1;
- (BOOL)requestStartWithConfig:(id)arg1 timeout:(double)arg2 error:(id *)arg3;
- (BOOL)_setUpSimulatorMessengerWithConfig:(id)arg1 error:(id *)arg2;
- (id)description;
- (void)dealloc;
- (id)init;
@end
@interface DTiPhoneSimulatorSessionConfig : NSObject <NSCopying>
{
BOOL _launchForBackgroundFetch;
BOOL _simulatedApplicationShouldWaitForDebugger;
NSString *_localizedClientName;
DTiPhoneSimulatorSystemRoot *_simulatedSystemRoot;
NSString *_simulatedDeviceInfoName;
NSNumber *_simulatedDeviceFamily;
NSString *_simulatedArchitecture;
NSNumber *_simulatedDisplayHeight;
NSNumber *_simulatedDisplayScale;
DTiPhoneSimulatorApplicationSpecifier *_applicationToSimulateOnStart;
NSNumber *_pid;
NSArray *_simulatedApplicationLaunchArgs;
NSDictionary *_simulatedApplicationLaunchEnvironment;
NSString *_simulatedApplicationStdOutPath;
NSString *_simulatedApplicationStdErrPath;
NSFileHandle *_stdinFileHandle;
NSFileHandle *_stdoutFileHandle;
NSFileHandle *_stderrFileHandle;
id _confinementService;
}
+ (id)displayNameForDeviceFamily:(id)arg1;
@property(retain) id confinementService; // @synthesize confinementService=_confinementService;
@property(retain) NSFileHandle *stderrFileHandle; // @synthesize stderrFileHandle=_stderrFileHandle;
@property(retain) NSFileHandle *stdoutFileHandle; // @synthesize stdoutFileHandle=_stdoutFileHandle;
@property(retain) NSFileHandle *stdinFileHandle; // @synthesize stdinFileHandle=_stdinFileHandle;
@property(copy) NSString *simulatedApplicationStdErrPath; // @synthesize simulatedApplicationStdErrPath=_simulatedApplicationStdErrPath;
@property(copy) NSString *simulatedApplicationStdOutPath; // @synthesize simulatedApplicationStdOutPath=_simulatedApplicationStdOutPath;
@property BOOL simulatedApplicationShouldWaitForDebugger; // @synthesize simulatedApplicationShouldWaitForDebugger=_simulatedApplicationShouldWaitForDebugger;
@property(copy) NSDictionary *simulatedApplicationLaunchEnvironment; // @synthesize simulatedApplicationLaunchEnvironment=_simulatedApplicationLaunchEnvironment;
@property(copy) NSArray *simulatedApplicationLaunchArgs; // @synthesize simulatedApplicationLaunchArgs=_simulatedApplicationLaunchArgs;
@property(copy) NSNumber *pid; // @synthesize pid=_pid;
@property(copy) DTiPhoneSimulatorApplicationSpecifier *applicationToSimulateOnStart; // @synthesize applicationToSimulateOnStart=_applicationToSimulateOnStart;
@property(copy) NSNumber *simulatedDisplayScale; // @synthesize simulatedDisplayScale=_simulatedDisplayScale;
@property(copy) NSNumber *simulatedDisplayHeight; // @synthesize simulatedDisplayHeight=_simulatedDisplayHeight;
@property(copy) NSString *simulatedArchitecture; // @synthesize simulatedArchitecture=_simulatedArchitecture;
@property(copy) NSNumber *simulatedDeviceFamily; // @synthesize simulatedDeviceFamily=_simulatedDeviceFamily;
@property(retain) NSString *simulatedDeviceInfoName; // @synthesize simulatedDeviceInfoName=_simulatedDeviceInfoName;
@property(copy) DTiPhoneSimulatorSystemRoot *simulatedSystemRoot; // @synthesize simulatedSystemRoot=_simulatedSystemRoot;
@property(copy) NSString *localizedClientName; // @synthesize localizedClientName=_localizedClientName;
@property BOOL launchForBackgroundFetch; // @synthesize launchForBackgroundFetch=_launchForBackgroundFetch;
- (id)description;
- (id)copyWithZone:(struct _NSZone *)arg1;
- (id)init;
@end
@interface DTiPhoneSimulatorSystemRoot : NSObject <NSCopying>
{
NSString *sdkRootPath;
NSString *sdkVersion;
NSString *sdkDisplayName;
}
+ (id)rootWithSDKVersion:(id)arg1;
+ (id)rootWithSDKPath:(id)arg1;
+ (id)defaultRoot;
+ (id)knownRoots;
+ (void)initialize;
@property(copy) NSString *sdkDisplayName; // @synthesize sdkDisplayName;
@property(copy) NSString *sdkVersion; // @synthesize sdkVersion;
@property(copy) NSString *sdkRootPath; // @synthesize sdkRootPath;
- (id)description;
- (long long)compare:(id)arg1;
- (id)copyWithZone:(struct _NSZone *)arg1;
- (BOOL)isEqual:(id)arg1;
- (id)initWithSDKPath:(id)arg1;
@end
@interface DTiPhoneSimulatorApplicationSpecifier : NSObject <NSCopying>
{
NSString *appPath;
NSString *bundleID;
NSString *toolPath;
}
+ (id)specifierWithToolPath:(id)arg1;
+ (id)specifierWithApplicationBundleIdentifier:(id)arg1;
+ (id)specifierWithApplicationPath:(id)arg1;
@property(copy, nonatomic) NSString *toolPath; // @synthesize toolPath;
@property(copy, nonatomic) NSString *bundleID; // @synthesize bundleID;
@property(copy, nonatomic) NSString *appPath; // @synthesize appPath;
- (id)description;
- (id)copyWithZone:(struct _NSZone *)arg1;
@end

View File

@@ -1,7 +1,8 @@
CONFIG += console CONFIG += console
QT += core QT -= core
QT += gui QT -= gui
QT -= test
CONFIG -= app_bundle CONFIG -= app_bundle
@@ -25,14 +26,11 @@ iPhoneSimulatorRemoteClientDirectLinking {
LIBS += \ LIBS += \
-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \ -F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
-F/Applications/Xcode.app/Contents/OtherFrameworks -F/Applications/Xcode.app/Contents/OtherFrameworks
QMAKE_LFLAGS += -Wl,-rpath,/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
-Wl,-rpath,/Applications/Xcode.app/Contents/OtherFrameworks \
LIBS += \ LIBS += \
-framework iPhoneSimulatorRemoteClient -framework DTViPhoneSimulatorRemoteClient
QMAKE_RPATHDIR += /Applications/Xcode5-DP5.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \ QMAKE_RPATHDIR += /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
/Applications/Xcode.app/Contents/OtherFrameworks /Applications/Xcode.app/Contents/OtherFrameworks \
/System/Library/PrivateFrameworks \ /System/Library/PrivateFrameworks
} }
TEMPLATE = app TEMPLATE = app
@@ -52,6 +50,7 @@ HEADERS += \
nsprintf.h \ nsprintf.h \
nsstringexpandpath.h \ nsstringexpandpath.h \
version.h \ version.h \
iphonesimulatorremoteclient/iphonesimulatorremoteclient.h dvtiphonesimulatorremoteclient/dvtiphonesimulatorremoteclient.h
OTHER_FILES = LICENSE OTHER_FILES = IOSSIM_LICENSE \
Info.plist

View File

@@ -6,7 +6,7 @@
*/ */
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "iphonesimulatorremoteclient/iphonesimulatorremoteclient.h" #import <dvtiphonesimulatorremoteclient/dvtiphonesimulatorremoteclient.h>
#import "version.h" #import "version.h"
@interface iPhoneSimulator : NSObject <DTiPhoneSimulatorSessionDelegate> { @interface iPhoneSimulator : NSObject <DTiPhoneSimulatorSessionDelegate> {
@@ -14,8 +14,7 @@
DTiPhoneSimulatorSystemRoot *sdkRoot; DTiPhoneSimulatorSystemRoot *sdkRoot;
NSFileHandle *stdoutFileHandle; NSFileHandle *stdoutFileHandle;
NSFileHandle *stderrFileHandle; NSFileHandle *stderrFileHandle;
DTiPhoneSimulatorSession *session; DTiPhoneSimulatorSession *mySession;
NSTimer *pidCheckingTimer;
BOOL startOnly; BOOL startOnly;
BOOL exitOnStartup; BOOL exitOnStartup;
BOOL shouldWaitDebugger; BOOL shouldWaitDebugger;
@@ -34,8 +33,7 @@
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path; - (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path;
- (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path; - (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path;
- (void)stop; - (void)stop;
- (void)checkPid:(NSTimer *)timer;
- (void)doExit:(int)errorCode; - (void)doExit:(int)errorCode;
- (void)changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice; - (NSString*)changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice;
@end @end

View File

@@ -10,8 +10,9 @@
#import "nsprintf.h" #import "nsprintf.h"
#import <sys/types.h> #import <sys/types.h>
#import <sys/stat.h> #import <sys/stat.h>
#import <objc/runtime.h> #import <Foundation/NSTask.h>
#import <AppKit/NSRunningApplication.h> #import <Foundation/NSFileManager.h>
@class DTiPhoneSimulatorSystemRoot;
NSString *simulatorPrefrencesName = @"com.apple.iphonesimulator"; NSString *simulatorPrefrencesName = @"com.apple.iphonesimulator";
NSString *deviceProperty = @"SimulateDevice"; NSString *deviceProperty = @"SimulateDevice";
@@ -21,6 +22,18 @@ NSString *deviceIphone = @"iPhone";
NSString *deviceIpad = @"iPad"; NSString *deviceIpad = @"iPad";
NSString *deviceIpadRetina = @"iPad (Retina)"; NSString *deviceIpadRetina = @"iPad (Retina)";
// The path within the developer dir of the private Simulator frameworks.
NSString* const kSimulatorFrameworkRelativePath = @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTiPhoneSimulatorRemoteClient.framework";
NSString* const kDVTFoundationRelativePath = @"../SharedFrameworks/DVTFoundation.framework";
NSString* const kDevToolsFoundationRelativePath = @"../OtherFrameworks/DevToolsFoundation.framework";
//NSString* const kSimulatorRelativePath = @"Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app";
static const char *gDevDir = 0;
@interface DVTPlatform : NSObject
+ (BOOL)loadAllPlatformsReturningError:(id*)arg1;
@end
/** /**
* A simple iPhoneSimulatorRemoteClient framework. * A simple iPhoneSimulatorRemoteClient framework.
*/ */
@@ -28,14 +41,12 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
- (id)init { - (id)init {
self = [super init]; self = [super init];
session = nil; mySession = nil;
pidCheckingTimer = nil;
return self; return self;
} }
- (void)dealloc { - (void)dealloc {
[session release]; [mySession release];
[pidCheckingTimer release];
[super dealloc]; [super dealloc];
} }
@@ -47,8 +58,88 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
exit(errorCode); exit(errorCode);
} }
// Helper to find a class by name and die if it isn't found.
-(Class) FindClassByName:(NSString*) nameOfClass {
Class theClass = NSClassFromString(nameOfClass);
if (!theClass) {
nsfprintf(stderr,@"Failed to find class %@ at runtime.", nameOfClass);
[self doExit:EXIT_FAILURE];
}
return theClass;
}
// Loads the Simulator framework from the given developer dir.
-(void) 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* dvtFoundationPath = [developerDir stringByAppendingPathComponent:kDVTFoundationRelativePath];
NSBundle* dvtFoundationBundle =
[NSBundle bundleWithPath:dvtFoundationPath];
if (![dvtFoundationBundle load]){
nsprintf(@"Unable to dvtFoundationBundle. Error: ");
[self doExit:EXIT_FAILURE];
return ;
}
NSString* devToolsFoundationPath = [developerDir stringByAppendingPathComponent:kDevToolsFoundationRelativePath];
NSBundle* devToolsFoundationBundle =
[NSBundle bundleWithPath:devToolsFoundationPath];
if (![devToolsFoundationBundle load]){
nsprintf(@"Unable to devToolsFoundationPath. Error: ");
return ;
}
// Prime DVTPlatform.
NSError* error;
Class DVTPlatformClass = [self FindClassByName:@"DVTPlatform"];
if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) {
nsprintf(@"Unable to loadAllPlatformsReturningError. Error: %@",[error localizedDescription]);
return ;
}
NSString* simBundlePath = [developerDir stringByAppendingPathComponent:kSimulatorFrameworkRelativePath];
NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath];
if (![simBundle load]){
nsprintf(@"Unable to load simulator framework. Error: %@",[error localizedDescription]);
return ;
}
return ;
}
// Finds the developer dir via xcode-select or the DEVELOPER_DIR environment
// variable.
NSString* FindDeveloperDir() {
if (gDevDir)
return [NSString stringWithCString:gDevDir encoding:NSUTF8StringEncoding];
// 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;
}
- (void) printUsage { - (void) printUsage {
fprintf(stdout, "<msg>Usage: iossim <command> <options> [--args ...]\n"); fprintf(stdout, "<msg>Usage: ios-sim <command> <options> [--args ...]\n");
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, "Commands:\n"); fprintf(stdout, "Commands:\n");
fprintf(stdout, " showsdks List the available iOS SDK versions\n"); fprintf(stdout, " showsdks List the available iOS SDK versions\n");
@@ -80,61 +171,60 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
- (int) showSDKs { - (int) showSDKs {
NSUInteger i; Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"];
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot");
if (tClass == nil) { NSArray *roots = [systemRootClass knownRoots];
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
return EXIT_FAILURE;
}
NSArray *roots = [tClass knownRoots];
nsprintf(@"<device_info>"); nsprintf(@"<device_info>");
for (i = 0; i < [roots count]; ++i) { for (NSUInteger i = 0; i < [roots count]; ++i) {
DTiPhoneSimulatorSystemRoot *root = [roots objectAtIndex:i]; DTiPhoneSimulatorSystemRoot *root = [roots objectAtIndex:i];
nsprintf(@"<item><key>sdk%d_name</key><value>%@</value></item>", i, [root sdkDisplayName]); nsprintf(@"<item><key>sdk%d_name</key><value>%@</value></item>", i, [root sdkDisplayName]);
nsprintf(@"<item><key>sdk%d_version</key><value>%@</value></item>", i, [root sdkVersion]); nsprintf(@"<item><key>sdk%d_version</key><value>%@</value></item>", i, [root sdkVersion]);
nsprintf(@"<item><key>sdk%d_sysroot</key><value>%@</value></item>", i, [root sdkRootPath]); nsprintf(@"<item><key>sdk%d_sysroot</key><value>%@</value></item>", i, [root sdkRootPath]);
} }
nsprintf(@"</device_info>"); nsprintf(@"</device_info>");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
- (void)session:(DTiPhoneSimulatorSession *)mySession didEndWithError:(NSError *)error { - (void)session:(DTiPhoneSimulatorSession *)session didEndWithError:(NSError *)error {
if (verbose) { if (verbose) {
nsprintf(@"<msg>Session did end with error %@</msg>", error); nsprintf(@"<msg>Session did end with error %@</msg>", error);
} }
if (stderrFileHandle != nil) { if (stderrFileHandle != nil) {
NSString *stderrPath = [[mySession sessionConfig] simulatedApplicationStdErrPath]; NSString *stderrPath = [[session sessionConfig] simulatedApplicationStdErrPath];
[self removeStdioFIFO:stderrFileHandle atPath:stderrPath]; [self removeStdioFIFO:stderrFileHandle atPath:stderrPath];
} }
if (stdoutFileHandle != nil) { if (stdoutFileHandle != nil) {
NSString *stdoutPath = [[mySession sessionConfig] simulatedApplicationStdOutPath]; NSString *stdoutPath = [[session sessionConfig] simulatedApplicationStdOutPath];
[self removeStdioFIFO:stdoutFileHandle atPath:stdoutPath]; [self removeStdioFIFO:stdoutFileHandle atPath:stdoutPath];
} }
if (error != nil) if (error != nil) {
[self doExit:EXIT_FAILURE]; [self doExit:EXIT_FAILURE];
else }
[self doExit:EXIT_SUCCESS];
[self doExit:EXIT_SUCCESS];
} }
- (void)session:(DTiPhoneSimulatorSession *)mySession didStart:(BOOL)started withError:(NSError *)error { - (void)session:(DTiPhoneSimulatorSession *)session didStart:(BOOL)started withError:(NSError *)error {
if (startOnly && mySession) { if (startOnly && session) {
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript" [NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript"
arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]]; arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]];
nsprintf(@"<msg>Simulator started (no session)</msg>"); nsprintf(@"<msg>Simulator started (no session)</msg>");
[self doExit:EXIT_SUCCESS]; [self doExit:EXIT_SUCCESS];
return; return;
} }
if (started) { if (started) {
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript" [NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript"
arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]]; arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]];
int pid = [session simulatedApplicationPID];
if (shouldStartDebugger) { if (shouldStartDebugger) {
char*args[4] = { NULL, NULL, (char*)[[[mySession simulatedApplicationPID] description] UTF8String], NULL }; char*args[4] = { NULL, NULL, (char*)[[[NSNumber numberWithInt:pid] description] UTF8String], NULL };
if (useGDB) { if (useGDB) {
args[0] = strdup("gdb"); args[0] = strdup("gdb");
args[1] = strdup("program"); args[1] = strdup("program");
@@ -156,35 +246,23 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
if (verbose) { if (verbose) {
nsprintf(@"<msg>Session started</msg>"); nsprintf(@"<msg>Session started</msg>");
} }
nsprintf(@"<inferior_pid>%@</inferior_pid>", [session simulatedApplicationPID]); nsprintf(@"<inferior_pid>%d</inferior_pid>", pid);
fflush(stdout); fflush(stdout);
if (exitOnStartup) { if (exitOnStartup) {
[self doExit:EXIT_SUCCESS]; [self doExit:EXIT_SUCCESS];
return; return;
} }
pidCheckingTimer = [[NSTimer scheduledTimerWithTimeInterval:5.0 target:self
selector:@selector(checkPid:) userInfo:nil repeats: TRUE] retain];
} else { } else {
nsprintf(@"<msg>Session could not be started: %@</msg>", error); nsprintf(@"<msg>Session could not be started: %@</msg>", error);
[self doExit:EXIT_FAILURE]; [self doExit:EXIT_FAILURE];
} }
} }
- (void)stop { - (void)stop {
if (session) if (mySession)
[session requestEndWithTimeout: 0.1]; [mySession requestEndWithTimeout: 0.1];
} }
- (void)checkPid:(NSTimer *)timer {
(void)timer;
if (session && [[session simulatedApplicationPID]intValue] > 0) {
if (kill((pid_t)[[session simulatedApplicationPID]intValue], 0) == -1) {
nsprintf(@"<msg>app stopped</msg>");
[self doExit:EXIT_SUCCESS];
return;
}
}
}
- (void)stdioDataIsAvailable:(NSNotification *)notification { - (void)stdioDataIsAvailable:(NSNotification *)notification {
[[notification object] readInBackgroundAndNotify]; [[notification object] readInBackgroundAndNotify];
NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem]; NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
@@ -208,7 +286,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path { - (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path {
*path = [NSString stringWithFormat:@"%@/ios-sim-%@-pipe-%d", NSTemporaryDirectory(), type, (int)time(NULL)]; *path = [NSString stringWithFormat:@"%@/ios-sim-%@-pipe-%d", NSTemporaryDirectory(), type, (int)time(NULL)];
if (mkfifo([*path UTF8String], S_IRUSR | S_IWUSR) == -1) { if (mkfifo([*path UTF8String], S_IRUSR | S_IWUSR) == -1) {
nsprintf(@"<msg>Unable to create %@ named pipe `%@'</msg>", type, *path); nsprintf(@"<msg>Unable to create %@ named pipe `%@</msg>'", type, *path);
[self doExit:EXIT_FAILURE]; [self doExit:EXIT_FAILURE];
} else { } else {
if (verbose) { if (verbose) {
@@ -246,33 +324,27 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
args:(NSArray *)args { args:(NSArray *)args {
DTiPhoneSimulatorApplicationSpecifier *appSpec; DTiPhoneSimulatorApplicationSpecifier *appSpec;
DTiPhoneSimulatorSessionConfig *config; DTiPhoneSimulatorSessionConfig *config;
NSError *error = 0; DTiPhoneSimulatorSession *session;
id tClass; NSError *error;
NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
if (!startOnly && ![fileManager fileExistsAtPath:path]) { if (!startOnly && ![fileManager fileExistsAtPath:path]) {
nsprintf(@"<msg>Application path %@ doesn't exist!</msg>", path); nsprintf(@"<msg>Application path %@ doesn't exist!</msg>", path);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Create the app specifier */ /* Create the app specifier */
tClass = objc_getClass("DTiPhoneSimulatorApplicationSpecifier"); appSpec = startOnly ? nil : [[self FindClassByName:@"DTiPhoneSimulatorApplicationSpecifier"] specifierWithApplicationPath:path];
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorApplicationSpecifier class is nil.</msg>");
return EXIT_FAILURE;
}
appSpec = startOnly ? nil : [tClass specifierWithApplicationPath:path];
if (verbose) { if (verbose) {
nsprintf(@"<msg>App Spec: %@</msg>", appSpec); nsprintf(@"<msg>App Spec: %@</msg>", appSpec);
nsprintf(@"SDK Root: %@", sdkRoot); nsprintf(@"<msg>SDK Root: %@</msg>", sdkRoot);
for (id key in environment) { for (id key in environment) {
nsprintf(@"<msg>Env: %@ = %@</msg>", key, [environment objectForKey:key]); nsprintf(@"<msg>Env: %@ = %@</msg>", key, [environment objectForKey:key]);
} }
} }
NSString *sdkVersion = [sdkRoot sdkVersion]; NSString *sdkVersion = [sdkRoot sdkVersion];
NSString *appSupportDir = [NSString stringWithFormat:@"%@/Library/Application Support/iPhone Simulator/%@", NSString *appSupportDir = [NSString stringWithFormat:@"%@/Library/Application Support/iPhone Simulator/%@",
NSHomeDirectory(), sdkVersion]; NSHomeDirectory(), sdkVersion];
@@ -288,12 +360,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
environment = mutableEnv; environment = mutableEnv;
/* Set up the session configuration */ /* Set up the session configuration */
tClass = objc_getClass("DTiPhoneSimulatorSessionConfig"); config = [[[[self FindClassByName:@"DTiPhoneSimulatorSessionConfig"] alloc] init] autorelease];
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorApplicationSpecifier class is nil.</msg>");
return EXIT_FAILURE;
}
config = [[[tClass alloc] init] autorelease];
[config setApplicationToSimulateOnStart:appSpec]; [config setApplicationToSimulateOnStart:appSpec];
[config setSimulatedSystemRoot:sdkRoot]; [config setSimulatedSystemRoot:sdkRoot];
[config setSimulatedApplicationShouldWaitForDebugger:shouldWaitDebugger]; [config setSimulatedApplicationShouldWaitForDebugger:shouldWaitDebugger];
@@ -333,16 +400,13 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
[config setSimulatedDeviceFamily:[NSNumber numberWithInt:1]]; [config setSimulatedDeviceFamily:[NSNumber numberWithInt:1]];
} }
} }
[self changeDeviceType:family retina:retinaDevice isTallDevice:tallDevice]; NSString* devicePropertyValue = [self changeDeviceType:family retina:retinaDevice isTallDevice:tallDevice];
[config setSimulatedDeviceInfoName:devicePropertyValue];
/* Start the session */ /* Start the session */
tClass = objc_getClass("DTiPhoneSimulatorSession"); session = [[[[self FindClassByName:@"DTiPhoneSimulatorSession"] alloc] init] autorelease];
if (tClass == nil) { mySession = session;
nsprintf(@"<msg>DTiPhoneSimulatorSession class is nil.</msg>");
return EXIT_FAILURE;
}
session = [[tClass alloc] init];
[session setDelegate:self]; [session setDelegate:self];
if (uuid != nil){ if (uuid != nil){
[session setUuid:uuid]; [session setUuid:uuid];
@@ -356,7 +420,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
- (void) changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice { - (NSString*) changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice {
NSString *devicePropertyValue; NSString *devicePropertyValue;
if (retina) { if (retina) {
if (verbose) { if (verbose) {
@@ -381,6 +445,8 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
} }
CFPreferencesSetAppValue((CFStringRef)deviceProperty, (CFPropertyListRef)devicePropertyValue, (CFStringRef)simulatorPrefrencesName); CFPreferencesSetAppValue((CFStringRef)deviceProperty, (CFPropertyListRef)devicePropertyValue, (CFStringRef)simulatorPrefrencesName);
CFPreferencesAppSynchronize((CFStringRef)simulatorPrefrencesName); CFPreferencesAppSynchronize((CFStringRef)simulatorPrefrencesName);
return devicePropertyValue;
} }
@@ -398,17 +464,41 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
exitOnStartup = NO; exitOnStartup = NO;
alreadyPrintedData = NO; alreadyPrintedData = NO;
startOnly = strcmp(argv[1], "start") == 0; startOnly = strcmp(argv[1], "start") == 0;
nsprintf(@"<query_result>");
nsprintf(@"<query_result>");
for (int i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--developer-path") == 0) {
++i;
if (i < argc)
gDevDir = argv[i];
}
}
NSString* developerDir = FindDeveloperDir();
if (!developerDir) {
nsprintf(@"Unable to find developer directory.");
exit(EXIT_FAILURE);
}
NSString* dvtFoundationPath = [developerDir stringByAppendingPathComponent:kDVTFoundationRelativePath];
if (![[NSFileManager defaultManager] fileExistsAtPath:dvtFoundationPath]) {
// execute old version
char *argNew = new char[strlen(argv[0] + 7)];
strcpy(argNew, argv[0]);
strcat(argNew, "_1_8_2");
char **argvNew = new char *[argc + 1];
argvNew[0] = argNew;
for (int iarg = 1; iarg < argc; ++iarg)
argvNew[iarg] = argv[iarg];
argvNew[argc] = 0;
execv(argNew, argvNew);
}
if (strcmp(argv[1], "showsdks") == 0) { if (strcmp(argv[1], "showsdks") == 0) {
[self doExit:[self showSDKs]]; [self LoadSimulatorFramework:developerDir];
return; exit([self showSDKs]);
} else if (strcmp(argv[1], "launch") == 0 || startOnly) { } else if (strcmp(argv[1], "launch") == 0 || startOnly) {
if (strcmp(argv[1], "launch") == 0 && argc < 3) { if (strcmp(argv[1], "launch") == 0 && argc < 3) {
nsprintf(@"<msg>Missing application path argument</msg>"); nsprintf(@"<msg>Missing application path argument</msg>");
[self printUsage]; [self printUsage];
[self doExit:EXIT_FAILURE]; exit(EXIT_FAILURE);
return;
} }
NSString *appPath = nil; NSString *appPath = nil;
@@ -425,6 +515,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
NSString *uuid = nil; NSString *uuid = nil;
NSString *stdoutPath = nil; NSString *stdoutPath = nil;
NSString *stderrPath = nil; NSString *stderrPath = nil;
NSString *xctest = nil;
NSTimeInterval timeout = 30; NSTimeInterval timeout = 30;
NSMutableDictionary *environment = [NSMutableDictionary dictionary]; NSMutableDictionary *environment = [NSMutableDictionary dictionary];
@@ -452,20 +543,15 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
} else if (strcmp(argv[i], "--timeout") == 0) { } else if (strcmp(argv[i], "--timeout") == 0) {
if (i + 1 < argc) { if (i + 1 < argc) {
timeout = [[NSString stringWithUTF8String:argv[++i]] doubleValue]; timeout = [[NSString stringWithUTF8String:argv[++i]] doubleValue];
NSLog(@"<msg>Timeout: %f second(s)</msg>", timeout); NSLog(@"Timeout: %f second(s)", timeout);
} }
} }
else if (strcmp(argv[i], "--sdk") == 0) { else if (strcmp(argv[i], "--sdk") == 0) {
i++; i++;
[self LoadSimulatorFramework:developerDir];
NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]; NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding];
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot"); Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"];
NSArray *roots; NSArray *roots = [systemRootClass knownRoots];
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
[self doExit:EXIT_FAILURE];
return;
}
roots = [tClass knownRoots];
for (DTiPhoneSimulatorSystemRoot *root in roots) { for (DTiPhoneSimulatorSystemRoot *root in roots) {
NSString *v = [root sdkVersion]; NSString *v = [root sdkVersion];
if ([v isEqualToString:ver]) { if ([v isEqualToString:ver]) {
@@ -491,7 +577,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
} else if (strcmp(argv[i], "--env") == 0) { } else if (strcmp(argv[i], "--env") == 0) {
i++; i++;
NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath]; NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath];
environment = [NSDictionary dictionaryWithContentsOfFile:envFilePath]; [environment setValuesForKeysWithDictionary:[NSDictionary dictionaryWithContentsOfFile:envFilePath]];
if (!environment) { if (!environment) {
fprintf(stdout, "<msg>Could not read environment from file: %s</msg>\n", argv[i]); fprintf(stdout, "<msg>Could not read environment from file: %s</msg>\n", argv[i]);
[self printUsage]; [self printUsage];
@@ -502,9 +588,13 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"stdoutPath: %@", stdoutPath); NSLog(@"stdoutPath: %@", stdoutPath);
} else if (strcmp(argv[i], "--stderr") == 0) { } else if (strcmp(argv[i], "--stderr") == 0) {
i++; i++;
stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath]; stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"stderrPath: %@", stderrPath); NSLog(@"stderrPath: %@", stderrPath);
} else if (strcmp(argv[i], "--xctest") == 0) {
i++;
xctest = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"xctest: %@", xctest);
} else if (strcmp(argv[i], "--retina") == 0) { } else if (strcmp(argv[i], "--retina") == 0) {
retinaDevice = YES; retinaDevice = YES;
} else if (strcmp(argv[i], "--tall") == 0) { } else if (strcmp(argv[i], "--tall") == 0) {
@@ -513,7 +603,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
i++; i++;
break; break;
} else { } else {
printf("<msg>unrecognized argument:%s</msg>\n", argv[i]); fprintf(stdout, "<msg>unrecognized argument:%s</msg>\n", argv[i]);
[self printUsage]; [self printUsage];
[self doExit:EXIT_FAILURE]; [self doExit:EXIT_FAILURE];
return; return;
@@ -525,13 +615,19 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
} }
if (sdkRoot == nil) { if (sdkRoot == nil) {
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot"); [self LoadSimulatorFramework:developerDir];
if (tClass == nil) { Class systemRootClass = [self FindClassByName:@"DTiPhoneSimulatorSystemRoot"];
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>"); sdkRoot = [systemRootClass defaultRoot];
[self doExit:EXIT_FAILURE]; }
return; if (xctest) {
} NSString *appName = [appPath lastPathComponent];
sdkRoot = [tClass defaultRoot]; NSString *executableName = [appName stringByDeletingPathExtension];
NSString *injectionPath = @"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection";
[environment setValuesForKeysWithDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
injectionPath,@"DYLD_INSERT_LIBRARIES",
xctest, @"XCInjectBundle",
[appPath stringByAppendingFormat:@"/%@", executableName],@"XCInjectBundleInto",
nil]];
} }
/* Don't exit, adds to runloop */ /* Don't exit, adds to runloop */
@@ -556,7 +652,7 @@ NSString *deviceIpadRetina = @"iPad (Retina)";
printf("%s\n", IOS_SIM_VERSION); printf("%s\n", IOS_SIM_VERSION);
[self doExit:EXIT_SUCCESS]; [self doExit:EXIT_SUCCESS];
} else { } else {
fprintf(stdout, "<msg>Unknown command</msg>\n"); fprintf(stderr, "Unknown command\n");
[self printUsage]; [self printUsage];
[self doExit:EXIT_FAILURE]; [self doExit:EXIT_FAILURE];
} }

View File

@@ -5,69 +5,25 @@
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file. * See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/ */
/* derived from https://github.com/phonegap/ios-sim */ /* derived from https://github.com/phonegap/ios-sim */
#import <AppKit/AppKit.h>
#import "iphonesimulator.h"
#include <QLibrary>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QApplication>
#else
#include <QGuiApplication>
#endif
#include <QString>
#include <QStringList>
/* to do: #import <AppKit/AppKit.h>
* - try to stop inferior when killed (or communicate with creator to allow killing the inferior) #import <Foundation/NSFileManager.h>
* - remove unneeded functionality and streamline a bit
*/ #import "iphonesimulator.h"
/* /*
* Runs the iPhoneSimulator backed by a main runloop. * Runs the iPhoneSimulator backed by a main runloop.
*/ */
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QApplication a(argc, argv);
#else
QGuiApplication a(argc, argv);
#endif
//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QString xcodePath = QLatin1String("/Applications/Xcode.app/Contents/Developer/");
for (int i = 0; i + 1 < argc; ++i) {
if (strcmp(argv[i], "--developer-path") == 0)
xcodePath = QCoreApplication::arguments().at(i+1);
}
if (!xcodePath.endsWith(QLatin1Char('/')))
xcodePath.append(QLatin1Char('/'));
/* manual loading of the private deps */
QStringList deps = QStringList()
<< QLatin1String("/System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols")
<< QLatin1String("/System/Library/PrivateFrameworks/CoreSymbolication.framework/CoreSymbolication")
<< (xcodePath + QLatin1String("../OtherFrameworks/DevToolsFoundation.framework/DevToolsFoundation"));
foreach (const QString &libPath, deps) {
QLibrary *lib = new QLibrary(libPath);
//lib->setLoadHints(QLibrary::ExportExternalSymbolsHint);
if (!lib->load())
printf("<msg>error loading %s</msg>", libPath.toUtf8().constData());
}
QLibrary *libIPhoneSimulatorRemoteClient = new QLibrary(xcodePath
+ QLatin1String("Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/iPhoneSimulatorRemoteClient.framework/iPhoneSimulatorRemoteClient"));
//libIPhoneSimulatorRemoteClient->setLoadHints(QLibrary::ResolveAllSymbolsHint|QLibrary::ExportExternalSymbolsHint);
if (!libIPhoneSimulatorRemoteClient->load())
printf("<msg>error loading iPhoneSimulatorRemoteClient</msg>");
iPhoneSimulator *sim = [[iPhoneSimulator alloc] init]; iPhoneSimulator *sim = [[iPhoneSimulator alloc] init];
/* Execute command line handler */ /* Execute command line handler */
[sim runWithArgc: argc argv: argv]; [sim runWithArgc: argc argv: argv];
/* Run the loop to handle added input sources, if any */ /* Run the loop to handle added input sources, if any */
[[NSRunLoop mainRunLoop] run];
int res = a.exec(); [pool release];
exit(res);
// [pool release];
return 0; return 0;
} }

View File

@@ -24,7 +24,7 @@ int nsfprintf (FILE *stream, NSString *format, ...) {
va_start(ap, format); va_start(ap, format);
{ {
retval = nsvfprintf(stream, format, ap); retval = nsvfprintf(stream, format, ap);
} }
va_end(ap); va_end(ap);
return retval; return retval;
@@ -37,7 +37,7 @@ int nsprintf (NSString *format, ...) {
va_start(ap, format); va_start(ap, format);
{ {
retval = nsvfprintf(stdout, format, ap); retval = nsvfprintf(stdout, format, ap);
} }
va_end(ap); va_end(ap);
return retval; return retval;

View File

@@ -1,5 +1,5 @@
/* /*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file. * See the LICENSE file for the license on the source code in this file.
*/ */
#import "nsstringexpandpath.h" #import "nsstringexpandpath.h"

View File

@@ -1 +1 @@
#define IOS_SIM_VERSION "1.8.2m" #define IOS_SIM_VERSION "1.9.0"

View File

@@ -0,0 +1,31 @@
Author: Landon Fuller <landonf@plausiblelabs.com>
Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
All rights reserved.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Modifications made by the following entities are licensed as above:
- Jeff Haynie, Appcelerator, Inc.
- https://github.com/hborders
- http://pivotallabs.com/users/scoward/blog
- Eloy Duran, Fingertips <eloy@fngtps.com>
- Fawzi Mohamed, digia <fawzi.mohamed@digia.com>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>@TYPEINFO@</string>
<key>CFBundleExecutable</key>
<string>@EXECUTABLE@</string>
<key>CFBundleIdentifier</key>
<string>org.qt-project.qt-creator.iosTool</string>
<key>LSUIElement</key>
<string>1</string>
</dict>
</plist>

View File

@@ -0,0 +1,30 @@
import qbs 1.0
import QtcTool
QtcTool {
name: "iossim"
condition: qbs.targetOS.contains("osx")
Depends { name: "Qt"; submodules: ["widgets"] }
Depends { name: "app_version_header" }
files: [
"main.mm",
"nsprintf.mm",
"nsstringexpandpath.mm",
"iphonesimulator.mm",
"iphonesimulator.h",
"nsprintf.h",
"nsstringexpandpath.h",
"version.h",
"iphonesimulatorremoteclient/iphonesimulatorremoteclient.h"
]
cpp.linkerFlags: base.concat(["-sectcreate", "__TEXT", "__info_plist", path + "/Info.plist",
"-fobjc-link-runtime"])
cpp.frameworks: base.concat(["Foundation", "CoreServices", "ApplicationServices", "IOKit",
"AppKit"])
cpp.frameworkPaths: base.concat("/System/Library/PrivateFrameworks")
toolInstallDir: project.ide_libexec_path + "/ios"
}

View File

@@ -0,0 +1,55 @@
CONFIG += console
QT += core
QT += gui
CONFIG -= app_bundle
include(../../../../qtcreator.pri)
# Prevent from popping up in the dock when launched.
# We embed the Info.plist file, so the application doesn't need to
# be a bundle.
QMAKE_LFLAGS += -sectcreate __TEXT __info_plist \"$$PWD/Info.plist\" \
-fobjc-link-runtime
LIBS += \
-framework Foundation \
-framework CoreServices \
-framework ApplicationServices \
-framework CoreFoundation \
-F/System/Library/PrivateFrameworks \
-framework IOKit -framework AppKit
iPhoneSimulatorRemoteClientDirectLinking {
LIBS += \
-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
-F/Applications/Xcode.app/Contents/OtherFrameworks
LIBS += \
-framework iPhoneSimulatorRemoteClient
QMAKE_RPATHDIR += /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks \
/Applications/Xcode.app/Contents/OtherFrameworks
/System/Library/PrivateFrameworks \
}
TEMPLATE = app
# put into a subdir, so we can deploy a separate qt.conf for it
DESTDIR = $$IDE_LIBEXEC_PATH/ios
include(../../../rpath.pri)
OBJECTIVE_SOURCES += \
main.mm \
nsprintf.mm \
nsstringexpandPath.mm \
iphonesimulator.mm
HEADERS += \
iphonesimulator.h \
nsprintf.h \
nsstringexpandpath.h \
version.h \
iphonesimulatorremoteclient/iphonesimulatorremoteclient.h
OTHER_FILES = IOSSIM_LICENSE \
Info.plist

View File

@@ -0,0 +1,41 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
#import "iphonesimulatorremoteclient/iphonesimulatorremoteclient.h"
#import "version.h"
@interface iPhoneSimulator : NSObject <DTiPhoneSimulatorSessionDelegate> {
@private
DTiPhoneSimulatorSystemRoot *sdkRoot;
NSFileHandle *stdoutFileHandle;
NSFileHandle *stderrFileHandle;
DTiPhoneSimulatorSession *session;
NSTimer *pidCheckingTimer;
BOOL startOnly;
BOOL exitOnStartup;
BOOL shouldWaitDebugger;
BOOL shouldStartDebugger;
BOOL useGDB;
BOOL verbose;
BOOL alreadyPrintedData;
BOOL retinaDevice;
BOOL tallDevice;
}
- (id)init;
- (void)dealloc;
- (void)runWithArgc:(int)argc argv:(char **)argv;
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path;
- (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path;
- (void)stop;
- (void)checkPid:(NSTimer *)timer;
- (void)doExit:(int)errorCode;
- (void)changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice;
@end

View File

@@ -0,0 +1,566 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import "iphonesimulator.h"
#import "nsstringexpandpath.h"
#import "nsprintf.h"
#import <sys/types.h>
#import <sys/stat.h>
#import <objc/runtime.h>
#import <AppKit/NSRunningApplication.h>
NSString *simulatorPrefrencesName = @"com.apple.iphonesimulator";
NSString *deviceProperty = @"SimulateDevice";
NSString *deviceIphoneRetina3_5Inch = @"iPhone Retina (3.5-inch)";
NSString *deviceIphoneRetina4_0Inch = @"iPhone Retina (4-inch)";
NSString *deviceIphone = @"iPhone";
NSString *deviceIpad = @"iPad";
NSString *deviceIpadRetina = @"iPad (Retina)";
/**
* A simple iPhoneSimulatorRemoteClient framework.
*/
@implementation iPhoneSimulator
- (id)init {
self = [super init];
session = nil;
pidCheckingTimer = nil;
return self;
}
- (void)dealloc {
[session release];
[pidCheckingTimer release];
[super dealloc];
}
- (void)doExit:(int)errorCode {
nsprintf(@"<exit code=\"%d\"/>", errorCode);
nsprintf(@"</query_result>");
fflush(stdout);
fflush(stderr);
exit(errorCode);
}
- (void) printUsage {
fprintf(stdout, "<msg>Usage: iossim <command> <options> [--args ...]\n");
fprintf(stdout, "\n");
fprintf(stdout, "Commands:\n");
fprintf(stdout, " showsdks List the available iOS SDK versions\n");
fprintf(stdout, " launch <application path> Launch the application at the specified path on the iOS Simulator\n");
fprintf(stdout, " start Launch iOS Simulator without an app\n");
fprintf(stdout, "\n");
fprintf(stdout, "Options:\n");
fprintf(stdout, " --version Print the version of ios-sim\n");
fprintf(stdout, " --developer-path <developerDir> path to the developer directory (in Xcode)");
fprintf(stdout, " --help Show this help text\n");
fprintf(stdout, " --verbose Set the output level to verbose\n");
fprintf(stdout, " --exit Exit after startup\n");
fprintf(stdout, " --wait-for-debugger Wait for debugger to attach\n");
fprintf(stdout, " --debug Attach LLDB to the application on startup\n");
fprintf(stdout, " --use-gdb Use GDB instead of LLDB. (Requires --debug)\n");
fprintf(stdout, " --sdk <sdkversion> The iOS SDK version to run the application on (defaults to the latest)\n");
fprintf(stdout, " --family <device family> The device type that should be simulated (defaults to `iphone')\n");
fprintf(stdout, " --retina Start a retina device\n");
fprintf(stdout, " --tall In combination with --retina flag, start the tall version of the retina device (e.g. iPhone 5 (4-inch))\n");
fprintf(stdout, " --uuid <uuid> A UUID identifying the session (is that correct?)\n");
fprintf(stdout, " --env <environment file path> A plist file containing environment key-value pairs that should be set\n");
fprintf(stdout, " --setenv NAME=VALUE Set an environment variable\n");
fprintf(stdout, " --stdout <stdout file path> The path where stdout of the simulator will be redirected to (defaults to stdout of ios-sim)\n");
fprintf(stdout, " --stderr <stderr file path> The path where stderr of the simulator will be redirected to (defaults to stderr of ios-sim)\n");
fprintf(stdout, " --timeout <seconds> The timeout time to wait for a response from the Simulator. Default value: 30 seconds\n");
fprintf(stdout, " --args <...> All following arguments will be passed on to the application</msg>\n");
fflush(stdout);
}
- (int) showSDKs {
NSUInteger i;
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
return EXIT_FAILURE;
}
NSArray *roots = [tClass knownRoots];
nsprintf(@"<device_info>");
for (i = 0; i < [roots count]; ++i) {
DTiPhoneSimulatorSystemRoot *root = [roots objectAtIndex:i];
nsprintf(@"<item><key>sdk%d_name</key><value>%@</value></item>", i, [root sdkDisplayName]);
nsprintf(@"<item><key>sdk%d_version</key><value>%@</value></item>", i, [root sdkVersion]);
nsprintf(@"<item><key>sdk%d_sysroot</key><value>%@</value></item>", i, [root sdkRootPath]);
}
nsprintf(@"</device_info>");
return EXIT_SUCCESS;
}
- (void)session:(DTiPhoneSimulatorSession *)mySession didEndWithError:(NSError *)error {
if (verbose) {
nsprintf(@"<msg>Session did end with error %@</msg>", error);
}
if (stderrFileHandle != nil) {
NSString *stderrPath = [[mySession sessionConfig] simulatedApplicationStdErrPath];
[self removeStdioFIFO:stderrFileHandle atPath:stderrPath];
}
if (stdoutFileHandle != nil) {
NSString *stdoutPath = [[mySession sessionConfig] simulatedApplicationStdOutPath];
[self removeStdioFIFO:stdoutFileHandle atPath:stdoutPath];
}
if (error != nil)
[self doExit:EXIT_FAILURE];
else
[self doExit:EXIT_SUCCESS];
}
- (void)session:(DTiPhoneSimulatorSession *)mySession didStart:(BOOL)started withError:(NSError *)error {
if (startOnly && mySession) {
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript"
arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]];
nsprintf(@"<msg>Simulator started (no session)</msg>");
[self doExit:EXIT_SUCCESS];
return;
}
if (started) {
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/osascript"
arguments:[NSArray arrayWithObjects:@"-e", @"tell application \"iPhone Simulator\" to activate", nil]];
if (shouldStartDebugger) {
char*args[4] = { NULL, NULL, (char*)[[[mySession simulatedApplicationPID] description] UTF8String], NULL };
if (useGDB) {
args[0] = strdup("gdb");
args[1] = strdup("program");
} else {
args[0] = strdup("lldb");
args[1] = strdup("--attach-pid");
}
// The parent process must live on to process the stdout/stderr fifos,
// so start the debugger as a child process.
pid_t child_pid = fork();
if (child_pid == 0) {
execvp(args[0], args);
} else if (child_pid < 0) {
nsprintf(@"<msg>Could not start debugger process: %@</msg>", errno);
[self doExit:EXIT_FAILURE];
return;
}
}
if (verbose) {
nsprintf(@"<msg>Session started</msg>");
}
nsprintf(@"<inferior_pid>%@</inferior_pid>", [session simulatedApplicationPID]);
fflush(stdout);
if (exitOnStartup) {
[self doExit:EXIT_SUCCESS];
return;
}
pidCheckingTimer = [[NSTimer scheduledTimerWithTimeInterval:5.0 target:self
selector:@selector(checkPid:) userInfo:nil repeats: TRUE] retain];
} else {
nsprintf(@"<msg>Session could not be started: %@</msg>", error);
[self doExit:EXIT_FAILURE];
}
}
- (void)stop {
if (session)
[session requestEndWithTimeout: 0.1];
}
- (void)checkPid:(NSTimer *)timer {
(void)timer;
if (session && [[session simulatedApplicationPID]intValue] > 0) {
if (kill((pid_t)[[session simulatedApplicationPID]intValue], 0) == -1) {
nsprintf(@"<msg>app stopped</msg>");
[self doExit:EXIT_SUCCESS];
return;
}
}
}
- (void)stdioDataIsAvailable:(NSNotification *)notification {
[[notification object] readInBackgroundAndNotify];
NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; /* dangerous if partially encoded data is at the boundary */
if (!alreadyPrintedData) {
if ([str length] == 0) {
return;
} else {
alreadyPrintedData = YES;
}
}
if ([notification object] == stdoutFileHandle) {
printf("<app_output>%s</app_output>\n", [str UTF8String]);
} else {
nsprintf(@"<app_output>%@</app_output>", str); // handle stderr differently?
}
fflush(stdout);
}
- (void)createStdioFIFO:(NSFileHandle **)fileHandle ofType:(NSString *)type atPath:(NSString **)path {
*path = [NSString stringWithFormat:@"%@/ios-sim-%@-pipe-%d", NSTemporaryDirectory(), type, (int)time(NULL)];
if (mkfifo([*path UTF8String], S_IRUSR | S_IWUSR) == -1) {
nsprintf(@"<msg>Unable to create %@ named pipe `%@'</msg>", type, *path);
[self doExit:EXIT_FAILURE];
} else {
if (verbose) {
nsprintf(@"<msg>Creating named pipe at `%@'</msg>", *path);
}
int fd = open([*path UTF8String], O_RDONLY | O_NDELAY);
*fileHandle = [[[NSFileHandle alloc] initWithFileDescriptor:fd] retain];
[*fileHandle readInBackgroundAndNotify];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(stdioDataIsAvailable:)
name:NSFileHandleReadCompletionNotification
object:*fileHandle];
}
}
- (void)removeStdioFIFO:(NSFileHandle *)fileHandle atPath:(NSString *)path {
if (verbose) {
nsprintf(@"<msg>Removing named pipe at `%@'</msg>", path);
}
[fileHandle closeFile];
[fileHandle release];
if (![[NSFileManager defaultManager] removeItemAtPath:path error:NULL]) {
nsprintf(@"<msg>Unable to remove named pipe `%@'</msg>", path);
}
}
- (int)launchApp:(NSString *)path withFamily:(NSString *)family
uuid:(NSString *)uuid
environment:(NSDictionary *)environment
stdoutPath:(NSString *)stdoutPath
stderrPath:(NSString *)stderrPath
timeout:(NSTimeInterval)timeout
args:(NSArray *)args {
DTiPhoneSimulatorApplicationSpecifier *appSpec;
DTiPhoneSimulatorSessionConfig *config;
NSError *error = 0;
id tClass;
NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
if (!startOnly && ![fileManager fileExistsAtPath:path]) {
nsprintf(@"<msg>Application path %@ doesn't exist!</msg>", path);
return EXIT_FAILURE;
}
/* Create the app specifier */
tClass = objc_getClass("DTiPhoneSimulatorApplicationSpecifier");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorApplicationSpecifier class is nil.</msg>");
return EXIT_FAILURE;
}
appSpec = startOnly ? nil : [tClass specifierWithApplicationPath:path];
if (verbose) {
nsprintf(@"<msg>App Spec: %@</msg>", appSpec);
nsprintf(@"SDK Root: %@", sdkRoot);
for (id key in environment) {
nsprintf(@"<msg>Env: %@ = %@</msg>", key, [environment objectForKey:key]);
}
}
NSString *sdkVersion = [sdkRoot sdkVersion];
NSString *appSupportDir = [NSString stringWithFormat:@"%@/Library/Application Support/iPhone Simulator/%@",
NSHomeDirectory(), sdkVersion];
NSMutableDictionary *mutableEnv = [NSMutableDictionary dictionaryWithDictionary:environment];
[mutableEnv setObject:appSupportDir forKey:@"CFFIXED_USER_HOME"];
[mutableEnv setObject:appSupportDir forKey:@"IPHONE_SHARED_RESOURCES_DIRECTORY"];
[mutableEnv setObject:appSupportDir forKey:@"HOME"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"IPHONE_SIMULATOR_ROOT"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_ROOT_PATH"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_FRAMEWORK_PATH"];
[mutableEnv setObject:[sdkRoot sdkRootPath] forKey:@"DYLD_LIBRARY_PATH"];
[mutableEnv setObject:@"YES" forKey:@"NSUnbufferedIO"];
environment = mutableEnv;
/* Set up the session configuration */
tClass = objc_getClass("DTiPhoneSimulatorSessionConfig");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorApplicationSpecifier class is nil.</msg>");
return EXIT_FAILURE;
}
config = [[[tClass alloc] init] autorelease];
[config setApplicationToSimulateOnStart:appSpec];
[config setSimulatedSystemRoot:sdkRoot];
[config setSimulatedApplicationShouldWaitForDebugger:shouldWaitDebugger];
[config setSimulatedApplicationLaunchArgs:args];
[config setSimulatedApplicationLaunchEnvironment:environment];
if (stderrPath) {
stderrFileHandle = nil;
} else if (!exitOnStartup) {
[self createStdioFIFO:&stderrFileHandle ofType:@"stderr" atPath:&stderrPath];
}
[config setSimulatedApplicationStdErrPath:stderrPath];
if (stdoutPath) {
stdoutFileHandle = nil;
} else if (!exitOnStartup) {
[self createStdioFIFO:&stdoutFileHandle ofType:@"stdout" atPath:&stdoutPath];
}
[config setSimulatedApplicationStdOutPath:stdoutPath];
[config setLocalizedClientName: @"iossim"];
// this was introduced in 3.2 of SDK
if ([config respondsToSelector:@selector(setSimulatedDeviceFamily:)]) {
if (family == nil) {
family = @"iphone";
}
if (verbose) {
nsprintf(@"using device family %@",family);
}
if ([family isEqualToString:@"ipad"]) {
[config setSimulatedDeviceFamily:[NSNumber numberWithInt:2]];
} else{
[config setSimulatedDeviceFamily:[NSNumber numberWithInt:1]];
}
}
[self changeDeviceType:family retina:retinaDevice isTallDevice:tallDevice];
/* Start the session */
tClass = objc_getClass("DTiPhoneSimulatorSession");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSession class is nil.</msg>");
return EXIT_FAILURE;
}
session = [[tClass alloc] init];
[session setDelegate:self];
if (uuid != nil){
[session setUuid:uuid];
}
if (![session requestStartWithConfig:config timeout:timeout error:&error]) {
nsprintf(@"<msg>Could not start simulator session: %@</msg>", error);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
- (void) changeDeviceType:(NSString *)family retina:(BOOL)retina isTallDevice:(BOOL)isTallDevice {
NSString *devicePropertyValue;
if (retina) {
if (verbose) {
nsprintf(@"<msg>using retina</msg>");
}
if ([family isEqualToString:@"ipad"]) {
devicePropertyValue = deviceIpadRetina;
}
else {
if (isTallDevice) {
devicePropertyValue = deviceIphoneRetina4_0Inch;
} else {
devicePropertyValue = deviceIphoneRetina3_5Inch;
}
}
} else {
if ([family isEqualToString:@"ipad"]) {
devicePropertyValue = deviceIpad;
} else {
devicePropertyValue = deviceIphone;
}
}
CFPreferencesSetAppValue((CFStringRef)deviceProperty, (CFPropertyListRef)devicePropertyValue, (CFStringRef)simulatorPrefrencesName);
CFPreferencesAppSynchronize((CFStringRef)simulatorPrefrencesName);
}
/**
* Execute 'main'
*/
- (void)runWithArgc:(int)argc argv:(char **)argv {
if (argc < 2) {
[self printUsage];
exit(EXIT_FAILURE);
}
retinaDevice = NO;
tallDevice = NO;
exitOnStartup = NO;
alreadyPrintedData = NO;
startOnly = strcmp(argv[1], "start") == 0;
nsprintf(@"<query_result>");
if (strcmp(argv[1], "showsdks") == 0) {
[self doExit:[self showSDKs]];
return;
} else if (strcmp(argv[1], "launch") == 0 || startOnly) {
if (strcmp(argv[1], "launch") == 0 && argc < 3) {
nsprintf(@"<msg>Missing application path argument</msg>");
[self printUsage];
[self doExit:EXIT_FAILURE];
return;
}
NSString *appPath = nil;
int argOffset;
if (startOnly) {
argOffset = 2;
}
else {
argOffset = 3;
appPath = [[NSString stringWithUTF8String:argv[2]] expandPath];
}
NSString *family = nil;
NSString *uuid = nil;
NSString *stdoutPath = nil;
NSString *stderrPath = nil;
NSTimeInterval timeout = 30;
NSMutableDictionary *environment = [NSMutableDictionary dictionary];
int i = argOffset;
for (; i < argc; i++) {
if (strcmp(argv[i], "--version") == 0) {
printf("%s\n", IOS_SIM_VERSION);
exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "--help") == 0) {
[self printUsage];
exit(EXIT_SUCCESS);
} else if (strcmp(argv[i], "--verbose") == 0) {
verbose = YES;
} else if (strcmp(argv[i], "--exit") == 0) {
exitOnStartup = YES;
} else if (strcmp(argv[i], "--wait-for-debugger") == 0) {
shouldWaitDebugger = YES;
} else if (strcmp(argv[i], "--debug") == 0) {
shouldWaitDebugger = YES;
shouldStartDebugger = YES;
} else if (strcmp(argv[i], "--use-gdb") == 0) {
useGDB = YES;
} else if (strcmp(argv[i], "--developer-path") == 0) {
++i;
} else if (strcmp(argv[i], "--timeout") == 0) {
if (i + 1 < argc) {
timeout = [[NSString stringWithUTF8String:argv[++i]] doubleValue];
NSLog(@"<msg>Timeout: %f second(s)</msg>", timeout);
}
}
else if (strcmp(argv[i], "--sdk") == 0) {
i++;
NSString* ver = [NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding];
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot");
NSArray *roots;
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
[self doExit:EXIT_FAILURE];
return;
}
roots = [tClass knownRoots];
for (DTiPhoneSimulatorSystemRoot *root in roots) {
NSString *v = [root sdkVersion];
if ([v isEqualToString:ver]) {
sdkRoot = root;
break;
}
}
if (sdkRoot == nil) {
fprintf(stdout,"<msg>Unknown or unsupported SDK version: %s</msg>\n",argv[i]);
[self showSDKs];
exit(EXIT_FAILURE);
}
} else if (strcmp(argv[i], "--family") == 0) {
i++;
family = [NSString stringWithUTF8String:argv[i]];
} else if (strcmp(argv[i], "--uuid") == 0) {
i++;
uuid = [NSString stringWithUTF8String:argv[i]];
} else if (strcmp(argv[i], "--setenv") == 0) {
i++;
NSArray *parts = [[NSString stringWithUTF8String:argv[i]] componentsSeparatedByString:@"="];
[environment setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
} else if (strcmp(argv[i], "--env") == 0) {
i++;
NSString *envFilePath = [[NSString stringWithUTF8String:argv[i]] expandPath];
environment = [NSDictionary dictionaryWithContentsOfFile:envFilePath];
if (!environment) {
fprintf(stdout, "<msg>Could not read environment from file: %s</msg>\n", argv[i]);
[self printUsage];
exit(EXIT_FAILURE);
}
} else if (strcmp(argv[i], "--stdout") == 0) {
i++;
stdoutPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"stdoutPath: %@", stdoutPath);
} else if (strcmp(argv[i], "--stderr") == 0) {
i++;
stderrPath = [[NSString stringWithUTF8String:argv[i]] expandPath];
NSLog(@"stderrPath: %@", stderrPath);
} else if (strcmp(argv[i], "--retina") == 0) {
retinaDevice = YES;
} else if (strcmp(argv[i], "--tall") == 0) {
tallDevice = YES;
} else if (strcmp(argv[i], "--args") == 0) {
i++;
break;
} else {
printf("<msg>unrecognized argument:%s</msg>\n", argv[i]);
[self printUsage];
[self doExit:EXIT_FAILURE];
return;
}
}
NSMutableArray *args = [NSMutableArray arrayWithCapacity:MAX(argc - i,0)];
for (; i < argc; i++) {
[args addObject:[NSString stringWithUTF8String:argv[i]]];
}
if (sdkRoot == nil) {
id tClass = objc_getClass("DTiPhoneSimulatorSystemRoot");
if (tClass == nil) {
nsprintf(@"<msg>DTiPhoneSimulatorSystemRoot class is nil.</msg>");
[self doExit:EXIT_FAILURE];
return;
}
sdkRoot = [tClass defaultRoot];
}
/* Don't exit, adds to runloop */
int res = [self launchApp:appPath
withFamily:family
uuid:uuid
environment:environment
stdoutPath:stdoutPath
stderrPath:stderrPath
timeout:timeout
args:args];
nsprintf(@"<app_started status=\"%@\" />", ((res == 0) ? @"SUCCESS" : @"FAILURE"));
fflush(stdout);
fflush(stderr);
if (res != 0)
[self doExit:EXIT_FAILURE];
} else {
if (argc == 2 && strcmp(argv[1], "--help") == 0) {
[self printUsage];
[self doExit:EXIT_SUCCESS];
} else if (argc == 2 && strcmp(argv[1], "--version") == 0) {
printf("%s\n", IOS_SIM_VERSION);
[self doExit:EXIT_SUCCESS];
} else {
fprintf(stdout, "<msg>Unknown command</msg>\n");
[self printUsage];
[self doExit:EXIT_FAILURE];
}
}
}
@end

77
src/tools/3rdparty/iossim_1_8_2/main.mm vendored Normal file
View File

@@ -0,0 +1,77 @@
/* Author: Landon Fuller <landonf@plausiblelabs.com>
* Copyright (c) 2008-2011 Plausible Labs Cooperative, Inc.
* All rights reserved.
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
/* derived from https://github.com/phonegap/ios-sim */
#import <AppKit/AppKit.h>
#import "iphonesimulator.h"
#include <QLibrary>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include <QApplication>
#else
#include <QGuiApplication>
#endif
#include <QString>
#include <QStringList>
/* to do:
* - try to stop inferior when killed (or communicate with creator to allow killing the inferior)
* - remove unneeded functionality and streamline a bit
*/
/*
* Runs the iPhoneSimulator backed by a main runloop.
*/
int main (int argc, char *argv[]) {
int qtargc = 1;
char *qtarg = 0;
if (argc)
qtarg = argv[0];
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QApplication a(qtargc, &qtarg);
#else
QGuiApplication a(qtargc, &qtarg);
#endif
//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QString xcodePath = QLatin1String("/Applications/Xcode.app/Contents/Developer/");
for (int i = 0; i + 1 < argc; ++i) {
if (strcmp(argv[i], "--developer-path") == 0)
xcodePath = QString::fromLocal8Bit(argv[i + 1]);
}
if (!xcodePath.endsWith(QLatin1Char('/')))
xcodePath.append(QLatin1Char('/'));
/* manual loading of the private deps */
QStringList deps = QStringList()
<< QLatin1String("/System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols")
<< QLatin1String("/System/Library/PrivateFrameworks/CoreSymbolication.framework/CoreSymbolication")
<< (xcodePath + QLatin1String("../OtherFrameworks/DevToolsFoundation.framework/DevToolsFoundation"));
foreach (const QString &libPath, deps) {
QLibrary *lib = new QLibrary(libPath);
//lib->setLoadHints(QLibrary::ExportExternalSymbolsHint);
if (!lib->load())
printf("<msg>error loading %s</msg>", libPath.toUtf8().constData());
}
QLibrary *libIPhoneSimulatorRemoteClient = new QLibrary(xcodePath
+ QLatin1String("Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/iPhoneSimulatorRemoteClient.framework/iPhoneSimulatorRemoteClient"));
//libIPhoneSimulatorRemoteClient->setLoadHints(QLibrary::ResolveAllSymbolsHint|QLibrary::ExportExternalSymbolsHint);
if (!libIPhoneSimulatorRemoteClient->load())
printf("<msg>error loading iPhoneSimulatorRemoteClient</msg>");
iPhoneSimulator *sim = [[iPhoneSimulator alloc] init];
/* Execute command line handler */
[sim runWithArgc: argc argv: argv];
/* Run the loop to handle added input sources, if any */
int res = a.exec();
exit(res);
// [pool release];
return 0;
}

View File

@@ -0,0 +1,6 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
int nsvfprintf (FILE *stream, NSString *format, va_list args);
int nsfprintf (FILE *stream, NSString *format, ...);
int nsprintf (NSString *format, ...);

View File

@@ -0,0 +1,44 @@
/*
* NSLog() clone, but writes to arbitrary output stream
*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
#import <stdio.h>
int nsvfprintf (FILE *stream, NSString *format, va_list args) {
int retval;
NSString *str = (NSString *) CFStringCreateWithFormatAndArguments(NULL, NULL, (CFStringRef) format, args);
retval = fprintf(stream, "%s\n", [str UTF8String]);
[str release];
return retval;
}
int nsfprintf (FILE *stream, NSString *format, ...) {
va_list ap;
int retval;
va_start(ap, format);
{
retval = nsvfprintf(stream, format, ap);
}
va_end(ap);
return retval;
}
int nsprintf (NSString *format, ...) {
va_list ap;
int retval;
va_start(ap, format);
{
retval = nsvfprintf(stdout, format, ap);
}
va_end(ap);
return retval;
}

View File

@@ -0,0 +1,11 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import <Foundation/Foundation.h>
@interface NSString (ExpandPath)
- (NSString *)expandPath;
@end

View File

@@ -0,0 +1,18 @@
/*
* See the IOSSIM_LICENSE file in this directory for the license on the source code in this file.
*/
#import "nsstringexpandpath.h"
@implementation NSString (ExpandPath)
- (NSString *)expandPath {
if ([self isAbsolutePath]) {
return [self stringByStandardizingPath];
} else {
NSString *cwd = [[NSFileManager defaultManager] currentDirectoryPath];
return [[cwd stringByAppendingPathComponent:self] stringByStandardizingPath];
}
}
@end

View File

@@ -0,0 +1 @@
#define IOS_SIM_VERSION "1.8.2m"