aboutsummaryrefslogtreecommitdiff
path: root/cmake/platforms/Android.cmake
blob: 9aad65cbe13ef0d9490cb80b9a07f0a5b28c1759 (plain) (blame)
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# Toolchain config for Android standalone NDK.
#
# Usage:
# build host llvm and clang first
# cmake -DCMAKE_TOOLCHAIN_FILE=../lldb/cmake/platforms/Android.cmake \
#       -DANDROID_TOOLCHAIN_DIR=<toolchain_dir> \
#       -DANDROID_ABI=<target_abi> \
#       -DCMAKE_CXX_COMPILER_VERSION=<gcc_version> \
#       -DLLVM_TARGET_ARCH=<llvm_target_arch> \
#       -DLLVM_TARGETS_TO_BUILD=<llvm_targets_to_build> \
#       -DLLVM_TABLEGEN=<path_to_llvm-tblgen> \
#       -DCLANG_TABLEGEN=<path_to_clang-tblgen>
#
# Current Support:
#   ANDROID_ABI = x86, x86_64
#   CMAKE_CXX_COMPILER_VERSION = 4.9
#   LLVM_TARGET_ARCH = X86
#   LLVM_TARGETS_TO_BUILD = X86
#   LLVM_TABLEGEN = path to host llvm-tblgen
#   CLANG_TABLEGEN = path to host clang-tblgen

if( DEFINED CMAKE_CROSSCOMPILING )
 return()
endif()

get_property( IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
if( IS_IN_TRY_COMPILE )
 # this seems necessary and works fine but I'm unsure if it breaks anything
 return()
endif()

set( CMAKE_SYSTEM_NAME Linux )
include( CMakeForceCompiler )

# flags and definitions
remove_definitions( -DANDROID -D__ANDROID__ )
add_definitions( -DANDROID -D__ANDROID_NDK__ -DLLDB_DISABLE_LIBEDIT )
set( ANDROID True )
set( __ANDROID_NDK__ True )
set( LLDB_DEFAULT_DISABLE_LIBEDIT True )

# linking lldb-server statically for Android avoids the need to ship two
# binaries (pie for API 21+ and non-pie for API 16-). It's possible to use
# a non-pie shim on API 16-, but that requires lldb-server to dynamically export
# its symbols, which significantly increases the binary size. Static linking, on
# the other hand, has little to no effect on the binary size.
if( NOT DEFINED LLVM_BUILD_STATIC )
 set( LLVM_BUILD_STATIC True  CACHE INTERNAL "" FORCE )
 set( LLVM_ENABLE_PIC   FALSE CACHE INTERNAL "" FORCE )
 set( BUILD_SHARED_LIBS FALSE CACHE INTERNAL "" FORCE )
endif()

set( ANDROID_ABI "${ANDROID_ABI}" CACHE INTERNAL "Android Abi" FORCE )
if( ANDROID_ABI STREQUAL "x86" )
 set( CMAKE_SYSTEM_PROCESSOR "i686" )
 set( ANDROID_TOOLCHAIN_NAME "i686-linux-android" )
elseif( ANDROID_ABI STREQUAL "x86_64" )
 set( CMAKE_SYSTEM_PROCESSOR "x86_64" )
 set( ANDROID_TOOLCHAIN_NAME "x86_64-linux-android" )
elseif( ANDROID_ABI STREQUAL "armeabi" )
 set( CMAKE_SYSTEM_PROCESSOR "armv5te" )
 set( ANDROID_TOOLCHAIN_NAME "arm-linux-androideabi" )
elseif( ANDROID_ABI STREQUAL "aarch64" )
 set( CMAKE_SYSTEM_PROCESSOR "aarch64" )
 set( ANDROID_TOOLCHAIN_NAME "aarch64-linux-android" )
elseif( ANDROID_ABI STREQUAL "mips" )
 set( CMAKE_SYSTEM_PROCESSOR "mips" )
 set( ANDROID_TOOLCHAIN_NAME "mipsel-linux-android" )
elseif( ANDROID_ABI STREQUAL "mips64" )
 set( CMAKE_SYSTEM_PROCESSOR "mips64" )
 set( ANDROID_TOOLCHAIN_NAME "mips64el-linux-android" )
else()
 message( SEND_ERROR "Unknown ANDROID_ABI = \"${ANDROID_ABI}\"." )
endif()

set( ANDROID_TOOLCHAIN_DIR "${ANDROID_TOOLCHAIN_DIR}" CACHE PATH "Android standalone toolchain directory" )
set( ANDROID_SYSROOT "${ANDROID_TOOLCHAIN_DIR}/sysroot" CACHE PATH "Android Sysroot" )

# CMAKE_EXECUTABLE_SUFFIX is undefined in CMAKE_TOOLCHAIN_FILE
if( WIN32 )
 set( EXECUTABLE_SUFFIX ".exe" )
endif()

set( PYTHON_EXECUTABLE "${ANDROID_TOOLCHAIN_DIR}/bin/python${EXECUTABLE_SUFFIX}" CACHE PATH "Python exec path" )

if( NOT CMAKE_C_COMPILER )
 set( CMAKE_C_COMPILER   "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}"     CACHE PATH "C compiler" )
 set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-g++${EXECUTABLE_SUFFIX}"     CACHE PATH "C++ compiler" )
 set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}"     CACHE PATH "assembler" )
 set( CMAKE_STRIP        "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-strip${EXECUTABLE_SUFFIX}"   CACHE PATH "strip" )
 set( CMAKE_AR           "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ar${EXECUTABLE_SUFFIX}"      CACHE PATH "archive" )
 set( CMAKE_LINKER       "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ld${EXECUTABLE_SUFFIX}"      CACHE PATH "linker" )
 set( CMAKE_NM           "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-nm${EXECUTABLE_SUFFIX}"      CACHE PATH "nm" )
 set( CMAKE_OBJCOPY      "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objcopy${EXECUTABLE_SUFFIX}" CACHE PATH "objcopy" )
 set( CMAKE_OBJDUMP      "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objdump${EXECUTABLE_SUFFIX}" CACHE PATH "objdump" )
 set( CMAKE_RANLIB       "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ranlib${EXECUTABLE_SUFFIX}"  CACHE PATH "ranlib" )
endif()

set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT} -funwind-tables -fsigned-char -no-canonical-prefixes" )
# TODO: different ARM abi have different flags such as neon, vfpv etc
if( X86 )
 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
elseif( ANDROID_ABI STREQUAL "armeabi" )
 # 64 bit atomic operations used in c++ libraries require armv7-a instructions
 # armv5te and armv6 were tried but do not work.
 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mthumb" )
 if( LLVM_BUILD_STATIC )
  # Temporary workaround for static linking with the latest API.
  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -DANDROID_ARM_BUILD_STATIC" )
 endif()
elseif( ANDROID_ABI STREQUAL "mips" )
 # http://b.android.com/182094
 list( FIND LLDB_SYSTEM_LIBS atomic index )
 if( index EQUAL -1 )
  list( APPEND LLDB_SYSTEM_LIBS atomic )
  set( LLDB_SYSTEM_LIBS ${LLDB_SYSTEM_LIBS} CACHE INTERNAL "" FORCE )
 endif()
 if( LLVM_BUILD_STATIC )
  # Temporary workaround for static linking with the latest API.
  set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -DANDROID_MIPS_BUILD_STATIC" )
 endif()
endif()

# Use gold linker and enable safe ICF in case of x86, x86_64 and arm
if ( ANDROID_ABI STREQUAL "x86"    OR
     ANDROID_ABI STREQUAL "x86_64" OR
     ANDROID_ABI STREQUAL "armeabi")
 set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold -Wl,--icf=safe" )
endif()

if( NOT LLVM_BUILD_STATIC )
 # PIE is required for API 21+ so we enable it if we're not statically linking
 # unfortunately, it is not supported before API 16 so we need to do something
 # else there see http://llvm.org/pr23457
 set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -pie -fPIE" )
endif()

# linker flags
set( ANDROID_CXX_FLAGS    "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" )
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" )

# cache flags
set( CMAKE_CXX_FLAGS           ""                        CACHE STRING "c++ flags" )
set( CMAKE_C_FLAGS             ""                        CACHE STRING "c flags" )
set( CMAKE_EXE_LINKER_FLAGS    "-Wl,-z,nocopyreloc"      CACHE STRING "executable linker flags" )
set( ANDROID_CXX_FLAGS         "${ANDROID_CXX_FLAGS}"    CACHE INTERNAL "Android c/c++ flags" )
set( ANDROID_LINKER_FLAGS      "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Android c/c++ linker flags" )

# final flags
set( CMAKE_CXX_FLAGS           "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
set( CMAKE_C_FLAGS             "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
set( CMAKE_EXE_LINKER_FLAGS    "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )

# global includes and link directories
set( ANDROID_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_DIR}/include/c++/${ANDROID_COMPILER_VERSION}" )
list( APPEND ANDROID_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_DIR}/include/python2.7" )
include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_INCLUDE_DIRS} )

# target environment
set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_DIR}/bin" "${ANDROID_TOOLCHAIN_DIR}/${ANDROID_TOOLCHAIN_NAME}" "${ANDROID_SYSROOT}" )

# only search for libraries and includes in the ndk toolchain
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )

################# BEGIN EVIL HACK ##################
# In the android-arm NDK unwind.h and link.h contains 2 conflicting
# typedef for _Unwind_Ptr. Force HAVE_UNWIND_BACKTRACE to 0 to prevent
# LLVM from finding unwind.h what would break the build.
if ( ANDROID_ABI STREQUAL "armeabi" )
 set( HAVE_UNWIND_BACKTRACE 0 CACHE INTERNAL "Hack to disable the finding of unwind.h on Android arm" )
endif()
################# END EVIL HACK ####################

################# BEGIN EVIL HACK ##################
# lldb-server links against libdl even though it's not being used and
# libdl.a is currently missing from the toolchain (b.android.com/178517).
# Therefore, in order to statically link lldb-server, we need a temporary
# workaround. This creates a dummy libdl.a stub until the actual
# libdl.a can be implemented in the toolchain.
if( LLVM_BUILD_STATIC )
 set( libdl "${CMAKE_BINARY_DIR}/libdl_stub" )
 file( MAKE_DIRECTORY ${libdl} )
 file( WRITE "${libdl}/libdl.c" "
#include <dlfcn.h>
void *       dlopen  (const char *filename, int flag)   { return 0; }
const char * dlerror (void)                             { return 0; }
void *       dlsym   (void *handle, const char *symbol) { return 0; }
int          dlclose (void *handle)                     { return 0; }
int          dladdr  (const void *addr, Dl_info *info)  { return 0; }")
 set( flags "${CMAKE_C_FLAGS}" )
 separate_arguments( flags )
 execute_process( COMMAND ${CMAKE_C_COMPILER} ${flags} -c ${libdl}/libdl.c -o ${libdl}/libdl.o )
 execute_process( COMMAND ${CMAKE_AR} rcs ${libdl}/libdl.a ${libdl}/libdl.o )
 set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${libdl}" )
endif()
################# END EVIL HACK ##################