Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / build_common / android / SConscript
1 ##
2 # This script includes android specific config (GNU GCC)
3 ##
4 import os
5 import platform
6 import subprocess
7
8 Import('env')
9 SConscript('../external_libs.scons')
10 SConscript('../../extlibs/android/ndk/SConscript')
11 SConscript('../../extlibs/android/gradle/SConscript')
12 SConscript('../../extlibs/android/sdk/SConscript')
13
14 help_vars = Variables()
15 help_vars.Add(PathVariable('ANDROID_GRADLE', 'Android Gradle directory', os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'gradle', 'gradle-2.2.1/bin/gradle')))
16 help_vars.Add(PathVariable('ANDROID_NDK', 'Android NDK root directory', os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'ndk', 'android-ndk-r10d')))
17
18 if env.get('ANDROID_NDK'):
19         android_ndk = env.get('ANDROID_NDK')
20 else:
21         print '''
22 *************************************** Info **********************************
23 *    Android NDK path isn't set, the default will be used. You can set        *
24 * environment variable ANDROID_NDK or add it in command line as:              *
25 *      # scons ANDROID_NDK=<path to android NDK> ...                          *
26 *******************************************************************************
27 '''
28         android_ndk = os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'ndk', 'android-ndk-r10d')
29
30 if env.get('ANDROID_GRADLE'):
31         android_gradle = env.get('ANDROID_GRADLE')
32 else:
33         print '''
34 *************************************** Info **********************************
35 *    Android Gradle path isn't set, the default will be used. You can set     *
36 * environment variable ANDROID_GRADLE or add it in command line as:           *
37 *      # scons ANDROID_GRADLE=<path to android GRADLE> ...                    *
38 *******************************************************************************
39 '''
40         android_gradle = os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'gradle', 'gradle-2.2.1', 'bin', 'gradle')
41
42 help_vars.Update(env)
43 Help(help_vars.GenerateHelpText(env))
44 src_dir = env.get('SRC_DIR')
45
46 # Overwrite suffixes and prefixes
47 if env['HOST_OS'] == 'win32':
48         env['OBJSUFFIX'] = '.o'
49         env['SHOBJSUFFIX'] = '.os'
50         env['LIBPREFIX'] = 'lib'
51         env['LIBSUFFIX'] = '.a'
52         env['SHLIBPREFIX'] = 'lib'
53         env['SHLIBSUFFIX'] = '.so'
54         env['LIBPREFIXES'] = ['lib']
55         env['LIBSUFFIXES'] = ['.a', '.so']
56         env['PROGSUFFIX'] = ''
57 elif platform.system().lower() == 'darwin':
58         env['SHLIBSUFFIX'] = '.so'
59         env['LIBSUFFIXES'] = ['.a', '.so']
60         env['PROGSUFFIX'] = ''
61
62 ######################################################################
63 # Set common flags
64 ######################################################################
65
66 # Android build system default cofig
67 env.AppendUnique(CPPDEFINES = ['ANDROID'])
68 env.AppendUnique(CFLAGS = ['-std=c99'])
69 env.AppendUnique(SHCFLAGS = ['-Wa,--noexecstack'])
70 env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections', '-Wl,-z,nocopyreloc'])
71
72 ######################################################################
73 # Probe Android NDK default flags
74 ######################################################################
75 ndk_build_cmd = android_ndk + '/ndk-build'
76 if env['HOST_OS'] == 'win32':
77         if os.path.isfile(ndk_build_cmd + '.cmd'):
78                 ndk_build_cmd += '.cmd'
79
80 if not os.path.isfile(ndk_build_cmd):
81         print '''
82 *************************************** Error *********************************
83 *   It seems android ndk path is not set properly, please check if "%s"
84 * is the root directory of android ndk.                                       *
85 *******************************************************************************
86 ''' % android_ndk
87         Exit(1)
88
89 # ANDROID_HOME build option
90 help_vars = Variables()
91 help_vars.Add(PathVariable('ANDROID_HOME', 'ANDROID SDK root directory', os.environ.get('ANDROID_HOME')))
92 help_vars.Update(env)
93 Help(help_vars.GenerateHelpText(env))
94
95 print '''
96 *************************************** Info **********************************
97 *   Environment variable ANDROID_HOME will use default value. To override     *
98 * root directory of android sdk, please specify ANDROID_HOME as follows:      *
99 *       scons ANDROID_HOME= <path to Android SDK>                             *
100 *******************************************************************************
101 '''
102
103 target_arch = env.get('TARGET_ARCH')
104
105 # Android ndk early version doesn't support C++11. Detect the toolchain version
106 # to make sure proper toolchain is used
107 for tc_ver in ['4.7', '4.8', '4.9', '']:
108         if os.path.exists(android_ndk + '/toolchains/x86-' + tc_ver):
109                 break
110
111 cmd = [ndk_build_cmd]
112 cmd.append('APP_ABI=' + target_arch)
113 cmd.append('APP_PLATFORM=android-21')
114 cmd.append('APP_STL=gnustl_shared')
115 if env.get('RELEASE'):
116         cmd.append('APP_OPTIM=release')
117 else:
118         cmd.append('APP_OPTIM=debug')
119 if tc_ver != '':
120         cmd.append('NDK_TOOLCHAIN_VERSION=' + tc_ver)
121 else:
122         print '''
123 *************************************** Warning *******************************
124 *   To support C++11, the toolchain should be >= 4.7, please make sure your   *
125 * android NDK is at least r8e!                                                *
126 *******************************************************************************
127 '''
128
129 cmd.append('-n')
130
131 p = subprocess.Popen(cmd, stdout = subprocess.PIPE)
132
133 for flags in p.stdout.readlines():
134         if cmp(flags[0:10], 'TC_PREFIX=') == 0: # toolchain prefix (include path)
135                 prefix = flags[10:].strip()
136                 env.Replace(CC = prefix + 'gcc')
137                 env.Replace(CXX = prefix + 'g++')
138                 env.Replace(AR = prefix + 'ar')
139                 env.Replace(RANLIB = prefix + 'ranlib')
140
141         elif cmp(flags[0:7], 'CFLAGS=') == 0:
142                 env.AppendUnique(CFLAGS = Split(flags[7:]))
143
144         elif cmp(flags[0:9], 'CXXFLAGS=') == 0:
145                 env.AppendUnique(CXXFLAGS = Split(flags[9:]))
146
147         elif cmp(flags[0:8], 'CPPPATH=') == 0:
148                 env.AppendUnique(CPPPATH = Split(flags[8:]))
149
150         elif cmp(flags[0:8], 'SYSROOT=') == 0:
151                 sysroot = flags[8:].strip()
152                 env.AppendUnique(LINKFLAGS = ['--sysroot=' + sysroot])
153
154         elif cmp(flags[0:8], 'LDFLAGS=') == 0:
155                 env.AppendUnique(LINKFLAGS = Split(flags[8:]))
156
157         elif cmp(flags[0:7], 'TC_VER=') == 0:  # set gnustl library path
158                 ver = flags[7:].strip()
159                 stl_path = android_ndk + '/sources/cxx-stl/gnu-libstdc++/' + ver + '/libs/' + target_arch
160                 if target_arch in ['armeabi', 'armeabi-v7a', 'armeabi-v7a-hard']:
161                         stl_path = stl_path + '/thumb/'
162
163                 env.AppendUnique(LIBPATH = [stl_path])
164                 env.Install(env.get('BUILD_DIR'), stl_path + '/libgnustl_shared.so')
165
166         elif cmp(flags[0:9], 'PLATFORM=') == 0:  # get target platform: android-x
167                 platform_ver = flags[9+8:].strip()
168                 if not platform_ver.isdigit():
169                         platform_ver = ''
170
171
172         elif cmp(flags[0:9], 'PLATFORM=') == 0:  # get target platform: android-x
173                 platform_ver = flags[9+8:].strip()
174                 if not platform_ver.isdigit():
175                         platform_ver = ''
176
177
178         elif cmp(flags[0:9], 'PLATFORM=') == 0:  # get target platform: android-x
179                 platform_ver = flags[9+8:].strip()
180                 if not platform_ver.isdigit():
181                         platform_ver = ''
182
183 # Determine dependency faux SYS_ROOT
184 dep_sys_root = os.path.join(env.get('SRC_DIR'), 'dep', 'android', target_arch, 'usr')
185 dep_src_dir =  os.path.join(dep_sys_root, 'include')
186 dep_lib_dir =  os.path.join(dep_sys_root, 'lib')
187
188 env['DEP_SYS_ROOT'] = dep_sys_root
189
190 # Add external libraries including boost
191 env.AppendUnique(CPPPATH = [ dep_src_dir ])
192 env.AppendUnique(LIBPATH = [ dep_lib_dir ])
193
194 ######################################################################
195 # Set release/debug flags
196 ######################################################################
197 if env.get('RELEASE'):
198         env.AppendUnique(CCFLAGS = ['-Os'])
199         env.AppendUnique(CPPDEFINES = ['NDEBUG'])
200         env.AppendUnique(LINKFLAGS = ['-s'])
201 else:
202         env.AppendUnique(CCFLAGS = ['-g'])
203
204 if env.get('LOGGING'):
205         env.AppendUnique(CPPDEFINES = ['TB_LOG'])
206
207
208 env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__ANDROID__'])
209 env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC'])
210 #env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread'])
211
212 env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
213 env.AppendUnique(LIBPATH = [src_dir + '/resource/csdk/connectivity/lib/android'])
214 env.AppendUnique(LIBS = ['log', 'coap'])
215
216 if env.get('SECURED') == '1':
217         env.AppendUnique(LIBS = ['tinydtls'])
218
219 # From android-5 (API > 20), all application must be built with flags '-fPIE' '-pie'.
220 # Due to the limitation of Scons, it's required to added it into the command line
221 # directly (otherwise, it will also be added when build share library)
222 env.Replace(CCCOM = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES')
223 env.Replace(CXXCOM = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES')
224 env.Replace(LINKCOM = '$LINK -o $TARGET -pie $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS')
225
226 # Fix android-ndk compatibility issue, make applications build on new NDK can run on old platform
227 if platform_ver == '' or int(platform_ver) > 20:
228         SConscript('compatibility/c_compat.scons')
229
230 SConscript('compatibility/cpp11_compat.scons')
231
232 # Make sure that boost for android is available
233 SConscript(env.get('SRC_DIR') + '/extlibs/boost/SConscript')
234 SConscript(env.get('SRC_DIR') + '/extlibs/expat/SConscript')