## # This script includes android specific config (GNU GCC) ## import os import platform import subprocess Import('env') SConscript('../external_libs.scons') help_vars = Variables() if not env.get('ANDROID_NDK'): SConscript('../../extlibs/android/ndk/SConscript') help_vars.Add(PathVariable('ANDROID_NDK', 'Android NDK root directory', os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'ndk', 'android-ndk-r10d'))) if not env.get('ANDROID_GRADLE'): SConscript('../../extlibs/android/gradle/SConscript') 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'))) if not env.get('ANDROID_HOME'): SConscript('../../extlibs/android/sdk/SConscript') if env.get('ANDROID_NDK'): android_ndk = env.get('ANDROID_NDK') else: print ''' *************************************** Info ********************************** * Android NDK path isn't set, the default will be used. You can set * * environment variable ANDROID_NDK or add it in command line as: * * # scons ANDROID_NDK= ... * ******************************************************************************* ''' android_ndk = os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'ndk', 'android-ndk-r10d') if env.get('ANDROID_GRADLE'): android_gradle = env.get('ANDROID_GRADLE') else: print ''' *************************************** Info ********************************** * Android Gradle path isn't set, the default will be used. You can set * * environment variable ANDROID_GRADLE or add it in command line as: * * # scons ANDROID_GRADLE= ... * ******************************************************************************* ''' android_gradle = os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'gradle', 'gradle-2.2.1', 'bin', 'gradle') help_vars.Update(env) Help(help_vars.GenerateHelpText(env)) src_dir = env.get('SRC_DIR') # Overwrite suffixes and prefixes if env['HOST_OS'] == 'win32': env['OBJSUFFIX'] = '.o' env['SHOBJSUFFIX'] = '.os' env['LIBPREFIX'] = 'lib' env['LIBSUFFIX'] = '.a' env['SHLIBPREFIX'] = 'lib' env['SHLIBSUFFIX'] = '.so' env['LIBPREFIXES'] = ['lib'] env['LIBSUFFIXES'] = ['.a', '.so'] env['PROGSUFFIX'] = '' elif platform.system().lower() == 'darwin': env['SHLIBSUFFIX'] = '.so' env['LIBSUFFIXES'] = ['.a', '.so'] env['PROGSUFFIX'] = '' ###################################################################### # Set common flags ###################################################################### # Android build system default cofig env.AppendUnique(CPPDEFINES = ['ANDROID']) env.AppendUnique(CFLAGS = ['-std=c99']) env.AppendUnique(SHCFLAGS = ['-Wa,--noexecstack']) env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections', '-Wl,-z,nocopyreloc']) ###################################################################### # Probe Android NDK default flags ###################################################################### ndk_build_cmd = android_ndk + '/ndk-build' if env['HOST_OS'] == 'win32': if os.path.isfile(ndk_build_cmd + '.cmd'): ndk_build_cmd += '.cmd' if not os.path.isfile(ndk_build_cmd): print ''' *************************************** Error ********************************* * It seems android ndk path is not set properly, please check if "%s" * is the root directory of android ndk. * ******************************************************************************* ''' % android_ndk Exit(1) # ANDROID_HOME build option if env.get('ANDROID_HOME'): android_gradle = env.get('ANDROID_HOME') else: help_vars = Variables() help_vars.Add(PathVariable('ANDROID_HOME', 'ANDROID SDK root directory', os.environ.get('ANDROID_HOME'))) help_vars.Update(env) Help(help_vars.GenerateHelpText(env)) print ''' *************************************** Info ********************************** * Environment variable ANDROID_HOME will use default value. To override * * root directory of android sdk, please specify ANDROID_HOME as follows: * * scons ANDROID_HOME= * ******************************************************************************* ''' target_arch = env.get('TARGET_ARCH') # Android ndk early version doesn't support C++11. Detect the toolchain version # to make sure proper toolchain is used for tc_ver in ['4.7', '4.8', '4.9', '']: if os.path.exists(android_ndk + '/toolchains/x86-' + tc_ver): break cmd = [ndk_build_cmd] cmd.append('APP_ABI=' + target_arch) cmd.append('APP_PLATFORM=android-21') cmd.append('APP_STL=gnustl_shared') if env.get('RELEASE'): cmd.append('APP_OPTIM=release') else: cmd.append('APP_OPTIM=debug') if tc_ver != '': cmd.append('NDK_TOOLCHAIN_VERSION=' + tc_ver) else: print ''' *************************************** Warning ******************************* * To support C++11, the toolchain should be >= 4.7, please make sure your * * android NDK is at least r8e! * ******************************************************************************* ''' cmd.append('-n') p = subprocess.Popen(cmd, stdout = subprocess.PIPE) for flags in p.stdout.readlines(): if cmp(flags[0:10], 'TC_PREFIX=') == 0: # toolchain prefix (include path) prefix = flags[10:].strip() env.Replace(CC = prefix + 'gcc') env.Replace(CXX = prefix + 'g++') env.Replace(AR = prefix + 'ar') env.Replace(RANLIB = prefix + 'ranlib') elif cmp(flags[0:7], 'CFLAGS=') == 0: env.AppendUnique(CFLAGS = Split(flags[7:])) elif cmp(flags[0:9], 'CXXFLAGS=') == 0: env.AppendUnique(CXXFLAGS = Split(flags[9:])) elif cmp(flags[0:8], 'CPPPATH=') == 0: ndk_arch = 'arch-' if cmp(target_arch, 'x86') == 0: ndk_arch += 'x86' elif cmp(target_arch, 'x86_64') == 0: ndk_arch += 'x86_64' elif cmp(target_arch, 'armeabi') == 0: ndk_arch += 'arm' elif cmp(target_arch, 'armeabi-v7a') == 0: ndk_arch += 'arm' elif cmp(target_arch, 'armeabi-v7a-hard') == 0: ndk_arch += 'arm' elif cmp(target_arch, 'arm64-v8a') == 0: ndk_arch += 'arm64' env.AppendUnique(CPPPATH = android_ndk+'/platforms/android-21/'+ndk_arch+'/usr/include') env.AppendUnique(CPPPATH = Split(flags[8:])) elif cmp(flags[0:8], 'SYSROOT=') == 0: sysroot = flags[8:].strip() env.AppendUnique(LINKFLAGS = ['--sysroot=' + sysroot]) elif cmp(flags[0:8], 'LDFLAGS=') == 0: env.AppendUnique(LINKFLAGS = Split(flags[8:])) elif cmp(flags[0:7], 'TC_VER=') == 0: # set gnustl library path ver = flags[7:].strip() stl_path = android_ndk + '/sources/cxx-stl/gnu-libstdc++/' + ver + '/libs/' + target_arch # if target_arch in ['armeabi', 'armeabi-v7a', 'armeabi-v7a-hard']: # stl_path = stl_path + '/thumb/' env.AppendUnique(LIBPATH = [stl_path]) env.Install(env.get('BUILD_DIR'), stl_path + '/libgnustl_shared.so') elif cmp(flags[0:9], 'PLATFORM=') == 0: # get target platform: android-x platform_ver = flags[9+8:].strip() if not platform_ver.isdigit(): platform_ver = '' elif cmp(flags[0:9], 'PLATFORM=') == 0: # get target platform: android-x platform_ver = flags[9+8:].strip() if not platform_ver.isdigit(): platform_ver = '' elif cmp(flags[0:9], 'PLATFORM=') == 0: # get target platform: android-x platform_ver = flags[9+8:].strip() if not platform_ver.isdigit(): platform_ver = '' # Determine dependency faux SYS_ROOT dep_sys_root = os.path.join(env.get('SRC_DIR'), 'dep', 'android', target_arch, 'usr') dep_src_dir = os.path.join(dep_sys_root, 'include') dep_lib_dir = os.path.join(dep_sys_root, 'lib') env['DEP_SYS_ROOT'] = dep_sys_root # Add external libraries including boost env.AppendUnique(CPPPATH = [ dep_src_dir ]) env.AppendUnique(LIBPATH = [ dep_lib_dir ]) ###################################################################### # Set release/debug flags ###################################################################### if env.get('RELEASE'): env.AppendUnique(CCFLAGS = ['-Os']) env.AppendUnique(CPPDEFINES = ['NDEBUG']) env.AppendUnique(LINKFLAGS = ['-s']) else: env.AppendUnique(CCFLAGS = ['-g']) if env.get('LOGGING'): env.AppendUnique(CPPDEFINES = ['TB_LOG']) env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__ANDROID__']) env.AppendUnique(CCFLAGS = ['-Wall', '-Wextra', '-fPIC']) env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) env.AppendUnique(LIBPATH = [src_dir + '/resource/csdk/connectivity/lib/android']) env.AppendUnique(LIBS = ['log', 'coap']) if env.get('SECURED') == '1': env.SConscript('#extlibs/mbedtls/SConscript') env.AppendUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto']) # From android-5 (API > 20), all application must be built with flags '-fPIE' '-pie'. # Due to the limitation of Scons, it's required to added it into the command line # directly (otherwise, it will also be added when build share library) env.Replace(CCCOM = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES') env.Replace(CXXCOM = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES') env.Replace(LINKCOM = '$LINK -o $TARGET -pie $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS') # Fix android-ndk compatibility issue, make applications build on new NDK can run on old platform if platform_ver == '' or int(platform_ver) > 20: SConscript('compatibility/c_compat.scons') SConscript('compatibility/cpp11_compat.scons') # Make sure that boost for android is available SConscript('#extlibs/boost/SConscript')