ToT Clang / LLVM in Xcode

It should be a trivial task.  It’s certainly an obvious goal, and I was quite perturbed to find no clear instructions, very little discussion of it at all, and a few awkward speed-bumps on the way.  But I did figure it out.  So here it is, for those lucky enough to find this before they too spend a couple of frustrating hours deducing it by trial and error.

First, follow the instructions from llvm.org:

svn co https://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co https://llvm.org/svn/llvm-project/cfe/trunk clang
cd ../projects
svn co https://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
cd ../..
mkdir build
cd build
../llvm/configure --enable-optimizations
make -j `sysctl -n hw.logicalcpu`

FYI other configure flags of interest include:

  • --enable-debug-runtime (meaning debug symbols for the runtime libraries)
  • --enable-debug-symbols (meaning for the compiler itself)
  • --enable-doxygen (generate documentation)
  • --enable-shared (use shared libraries instead of static ones)

You now have the compiler built – you’ll find the /bin and /lib folders under “Release+Asserts” (or maybe “Debug+Asserts”, or just “Release”/”Debug”, depending on your exact configure flags).

Next, getting Xcode to use it.  To begin with, grab a handy template plug-in by Gus Mueller.  Unzip that and edit the Info.plist and the xcspec file contained within, to at a minimum specify the path to your build of the compiler, and perhaps change the identifiers to your own name.

Aside: Be careful if you’re using a text editor like TextEdit – in my case it thought it’d be hilarious to randomly replace normal quote characters with “smart” quotes, the presence of which will cause Xcode to refuse to load the plugin completely.  Thanks, TextEdit.

Next, drop your xcplugin bundle into /Library/Application Support/Developer/Shared/Xcode/Plug-ins/.  The “Plug-ins” folder probably won’t exist yet; feel free to create it.

Note: I’m assuming you’re using Xcode 4.3 or later – i.e. the “App Store”-compatible Xcode that’s a single app, rather than the older Developer folder.  If you’re using an earlier Xcode, you’ll need to put your plug-in in /Developer/Library/Xcode/Plug-ins instead.

Now Xcode will show (after you relaunch it) your custom compiler as an option in the build settings of any given project (see the GCC_VERSION setting, labelled “Compiler for C/C++/Objective-C”).

However, there’s a few wrinkles:

  1. If you try to compile a project that uses ARC, you’ll get an obnoxious linker error complaining about not being able to find libarclite_macosx.a.  This is apparently some private Apple library that you cannot get the source to, let alone have bundled into the llvm repositories.  Luckily, if you’re on Lion or later, you’ll find it already installed in /usr/lib/arc/.  Copy that whole folder to the “lib” folder in your custom-built clang, and you’ll be good to go.
  2. The real-time syntax checking within Xcode will still use the built-in llvm, so any new features you use (like auto-boxing or NSNumber/NSDictionary/NSArray literals) will confuse the hell out of it.  I’m searching for a solution for that (but I presume Xcode links in the relevant parts of llvm directly, possibly statically, so I doubt it’s trivial or even advisable).  If it really bothers you, you can disable it by turning off “Show live issues” in the “General” tab of Xcode’s preferences.
  3. The Static Analyzer phase still won’t use your custom compiler.  The only way I’ve found around that so far is to explicitly override CC to point to your custom compiler (which should be totally redundant; sigh).  You can do that either via an xcconfig file or via the “Add Build Setting” > “Add User-Defined Setting” button at the bottom right of the Build Settings tab  in the project/target inspector.

References:

12 thoughts on “ToT Clang / LLVM in Xcode”

  1. Just as an aside, I’ve found that adding a user defined setting of “CC” equal to /opt/bin/clang is preferable to using the plugin. Just change your build script to use:
    ./configure –prefix=/opt –enable-optimized

    You’ll even be able to use the latest static analyzer as well.

    Reply
  2. It seems I can’t get this to work… I followed your instructions and edited only the paths ans nothing else (for troubleshooting) in the .xcspec file to “/Users/JayZ/usr/bin/clang” and, since I am using XCode 4.2, copied the xcplugin to /Developer/Library/Xcode/Plug-ins. Unfortunately I fail to be able to choose the compiler within XCode. I am using Snow Leopard. Any help appreciated ;)

    Reply
  3. Gus’ suggestion works great for me. I set CC=/path/to/clang in my .xcconfig file and presto! I still have to copy the ‘arc’ folder as the article describes. After that I got other link errors though:

    Undefined symbols for architecture x86_64:
    “_llvm_gcda_emit_arcs”, referenced from:
    “_llvm_gcda_emit_function”, referenced from:
    “_llvm_gcda_end_file”, referenced from:
    “_llvm_gcda_start_file”, referenced from:

    Which I fixed by temporarily disabling code coverage (GCC_INSTRUMENT_PROGRAM_FLOW_ARCS, GCC_GENERATE_TEST_COVERAGE_FILES).

    Reply
  4. Setting CC=/path/to/clang in an .xcconfig file works well for me too, but clang (llvm 3.3 svn) isn’t able to find the , , or library headers in my code. [This is true for the released version of clang (llvm 3.2) as well.] The Apple-supplied version of clang (Xcode installed command-line tool), by contrast, finds the header files. (I’m running OS X 10.8.2).

    Does anyone know how to show clang where these header files are located?

    Reply
  5. PS. The library headers that are missing are for cmath, complex, and iostream (the angular brackets were edited out in my first comment).

    Reply
  6. Using libc++ and -fsanitize=undefined, i386 architecture, I get link errors on 4 missing symbols:


    typeinfo for __cxxabiv1::__class_type_info
    typeinfo for __cxxabiv1::__si_class_type_info
    typeinfo for __cxxabiv1::__vmi_class_type_info
    typeinfo for std::type_info

    Any idea what I’m missing?

    Reply
  7. XCode 4.6.2 (OS X 10.8.4) correctly recognizes my locally installed clang, but in case of errors it fails in displaying the error line(s). The only output available is ‘Command /usr/local/bin/clang failed with exit code 1’ along with the output resulting from the compilation attempt.

    How can I instruct XCode so as to highlight the error line(s) as if I were using the built-in clang? Thanks.

    Reply

Leave a Reply to Yuriy Cancel reply