Code portability cleanup.
[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 # Overwrite suffixes and prefixes
27 if env['HOST_OS'] == 'win32':
28         env['OBJSUFFIX'] = '.o'
29         env['SHOBJSUFFIX'] = '.os'
30         env['LIBPREFIX'] = 'lib'
31         env['LIBSUFFIX'] = '.a'
32         env['SHLIBPREFIX'] = 'lib'
33         env['SHLIBSUFFIX'] = '.so'
34         env['LIBPREFIXES'] = ['lib']
35         env['LIBSUFFIXES'] = ['.a', '.so']
36         env['PROGSUFFIX'] = ''
37 elif platform.system().lower() == 'darwin':
38         env['SHLIBSUFFIX'] = '.so'
39         env['LIBSUFFIXES'] = ['.a', '.so']
40         env['PROGSUFFIX'] = ''
41
42 ######################################################################
43 # Set common flags
44 ######################################################################
45
46 # Android build system default cofig
47 env.AppendUnique(CPPDEFINES = ['ANDROID'])
48 env.AppendUnique(CFLAGS = ['-std=c99'])
49 env.AppendUnique(SHCFLAGS = ['-Wa,--noexecstack'])
50 env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections', '-Wl,-z,nocopyreloc'])
51
52 ######################################################################
53 # Probe Android NDK default flags
54 ######################################################################
55 ndk_build_cmd = android_ndk + '/ndk-build'
56 if env['HOST_OS'] == 'win32':
57         if os.path.isfile(ndk_build_cmd + '.cmd'):
58                 ndk_build_cmd += '.cmd'
59
60 if not os.path.isfile(ndk_build_cmd):
61         print '''
62 *************************************** Error *********************************
63 *   It seems android ndk path is not set properly, please check if "%s"
64 * is the root directory of android ndk.                                       *
65 *******************************************************************************
66 ''' % android_ndk
67         Exit(1)
68
69 ANDROID_HOME = os.environ.get('ANDROID_HOME')
70 if ANDROID_HOME is not None:
71         ANDROID_HOME = os.path.abspath(ANDROID_HOME)
72
73 if ANDROID_HOME is None or not os.path.exists(ANDROID_HOME):
74         print '''
75 *************************************** Warning *******************************
76 *   Enviornment variable ANDROID_HOME is not set properly. It should be the   *
77 * root directory of android sdk. If you'd like build Java code, it's required.*
78 *******************************************************************************
79 '''
80
81 target_arch = env.get('TARGET_ARCH')
82
83 # Android ndk early version doesn't support C++11. Detect the toolchain version
84 # to make sure proper toolchain is used
85 for tc_ver in ['4.7', '4.8', '4.9', '']:
86         if os.path.exists(android_ndk + '/toolchains/x86-' + tc_ver):
87                 break
88
89 cmd = [ndk_build_cmd]
90 cmd.append('APP_ABI=' + target_arch)
91 cmd.append('APP_STL=gnustl_static')
92 if env.get('RELEASE'):
93         cmd.append('APP_OPTIM=release')
94 else:
95         cmd.append('APP_OPTIM=debug')
96 if tc_ver != '':
97         cmd.append('NDK_TOOLCHAIN_VERSION=' + tc_ver)
98 else:
99         print '''
100 *************************************** Warning *******************************
101 *   To support C++11, the toolchain should be >= 4.7, please make sure your   *
102 * android NDK is at least r8e!                                                *
103 *******************************************************************************
104 '''
105
106 cmd.append('-n')
107
108 p = subprocess.Popen(cmd, stdout = subprocess.PIPE)
109
110 for flags in p.stdout.readlines():
111         if cmp(flags[0:10], 'TC_PREFIX=') == 0: # toolchain prefix (include path)
112                 prefix = flags[10:].strip()
113                 env.Replace(CC = prefix + 'gcc')
114                 env.Replace(CXX = prefix + 'g++')
115                 env.Replace(AR = prefix + 'ar')
116                 env.Replace(RANLIB = prefix + 'ranlib')
117
118         elif cmp(flags[0:7], 'CFLAGS=') == 0:
119                 env.AppendUnique(CFLAGS = Split(flags[7:]))
120
121         elif cmp(flags[0:9], 'CXXFLAGS=') == 0:
122                 env.AppendUnique(CXXFLAGS = Split(flags[9:]))
123
124         elif cmp(flags[0:8], 'CPPPATH=') == 0:
125                 env.AppendUnique(CPPPATH = Split(flags[8:]))
126
127         elif cmp(flags[0:8], 'SYSROOT=') == 0:
128                 sysroot = flags[8:].strip()
129                 env.AppendUnique(LINKFLAGS = ['--sysroot=' + sysroot])
130                 env.AppendUnique(LIBPATH = [sysroot + '/usr/lib'])
131
132         elif cmp(flags[0:8], 'LDFLAGS=') == 0:
133                 env.AppendUnique(LINKFLAGS = Split(flags[8:]))
134
135         elif cmp(flags[0:7], 'TC_VER=') == 0:  # set gnustl library path
136                 ver = flags[7:].strip()
137                 env.AppendUnique(LIBPATH = [android_ndk + '/sources/cxx-stl/gnu-libstdc++/'
138                                 + ver + '/libs/' + target_arch])
139
140         elif cmp(flags[0:9], 'PLATFORM=') == 0:  # get target platform: android-x
141                 platform_ver = flags[9+8:].strip()
142                 if not platform_ver.isdigit():
143                         platform_ver = ''
144
145 ######################################################################
146 # Set release/debug flags
147 ######################################################################
148 if env.get('RELEASE'):
149         env.AppendUnique(CCFLAGS = ['-Os'])
150         env.AppendUnique(CPPDEFINES = ['NDEBUG'])
151         env.AppendUnique(LINKFLAGS = ['-s'])
152 else:
153         env.AppendUnique(CCFLAGS = ['-g'])
154
155 # From android-5 (API > 20), all application must be built with flags '-fPIE' '-pie'.
156 # Due to the limitation of Scons, it's required to added it into the command line
157 # directly (otherwise, it will also be added when build share library)
158 env.Replace(CCCOM = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES')
159 env.Replace(CXXCOM = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES')
160 env.Replace(LINKCOM = '$LINK -o $TARGET -pie $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS')
161
162 # Fix android-ndk compatibility issue, make applications build on new NDK can run on old platform
163 if platform_ver == '' or int(platform_ver) > 20:
164         SConscript('compatibility/c_compat.scons')
165
166 SConscript('compatibility/cpp11_compat.scons')