From the official instructions:
git clone https://github.com/llvm/llvm-project.git # Alternatively, download and extract the monorepo source code from https://releases.llvm.org/download.html
cd llvm-project
mkdir build
cd build
cmake -G <generator> [options] ../llvm
Our script buildllvm-iOS.sh and buildllvm-iOS-Simulator.sh build LLVM, Clang and LLD for iOS and iOS simulator respectively. We disable various stuffs such as terminfo
since there is no terminal in iOS; otherwise, there will be problem when linking in Xcode. Needs:
- Xcode: Download from app store.
- CMake: See installation instruction to add to PATH.
- Ninja: Download and extract the ninja executable to
~/Downloads
folder.
Once the tools are ready, run the script in the llvm-project
top folder (or llvm-project-VERSION
if you download the source zipped package instead of cloning).
Once the build process is completed, the library and include headers should be available at ~/Download/LLVM-iOS
or ~/Download/LLVM-iOS-Simulator
.
Before being able to use in Xcode, in the built folder, we first need to move the lib/clang/
and lib/cmake
and lib/*.dylib
out of lib/
:
cd ~/Download/LLVM-iOS
mkdir lib2
mv lib/clang lib2/
mv lib/cmake lib2/
mv lib/*.dylib lib2/
Otherwise, iOS will crash when loading dynamic libraries.
We provide a sample iOS app project in the Sample/ folder; no license attached so feel free to do whatever you want with it.
In this project, we use Clang's C interpreter example located in examples/clang-interpreter/main.cpp
of Clang source code to interpret a simple C++ program.
(The file was renamed to Interpreter.cpp
to fit in with iOS development style.)
The code is pretty much copied verbatim except for some minor modifications, namely:
-
We change the
main
function name toclangInterpret
since iOS app already hasmain
function. -
We comment out the last line
// llvm::llvm_shutdown();
so that you can call clangInterpret
again in the app. Originally, the example was a one-shot command line program where this makes sense.
- We add a third parameter
llvm::raw_ostream &errorOutputStream
to clangInterpret
and replace all llvm::errs()
with errorOutputStream
so we can capture the compilation output and pass it back to the app front-end to display to users.
In the latest version, you should be able to edit the program, interpret it and see the output.
Read on for details on how to create and configure your own project.
- Create a new iOS app project in Xcode, say
Sample
and copy the built folder, say~/Download/LLVM-iOS-Simulator
, to the root folder of your project:
cp ~/Download/LLVM-iOS-Simulator LLVM # Assuming at Sample project folder
We shall assume the target folder is LLVM
. Note that you must copy the LLVM-iOS-Simulator
when running on simulator.
-
Add the LLVM static libraries to your project by right click on the Sample project, choose Add files to "YOUR PROJECT NAME" and select the LLVM/lib folder. Enable Create groups but not Copy items if needed.
-
Next, we add
LLVM/include
to header search path. Go to Build settings your project, click on All and search forheader
. You should find Header Search Paths under Search Paths. Add a new item$(PROJECT_DIR)/LLVM/include
.
- Finally, you probably want to write your app in Swift but LLVM library is written in C++ so we need to create a bridge to expose LLVM backend to your app Swift frontend.
This is accomplished via Objective-C i.e. Swift -> Objective-C -> C++.
Add to your project a new header file, say
LLVMBridge.h
and the implementation Objective-C++ file, sayLLVMBridge.mm
. We set Objective-C bridging header to expose the Objective-C (and hence, C++) code to Swift. Go to Build settings your project and search forbridg
and you should find Objective-C Bridging Header under Swift Compiler - General. Set it toSample/LLVMBridge.h
or a header file of your choice (but that header should includeLLVMBridge.h
).
Now you are ready to make use of LLVM glory.
You might want to start with Anthony Nguyen's Using C++ in Objective-C iOS app: My first walk for a quick intro on how to make use of C++ in Swift. This is the basis for our Sample app.
More advanced coverage on interoperability could be found in Understanding Objective-C and Swift interoperability by RDerik and Advanced ObjC <-> Swift Interoperability by Nikita Lutsenko.
Last but not least, Apple's Programming with Objective-C is fairly useful in helping us write the Objective-C bridging class: Once we pass to C++, we are in our home turf.