在Mac上通过gcc编译iOS Objective-C命令行应用程序

17

这是一个非常简单的Objective-C控制台应用程序:

#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;
}

在我的Mac上使用 gcc main.m -o main -ObjC -framework Foundation -framework CoreLocation 进行编译。

我还在我的Mac上安装了iOS SDK。如何修改此命令以便在我的计算机上编译相同的代码,以供(越狱的)iOS设备使用?

然后,我可以通过ssh传输可执行文件并使用 ldid 进行签名。

4个回答

19

对于简单情况,这可能已经足够了:

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

更新:

这个命令不适用于iOS命令行应用程序 - 必须设置正确的arch。目前我手头没有iOS开发环境;也许-march标志会有所帮助。

请参见被接受的答案。


你也可以将 gcc 替换为 clang,而不需要在这里进行任何其他更改。 - Keith Smiley
1
@keith:是的,这可能是正确的未来答案。苹果可能会在某个时候停止在clang周围提供gcc包装器。 - radiospiel
需要设置架构吗? - 0xcaff
如果你在越狱的iDevice上使用gcc编译,这个命令就可以工作了,对吧? - 0xcaff
@caffinatedmonkey 由于arch通常设置为主机系统,因此在设备上不需要任何arch设置,是的。 - radiospiel
您还可以使用-include 'Foundation/Foundation.h'作为附加的gcc参数,以避免在编译源文件时需要显式包含Foundation.h - Tyler

4

要在您的Mac上编译iOS代码,您需要使用交叉编译器,即在Intel平台上运行并能够生成ARM二进制代码的编译器。

Xcode确实提供了这样的交叉编译器。它位于以下位置(假设您正在使用从App Store分发的Xcode 4.3)

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

对于一个简单的“hello world”程序,我正在使用以下进行编译:

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/

4
假设您不想使用老旧的GCC,故意触发我的项目中的错误以便进入Xcode命令行的位置,编译时显示了以下内容:
/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 [一个簿记文件] -I[一个头文件列表] -iquote [更多头文件] -I[一个包含路径] -fpch-preprocess -F[指向调试文件目录的指针] -include [我的前缀头文件] -c AppDelegate.m -o AppDelegate.o
如果您不想使用Xcode,则至少可以剪切与Interface Builder Outlet有关的内容。而在我的项目中构建armv6而不是v7可能是一个错误。
然后,进行链接:
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang -arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk -L[适当的内容] -F[适当的内容] -filelist [一个.LinkFileList] -dead_strip -miphoneos-version-min=3.2 -framework SystemConfiguration -framework UIKit -framework Foundation -framework CoreGraphics -o [适当的内容]
.LinkedFileList文件似乎只是一个对象文件列表,每行一个。Xcode在其中放置了每个对象文件的完整路径,尽管我认为相对路径也是可以接受的。
我知道这不是一个完整的答案,但希望它有所帮助?

1

为什么不使用xcodebuild而是直接调用gcc


“xcodebuild”不是专门用于编译Xcode项目吗?我想知道如何避免使用Xcode。 - Klaus
4
好的。也许你可以这样做:创建一个iOS Xcode项目,然后从命令行调用xcodebuild...观察他在命令行中执行的对gcc的调用。然后,您就应该能够看到它使用了哪些命令行参数...并且应该能够在没有xcodebuild的情况下使用gcc进行自己的操作。 - AliSoftware

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接