11

How to cross-compile clang/llvm for iOS? I need to get libclang (.a or .dylib i believe) to use it via C API in my iOS app.

4ntoine
  • 19,816
  • 21
  • 96
  • 220
  • 2
    There's already a build of a complete LLVM toolchain (including libllvm and libclang) by C0deh4cker in Cydia. You can download the package from his repository using a browser or wget/curl, then add the `.a` libraries to your project. You can't use `.dylib`s on a non-jailbroken device (you **can** use them if you jailbreak, though.) – The Paramagnetic Croissant May 30 '14 at 04:42
  • Thanks, the reason i'm asking is that llvm 3.1 is available in his repo and 3.4 is the latest. I believe a lot was done for one year between 3.1 and 3.4 releases – 4ntoine May 30 '14 at 05:52

2 Answers2

12
# Get LLVM/Clang

mkdir llvm
curl -O http://llvm.org/releases/3.4/llvm-3.4.src.tar.gz
tar xzfv llvm-3.4.src.tar.gz
cd llvm-3.4/tools/
curl -O http://llvm.org/releases/3.4/clang-3.4.src.tar.gz
tar xzfv clang-3.4.src.tar.gz
mv clang-3.4 clang
cd ..

# Assuming Xcode 5.1 (LLVM 3.5+ requires -stdlib=libc++ as well)

export CC="clang -arch armv7 -mios-version-min=5.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk"
export CXX="clang++ -arch armv7 -mios-version-min=5.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk"

mkdir build
cd build

../configure \
  --prefix=/Users/thomas/tmp/llvm-ios \
  --host=arm-apple-darwin11 \
  --enable-optimized \
  --disable-assertions

unset CC CXX # important! (Otherwise the next step will fail)

make VERBOSE=1 -j...

After a while you will get:

/Users/thomas/tmp/llvm-3.4/lib/Support/Unix/Program.inc:46:10: fatal error: 'crt_externs.h' file not found
#include <crt_externs.h> // _NSGetEnviron
         ^

Comment the header file and hack the call to _NSGetEnviron() out (you'll get this three times)

make install
Thomas
  • 3,074
  • 1
  • 25
  • 39
  • i've got an error you wrote about. What is _NSGetEnviron()? I've googled a bit but i did not found it in documentation. Is it ok to return nil for it? – 4ntoine May 31 '14 at 06:43
  • 1
    Yes, replacing them with NULL should be "safe". _NSGetEnviron() is not allowed on iOS (otherwise Apple will reject your App: https://www.google.com/#q=_NSGetEnviron()+ios+rejected) – Thomas May 31 '14 at 07:50
  • thanks a lot! are there any other invocations that can prevent the app from being distributed via AppStore? – 4ntoine May 31 '14 at 13:06
  • Sorry, I don't know, only Apple can tell you. I don't know if Clang invokes any other private iOS API calls. – Thomas May 31 '14 at 13:10
  • I wanted to test it in simulator and i'm getting linker error: file was built for x86_64 which is not the architecture being linked (i386). What should i change in order to compile for simulator? – 4ntoine Jun 02 '14 at 16:35
  • `-arch i386` probably. If you get x86_64, then you didn't follow the instructions exactly anyway, it should show armv7 not x86_64. Ensure `lipo -info .a` says armv7. – Thomas Jun 03 '14 at 09:11
  • no, i was able to compile for arm just perfect. the problem is that simulator is not arm, it's i386. now i try to change it to compile for i386 and then i will be able to use lipo to create fat library. i also tried to use i386 and choose iPhoneSimulator path – 4ntoine Jun 03 '14 at 09:13
  • Ok. You can usually pass multiple arch flags at a time, e.g.: `-arch armv7 -arch arm64 -arch i386` no need to lipo them manually. – Thomas Jun 03 '14 at 09:14
  • i though i should use another `-isysroot` for simulator: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk so i'm sure i can use different -arch at a time – 4ntoine Jun 03 '14 at 09:16
  • Depends whether the SDK contains the i386 arch or not, better try your solution first. – Thomas Jun 03 '14 at 09:17
  • sorry, it was: "i'm not sure i can't use .. at time" – 4ntoine Jun 03 '14 at 09:30
  • http://stackoverflow.com/questions/24011670/how-to-cross-compile-llvm-clang-for-ios-simulator – 4ntoine Jun 03 '14 at 09:32
  • I had the following error : `clang/llvm-3.7.0.src/lib/LineEditor/LineEditor.cpp:17:10: fatal error: 'histedit.h'` file not found, any idea ? – Olórin Oct 17 '15 at 18:52
  • 1
    @user10000100_u: Try `--disable-libedit` or `--enable-libedit=no`. – Thomas Oct 18 '15 at 09:08
  • @Thomas Great, made my day ! (Had first a couple of crt_externs.h/_NSGetEnviron error easily fixed.) I confirm I now have clang and clang++ working on my iPad mini 3. ;-) Question (orthogonal to the current one) : where do I find all libraries files ? (Like iostream etc etc...) – Olórin Oct 18 '15 at 11:03
  • @user10000100_u: :-) The headers and libraries are included in the Xcode iOS SDK. – Thomas Oct 18 '15 at 12:20
  • @Thomas I know but I thought about this : when I build clang+llvm for my macbook, I had an `/include/c++` folder among `/include/clang`, `/include/clang-c`, `/include/llvm` and `/include/llvm-c` folders, and I did not have the same `/include/c++` after the cross build for iOS. Maybe I could use this `/include/c++` ? Or is the headers and libs from the iOS SDK better ? In fact, is there an option to pass to configure that would allow me to produce so an `/include/c++` folder for my iOS target ? – Olórin Oct 18 '15 at 12:24
  • @user10000100_u: You need the iOS SDK. `clang -isysroot `. – Thomas Oct 18 '15 at 12:27
  • @Thomas Ok, fair enough. (Really the) last question : which clang environment variable (if any) should I modify by an export so that I don't have to `-isysroot` when I only want to `#include ` and other "basic" headers ? – Olórin Oct 18 '15 at 12:29
  • @user10000100_u: There is no env. variable for it. You could write a simple bash wrapper script which adds `-isysroot` for you. – Thomas Oct 18 '15 at 12:37
  • @Thomas Oh ok thanks. I naïvely thought that there was one, as the ones for shared libs for gcc, like `LD_LIBRARY_PATH`etc. Ok, will stop questionning you ;-) and will try to build GNU stuff on my iPad now that I have a c/c++ compilers and linkers ;-) Thanks again for all your help. – Olórin Oct 18 '15 at 12:39
  • @Thomas Hum, really sorry, but last point ;-) : when you write ``, does this mean that, only to be able to `#include `, I am obliged to have an SDK folder on my iPad having the same tree structure as the one (concerning iOS8.4) on my mac !? – Olórin Oct 18 '15 at 12:57
  • @user10000100_u: Copy the iOS SDK onto the device, then pass `-isysroot ` to clang. – Thomas Oct 18 '15 at 13:10
  • @Thomas Ok then. Thx ! But now I have a really serious issue : `clang++: error: unable to execute command: Executable "ld" doesn't exist!`, especially as I see that `llvm-ld` has been removed since 3.4... Fun begins now. ;-) – Olórin Oct 18 '15 at 13:19
  • @Thomas Out of curiosity : did you test all of this on an iDevice ? How did you manage to have/build a descent linker/`"ld` replacement" ? – Olórin Oct 18 '15 at 14:01
  • @Thomas Retrospectively I think there must be an issue with the `configure` step. On the iDevice when I try to compile an only "return 0" main cpp with `clang++ -v testcpp.cpp -o testcpp` it produce a natural error saying that `ld` is missing, but it shows something strange : `"ld" -demangle -dynamic -arch armv4t -macosx_version_min 10.10.0 -o testcpp /var/tmp/testcpp-a74741.o -lc++ -lSystem` What does this `-macosx_version_min 10.10.0` do here ? It is as if the compiler was looking for the (mac os) linker of the plateform it was cross-build with instead of the iOS one... What do you think ? – Olórin Oct 18 '15 at 17:41
  • Hello there, sorry to revive this thread, @Thomas may you have any suggestions on building clang/llvm as a library now, as in newer llvm versions `configure` is deprecated, the only option to cross-compile is to use cmake, but I hate to say that I'm stuck. Was able to update the patch [found here](https://github.com/topmonks/libclang-ios) to match the changes in llvm source and also [saw this gist](https://gist.github.com/holzschu/9aa539ba7f44b5ea0c18dccdfd85b212). But what I'm failing at is the last step: totally lost in build flags and unable to deduce what I really want. – Ilya Oct 22 '20 at 08:09
1

iOSToolChain in the https://coolstar.org/publicrepo/ in Cydia.

Clang and LLVM on iOS.

I used it on a jailbroken device to compile C apps for iOS (ARM 32 bit or ARM 64 bit).

There is a good reference post here: Compile IOS program from linux commandline

rustyMagnet
  • 3,479
  • 1
  • 31
  • 41