Skip to content

Instantly share code, notes, and snippets.

@bellbind
Created July 25, 2012 08:22
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bellbind/3175073 to your computer and use it in GitHub Desktop.
Save bellbind/3175073 to your computer and use it in GitHub Desktop.
[macosx][ios][objective-c]Building iOS 5.1 app with command line (completely Xcode-less programming)
#!/bin/bash
# build for target iPad/iPhone binary
XCODE=/Applications/Xcode.app
TOOLCHAIN=$XCODE/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
CC=$TOOLCHAIN/usr/bin/clang
PLATFORMS=$XCODE/Contents/Developer/Platforms
PLATFORM=$PLATFORMS/iPhoneOS.platform/Developer
SYSROOT=$PLATFORM/SDKs/iPhoneOS5.1.sdk
$CC -arch armv7 -mthumb -isysroot $SYSROOT \
-miphoneos-version-min=5.1 \
-framework Foundation -framework CoreGraphics -framework UIKit \
"$@"
#!/bin/bash
# build for IOS Simulator
XCODE=/Applications/Xcode.app
TOOLCHAIN=$XCODE/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
CC=$TOOLCHAIN/usr/bin/clang
PLATFORMS=$XCODE/Contents/Developer/Platforms
PLATFORM=$PLATFORMS/iPhoneSimulator.platform/Developer
SYSROOT=$PLATFORM/SDKs/iPhoneSimulator5.1.sdk
$CC -arch i386 -isysroot $SYSROOT \
-miphoneos-version-min=5.1 -ObjC++ -fobjc-abi-version=3 \
-framework Foundation -framework CoreGraphics -framework UIKit \
"$@"
// ./compile-simulator.sh hello.m -o hello
// ./simulator.sh hello
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder<UIApplicationDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(id)application didFinishLaunchingWithOptions:(id)opts
{
CGRect frame = [[UIScreen mainScreen] bounds];
UIWindow* window = [[UIWindow alloc] initWithFrame:frame];
window.backgroundColor = [UIColor whiteColor];
[window makeKeyAndVisible];
UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = frame;
[button setTitle:@"Touch" forState:UIControlStateNormal];
[window addSubview:button];
[button addTarget:self action:@selector(hello:)
forControlEvents:UIControlEventTouchDown];
return YES;
}
- (void)hello:(id)sender
{
id alert = [[UIAlertView alloc]
initWithTitle:@"Alert" message:@"Hello" delegate:nil
cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
[alert show];
[alert release];
}
@end
int main(int argc, char** argv)
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil,
NSStringFromClass([AppDelegate class]));
}
}
{"UIDeviceFamily":[1,2]}
#!/bin/bash
XCODE=/Applications/Xcode.app
PLATFORMS=$XCODE/Contents/Developer/Platforms
APPS=$PLATFORMS/iPhoneSimulator.platform/Developer/Applications
SIM=$APPS/iPhone\ Simulator.app/Contents/MacOS/iPhone\ Simulator
"$SIM" -SimulateApplication "$@"
// ./compile-simulator.sh webkit.m -o webkit
// ./simulator.sh webkit
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder<UIApplicationDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(id)application didFinishLaunchingWithOptions:(id)opts
{
CGRect frame = [[UIScreen mainScreen] applicationFrame];
UIWindow* window = [[UIWindow alloc] initWithFrame:frame];
window.backgroundColor = [UIColor whiteColor];
[window makeKeyAndVisible];
UIWebView* webview = [[UIWebView alloc] initWithFrame:frame];
webview.scalesPageToFit = YES;
[window addSubview:webview];
id url = [NSURL URLWithString:@"http://google.com/"];
id req = [NSURLRequest requestWithURL:url];
[webview loadRequest:req];
return YES;
}
@end
int main(int argc, char** argv)
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil,
NSStringFromClass([AppDelegate class]));
}
}
@bellbind
Copy link
Author

Tested on MacOS X Lion (10.7.4) and Xcode 4.3.3 with Command Line Tools and iOS 5.1 Simulator.

Also tested OS X Mountain Lion(10.8) and Xcode 4.4 with Command Line Tools and iOS 5.1 Simulator.

@bellbind
Copy link
Author

/usr/bin/clang also works well instead of toolshain's clang

About compiler options:

  • -miphoneos-version-min=5.1 : it is for compiling @autorelease block

About compile options for simulator:

  • -arch i386 : iPhone Simulator runs i386 binary (not arm binary)
  • -ObjC++ : it is for compiling @property and @synthesis notations
  • -fobjc-abi-version=3 : it is for avoiding linker error with Simulator UIKit, e.g. objc_class_name_UIWindow

(Building for ARM not required both -ObjC++ and -fobjc-abi-version options)

@bellbind
Copy link
Author

To display apps for ipad/retina display, it requires Info.plist file in the same directory of executable.

Compile to Info.plist file from the Info.plist.json with /usr/bin/plutil command as:

plutil -convert binary1 -o Info.plist Info.plist.json

@bellbind
Copy link
Author

You can also make executables as universal binary and can run them on the iPhone Simulator.
For example:

./compile-arm.sh hello.m -o hello.arm
./compile-simulator.sh hello.m -o hello.sim
lipo -create -output hello -arch armv7 hello.arm -arch i386 hello.sim

./simulator.sh hello

@bellbind
Copy link
Author

Running on iPhone Simulator 6.1 requires "AppName.app" directory. e.g.:

mkdir hello.app/
./compile-simulator.sh hello.m -o hello.app/hello
plutil -convert binary1 -o hello.app/Info.plist Info.plist.json
./simulator.sh hello.app/hello

The compile options are also switched "-miphoneos-verson-min=6.1" and "SYSROOT=$PLATFORM/SDKs/iPhoneSimulator6.1.sdk"

@guilleiguaran
Copy link

Thanks!!!!

@robertomiranda
Copy link

❤️

@vegertar
Copy link

vegertar commented May 6, 2014

Nice!

@vegertar
Copy link

vegertar commented May 7, 2014

makefile

prerequisite

SDK := 7.1
XCODE := /Applications/Xcode.app
TOOLCHAIN := $(XCODE)/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
PLATFORMS := $(XCODE)/Contents/Developer/Platforms
APPS := $(PLATFORMS)/iPhoneSimulator.platform/Developer/Applications
SIM := $(APPS)/iPhone\ Simulator.app/Contents/MacOS/iPhone\ Simulator
OBJCC = $(TOOLCHAIN)/usr/bin/clang
OBJCXX = $(TOOLCHAIN)/usr/bin/clang++

runtime env

ifeq ($(arm),1)
PLATFORM := $(PLATFORMS)/iPhoneOS.platform/Developer
SYSROOT := $(PLATFORM)/SDKs/iPhoneOS$(SDK).sdk
OBJCXXFLAGS := -arch armv7 -mthumb
else
PLATFORM := $(PLATFORMS)/iPhoneSimulator.platform/Developer
SYSROOT := $(PLATFORM)/SDKs/iPhoneSimulator$(SDK).sdk
OBJCXXFLAGS := -arch i386
endif

optimization

ifeq ($(release),)
OBJCXXFLAGS := -g -fno-inline -O0
else
OBJCXXFLAGS := -DNDEBUG -O4
endif

target & sources

TARGET := a.out
SRCS := $(wildcard *.mm)

compiling & linking

INCPATH :=
LIBPATH :=

OBJCXXFLAGS +=
-isysroot $(SYSROOT)
-fobjc-arc
-std=c++11
-ObjC++
-Werror -Wall \

LDFLAGS +=
-miphoneos-version-min=$(SDK)
-isysroot $(SYSROOT)
-framework Foundation
-framework CoreGraphics \

ifeq ($(ui),1)
LDFLAGS += -framework UIKit
endif

rules

all: $(TARGET)

run:
./$(TARGET)

sim-run:
$(SIM) -SimulateApplication $(TARGET)

clean:
rm -f *.out *.o *~

$(TARGET): $(SRCS:%.mm=%.o)
$(OBJCXX) -o $@ $^ $(LDFLAGS) $(LIBPATH)

%.o: %.mm
$(OBJCXX) -o $@ -c $&lt; $(OBJCXXFLAGS) $(INCPATH)

.PHONY: all run sim-run clean

@vegertar
Copy link

vegertar commented May 7, 2014

I'm sorry about such indent!

@bellbind
Copy link
Author

I made them for Swift3 and Xcode8.1 environment: https://gist.github.com/bellbind/20b59a4ab86d11e5e358a472c7ae5986

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment