17

Here is a very simple Objective-C console app:

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    NSLog(@"Hello world!");

    [pool drain];

    return 0;
}

I compile it with gcc main.m -o main -ObjC -framework Foundation -framework CoreLocation on my Mac.

I also have the iOS SDK installed on my mac. How can I modify this command to compile the same code, on my computer, for use on a (jailbroken) iOS device ?

I could then transfer the executable through ssh and sign it with ldid.

Klaus
  • 1,241
  • 4
  • 14
  • 31

4 Answers4

19

For simple cases this might be good enough:

gcc -o output -Wall -std=c99 source.m -framework Foundation -lobjc 

Update:

This command does not work for an iOS command line application - the arch must be set correctly. I have no iOS dev environment at hand currently; probably the -march flag would help.

See the accepted answer.

radiospiel
  • 2,450
  • 21
  • 28
  • You can also replace `gcc` with `clang` without changing anything else here. – Keith Smiley Nov 21 '13 at 14:30
  • 1
    @keith: Yes, this is probably the correct future answer. Apple might stop shipping the gcc wrapper around clang at some point. – radiospiel Nov 21 '13 at 20:56
  • Doesn't the arch need to be set? – 0xcaff Jan 05 '14 at 03:59
  • This command would work if you compile on a jailbroken iDevice with gcc, Right? – 0xcaff Jan 06 '14 at 03:33
  • @caffinatedmonkey as arch is usually set to the host system it should work without any arch setting on the device, yes. – radiospiel Jan 08 '14 at 09:31
  • You can also use `-include 'Foundation/Foundation.h'` as an additional gcc parameter to avoid needing to explicitly include `Foundation.h` in the source file being compiled. – Tyler Oct 09 '14 at 22:21
4

Assuming you're not wedded to fusty old GCC, deliberately triggering errors in my project so as to get into a position where Xcode will reveal the command line used revealed the following for compilation:

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang -x objective-c -arch armv6 -fmessage-length=0 -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -std=gnu99 -Wno-trigraphs -fpascal-strings -O0 -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -DDEBUG=1 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -gdwarf-2 -mthumb "-DIBOutlet=attribute((iboutlet))" "-DIBOutletCollection(ClassName)=attribute((iboutletcollection(ClassName)))" "-DIBAction=void)attribute((ibaction)" -miphoneos-version-min=3.2 -iquote [a bookkeeping file] -I[a list of headers] -iquote [more headers] -I[an include path] -fpch-preprocess -F[pointer to directory for debug files] -include [my prefix header] -c AppDelegate.m -o AppDelegate.o

If you're declining the use of Xcode then I guess you can cut the stuff about Interface Builder outlets at the very least. And building for armv6 rather than v7 is probably an error in my project.

And then, to link:

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang -arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -L[something appropriate] -F[something appropriate] -filelist [a .LinkFileList] -dead_strip -miphoneos-version-min=3.2 -framework SystemConfiguration -framework UIKit -framework Foundation -framework CoreGraphics -o [something appropriate]

The .LinkedFileList file seems just to be a list of object files, one per line. Xcode has put the full path to each in there, though I'd guess relative paths to be acceptable.

I appreciate this isn't a full answer, but hopefully it helps?

Tommy
  • 99,986
  • 12
  • 185
  • 204
4

To compile iOS code on your mac, you need to use cross compiler, i.e. an compiler running on an Intel platform and able to generate ARM binary code.

Xcode does provide such a cross compiler. It is located at (assuming you are using Xcode 4.3 distributed from the App Store)

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2

For a simple, "hello world" kind of program, I am compiling using

alias c="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2"
c -o hello hello.c -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/
rgajrawala
  • 2,148
  • 1
  • 22
  • 35
Sébastien Stormacq
  • 14,301
  • 5
  • 41
  • 64
1

Why not using xcodebuild instead of directly call gcc?

AliSoftware
  • 32,623
  • 6
  • 82
  • 77
  • Isn't `xcodebuild` meant for compiling Xcode projects only ? I wondered how to avoid using Xcode. – Klaus Sep 19 '11 at 15:48
  • 4
    Oh. Sure. Then maybe you can do this: do create an iOS Xcode project, then call `xcodebuild`from command line... and observe the calls to gcc he's performing in command line. Then you should be able to see what command line parameter it uses... Nad should be able to use it yourself using `gcc` without `xcodebuild` – AliSoftware Sep 19 '11 at 16:00