If you, like me, are an old-time Unix command-line fanatic now doing iOSdevelopment, you've probably wondered if you can build an iPhone app fromscratch, entirely outside of XCode. After all, Mac OS/X is a *nix,and all the familiar tools — Make, cc, ld — are all there. So,can you build and compile completely outside of XCode? As it turns out, yes,you can, and there are actually some speed advantages to doing so.
Now, before I continue — if you're looking to incorporate an automatedbuild system like Cruise Control or Hudson into your development process insupport of a development effort that normally works with XCode, you're probably far better off looking into the command-line tool
xcodebuild
that ships as part of XCode. However, if you just want to throw togethera POC really quick, and you know your Objective-C syntax well enough thatyou don't really need the overhead of the XCode IDE (which can be quite a bit,in spite of Apple's impressive efforts to keep it manageable), you can compileand simulate an iPhone app using only command-line tools like we used to backin the day when men were men, women were women, and a compiler and a texteditor was all we needed.XCode is pretty good about telling you what it's doing for you behind thescenes, as long as you know where to look. For example, you can see all ofthe build parameters that were run as part of a build by opening up the LogNavigator (Command+7) and clicking one of the 'build' logs as shown in figure1.
In the Terminal app on your Mac, press the Up Arrow key. The last command you entered appears on the command line. Continue pressing the Up Arrow key until you. It includes files like the Mail.app and Chess.app apps included with Mac OS X, so you can’t remove these — even from the command line as the root user. This also means that malware can’t modify and infect those applications, however.
Figure 1: Viewing the build logs. https://greatpurple488.weebly.com/better-to-have-a-mac-or-pc-for-programming-2018.html.
As you can see, there's a lot of stuff going on in there, and as itturns out, it's not all stuff you necessarily need.
The smallest iPhone app I can think of that (arguably) does something 'useful'is shown in listing 1 below.
Listing 1: window.m, A useful(?) iPhone app
This 'app' opens a window and displays 'Hello, World' as illustrated in Figure 2 (it also leaks its
UIWindow
instance because I didn'tcreate an autorelease pool. I hope your computer has enough memory tocompensate for this).Figure 2: Hello, World
If you save this as, say
window.m
, you can compile and launchit (in the simulator) without ever starting up XCode. Youmust have XCode installed — the simulator isn't distributedindependently of XCode and even the cross-compile libraries (which I'll detailfurther below) are part of the XCode bundle. However, you don't have tohave it running to compile and test an app.
LLVM
, or Low Level Virtual Machine, is Apple's preferred Objective-C compiler these days. Ifyou've been doing iOS programming for a while, you probably know that it usedto all be done in gcc
(and can still be done that way, if you're so inclined), but thedefault is LLVM (clang
on the command line), so that's what I'll use here. clang
is invoked from the command line just like gcc
— you giveit an input file and an output file. I'll go ahead and create a Makefile
for this process; the first iteration is shown in listing 2.Listing 2: Rough cut at a makefile
This fails (and honestly, you probably expected that) with:
If you have any experience with C programming, you can immediately seethe problem here; I didn't give the compiler a
-I
flag pointingto this header file. Interestingly, though, this minimal makefile didn't error on my importof <Foundation/Foundation.h>
on line 1 — yet I didn't tellit where to find this include file. In fact, it would have compiled without complaining if I had given it an input that didn't require UIKit. For instance,listing 3 will compile just fine.Listing 3: minimal.m, non-GUI objective-C class
![Mac Running App From Command Line Mac Running App From Command Line](/uploads/1/3/4/1/134135731/607280818.jpg)
minimal.m
won't link, however, because although the header <Foundation/NSString.h>
is found, the Foundationlibrary itself isn't. To include it, you have to specify the framework:From a coding perspective,
-framework
works a lot like the -l
flag in gcc
.But — where didclang
findNSString.h
? It's not in /usr/include
, or /usr/local/include
Iptv app mac os. — in fact, you'll search in vain fora file anywhere on your system named 'NSString.h' that's contained in adirectory named 'Foundation'. However, if you do look for 'NSString.h',you'll find a copy in /System/Library/Frameworks/Foundation.framework/Headers
.But, by the strict 'rules' of C compilation, that can't be where clang
resolved it, because it's not in a directory named 'Foundation'.This is another Objective-C extension to clang
. In addition toregular header include searches (like /usr/include
), there's thenotion of Framework searches. By default, clang
will look under /System/Library/Framework for frameworks to include.Any such framework, if it has a Headers
directory, will beresolved as Framework Name/header file. An ordinary iOSdeveloper would not need to know or care about such low-level details, butwhen you're working so close to the system core, it does matter.So what are these 'frameworks'? Since NeXT's NeXTSTEP operating system andit's derivatives (Mac OS/X and GNUStep) are the only users of Objective C, it's sort of difficult to tease apart which parts of
clang
are 'pure' Objective C and which parts are Mac OS/Xextensions. I believe, however, that this concept of a 'framework' is a nativepart of objective C. Essentially, a framework is a bundling of librariesand their headers and associated resources with built-in support for versioning.Anybody who's spent much time compiling and maintaining C-based packages ona Unix system can see how useful this is; the Linux community has been tryingto standardize on something like this with pkginfo and RPM's for quite a while.clang
has a -l
Free mmorpg games for mac. flag that will link ordinaryC libraries, but you'll likely never use this for iOS development.So, what about
UIKit
? Well, it's not there under/System/Library/Frameworks
. That's because it's not part ofMac OS/X; it's part of iOS. So how can you link to it? This is where thesimulator starts to come into play. XCode installs the iPhone simulator anda set of cross-compile libraries for you to build against. XCode has atendency to move things around from one version to the next, so you may haveto hunt around to find the 'core' directory, but as of XCode 4.6.1, thecross-compile libraries are found under:Underneath this directory is another
/System/Library/Framework
,this time with a set of the Frameworks that iOS includes. (In fact, thisdirectory serves as the root directory of an entire iOS 'installation'). So,to get clang to compile an app that depends on UIKit
, you haveto add this directory to the framework search directory. You do this viathe OS/X-specific '-F' flag to clang. So, the updated makefile looks likelisting 4:Barto galeno ao vivo rar. Listing 4: First attempt at a cross-compile to iOS
The results are a little better, but this fails with:UIKit has a dependency on a framework called
Core
. This framework ispart of Mac OS/X, so clang
finds it and tries to use it, butUIKit
relies on a different version of Core
thanthe one that Mac OS/X uses. The problem here is that clang
is trying to resolve its frameworks from the simulatordirectory, but it's still finding headers under /usr/include. The UnixC programmer's solution, of course, is to add a '-I' as shown in listing 5.Listing 5: Second attempt at a cross-compile to iOS
Uninstall apps on Mac with App Cleaner & Uninstaller. The first way of uninstalling apps is to use a. At this point, OS X will move the app to the Trash, but if you change your mind, you can simply drag the app back to the Applications folder. To delete the app forever, click and hold the Trash. How to Delete Apps in the Finder on Mac Manually (the Hard Way) Unlike Windows computers, Mac. How to Delete an App on Mac from Launchpad. The first way we want to recommend to you is using. How to delete apps on mac.
This gets us further, but the compiler now emits a lot of errors along thelines of:Again,
clang
is trying to generate a Mac OS/X executable whenwhat we want is an iOS executable. The solution is to add:In fact, with isysroot
, you can get rid of the -F
and -I
flags; this replaces the '/' directory as it pertainsto the compiler. Now, the compile completes, but the link step fails due to:This is because, although I've requested some cross-compile options, I stillhaven't actually asked for a cross-compile. I have to do that with:Almost there. This fails for me with a handful of 'Undefined symbols for architecture i386'. The reason is because I'm running on a 64-bit machine;to work around this, I have to addAnd voila! I get the executable file window
. The completedmake file is shown in listing 6.Listing 6: Successful attempt at a cross-compile to iOS
These are the fewest command-line parameters you can pass into
clang
and still get a working iOS executable.Now, how about running it? If I try to invoke it directly from the commandline, it predictably fails with:Which makes sense - I compiled something for iOS, but now I'm trying torun it on a OS/X. As you undoubtedly know, XCode includes an iPhone emulator,and you can invoke it from the command line and pass in an app to simulatewith the -SimulateApplication
parameter. You can invoke itfrom the command line like this:(Notice the './' in front of the application name; if you omit this, the simulatorwon't find your executable).How to get older versions of apps on mac. If the app has an 'Update' banner, that is usually a good indicator that it is an older version of the app. This is an older version of the Pages app, as indicated by the 'Update' banner Another.
So there you have it — without XCode running or open, I've compiledand tested a complete, working iOS app.Note that this whole process does not build an actual iPhone bundle.iPhone runs under an
arm
architecture, whereas this build, althoughit was a cross-compile, still runs on an intel
processor. Tobuild for an actual deployment to an iphone, you'd have to change thearchitecture to arm
, and to get it to install on a real device,you'd also have to deal with code signing. Still, it's interesting and funto see how far you can go without actually running XCode.Add a comment:
Completely off-topic or spam comments will be removed at the discretion of the moderator.
You may preserve formatting (e.g. a code sample) by indenting with four spaces preceding the formatted line(s)
All postings and use of the content on this site are subject to the. Keynote mac app store. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. Apple may provide or recommend responses as a possible solution based on the information provided; every potential issue may involve several factors not detailed in the conversations captured in an electronic forum and Apple can therefore provide no guarantee as to the efficacy of any proposed solutions on the community forums. Apple Footer.This site contains user submitted content, comments and opinions and is for informational purposes only.
Awesome! Beautiful work! Thank you!
Hi Joshua, thank you for this post. I think you should take a look at `xcrun`. This tool may help you to get rid of magic strings. So command xcrun -sdk iphonesimulator6.1 -show-sdk-path will print '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk'
Hi thnx for this tutorial, However i am trying to run same example in my mac, but i am getting the following error. make window clang clang: error: no input files make: *** [window] Error 1 This is my Makefile content XCODE_BASE=/Applications/Xcode.app/Contents SIMULATOR_BASE=$(XCODE_BASE)/Developer/Platforms/iPhoneSimulator.platform FRAMEWORKS=$(SIMULATOR_BASE)/Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/Frameworks/ INCLUDES=$(SIMULATOR_BASE)/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/include window: window.m clang -arch i386 -mios-simulator-version-min=6.1 -fobjc-abi-version=2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk -o window window.m -framework Foundation -framework UIKit Thank you.
Ah, I'm so sorry Anantha, I omitted a backslash from listing 6. It should read:
Canon mg 3000 printer app for mac. In fact, the backslashes in the code listing were there strictly for formatting reasons. So, you can jam all of this onto a single very long line; to simplify (but slightly uglify):
window: window.m
clang -arch i386 -mios-simulator-version-min=6.1 -fobjc-abi-version=2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk -o window window.m -framework Foundation -framework UIKit
The line break after 'window.m' (as well as a hard-tab character) are required by the Make utility. Mac app update turn off.
Very interesting! Do you've any second part of this article, detailing how to create an app bundle, and code-sign it from just the command-line, without creating any xcode project, and without starting Xcode? Or do you know of any web page or document explaining it? I really want to build iOS apps from the command-line, because it's more convenient for me. Please point me in the right direction, because, honestly, your page is perhaps the only webpage in the World explaining iOS development in a language I can understand. ardi
I tried these steps on IOS 7.1 and looks like there is an error 'Download Failed' when Safari tries to download the file to install/run on the device. A bit of googling around revealed some issues with signing the apps is more strictly enforced i iOS7. Do you have any suggestions for how to sign the app from the command line?
Great post! I am trying to build a C library this way. The problem is that the lib contains a lot of implicit type conversions, which is treated as error by clang. Is it possible to disable this behavior of clang? Thanks!
Nice, and to the point. I was however looking to build an iPhone app, unsigned, to run on console (yes, its jailbroken).
Thanks a lot for this post. This is exactly I was looking for. I tried to play with clang ast dump feature but it always failed on importing headers from frameworks
Hey, Nice post. Helped me a lot. The framework and standard include paths are updated I guess so that fails but on including -isysroot and giving the SDK path works :) This post is the only clear and crisp explanation I could find. Great job for that :D Regards, Shravya
Thanks, this has been by far my most popular blog post. I understand that quite a bit has changed since I wrote it for iOS 4 - maybe it's time for an update.
Fantastic! Can you write more? Will be nice to build real iOS app
Josh,
Great article.
As I'm sure you're aware, some things have changed since 4 - however I'm sure most readers of the page would be able to fill in the holes.
I personally love to build projects this way. However, I can't seem to find a way to easily debug an iOS app (or any other executable) on OS X without an Xcode project.
Would be nice to be able to keep the build external from Xcode, but still leverage Xcode's debugging, and launching to external devices.
Thoughts?
- Zach
Great article.
As I'm sure you're aware, some things have changed since 4 - however I'm sure most readers of the page would be able to fill in the holes.
I personally love to build projects this way. However, I can't seem to find a way to easily debug an iOS app (or any other executable) on OS X without an Xcode project.
Would be nice to be able to keep the build external from Xcode, but still leverage Xcode's debugging, and launching to external devices.
Thoughts?
- Zach
Mac Run App From Command Line With Arguments
With Xcode 7.3 in order to run the application in the simulator from the command line you need to run:
Hey Josh,
Great blog! Did you know you share the same name as a teen murderer?
Great blog! Did you know you share the same name as a teen murderer?
Mac Command Line Tools
Unfortunately, yes, I do know that (unfortunate that it's the case, not that I know it). I can prove pretty conclusively that he and I are very different people, though, if it's ever in doubt.