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