How to build Clang toolchains for Android

by zet

Build the Clang Toolchains for Android

The following process is used to build the Clang that is used by both the Android platfrom and the NDK. And this process is done in the AOSP tree.

Both GNU/Linux and Windows toolchains are built on GNU/Linux machines. Windows host binaries are built with mingw.

My developing environment is Linux Mint 17.3


Source versions in AOSP

  • Create the work directory
  mkdir working_directory
  TOOLCHAINS_BUILD_TOP=work_direcory # optional, only for clear description
									                   # below
  export TOOLCHAINS_BUILD_TOP
  cd work_directory				           # build will be done in this directory

There are two versions Clang/LLVM code tree in AOSP, the first is: aosp/platform/external/(clang|llvm), and the second is: aosp/toolchain/(clang|llvm).

Something most important is:

Personal Communication from Stephen Hines @ google

the first tree is a dead-end. That was a prior forked version of Clang/LLVM was previously used for the NDK conpiler (but not for the AOSP platform compiler). We have since condensed down to use the same conpiler for the NDK as is used by the platform (AOSP).

So, the first tree(toolchain/clang) is a dead one. But if you are very curious about what had the googelers done to the toolchain/(clang|llvm), you can clone the source code.

  # ustc source is available too
  git clone https://aosp.tuna.tsinghua.edu.cn/toolchain/clang
  git clone https://aosp.tuna.tsinghua.edu.cn/toolchain/llvm
  git branch -a
  git branch release_36   # Only doing a checkout, can see the source code

Now, we have the source code of NDK compiler, download the Clang/LLVM-3.6 official source, and compare the two project(NDK version and official version), you will see there is little differece between them. NDK Clang version added some class to support new ABI(e.g. NDK64ABI) and new Target(e.g. Android64Target), that’s all.

Prerequisites

  • get and config the repo

    mkdir ~/bin
    PATH=~/bin:$PATH
    curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    chmod a+x ~/bin/repo
    
  • checkout the clang

    We have three source repository that repo can get the source code in The following section, The last one is google official source had fucked by GFW. Only execute one of the three repo init below.

    repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b llvm
    repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b llvm
    repo init -u https://android.googlesource.com/platform/manifest -b llvm  
    
    repo sync  # get the toolchain source
    
    • Some description about repo

      • The souce code of toolchain should be get by repo, repo is designed for manage the complex dependencies of sub-project of AOSP, implementated by a set of Python scripts. repo wraps some git plumbing, and according to a config file locate at $TOOLCHAINS_BUILD_TOP/.repo/manifests/default.xml to deal with the dependency and repository locations of sub-project of every topic(which is a set of git branchs). $TOOLCHAINS_BUILD_TOP/.repo/manifests is a local git respository contains versions of config file. According to this, we have a new way get topic(for example, after we get clang/llvm, we want gcc now).
        cd $TOOLCHAINS_BUILD_TOP/.repo/manifests
        git branch -a 	  # list of all the topic,
                                    # e,g. : remotes/origin/gcc, the topic of gcc
        git checkout gcc  # the config file : default.xml is for gcc NOW
        repo sync			    # get the gcc source
      

      Follow the analysis, we may get a successfull compiled Clang/LLVM topic according to the config file(default.xml), but there is another magic piece: the relationship of every sub-project in local of a successfull Clang/LLVM topic is not identical with the repository of same name of AOSP. So, recommending for repo.

  • additional java dependencies

    There is request about java environment in line 200+ at $TOOLCHAINS_BUILD_TOP/build/core/main.mk : at least OpenJDK1.8.

    sudo add-apt-repository ppa:openjdk-r/ppa # add PPA
    sudo apt-get update 
    sudo apt-get install openjdk-8-jdk
    sudo update-alternatives --config java    # config the default java
    sudo update-alternatives --config javac   # config the default javac
    

generating

Run this build script, there is a two stage build. and the second stage will use the binary generated by the first stage. in other word, the last deliver binary is generated by itself.

  python external/clang/build.py

check

  cd $TOP_SOURCE/external/llvm
  ./android_test.sh