Building Clang and libc++ on Ubuntu Linux
Posted on January 17, 2013 by Sol

Updated on 26 January 2014 for Ubuntu 12.04.4 and Clang 3.4.

Clang with libc++ represents today a viable alternative to GCC for C and C++ programmers. I make no claim that Clang with libc++ is necessarily superior to GCC with libstdc++, but it is definitely a more feature complete C++11 alternative. According to the libc++ website, libc++ is 100% complete C++11 implementation on Apple’s OS X and, from my tests, works equally well on Linux. Even if you plan to ship your C++ application compiled with GCC, I think it is a good test to check your app for errors by building it with a different compiler and library.

In this short post, I’m going to show you how to build the latest Clang and libc++ on a Linux box. I’ve tested this procedure on Ubuntu 12.04.4, Ubuntu 12.10 and Linux Mint 14.

Let’s start by updating your Linux system (this is a recommended but optional step), open a Terminal and paste the next two lines:

1
2
sudo apt-get update
sudo apt-get upgrade

Now, let’s install some additional, but necessary, apps:

1
sudo apt-get install g++ subversion cmake

Next step, is to get the latest version of Clang and LLVM:

1
2
3
4
5
cd ~
mkdir Clang && cd Clang
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

and to build Clang and LLVM:

1
2
3
4
5
cd ..
cd ..
mkdir build && cd build
../llvm/configure --prefix=/usr/clang_3_4 --enable-optimized --enable-targets=host --disable-compiler-version-checks
make -j 8

The above step will take some time …

Let’s install Clang:

1
sudo make install

In order to be able to use Clang we’ll need to add it to our system path, you can do this with:

1
export PATH=/usr/clang_3_4/bin:$PATH

or, to permanently add Clang to your system path, paste the above line at the end of your .bashrc file. If you don’t know how to find .bashrc, try this:

1
2
3
cd ~
gedit ~/.bashrc
. .bashrc

For building libc++, we’ll need the include path used by your system C++ compiler and the target platform, we can get these with:

1
echo | g++ -Wp,-v -x c++ - -fsyntax-only

This is the result of the above line on my system:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
sol@sols:~$ echo | g++ -Wp,-v -x c++ - -fsyntax-only
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/4.6
 /usr/include/c++/4.6/x86_64-linux-gnu/.
 /usr/include/c++/4.6/backward
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
sol@sols:~$ 

The first highlighted line from above gives us the include path and the second line the target platform (a 64 bits Linux system). As a side note, on Ubuntu 12.10 you will get 4.7 instead of 4.6!

Let’s get and install the latest libc++:

1
2
3
4
5
6
cd ~/Clang
svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
mkdir build_libcxx && cd build_libcxx
CC=clang CXX=clang++ cmake -G "Unix Makefiles" -DLIBCXX_CXX_ABI=libsupc++ -DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.6/;/usr/include/c++/4.6/x86_64-linux-gnu/" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr $HOME/Clang/libcxx
make -j 8
sudo make install

If you build libc++ on a different system, remember to change the include path for your system and the target machine accordingly. For e.g. on Ubuntu 12.10 or Linux Mint 14 (64 bits), the above highlighted line will became:

1
CC=clang CXX=clang++ cmake -G "Unix Makefiles" -DLIBCXX_CXX_ABI=libsupc++ -DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr $HOME/Clang/libcxx

Now, you should be able to compile any valid C++11 program with:

1
clang++ -std=c++11 -stdlib=libc++ <your_program_name>

Let’s test our new compiler, save the next piece of code in a file named example_001.cpp:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
//Program to test the new C++11 lambda syntax
#include <iostream>

using namespace std;

int main()
{
    cout << [](int m, int n) { return m + n;} (2,4) << endl;
    return 0;
}

Here is the result of building and running the above code on my machine:

1
2
3
clang++ -std=c++11 -stdlib=libc++ example_001.cpp -o example_001
./example_001
6

Obviously, you don’t need Clang and libc++ to compile a C++11 lambda, GCC will work just fine. Let’s try something that, at the time of this writing, it is not possible to compile with GCC:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//Program to test the new C++11 regular expressions syntax
#include <iostream>
#include <regex>
#include <string>

using namespace std;

int main()
{
    string input;
    regex rr("((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?((e|E)((\\+|-)?)[[:digit:]]+)?");
    //As long as the input is correct ask for another number
    while(true)
    {
        cout<<"Give me a real number!"<<endl;
        cin>>input;
        //Exit when the user inputs q
        if(input=="q")
            break;
        if(regex_match(input,rr))
            cout<<"float"<<endl;
        else
        {
            cout<<"Invalid input"<<endl;
        }
    }
}

If you are interested in learning more about the new C++11 syntax I would recommend reading Professional C++ by M. Gregoire, N. A. Solter, S. J. Kleper 2nd edition:

or, if you are a C++ beginner you could read C++ Primer (5th Edition) by S. B. Lippman, J. Lajoie, B. E. Moo.

blog comments powered by Disqus