Attend XDA's Second Annual Developer Conference, XDA:DevCon 2014!
5,729,749 Members 50,186 Now Online
XDA Developers Android and Mobile Development Forum

[DEV] [GUIDE] [LINUX] Comprehensive Guide to Cross-Compiling

Tip us?
 
JustArchi
Old
#11  
JustArchi's Avatar
Recognized Contributor / Recognized Developer - OP
Thanks Meter 20484
Posts: 6,381
Join Date: Mar 2013
Location: Warsaw

 
DONATE TO ME
Quote:
Originally Posted by EnerJon View Post
Actually i was making a tool for windows to generate/apply OTA for Android ROMs... i wanted to compile/port "IMGDIFF2" and "applypatch" from android sources...
Then you should find your sources for IMGDIFF2 and applypatch and compile from source for Android, just like example hello.c above.
The Following User Says Thank You to JustArchi For This Useful Post: [ Click to Expand ]
 
Odysseus1962
Old
(Last edited by Odysseus1962; 26th April 2014 at 07:24 AM.)
#12  
Odysseus1962's Avatar
Senior Member
Thanks Meter 441
Posts: 541
Join Date: Sep 2013
Location: Miami
@JustArchi I saw this guide mentioned on the portal and read through it. Very interesting stuff. Great work explaining. I've got several questions, however, perhaps you can elaborate on.

My primary PC OS is Gentoo Linux (I've been using it for 10 years), in patricular ~amd64 which is the equivalent of Debian unstable. In Gentoo, all packages are compiled from the sources. I have a very up to date complete toolchain already installed and functioning properly as part of the native package installation system which uses portage for maintaining and updating.

I've already compiled CM and AOSP for my device, but I can't for the life of me understand why when setting up my build environment using either Google or CM tools several much older versions of GCC and GLIBC are installed into my source repos and used to build the ROM when the prerequisites for building the environment already require a working toolchain on the host build box?

Isn't there a way to just use the native toolchain from the host? Ideally, I'd love to free up the space used by these extra compilers and libraries for sources instead. Additionally, since my toolchain is much newer (gcc-4.8.2, glibc-2.19, etc) and optimized for my hardware than these generic prebuilt binaries, my ROM builds would compile faster and more optimized if I could use it instead.

The big question I ask is would you know what I'd have to do to setup my native environment to build Android? I'd truly love to be able to get rid of these other toolchains and free up the space on my harddrive. Any help would be greatly appreciated. TIA
Current device: LG G2 (D801)
ROM: Stock KK-4.4.2 - rooted and debloated by me.
An incredible handset. The first smartphone I've owned where I didn't immediately replace the stock ROM.

Previous device: HTC Amaze 4G
Final ROM: CM-10 - Compiled and customized by me
To whoever stole it: What goes around comes around!

Previous device: HTC HD2 (TMOUS - LEO1024)
Final ROM: NexusHD2-JellyBean-CM10.1.3 v2.7 - Tytung
Had more lives than a cat
Lesson: If it ain't broke, don't fix it!
RIP
 
DerRomtester
Old
#13  
DerRomtester's Avatar
Senior Member
Thanks Meter 432
Posts: 682
Join Date: Aug 2012
Location: Neumarkt
Quote:
Originally Posted by JustArchi View Post
When making standalone toolchain you should use clang instead of gcc. You should also study my cc.sh script and adapt to your own. After that, steps are nearly the same.



Using Cygwin for such kind of things is... bad. Install VirtualBox and any Linux distro if you want to master cross-compile technique.
I try this. I would like to cross compile a kernel with clang. Hopefully i get it working.
 
JustArchi
Old
#14  
JustArchi's Avatar
Recognized Contributor / Recognized Developer - OP
Thanks Meter 20484
Posts: 6,381
Join Date: Mar 2013
Location: Warsaw

 
DONATE TO ME
Quote:
Originally Posted by Odysseus1962 View Post
@JustArchi I saw this guide mentioned on the portal and read through it. Very interesting stuff. Great work explaining. I've got several questions, however, perhaps you can elaborate on.

My primary PC OS is Gentoo Linux (I've been using it for 10 years), in patricular ~amd64 which is the equivalent of Debian unstable. In Gentoo, all packages are compiled from the sources. I have a very up to date complete toolchain already installed and functioning properly as part of the native package installation system which uses portage for maintaining and updating.

I've already compiled CM and AOSP for my device, but I can't for the life of me understand why when setting up my build environment using either Google or CM tools several much older versions of GCC and GLIBC are installed into my source repos and used to build the ROM when the prerequisites for building the environment already require a working toolchain on the host build box?

Isn't there a way to just use the native toolchain from the host? Ideally, I'd love to free up the space used by these extra compilers and libraries for sources instead. Additionally, since my toolchain is much newer (gcc-4.8.2, glibc-2.19, etc) and optimized for my hardware than these generic prebuilt binaries, my ROM builds would compile faster and more optimized if I could use it instead.

The big question I ask is would you know what I'd have to do to setup my native environment to build Android? I'd truly love to be able to get rid of these other toolchains and free up the space on my harddrive. Any help would be greatly appreciated. TIA
You need special compiler capable of compiling for specific architecture, this is not the same as native GCC toolchain for amd64. When you're using native compiler, output is always designed for amd64 or i386, when using cross-compiler, output is always designed for ARM, or other specific architecture.
The Following User Says Thank You to JustArchi For This Useful Post: [ Click to Expand ]
 
Odysseus1962
Old
#15  
Odysseus1962's Avatar
Senior Member
Thanks Meter 441
Posts: 541
Join Date: Sep 2013
Location: Miami
Quote:
Originally Posted by JustArchi View Post
You need special compiler capable of compiling for specific architecture, this is not the same as native GCC toolchain for amd64. When you're using native compiler, output is always designed for amd64 or i386, when using cross-compiler, output is always designed for ARM, or other specific architecture.
Thanks for the quick response. I'm a bit disappointed, but I'm still wondering that there has to be some way for me to utilize the ARM toolchain I currently have installed to cross-compile from the sources a more updated optimized toolchain for me to build with. Unfortunately (for me), that Gentoo is more of a niche Linux distro so finding help in their forums for working with ARM is difficult. As it is, it took much effort and trial and error to setup my current configuration to build with since nearly everything on the net is geared towards Ubuntu / Debian (both of which I feel are loaded with useless cruft and dependencies for things I have never and will never use).

Anyhow thanks again for this great guide, and for your continued work here helping us all.

Ciao
Current device: LG G2 (D801)
ROM: Stock KK-4.4.2 - rooted and debloated by me.
An incredible handset. The first smartphone I've owned where I didn't immediately replace the stock ROM.

Previous device: HTC Amaze 4G
Final ROM: CM-10 - Compiled and customized by me
To whoever stole it: What goes around comes around!

Previous device: HTC HD2 (TMOUS - LEO1024)
Final ROM: NexusHD2-JellyBean-CM10.1.3 v2.7 - Tytung
Had more lives than a cat
Lesson: If it ain't broke, don't fix it!
RIP
 
lucacerio
Old
#16  
Member
Thanks Meter 9
Posts: 89
Join Date: Jan 2011
Dropbox link is down

Inviato dal mio GT-I9300 utilizzando Tapatalk
 
JustArchi
Old
#17  
JustArchi's Avatar
Recognized Contributor / Recognized Developer - OP
Thanks Meter 20484
Posts: 6,381
Join Date: Mar 2013
Location: Warsaw

 
DONATE TO ME
 
Code:
#!/bin/bash

#      _           _      _             _     _
#     | |_   _ ___| |_   / \   _ __ ___| |__ (_)
#  _  | | | | / __| __| / _ \ | '__/ __| '_ \| |
# | |_| | |_| \__ \ |_ / ___ \| | | (__| | | | |
#  \___/ \__,_|___/\__/_/   \_\_|  \___|_| |_|_|
#
# Copyright 2014 Łukasz "JustArchi" Domeradzki
# Contact: JustArchi@JustArchi.net
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#############
### BASIC ###
#############

# Root of NDK, the one which contains $NDK/ndk-build binary
NDK="/root/ndk"

# Root of NDK toolchain, the one used in --install-dir from $NDK/build/tools/make-standalone-toolchain.sh. Make sure it contains $NDKTC/bin directory with $CROSS_COMPILE binaries
NDKTC="/root/ndkTC"

# Optional, may help NDK in some cases, should be equal to GCC version of the toolchain specified above
export NDK_TOOLCHAIN_VERSION=4.8

# This flag turns on ADVANCED section below, you should use "0" if you want easy compiling for generic targets, or "1" if you want to get best optimized results for specific targets
# In general it's strongly suggested to leave it turned on, but if you're using makefiles, which already specify optimization level and everything else, then of course you may want to turn it off
ADVANCED="1"

################
### ADVANCED ###
################

# Device CFLAGS, these should be taken from TARGET_GLOBAL_CFLAGS property of BoardCommonConfig.mk of your device, eventually leave them empty for generic non-device-optimized build
# Please notice that -march flag comes from TARGET_ARCH_VARIANT
DEVICECFLAGS="-march=armv7-a -mtune=cortex-a9 -mfpu=neon -mfloat-abi=softfp"

# This specifies optimization level used during compilation. Usually it's a good idea to keep it on "-O2" for best results, but you may want to experiment with "-Os", "-O3" or "-Ofast"
OLEVEL="-O2"

# This specifies extra optimization flags, which are not selected by any of optimization levels chosen above
# Please notice that they're pretty EXPERIMENTAL, and if you get any compilation errors, the first step is experimenting with them or disabling them completely, you may also want to try different O level
OPTICFLAGS="-s -flto=8 -ffunction-sections -fdata-sections -fvisibility=hidden -funswitch-loops -frename-registers -frerun-cse-after-loop -fomit-frame-pointer -fgcse-after-reload -fgcse-sm -fgcse-las -fweb -ftracer -fstrict-aliasing"

# This specifies extra linker optimizations. Same as above, in case of problems this is second step for finding out the culprit
LDFLAGS="-Wl,-O1 -Wl,--as-needed -Wl,--relax -Wl,--sort-common -Wl,--gc-sections"

# This specifies additional sections to strip, for extra savings on size
STRIPFLAGS="-s -R .note -R .comment -R .gnu.version -R .gnu.version_r"

# Additional definitions, which may help some binaries to work with android
DEFFLAGS="-DNDEBUG -D__ANDROID__"

##############
### EXPERT ###
##############

# This specifies host (target) for makefiles. In some rare scenarios you may also try "--host=arm-linux-androideabi"
# In general you shouldn't change that, as you're compiling binaries for low-level ARM-EABI and not Android itself
CONFIGANDROID="--host=arm-linux-eabi"

# This specifies the CROSS_COMPILE variable, again, in some rare scenarios you may also try "arm-eabi-"
# But beware, NDK doesn't even offer anything apart from arm-linux-androideabi one, however custom toolchains such as Linaro offer arm-eabi as well
CROSS_COMPILE="arm-linux-androideabi-"

# This specifies if we should also override our native toolchain in the PATH in addition to overriding makefile commands such as CC
# You should NOT enable it, unless your makefile calls "gcc" instead of "$CC" and you want to point "gcc" (and similar) to NDKTC
# However, in such case, you should either fix makefile yourself or not use it at all
# You've been warned, this is not a good idea
TCOVERRIDE="0"

# Workaround for some broken compilers with malloc problems (undefined reference to rpl_malloc and similar errors during compiling), don't uncomment unless you need it
#export ac_cv_func_malloc_0_nonnull=yes

############
### CORE ###
############

# You shouldn't edit anything from now on
if [ "$ADVANCED" -ne 0 ]; then # If advanced is specified, we override flags used by makefiles with our optimized ones, of course if makefile allows that
	export CFLAGS="$OLEVEL $DEVICECFLAGS $OPTICFLAGS $DEFFLAGS"
	export LOCAL_CFLAGS="$CFLAGS"
	export CXXFLAGS="$CFLAGS" # We use same flags for CXX as well
	export LOCAL_CXXFLAGS="$CXXFLAGS"
	export CPPFLAGS="$CPPFLAGS" # Yes, CPP is the same as CXX, because they're both used in different makefiles/compilers, unfortunately
	export LOCAL_CPPFLAGS="$CPPFLAGS"
	export LDFLAGS="$LDFLAGS"
	export LOCAL_LDFLAGS="$LDFLAGS"
fi

if [ ! -z "$NDK" ] && [ "$(echo $PATH | grep -qi $NDK; echo $?)" -ne 0 ]; then # If NDK doesn't exist in the path (yet), prepend it
        export PATH="$NDK:$PATH"
fi

if [ ! -z "$NDKTC" ] && [ "$(echo $PATH | grep -qi $NDKTC; echo $?)" -ne 0 ]; then # If NDKTC doesn't exist in the path (yet), prepend it
        export PATH="$NDKTC/bin:$PATH"
fi

export CROSS_COMPILE="$CROSS_COMPILE" # All makefiles depend on CROSS_COMPILE variable, this is important to set"
export AS=${CROSS_COMPILE}as
export AR=${CROSS_COMPILE}ar
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export CPP=${CROSS_COMPILE}cpp
export LD=${CROSS_COMPILE}ld
export NM=${CROSS_COMPILE}nm
export OBJCOPY=${CROSS_COMPILE}objcopy
export OBJDUMP=${CROSS_COMPILE}objdump
export READELF=${CROSS_COMPILE}readelf
export RANLIB=${CROSS_COMPILE}ranlib
export SIZE=${CROSS_COMPILE}size
export STRINGS=${CROSS_COMPILE}strings
export STRIP=${CROSS_COMPILE}strip

if [ "$TCOVERRIDE" -eq 1 ]; then # This is not a a good idea...
	alias as="$AS"
	alias ar="$AR"
	alias gcc="$CC"
	alias g++="$CXX"
	alias cpp="$CPP"
	alias ld="$LD"
	alias nm="$NM"
	alias objcopy="$OBJCOPY"
	alias objdump="$OBJDUMP"
	alias readelf="$READELF"
	alias ranlib="$RANLIB"
	alias size="$SIZE"
	alias strings="$STRINGS"
	alias strip="$STRIP"
fi

export CONFIGANDROID="$CONFIGANDROID"
export CCC="$CC $CFLAGS $LDFLAGS"
export CXX="$CXX $CXXFLAGS $LDFLAGS"
export SSTRIP="$STRIP $STRIPFLAGS"

echo "Done setting your environment"
echo
echo "CFLAGS: $CFLAGS"
echo "LDFLAGS: $LDFLAGS"
echo "CC points to $CC and this points to $(which "$CC")"
echo
echo "Use \"\$CC\" command for calling gcc and \"\$CCC\" command for calling our optimized CC"
echo "Use \"\$CXX\" command for calling g++ and \"\$CCXX\" for calling our optimized CXX"
echo "Use \"\$STRIP\" command for calling strip and \"\$SSTRIP\" command for calling our optimized STRIP"
echo
echo "Example: \"\$CCC myprogram.c -o mybinary && \$SSTRIP mybinary \""
echo
echo "When using makefiles with configure options, always use \"./configure \$CONFIGANDROID\" instead of using \"./configure\" itself"
echo "Please notice that makefiles may, or may not, borrow our CFLAGS and LFLAGS, so I suggest to double-check them and eventually append them to makefile itself"
echo "Pro tip: Makefiles with configure options always borrow CC, CFLAGS and LDFLAGS, so if you're using ./configure, probably you don't need to do anything else"


Temporary replacement for cc.sh, as dropbox will be up soon.
The Following User Says Thank You to JustArchi For This Useful Post: [ Click to Expand ]
 
sfortier
Old
(Last edited by sfortier; 6th May 2014 at 10:32 PM.)
#18  
Junior Member
Thanks Meter 1
Posts: 27
Join Date: Aug 2007
Hi!
Great info.
To cross compile some packages with autotools (./configure; make; make install) it's needed to export the SYSROOT path ($ndkTC/sysroot) and include the option --sysroot=$SYSROOT on CFLAGS. Some need too --with-sysroot=$SYSROOT as configure option. This way the configure script and linker can find the libraries.
If i'm building a library that must be used as dependence to other program I use to include --static to build a static library and --prefix=$SYSROOT/usr on configure options to install the lib on toolchain sysroot folder...
Thanks.
 
JustArchi
Old
#19  
JustArchi's Avatar
Recognized Contributor / Recognized Developer - OP
Thanks Meter 20484
Posts: 6,381
Join Date: Mar 2013
Location: Warsaw

 
DONATE TO ME
Quote:
Originally Posted by sfortier View Post
Hi!
Great info.
To cross compile some packages with autotools (./configure; make; make install) it's needed to export the SYSROOT path ($ndkTC/sysroot) and include the option --sysroot=$SYSROOT on CFLAGS. Some need too --with-sysroot=$SYSROOT as configure option. This way the configure script and linker can find the libraries.
If i'm building a library that must be used as dependence to other program I use to include --static to build a static library and --prefix=$SYSROOT/usr on configure options to install the lib on toolchain sysroot folder...
Thanks.
Hey.

Nice to know, I'll update my script with that. Thanks!
 
sfortier
Old
#20  
Junior Member
Thanks Meter 1
Posts: 27
Join Date: Aug 2007

My last attempt to cross compile something was qemu (i'm was thinking on run windows on my tablet... )
I needed to build glib, pixmap, libpng, zlib, libjpeg-turbo, libiconv, libffi, libintl. Now I have my toolchain with all these usefull static (I prefer static libs to simplify binary installation) libs installed!

Tags
justarchi cross compiler compiling guide
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes