Skip to content

Commit

Permalink
Localize libffiInstallDir and various update to the README now that b…
Browse files Browse the repository at this point in the history
…uild_llvm no longer calls build_libffi and the auto**** tools is no longer necessary
  • Loading branch information
light-tech committed Dec 17, 2022
1 parent 8e51b8c commit 364b93e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 30 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The goal of this project is to illustrate how to use LLVM + Clang to provide an

For the eager reader, we provide a sample iOS app project which has **NO license attached** so feel free to do whatever you want with it.
In this app, we use Clang's C interpreter example located in `examples/clang-interpreter/main.cpp` of Clang source code to _interpret a simple C++ program_ and _print out the output on the iOS app's user interface_.
(The file was renamed to `Interpreter.cpp` to fit in with iOS development style.)
(The file was renamed to `Interpreter.cpp` to fit in with iOS development style. Also note that the example was removed from LLVM 14 but it should be available prior.)
The code is pretty much copied verbatim except for some minor modifications, namely:

1. We change the `main` function name to `clangInterpret` since iOS app already has `main` function.
Expand Down Expand Up @@ -67,24 +67,26 @@ I recommend reading [LLVM Programmer's Manual](https://llvm.org/docs/Programmers
- Note that we need the Xcode command line tools as well.
* [CMake](https://cmake.org/download/): See [installation instruction](https://tudat.tudelft.nl/installation/setupDevMacOs.html) to add to `$PATH`.
* [Ninja](https://ninja-build.org/): Download the [binary](https://github.com/ninja-build/ninja/releases) and add it to `$PATH`.
* Various GNU build tools [autoconf](https://www.gnu.org/software/autoconf/), [automake](https://www.gnu.org/software/automake/) and [libtool](https://www.gnu.org/software/libtool/): You can use our script `build-tools.sh` to create a local copy for building LLVM.

Except for Xcode, the other items can be easily installed with Homebrew:
```shell
brew install cmake ninja autoconf automake libtool
brew install cmake ninja
```

_WARNING_: It has come to our attention that LLVM's CMake Build configuration have some dependency discovery that might be interfered by Homebrew. For example, LLVM depends on `libz` that is both supplied by Xcode and Homebrew. Since we are building for iOS, we really want the Xcode version of the library. But CMake can discover the Homebrew version and uses it instead! So you might want to build on a pristine machine. Don't get yourself **Homescrewed**<sup>TM</sup>!

### Build LLVM and co.

Apple has introduced [XCFramework](https://developer.apple.com/videos/play/wwdc2019/416/) to allow packaging a library for multiple-platforms (iOS, Simulator, watchOS, macOS) and CPU architectures (x86_64, arm64) that could be easily added to a project.
Apple has introduced [XCFramework](https://developer.apple.com/videos/play/wwdc2019/416/) to allow packaging a library for multiple-platforms (iOS, Simulator, watchOS, macOS) and CPU architectures (x86_64, arm64) that could be easily added to a project so that we do not have to switch out the libraries when we build the app for different targets (e.g. testing the app on real iPhone arm64 vs on the simulator x86_64).

Our script [build-llvm.sh](build-llvm.sh) builds LLVM for several iOS platforms and [create-xcframework.sh](create-xcframework.sh) packages it as an XCFramework so we do not have to switch out the libraries when we build the app for different targets (e.g. testing the app on real iPhone arm64 vs simulator x86_64). The script assumes the various tools aforementioned are installed and asccessible in `$PATH`.
Our script [build-llvm.sh](build-llvm.sh) provides functions to build LLVM and libffi dependency for several iOS platforms.
It also has a function `create_xcframework` to produce an XCFramework from them.
The script assumes the various tools aforementioned are installed and asccessible in `$PATH`.

At this repo root:
```shell
source build-llvm.sh
build_libffi iphoneos
build_llvm iphoneos # iphonesimulator maccatalyst iphonesimulator-arm64 maccatalyst-arm64
create-xcframework iphoneos # iphonesimulator maccatalyst
```
Expand Down
46 changes: 21 additions & 25 deletions build-llvm.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# Build LLVM XCFramework
#
# We assume that all required build tools (CMake, ninja, etc.) are either installed and accessible in $PATH
# or are available locally within this repo root at $REPO_ROOT/tools/bin (building on GitHub Action).
# We assume that all required build tools (CMake, ninja, etc.) are either installed and accessible in $PATH.

# Assume that this script is source'd at this repo root
export REPO_ROOT=`pwd`

### Setup $targetBasePlatform, $targetArch and $libffiInstallDir from platform-architecture string
### Setup the environment variable $targetBasePlatform and $targetArch from the platform-architecture string
### Argument: the platform-architecture string, must be one of the following
###
### iphoneos iphonesimulator iphonesimulator-arm64 maccatalyst maccatalyst-arm64
###
### The base platform would be one of iphoneos iphonesimulator maccatalyst and the architecture
### would be either arm64 or x86_64.
setup_variables() {
local targetPlatformArch=$1

Expand Down Expand Up @@ -37,7 +42,8 @@ setup_variables() {
esac
}

# Build libffi for a given platform
### Build libffi for a given platform
### Argument: the platform-architecture
build_libffi() {
local targetPlatformArch=$1
setup_variables $targetPlatformArch
Expand Down Expand Up @@ -86,7 +92,7 @@ build_libffi() {
done

local libffiInstallDir=$libffiBuildDir/Release-$targetBasePlatform
# lipo -info $libffiInstallDir/libffi.a
lipo -info $libffiInstallDir/libffi.a
mv $libffiInstallDir $REPO_ROOT/libffi-$targetPlatformArch
}

Expand All @@ -98,23 +104,15 @@ get_llvm_src() {
mv llvm-project-15.0.6.src llvm-project
}

# Prepare the LLVM built for usage in Xcode
### Prepare the LLVM built for usage in Xcode
### Argument: the platform-architecture
prepare_llvm() {
local targetPlatformArch=$1
local libffiInstallDir=$REPO_ROOT/libffi-$targetPlatformArch

echo "Prepare LLVM for $targetPlatformArch"
cd $REPO_ROOT/LLVM-$targetPlatformArch

# Remove unnecessary executables and support files
#rm -rf bin libexec share

# Move unused stuffs in lib to a temporary lib2 (restored when necessary)
#mkdir lib2
#mv lib/cmake lib2/
#mv lib/*.dylib lib2/
#mv lib/libc++* lib2/
#rm -rf lib2 # Comment this if you want to keep

# Copy libffi
cp -r $libffiInstallDir/include/ffi ./include/
cp $libffiInstallDir/libffi.a ./lib/
Expand All @@ -132,19 +130,16 @@ prepare_llvm() {
rm -rf lib/*.a
}

# Build LLVM for a given iOS platform
# Assumptions:
# * ninja was extracted at this repo root
# * LLVM is checked out inside this repo
# * libffi is either built or downloaded in relative location libffi/Release-*
### Build LLVM for a given iOS platform
### Argument: the platform-architecture
### Assumptions:
### * LLVM is checked out inside this repo
### * libffi is built at libffi-[platform]
build_llvm() {
local targetPlatformArch=$1

# build_libffi $targetPlatformArch

local llvmProjectSrcDir=$REPO_ROOT/llvm-project
local llvmInstallDir=$REPO_ROOT/LLVM-$targetPlatformArch
libffiInstallDir=$REPO_ROOT/libffi-$targetPlatformArch
local libffiInstallDir=$REPO_ROOT/libffi-$targetPlatformArch

setup_variables $targetPlatformArch

Expand Down Expand Up @@ -247,6 +242,7 @@ merge_archs() {
}

# Input: List of (base) platforms to be included in the XCFramework
# Argument: the list of platform-architectures to include in the framework
create_xcframework() {
local xcframeworkSupportedBasePlatforms=("$@")

Expand Down

0 comments on commit 364b93e

Please sign in to comment.