sudo apt-get install gawk bison flex texinfo automake libtool cvs curl aria2 patch lzma libncurses5-dev g++ openjdk-7-jre-headless build-essential libcloog-ppl-dev gettext help2man
git clone https://github.com/crosstool-ng/crosstool-ng.git
Listing my .config here:
# Automatically generated file; DO NOT EDIT.
# Crosstool-NG Configuration
# Paths and misc options
# crosstool-NG behavior
# CT_OBSOLETE is not set
# CT_ALLOW_BUILD_AS_ROOT is not set
# CT_DEBUG_CT is not set
# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set
# CT_DOWNLOAD_AGENT_CURL is not set
# CT_DOWNLOAD_AGENT_NONE is not set
# CT_FORBID_DOWNLOAD is not set
# CT_FORCE_DOWNLOAD is not set
CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
# CT_ONLY_DOWNLOAD is not set
# CT_USE_MIRROR is not set
# CT_FORCE_EXTRACT is not set
# CT_ONLY_EXTRACT is not set
# CT_PATCH_LOCAL is not set
# CT_PATCH_BUNDLED_LOCAL is not set
# CT_PATCH_LOCAL_BUNDLED is not set
# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set
# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set
# CT_PATCH_NONE is not set
# Build behavior
# CT_CONFIG_SHELL_SH is not set
# CT_CONFIG_SHELL_ASH is not set
# CT_CONFIG_SHELL_CUSTOM is not set
# CT_LOG_ERROR is not set
# CT_LOG_WARN is not set
# CT_LOG_INFO is not set
# CT_LOG_ALL is not set
# CT_LOG_DEBUG is not set
# CT_LOG_SEE_TOOLS_WARN is not set
# Target options
# CT_ARCH_alpha is not set
# CT_ARCH_avr is not set
# CT_ARCH_m68k is not set
# CT_ARCH_microblaze is not set
# CT_ARCH_mips is not set
# CT_ARCH_nios2 is not set
# CT_ARCH_powerpc is not set
# CT_ARCH_s390 is not set
# CT_ARCH_sh is not set
# CT_ARCH_sparc is not set
# CT_ARCH_x86 is not set
# CT_ARCH_xtensa is not set
# Generic target options
# CT_MULTILIB is not set
# CT_ARCH_BE is not set
# CT_ARCH_32 is not set
# Target optimisations
# arm other options
# CT_ARCH_ARM_MODE_THUMB is not set
# CT_ARCH_ARM_INTERWORKING is not set
# Toolchain options
# General toolchain options
# CT_STATIC_TOOLCHAIN is not set
# Tuple completion and aliasing
# Toolchain type
# CT_NATIVE is not set
# CT_CROSS_NATIVE is not set
# CT_CANADIAN is not set
# Build system
# Misc options
# CT_TOOLCHAIN_ENABLE_NLS is not set
# Operating System
# CT_KERNEL_bare_metal is not set
# CT_KERNEL_LINUX_CUSTOM is not set
# CT_KERNEL_V_4_9 is not set
# CT_KERNEL_V_4_4 is not set
# CT_KERNEL_V_4_1 is not set
# CT_KERNEL_V_3_16 is not set
# CT_KERNEL_V_3_12 is not set
# CT_KERNEL_V_3_10 is not set
# CT_KERNEL_V_3_4 is not set
# CT_KERNEL_V_3_2 is not set
# Common kernel options
# linux other options
# CT_KERNEL_LINUX_VERBOSITY_1 is not set
# CT_KERNEL_LINUX_VERBOSITY_2 is not set
# CT_KERNEL_LINUX_INSTALL_CHECK is not set
# Binary utilities
# GNU binutils
# CT_BINUTILS_CUSTOM is not set
# CT_BINUTILS_SHOW_LINARO is not set
# CT_BINUTILS_V_2_27 is not set
# CT_BINUTILS_V_2_26 is not set
# CT_BINUTILS_LINKER_LD_GOLD is not set
# CT_BINUTILS_LINKER_GOLD_LD is not set
# CT_BINUTILS_PLUGINS is not set
# CT_BINUTILS_FOR_TARGET is not set
# binutils other options
# CT_LIBC_musl is not set
# CT_LIBC_uClibc is not set
# CT_LIBC_GLIBC_CUSTOM is not set
# CT_CC_GLIBC_SHOW_LINARO is not set
# CT_LIBC_GLIBC_V_2_24 is not set
# CT_LIBC_GLIBC_V_2_23 is not set
# Common C library options
# CT_CREATE_LDSO_CONF is not set
# glibc other options
# CT_LIBC_ENABLE_FORTIFIED_BUILD is not set
# CT_LIBC_DISABLE_VERSIONING is not set
# CT_LIBC_LOCALES is not set
# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set
# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set
# C compiler
# CT_CC_GCC_CUSTOM is not set
# CT_CC_GCC_SHOW_LINARO is not set
# CT_CC_GCC_V_5_4_0 is not set
# CT_CC_GCC_V_4_9_4 is not set
# CT_CC_GCC_SYSTEM_ZLIB is not set
# Optimisation features
# Settings for libraries running on target
# CT_CC_GCC_LIBMUDFLAP is not set
# CT_CC_GCC_LIBGOMP is not set
# CT_CC_GCC_LIBSSP is not set
# CT_CC_GCC_LIBQUADMATH is not set
# CT_CC_GCC_LIBSANITIZER is not set
# Misc. obscure options.
# CT_CC_GCC_DISABLE_PCH is not set
# CT_CC_GCC_BUILD_ID is not set
# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set
# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set
# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set
# CT_CC_GCC_DEC_FLOAT_BID is not set
# CT_CC_GCC_DEC_FLOAT_DPD is not set
# CT_CC_GCC_DEC_FLOATS_NO is not set
# Additional supported languages:
# CT_CC_LANG_FORTRAN is not set
# CT_CC_LANG_JAVA is not set
# CT_CC_LANG_ADA is not set
# CT_CC_LANG_OBJC is not set
# CT_CC_LANG_OBJCXX is not set
# CT_CC_LANG_GOLANG is not set
# Debug facilities
# CT_DEBUG_duma is not set
# CT_DEBUG_gdb is not set
# CT_DEBUG_ltrace is not set
# CT_DEBUG_strace is not set
# Companion libraries
# CT_ZLIB is not set
# CT_LIBICONV_V_1_14 is not set
# CT_ISL_V_0_17_1 is not set
# CT_ISL_V_0_16_1 is not set
# CT_ISL_V_0_15 is not set
# CT_NCURSES_NEW_ABI is not set
# CT_NCURSES_TARGET_DISABLE_DB is not set
# Companion libraries common options
# CT_COMPLIBS_CHECK is not set
# Companion tools
# CT_COMP_TOOLS_FOR_HOST is not set
# CT_COMP_TOOLS_autoconf is not set
# CT_COMP_TOOLS_m4 is not set
# CT_COMP_TOOLS_make is not set
# Test suite
# CT_TEST_SUITE_GCC is not set
For compiling anything on Android, you need a good toolchain to cross compile files. To just compile a kernel, you may try using the precompiled toolchain that comes with Android NDK (easy way out). However that one is not optimized for your machine. Neither does it have many prerequisites required if you want to compile other Linux binaries like dosfstools, Over the course of your Android development life, you’ll find yourself missing many linux utilities on Android and will not even find precompiled versions online. So you need to be able to build Linux utilites which can work on your phone too (cross compiling).
Thanks to Ahmet Ipkin (TheGanymedes on XDA), you now have a good guide to making a toolchain for Android. My post is based entirely on his original post, and I urge you to read his opening post completely to understand the details. If it helped you, please consider a paypal donation to him. I will be quoting his post on the actual guide to compile a toolchain, after I add some notes that I felt needed to be inserted to help newbies. 🙂
sudo apt-get install gawk bison flex texinfo automake libtool cvs curl aria2 patch lzma libncurses5-dev g++ openjdk-7-jre-headless build-essential libcloog-ppl-dev gettext
To debug issues, it is good to watch the build.log
tail -f /home/droidzone/x-tools/arm-msm-linux-gnueabi/build.log
List of Toolchain Options: (Also includes Compatibility Table for different tool versions)
Sources for tarballs:
I found that ct-ng allowed you to select only very old versions of included requirements like gcc. So I downloaded them from:
http://ftp.gnu.org/gnu/gcc/ for gcc
Libelf from http://www.mr511.de/software/
Note that once you add them, you have to go to the actual source dir of ct-ng from where you execute ./configure, and execute the following cmd lines:
Adding Latest Versions of Included software
./scripts/addToolVersion.sh --binutils -s -c 2.20.1a
./scripts/addToolVersion.sh --gcc -s -c 4.6.1
./scripts/addToolVersion.sh --glibc -s -c 2.1.3
Note that after you do this, you have to run
./configure --prefix="path to dir where you will be building ct-ng"
cd [to dir where you will make ct-ng"
Then, moving to the tarballs dir, wget the latest packages…
Errors I got while building:
Tip: The first time you build, it is good to check the following options:
Menuconfig>Paths and Misc options:
[x]Save intermediary steps
This will allow you to continue without redoing the steps which succeeded!
- Error: Installing C library headers, Linux version is unavailable in installed headers files
Installing C library headers
[ERROR] Linux version is unavailable in installed headers files
[ERROR] Build failed in step 'Installing C library headers'
[ERROR] Error happened in '/home/droidzone/ct-ng/lib/ct-ng-1.9.3/scripts/build/libc/glibc.sh' in function 'do_libc_headers' (line unknown, sorry)
[ERROR] called from '/home/droidzone/ct-ng/lib/ct-ng-1.9.3/scripts/crosstool-NG.sh' at line # 597 in function 'main'
According to TheGanymedes, the solution is:
It shows that it couldn’t validate version of the linux kernel. Just open a terminal, go to the kernel directory and write “make ARCH=arm menuconfig”. After writing this, look through all options – you shall find one that allows you to pick your board model, cpu model etc. Pick board model as Qualcomm/msm and as cpu model pick qsd8x50. Sorry that I don’t know the exact names of the options.
After this, quit from that menu with esc-esc keys, and save config. The other options are unnecessary, just board and cpu type is all we need.
Now, write make ARCH=arm CROSS_COMPILE=arm-linux- . It’s going to fail, but will create the necessary version files and this was all we need. Now you can use crosstool-ng.
This is the location to find those options:
System type>ARM System type> Qualcomm MSM/QSD
Qualcomm MSM Soc tyoe: QSD8x50
- Error: Errors with PPL/CLOOG. This was a tough one, since TheGanymedes forgot to mention that this would happen. ;). This is apparently (according to him) because ct-ng for some reason cannot build PPL/CLOOG. For this, you have to disable Graphite loop optimizations. Only then will ct-ng build
C compiler> Untick “Enable Graphite loop optimizations”
- Error: Other errors with specific components. This may occur if your net connection is crappy and downloads files. In these cases, though the error message may be rather obscure, you can usually find out what step it failed at, by examining the file ~/x-tools/crosscompilername/.build/build.log. Note that .build is a hidden folder.
- Error: [ERROR] Build failed in step ‘Retrieving needed toolchain components’ tarballs’ called in step ‘(top-level)’
- Now, this is a rather obscure issue which happened both on my local system and on the ssh at sourceforge. The reason was the compiler trying to create a symbolic link that already existed.
- Solution: Go to ct-ng dir where you execute ./ct-ng build. Within it, do an rm -rf ./build/* ; rmdir ./build
- Workarounds for getting crosstool itself to build under an ssh environment. The issue was that many dependencies of ct-ng, like autoconf, automake, lzma, texinfo (makeinfo) are not installed on the target system and we have no way of using aptitude. So the solution is to build all these utilities from source. A nice hint to do this to:
- mkdir -p ~/bin
- Add a path to your ~/.bashrc, and add the line: PATH=$PATH:~/bin:~/bin/bin
- Now, configure each dependency while building with: ./configure –prefix=/absolutepath_to_$HOME/bin. Note that instead of building binaries in ~/bin, this builds them in ~/bin/bin. This is a good substitution when you dont have Write rights to /usr/bin (cant do a ‘sudo make install’).
- Then, make
- make install. Make install will install to $HOME/bin/bin 🙂
Before you start anything, don’t forget to install build-essentials package. Under ubuntu, the command necessary for it is:sudo apt-get install build-essential – I don’t know about other distros..
Well, as promised, now we should write the steps; right?… Now, before we begin, I should really warn that the process is really head spinning if you’re to do all by yourself; so take heed to the warnings I give you (I learned the hard way)
Well, first thing is first, we need a Cross Compiler Toolchain, properly built that allows us to build applications, libraries etc. There is one toolchain that’s already given to you with Android Native Development Kit (called NDK) but that one is quite restricted because it’s built with support for Bionic (trimmed C library that is presented in Android), not Glibc or uGlibC. If you want to develop more native-like applications (especially linux programs) you need GlibC or uGlibC. You can try to build these libraries with that toolchain too, but don’t do that, because it’s going to fail as well. The reason is that some sort of Chicken-Egg problem is eminent in GlibC-GCC compilation
Let’s put the steps to be followed first to build a nice toolchain. I assume you’re using Linux – because the tools are developed for this platform only. If you’re going to use them in Windows, you need Cygwin or such tools but I can’t supply help about that, for since I didn’t use them before at all. Google is your friend about this
(Note, the packages I wrote at this list are available at GNU’s website www.gnu.org freely, open source)
1- We’re going to build “binutils” first. This package includes some important stuff like assembler, linker, archiver (for libraries) etc..
2- We’re going to build GCC’s prerequisites. These are GMP, MPRF and MPC packages.
3- We’re going to build a “bootstap” gcc (God, I hate that name. I like to call it “naked gcc” more ). This GCC just converts source codes to pure assemblies: thus cannot generate linkages or such. We’re going to use it to build “actual” tools we’re going to use.
4- We’re going to extract Kernel source/headers – use Desire Kernel’s here. There is some copying, and such to be done tho.
5- We’re going to make GlibC headers installed, which will allow us to build more “complex” gcc, which can link applications with those libraries when the library binaries are given (so such thing is there yet, but we fool it )
6- We’re going to build a very limited GlibC which will give us support for building more “complex” gcc.
7- We’re going to build GCC again. This is called “Pass 1 GCC” or “GCC Stage 1”. This GCC can link applications to libraries, with the information in Kernel headers and library headers (it’s why we give it the headers, so it can create applications suitable with the Kernel architecture).
8- We’re to build actual GlibC now. This glibC will be used for our compiled applications, statically or dynamically. You can, at the end of this step, copy the files to your devices and they would work, but picking files here is harder, so I’d recommend you to leave this alone for now
9- We’re going to build “Pass 2 GCC” or “GCC Step 2” This is a full fledged GCC that can do anything we want
Complex isn’t it? This is precisely why I recommend you to use Crostool-NG. The other tools (like Buildtools or Crosstool) (sadly) don’t create GlibC based toolchains, or use old versions of them, so using this one is recommended. This package automatically will download, setup and link your all toolchain without you worrying about something (believe me, this is what you need. I gave 8 days without this to create a working GCC and Crosstool-NG made another one to me in 50 minutes. )
Well, however, Crosstool-NG won’t create “nice” applications (they’ll run allright, but they won’t be optimized) without some settings done, so, let’s go there. First, we need to install Crosstool-NG itself. To do that; go to http://crosstool-ng.org/website, download and extract it to some place. Even though the steps are written in Crosstool website, you don’t need all commands there (like setting PATH is unnecessary). The commands you should use is, after CD’ing to the Crosstool dir;
I used prefix as /home/ahmet/crosstool for instance. Note that this is not going to be where your toolchain is, this is where your “toolchain creator” is .
—- NECESSARY KERNEL HEADER CHANGES —-
OK now, before we start compiling; we need to make some folder moving, copying etc. in Kernel directory. This is needed, because tree structure changed a tad in 2.6 kernels and unless you compiled this kernel before, some directories won’t be in their correct place for our cross compiler. Switch to the directory which you extracted the kernel image. Now, from now on, I’m going to assume you’re an Qualcomm/MSM board (like Desire, Nexus One etc.) user; but if you’re not, change my descriptions accordingly:
1- Go to <kernel dir>/arch/arm/include folder. Copy “asm” directory and paste it into <kernel dir>/include directory.
2- Go to <kernel dir>/arch/arm/mach-msm/include folder. Copy “mach” directory and paste it to <kernel dir>/include/asm directory. It’s going to complain that there is another mach folder there and will ask if you want to merge/overwrite. Say yes to all questions.
Now our kernel headers folder is showing a Desire device. Note that if you’re not a Desire user, you should use your cpu folder instead of ARM and your board manufacturer in mach-xxxxx instead of mach-msm.
Note this kernel directory, we’re going to use it to configure crosstool..
— CONFIGURING CROSSTOOL —
After issuing the commands, the crosstool-ng will give you a configuration menu. Most of the setting here are unchanged, but the ones you should change are given below.
1- Paths and misc options
a) Try features marked as EXPERIMENTAL (this is needed to build a toolchain with the latest GlibC support) -> Enabled
b) Local Tarballs directory -> The folder address that you want downloaded stuff to be kept. You might use them again (like for compiling GlibC again for device, you will use them
c) Save New Tarballs -> Enabled ( so that new downloaded files aren’t erased )
d) Working Directory and Prefix directory -> Normally you don’t have to change them, but you can if you want to install your toolchain to some other location. CT_TARGET signifies your target name (like arm-msm-linux-gnueabi – arm is cpu model, msm is vendor (can be anything), linux is showing the binaries are for linux system (you can use android, but then you’ll get not GlibC but Bionic) and gnueabi shows you’re going to use open-source EABI structure for your executables. The other option is ELF but EABI is more flexible (because also supports ELF).
e) Strip all toolchain executables -> do it if you don’t want to debug GCC itself. this makes toolchain smaller of size, and a tad faster.
The other options can stay the way they are, or you can change them accordingly here. You can get help with ? key, and if you don’t understand anything, just leave them default – there are very complex things there that you don’t need to know if you’re not planning to be a expert on subject
2- Target options
a) Target Architecture -> arm should be selected, cos Desire uses ARM. If you plan to make toolchain for, say, powerpc, pick that.
b) Endianness -> Should be little. ARM processors in Desire uses little endian system.
c) Architecture level -> “armv7-a” this is should be written. Desire uses ARMv7 based instructions and if you leave here empty, the applications will be built with armv5 support – they’re still going to run but not use advanced v7 features.
d) Use Specific FPU -> “neon” . Desire uses NEON structure for floating point arithmetic, and if you leave here empty, the applications will not use Desire’s FPU abilities (everything will be software based, which is slower)
e) Default instruction set mode -> arm . You can use thumb here for allegedly faster code but not every build system supports it. Leave it ARM.
f) Use EABI -> enabled. EABI is necessary for most flexible desing of binaries.
The other settings be as they were.
3- Toolchain options
a) Tuple’s vendor string -> You can leave here empty if you don’t want to; it’s not necessary to use a string here. I used “msm” but you can write anything. This string here is used in toolchain name as arm-xxxxx-linux-gnueabi, so make it short, I recommend
b) Tuple’s alias -> make it something short like “arm-linux” This alias string is used to make calls to your toolchain easier. Instead of writing arm-msm-linux-gnueabi-gcc everytime, you can use arm-linux-gcc to compile your applications. Can write anything here (like toolchain if you want to use toolchain-gcc to compile your applications)
The other settings can stay as they are, for since default values are the best in our case. You can tweak them only if you know Desire cpu like the back of your hand
4- Operating system
a) Target OS -> Use “linux” if you want the applications to run in Android and Linux; use “bare metal” if you’re to compile low level applications which won’t use linux headers. Default is linux.
b) Get Kernel headers from -> say “pre installed” because otherwise it’s going to download standard Linux headers from internet. We needed some changes, so this option is compulsory to be “pre installed”
c) Path to custom headers directory/tarball -> Path to your kernel source folder – which you made changes above.WARNING: I say specifically extracted, because standart tarball won’t work for us. We’re going to make some changes in kernel directories, which is non-standart (Instructions were above).
d) This is a tarball -> No . We’re going to use extracted folder.
e) Build shared libraries -> say “yes”; because we want dynamic linkage, not static one
f) Check kernel headers -> say “no” otherwise some unnecessary check causes compilation to stop.
5- Binary utilities
a) Binutils version – pick the latest one, 2.20.1a. If you use older versions with newer GCC/GlibC, it’s not going to succeed.
Leave others as they are, they are not big deal..
6- C Compiler
a) GCC Version -> pick 4.6.1 for since it’s the latest and most bug free. Just stay away from 4.5
b) Pick the languages you want support for. I’ve read online that Java is a tad troublesome in Android platform, for since Java in Android uses Dalvik, not Sun systems. You can try it at your second toolchain if you want Definitely pick C++ tho
c) Link libstdc++ statically -> say yes; it really saves you from big configure scripts later – apparently needed to avoid PPL problems as well
d) Compile lidmudflap/libgomp/libssp -> say no. These libraries are not the most suitable libraries for ARM platform (at least at cross-compiler level. You can compile them later, if you want, with your cross-toolchain.)
You can leave others as default
7- C library
a) C library -> gLibC (recommended). You can use other libraries which are eGlibC (embedded Glibc, like Bionic) and uGlibC (micro-glibc) too, but GlibC is the most spanning solution above those. The libraries are bigger, but they support more.
b) glibC version -> Use 2.13 (experimental) it compiles just fine, and you get a new version of GlibC. Not the newest, but that’s ok
c) Threading implementation -> nptl (recommended) . You can use linuxthreads too, but nptl is more advanced ( like giving support to Thread-Local-Storage and such)
d) Force Unwind Support -> Enabled . If you don’t use this option, for since we’re making this toolchain from scratch, it’s going to give you error during compiling that it couldn’t find necessary headers (we’re building them now, dumbass!)
Leave others default if you don’t know what they’re about
8- Companion Libraries
Well, go and pick the latest versions, even though when it says “Experimental”, otherwise your GCC compilation will give you error about these libraries being old.
After setting these settings, press ESC key twice till it goes way back and ask if you want to save configuration; say yes.
— STARTING COMPILATION —
Now to start compilation write
This is going to take approx. 45 minutes, so go watch some episodes of Big Bang Theory or something. Normally, there should be no errors but if there is; most probably either you made a wrong configuration, or didn’t set your kernel folders well. Try again with other settings, google your problem etc..
After this process, you’re going to have a cross-compiler at your use at /home/<username>/x-tool/arm-<vendor>-linux-gnueabi/bin folder. Note that Crosstool-NG automatically makes this folder read only to make you prevent screwing your toolchain You must edit your path variable to show “/home/<username>/x-tool/arm-<vendor>-linux-gnueabi/bin” folder as well for less headaches during compiling later
Whilst compiling other application, most used configure options you’re going to use is “–host=arm-<vendor>-linux-gnueabi” and “–prefix=/some/folder/you/want/this/application/copied”. After compilation, you can send binaries to your phone from prefix folder.
More options about GCC and Configure is available at GCC and Autoconf man pages; check them as well
Happy cross-compiling people