You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+38-19Lines changed: 38 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,20 +7,25 @@ Build LLVM for iOS (physical device and simulator)
7
7
From [the official instructions](https://llvm.org/docs/GettingStarted.html):
8
8
9
9
```shell
10
-
git clone https://github.com/llvm/llvm-project.git # Alternatively, download and extract the monorepo source code from https://releases.llvm.org/download.html
10
+
# Alternative to git clone is to download and extract the monorepo source code from https://releases.llvm.org/download.html
Our script [buildllvm-iOS.sh](buildllvm-iOS.sh) and [buildllvm-iOS-Simulator.sh](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:
18
+
Our script [buildllvm-iOS.sh](buildllvm-iOS.sh) and [buildllvm-iOS-Simulator.sh](buildllvm-iOS-Simulator.sh) build LLVM, Clang, LLD and LibC++ for iOS and iOS simulator respectively.
19
+
We disable various stuffs such as `terminfo` since there is no terminal in iOS; otherwise, there will be problem when linking in Xcode.
20
+
Needs:
18
21
*[Xcode](https://developer.apple.com/xcode/): Download from app store.
19
22
*[CMake](https://cmake.org/download/): See [installation instruction](https://tudat.tudelft.nl/installation/setupDevMacOs.html) to add to PATH.
20
23
*[Ninja](https://github.com/ninja-build/ninja/releases): Download and extract the ninja executable to `~/Downloads` folder.
21
24
22
25
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).
23
-
Once the build process is completed, the library and include headers should be available at `~/Download/LLVM-iOS` or `~/Download/LLVM-iOS-Simulator`.
26
+
27
+
Once the build process is completed, the library and include headers should be installed at `~/Download/LLVM-iOS` or `~/Download/LLVM-iOS-Simulator`.
28
+
(We will subsequently refer to these directories as the _LLVM installation dir_.)
24
29
25
30
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/`:
26
31
```shell
@@ -31,13 +36,14 @@ mv lib/cmake lib2/
31
36
mv lib/*.dylib lib2/
32
37
```
33
38
Otherwise, iOS will crash when loading dynamic libraries.
34
-
Maybe remove the unnecessary stuffs in `bin` as well.
35
-
Running our script [prepare-llvm.sh](prepare-llvm.sh) in the LLVM installation folder i.e. `~/Download/LLVM-iOS` or `~/Download/LLVM-iOS-Simulator` will perform the necessary set-up.
39
+
Running our script [prepare-llvm.sh](prepare-llvm.sh) in the LLVM installation dir will perform the necessary set-up.
40
+
41
+
Optionally, you could move the `liblld*` to `lib2` as well and the `bin` since it's unlikely you need binary linkage and the `clang` command line program in iOS app.
36
42
37
43
Our Sample iOS Project
38
44
----------------------
39
45
40
-
We provide a sample iOS app project in the [Sample/](Sample) folder; no license attached so feel free to do whatever you want with it.
46
+
We provide a sample iOS app project in the [Sample/](Sample) folder; _no license attached_ so feel free to do whatever you want with it.
41
47
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.
42
48
(The file was renamed to `Interpreter.cpp` to fit in with iOS development style.)
43
49
The code is pretty much copied verbatim except for some minor modifications, namely:
@@ -48,18 +54,24 @@ The code is pretty much copied verbatim except for some minor modifications, nam
48
54
```c++
49
55
// llvm::llvm_shutdown();
50
56
```
51
-
so that you can call `clangInterpret` again in the app. Originally, the example was a one-shot command line program where this makes sense.
57
+
so that you can _call `clangInterpret` again_ in the app.
58
+
This line only makes sense in the original program because it was a one-shot command line program.
52
59
53
60
3. We add a third parameter
54
61
```c++
55
62
llvm::raw_ostream &errorOutputStream
56
63
```
57
-
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.
64
+
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 the user.
65
+
66
+
4.**For real iOS device**: The implementation of [`llvm::sys::getProcessTriple()`](https://github.com/llvm/llvm-project/blob/master/llvm/lib/Support/Host.cpp) is currently bogus according to the implementation of [`JITTargetMachineBuilder::detectHost()`](https://github.com/llvm/llvm-project/blob/master/llvm/lib/ExecutionEngine/Orc/JITTargetMachineBuilder.cpp): _FIXME: getProcessTriple is bogus. It returns the host LLVM was compiled on, rather than a valid triple for the current process._
67
+
So we need to add the appropriate conditional compilation directive `#if TARGET_OS_SIMULATOR ... #else ... #endif` to give it the correct triple. (The platform macro is documented at `<TargetConditionals.h>`.)
68
+
69
+
In the latest version, you should be able to edit the program, interpret it and see the output in the app UI.
58
70
59
-
In the latest version, you should be able to edit the program, interpret it and see the output.
60
71
Before building the project, you need to copy the LLVM installation folder, say `~/Download/LLVM-iOS-Simulator`, to the root folder of the project like this
61
72
```shell
62
-
cp ~/Download/LLVM-iOS-Simulator LLVM # Assuming at Sample project folder
73
+
# At Sample project folder:
74
+
cp ~/Download/LLVM-iOS-Simulator LLVM
63
75
```
64
76
Here, we copy the `LLVM-iOS-Simulator` to build the app and run it on the simulator.
65
77
@@ -68,7 +80,8 @@ Here, we copy the `LLVM-iOS-Simulator` to build the app and run it on the simula
68
80
69
81
Read on for details on how to create and configure your own project.
70
82
71
-
**Known Limitation**: For simulator, can only build **Debug** version only! The current app does not work on real device yet!
83
+
**Known Limitation**: For simulator, can only build **Debug** version only!
84
+
The current app does not work on real device yet (UI is OK but cannot interpret)!
72
85
73
86
Behind the Scene: Configure iOS App Xcode Project
74
87
-------------------------------------------------
@@ -77,12 +90,7 @@ These days, you probably want to write your app in _Swift_ whereas LLVM library
* Objective-C: simple class say `LLVMBridge` to expose service such as compilation; basically to convert data types between C++ and Swift such as Swift's `Data` to Objective-C's `NSData` to C++'s buffer `char*`.
83
-
* C++: actual implementation of processing functionality.
84
-
85
-
Go to [Further Readings](#further-readings) for more details.
93
+
Go to [Further Readings](#further-readings) for more details on Swift-C++ interoperability.
86
94
87
95
1. Create a new iOS app project in Xcode and copy an LLVM installation to the project folder.
88
96
Unfortunately, LLVM cannot build fat binary for iOS at the moment so we have to manually switch between the two LLVM installations when we switch testing between real iOS device (ARM) or iOS simulator (x86_64).
@@ -102,10 +110,12 @@ Add a new item `$(PROJECT_DIR)/LLVM/include`.
102
110
Again, go to **Build settings** your project and search for `bridg` and you should find **Objective-C Bridging Header** under **Swift Compiler - General**.
103
111
Set it to `PROJECT_NAME/LLVMBridge.h` or if you are using more than just LLVM, a header file of your choice (but that header should include `LLVMBridge.h`).
104
112
113
+
**Note**: Only Objective-C classes in *Objective-C Bridging Header* are visible to Swift!
At this point, we should be able to run the project on iOS simulator.
108
-
**To build the app on real iOS device, an extra step is needed.**
118
+
**To build the app for real iOS devices, an extra step is needed.**
109
119
110
120
5. Since we are using a bunch of precompiled static libraries (and not the actual C++ source code in our app), we need to disable bitcode. Search for `bitcod` and set **Enable Bitcode** setting to `No`.
111
121
@@ -116,7 +126,7 @@ Now you are ready to make use of LLVM glory.
116
126
Further Readings
117
127
----------------
118
128
119
-
You might want to start with _Anthony Nguyen_'s
129
+
To start, you might want to start with _Anthony Nguyen_'s
120
130
[Using C++ in Objective-C iOS app: My first walk](https://medium.com/@nguyenminhphuc/using-c-in-objective-c-ios-app-my-first-walk-77319d94a940)
121
131
for a quick intro on how to make use of C++ in Objective-C.
122
132
(Note that both C++ and Objective-C are extensions of C and reduces to C.)
@@ -125,5 +135,14 @@ An easy read on Objective-C and Swift interoperability could be found in
125
135
by _RDerik_.
126
136
Combining these two articles is the basis for our Sample app.
127
137
138
+
A typical approach to allow C++ in Swift-based iOS app will be using
139
+
*_Swift_ : Anything iOS-related (UI, file system access, Internet, ...)
140
+
*_Objective-C_ : Simple classes (like `LLVMBridge` in our Sample app) to expose service written in C++.
141
+
The main role is to convert data types between C++ and Swift.
142
+
For example: Swift's `Data` to Objective-C's `NSData` to C++'s buffer `char*` (and length).
143
+
*_C++_ : Actual implementation of processing functionality.
144
+
145
+
**Tip**: When writing bridging classes, you should use `NSData` for arguments instead of `NSString` and leave the `String <-> Data` conversion to Swift since you will want a `char*` in C++ anyway.
146
+
128
147
_Apple_'s [Programming with Objective-C](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011210)
129
148
is fairly useful in helping us write the Objective-C bridging class `LLVMBridge`: Once we pass to C++, we are in our home turf.
0 commit comments