Thanks to Xcode’s support for custom script build phases and environment variables compatible with GNU Make, you can integrate your PureScript code fairly painlessly. In this post I’ll show you the basics of using PureScript in an Xcode project. I’m just going to focus on that, so you won’t get any details on things like the (bidirectional) FFI here — I plan to cover that in another post.
To keep things simple, in this post I’ll assume:
- You’re running macOS El Capitan (10.11) or later
- You’re already familiar with PureScript, and have a recent version installed
- You have a recent version of Xcode (7.3+) installed
- You’re familiar with the basics of iOS/macOS development using Xcode
These instructions should apply to all Xcode-based targets, although I’ve only tested iOS and macOS for now.
Step 1: Install the PureScript-to-C++11 compiler,
- Go to the pure11 repo releases and download the latest
pcc.zipfile. If you already have a version installed, be sure to use a version dated 2016-11-22 or later, since that’s when extra support for Xcode was added.
- Unzip and copy to the same directory you installed other PureScript utilities (particulary
psc-package). This restriction might be removed later.
Step 2: Create a new Xcode iOS project in the standard way
Using Xcode’s menus:
Single View Application –>
Language: Objective-C (for now, we’ll do Swift in a later post)
Save the project anywhere you like
- Make sure to do your normal selection of Team, Provisioning Profile, etc. If you aren’t a registered developer and only plan to try this on the simulator, I believe you won’t need them.
Step 3: Create some PureScript code to use in your project
Create a directory anywhere you like. We’ll refer to it as your PureScript working directory. In that directory, create a subdirectory called “
src, create a PureScript source file, naming it “
PMath.purs”. Add the following code to
In the Terminal, from your working directory (one level up from
src), run the
pcccommand with just the
Step 4: Add PureScript code to your project settings
From Xcode’s “Project navigator,” select your project (topmost level). You should see various tabs in the main window. Select “Build Phases” and:
- Click the “+” –> “New Run Script Phase”
- Drag the new “Run Script” section to be before “Compile Sources”
Expand the “Run Script” section (triangle), and in its editor add the following:
cd path/to/your/working_dir sh psc-xcode.sh
It should look similar to this screenshot:
Now go to the “Build Settings” tab. Using the embedded search control (upper right), enter “header search”. If you don’t see any results, make sure you have the “All” button selected (instead of “Basic” or “Customized”). Select the “Header Search Paths” item and add the value “
path/to/your/working_dir/output” to it, meaning the “
output” subdirectory in your working directory (it doesn’t exist yet, but it will be generated during the build process). Make sure to press “return” to save the value.
Again from “Build Settings,” change your search term to “linker flags” to find “Other Linker Flags.” Add the values
-lc++ path/to/your/working_dir/output/bin/purescript.o”, as shown below. This “
.o” file is a native combined object file containing all of your compiled PureScript modules (sort of like a static lib), which will be generated during the build process. Again, remember to press “return”.
Step 5: Add some Objective-C++ code that calls your PureScript code
In your Xcode project, rename
ViewController.mm— make sure you do this from Xcode, not the Terminal.
ViewController.mmyou should see implementations for methods like
viewDidLoad. Add the implementation for
viewDidAppearshown below, as well as adding
using PMath::fib;near the top. Ignore any of the “live” errors for now.
Step 6: Build the project and run it
For now, make sure your project is set to build a simulator target (it should be, by default). Build using Xcode’s usual menu, Product –> Build (or shortcut Command-B). You should get a “build succeeded”.
Run it! (menu Product –> Run or shortcut Command-R)
With Debug builds, you can use Xcode’s debugger as well (on the generated C++ code):
You can now proceed to make changes to any source files (including your PureScript ones) and simply rebuild/test/repeat using Xcode. As you’re developing your app, if you just want to type check your PureScript changes (not recompile all the way to a binary target), use Terminal to run “
make codegen” from your working directory.
If you take a peek at the
psc-xcode.sh script, you’ll see that your compiled PureScript C++ objects will respect your project settings for things like Debug/Release builds and target architecture — and will rebuild appropriately if any of these things change. This also means you can do device hardware builds; as with any normal iOS project, simply change your target to one of the device variants and build.