What is “Nougat”? — Part 4
In the first three parts of this series, we took a look at the basic concepts and design principles behind Oxygene “Nougat”, and the IDE experience. In this fourth installment, i’d like to give you an overview of the build and deploy process, and a quick peek at debugging.
Building your project is something that happens behind the scenes and most of the time, we don’t think much of it. We press F5 in the IDE, and a few seconds later our app is running. But a lot is going on behind the scenes to get from your source code to the final executable — and a lot more than usual, for building Mac and iOS apps.
Let’s have a look. All that we’ll be seeing here happens, of course, behind the scenes and automatically, without you having to worry about a thing.
It all starts with the Oxygene compiler, which takes your source files and turns them into executable code. For Nougat, that is the same Oxygene compiler you know and love, only instead of emitting a final “.exe” or “.jar” file as it would do for .NET or Java, it generates a file with CPU-native binary code for either x64 or armv7(s), and a “.o”. (In fact, if you’re building an iOS app with armv7 and armv7s support, the latter being new for the iPhone 5, it will generate two such files.)
On the back-end, Oxygene leverages the great LLVM compiler, which generates highly efficient code.
The “.o” is not the final executable, it still has to be linked. So next, our toolchain calls “ld”, which is the linker. This happens via CrossBox, passing the “.o” file over to the Mac, linking it against all the frameworks it needs, and returning the final executable (which is extension-less) back.
At this stage, we’re done if we’re building a Mac console app, that is, a simple executable that you want to run from the command line. Most Mac (and all iOS) apps aren’t simple console apps, so there’s more that needs to be done to get a final, runnable app — and Nougat does that for you, of course.
Mac and iOS apps come as what is called “Bundles” — which are really folders with an .app extension that are treated as individual files by the OS X finder and other parts of the OS. In the Project Properties of your Nougat app, you’ll find a checkbox called “Create .app Bundle” (checked by default in most templates) that enables this functionality:
With the option set, Nougat’s build chain will take the executable generated above, along with any other files your app needs (such as images or other resources) and generates a full .app bundle. It will also automatically generate an Info.plist file describing your app, or take an existing Info.plist file that’s part of your project and adjust/tweak it as necessary.
The Info.plist file, next to the executable, is an important part of the .app bundle that tells the OS how to run our app, what documents it supports, what application icon to use, etc.
If you’re building a Mac app application, you can be done at this point, and the resting .app bundle is fully runnable. However, these days it’s good practice to digitally sign your application (and in fact that’s required for iOS apps, and also for Mac apps if you want to use the Mac App Store).
How do you sign your app? Nothing easier than that. Looking at the Project Properties again, there’s an option called “Code signing certificate name”, along with a drop down that shows you all the (relevant) certificates Nougat found on your Mac that can be used for signing apps (this list will differ between Mac and iOS projects). Simply select the right certificate, and when you build, Nougat will automatically code-sign the final .app bundle for you.
For iOS apps you will usually choose a “iPhone Distribution: XXX” or “iPhone Developer: XXX” certificate issued by Apple, where XXX is your name or your company name. Distribution certificates are used to build apps to ship on the app store or deploy to beta testers or inside your company; Developer certificates are used while you’re testing your apps on your own devices.
For the Mac, you can choose between “3rd Party Mac Developer Application: XXX” certificates for deployment of Mac App Store apps, or you can use Apple’s new “Developer ID Application” certificates, for non-MAS apps.
In either case, all you need to do is select the certificate, and off you go.
iOS applications also need what is called a “provisioning profile”, generated on Apple’s developer portal, to govern how they can be run. As you might have guessed, there’s an option in Project Properties that lets you pick the provisioning profile you want to use from a list, and Nougat takes care of the rest.
The actual code signing, once again, happens on the Mac, marshaled over transparently via CrossBox, so you don’t even notice it’s happening.
There’s a few more things that might have to be done as part of this process (for example .xib and .storyboard files that might be part of your project will get post-processed into a binary format before being included in your .app bundle), but finally, we have a finished .app bundle that’s ready to be used — run, debugged or, hopefully at some stage, be submitted to the App Store.
Running and Debugging also happens seamlessly. In the CrossBox menu we already saw in my previous post, you can select a Mac or a Device (real or virtual) connected to your Mac:
The menu will list any Mac on the network that’s running CrossBox, as well as any remote CrossBox server you might have connected to. Underneath each Mac, you can select the device you are building for and deploying/running/debugging on. For Mac OS X applications that is just the Mac itself, but for iOS, you can choose between the “iOS Simuator”, a generic “iOS Device” (which lets you build for a device seven without having a real one attached), as well as any actual devices connected to your Mac:
For iOS, the selection you make here affects several parts of the build process. First of all, the Mac you select is of course the one that will be used for all tasks that need to be handled Mac side (linking, code signing, etc).
More importantly, by either choosing “iOS Simulator” or a device (whether a real one or the generic “iOS Device”), you are telling Nougat whether to build your project for device hardware (i.e. in most cases armv7 and armv7s binary, and against the real iOS SDK) or for the Simulator (in which case it will generate an i386 binary, linked against a separate Simulator version of the SDK).
Finally, the device choice also influences how your finished application runs. If you selected a real device, Nougat will deploy the .app to that device, and optionally launch it there, to run or be debugged, and if you selected the iOS Simulator, the app will launch in the simulator on the Mac. (Obviously, an app cannot be deployed or run on the generic “iOS Device”, that option is for building the app only.)
Debugging the application is almost unspectacular, in spite of a lot of effort having gone (and continuing to go) into this: Nougat adds a full Mac and iOS debugging engine into Visual Studio, based on the LLDB debugger, allowing you to use virtually all of the capabilities of the Visual Studio debugger that you are used to from .NET (and Java — where we did the same). You’ll be using the debugger as you always have:
Ok, so this post took you on a quick tour on what happens behind the scenes when you press “Start” to build and run your Mac or iOS project.
In hindsight, there’s a lot happening, but none of it is any black magic. Nougat takes care of all the gory details for you, so you don’t have to worry about provisioning profiles, code signing and the like, but it will document all the steps it takes (and any command line tools it runs) in the MSBuild log, so that there’s no “black box” and you can know what’s going on, if you care.
Reminder: Keep in mind that the Nougat beta is active now (we started last Monday), so if you pre-ordered the Oxygene 5.2 bundle or own a Suite Subscription for Xcode (we’ll have to rename that one, won’t we?), you have access to the beta now. If you didn’t — well, what are you waiting for? Order your copy now!
Stay tuned for more.