Improve android building 31/21631/13
authorMats Wichmann <mats@linux.com>
Mon, 10 Jul 2017 13:38:27 +0000 (07:38 -0600)
committerRick Bell <richard.s.bell@intel.com>
Thu, 31 Aug 2017 19:48:06 +0000 (19:48 +0000)
build_common/SConscript:
    - ANDROID_NDK, ANDROID_HOME, ANDROID_GRADLE option variables
    setup moved to end.  A visit if needed to respective SConscripts
    will cause the default path to be computed, this path is
    then supplied to the variable setup.  The comment in the later
    section will describe more.
build_common/android/SConscript:
    - option var setup not heeded here. Just call ndk, gradle, sdk
    SConscript if path not already set.
    - API_VER is set at top, idea is to have one place to change
    to experiment with new verisons.
    - all three paths are printed from one "print", this can easily
    be disabled if not wanted.
build_common/linux/SConscript,
build_common/windows/SConscript:
    - just pick up gradle info from SConscript, no need for the
    option var setup.
extlibs/android/gradle/SConscript:
    - clean up; version is now set in a single variable
extlibs/android/ndk/SConscript:
    - clean up; version is now set in a single variable
    - adds Mac support - untested, but why not: sdk script does it
extlibs/android/sdk/SConscript:
    - clean up; version is now set in a single variable

Change-Id: I7e4355493808eddce6899fe657657e56c339ae5d
Signed-off-by: Mats Wichmann <mats@linux.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/21631
Reviewed-by: George Nash <george.nash@intel.com>
Reviewed-by: Larry Sachs <larry.j.sachs@intel.com>
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Rick Bell <richard.s.bell@intel.com>
build_common/SConscript
build_common/android/SConscript
build_common/linux/SConscript
build_common/windows/SConscript
extlibs/android/gradle/SConscript
extlibs/android/ndk/SConscript
extlibs/android/sdk/SConscript

index 8c8ae70..1a87b03 100755 (executable)
@@ -177,6 +177,10 @@ help_vars.AddVariables(
                  'Enable routing',
                  default='EP',
                  allowed_values=('GW', 'EP')),
+    EnumVariable('WITH_UPSTREAM_LIBCOAP',
+                 'Use latest stable version of LibCoAP downloaded from github',
+                 default=default_with_upstream_libcoap,
+                 allowed_values=('0', '1')),
     EnumVariable('BUILD_SAMPLE',
                  'Build with sample',
                  default='ON',
@@ -184,22 +188,9 @@ help_vars.AddVariables(
     ('DEVICE_NAME',
                  'Network display name for device (For Arduino)',
                  device_name),
-    PathVariable('ANDROID_NDK',
-                 'Android NDK path',
-                 default=None,
-                 validator=PathVariable.PathAccept),
-    PathVariable('ANDROID_HOME',
-                 'Android SDK path',
-                 default=None,
-                 validator=PathVariable.PathAccept),
-    PathVariable('ANDROID_GRADLE',
-                 'Gradle executable location',
-                 default=None,
-                 validator=PathVariable.PathIsFile),
-    EnumVariable('WITH_UPSTREAM_LIBCOAP',
-                 'Use latest stable version of LibCoAP downloaded from github',
-                 default=default_with_upstream_libcoap,
-                 allowed_values=('0', '1')),
+#    ANDROID_NDK set at end after default computed
+#    ANDROID_HOME set at end after default computed
+#    ANDROID_GRADLE set at end after default computed
     BoolVariable('WITH_ENV',
                  'Use compiler options from environment',
                  default=False),
@@ -237,6 +228,7 @@ else:
 
 if target_os in targets_without_dtls_support:
     help_vars.Add(
+        # cannot be a bool since True not allowed
         EnumVariable('SECURED',
                      'Build with DTLS',
                      default='0',
@@ -309,8 +301,6 @@ else:
         LIB_INSTALL_DIR=ARGUMENTS.get('LIB_INSTALL_DIR')  #for 64bit build
     )
 
-Help(help_vars.GenerateHelpText(env))
-
 if env.get('WITH_ENV'):
     env['ENV'] = os.environ
     if 'CC' in os.environ:
@@ -828,4 +818,40 @@ env = conf.Finish()
 
 env.SConscript('external_libs.scons')
 
+# these variables depend on a subsidiary script having set a path to
+# use as the default. Such paths may include embedded version strings,
+# for example, and we want to not embed those all over, so defer setting
+# the help until we're back from those scripts. Then we can finally
+# build the help message. However, it's also possible that we never
+# needed to call those subsidary scripts, and then we come back with
+# values unset, so deal with that as well.
+if env.get('ANDROID_NDK'):
+    android_ndk = env['ANDROID_NDK']
+else:
+    android_ndk = None
+if env.get('ANDROID_GRADLE'):
+    android_gradle = env['ANDROID_GRADLE']
+else:
+    android_gradle = None
+if env.get('ANDROID_HOME'):
+    android_sdk = env['ANDROID_HOME']
+else:
+    android_sdk = None
+help_vars.AddVariables(
+    PathVariable('ANDROID_NDK',
+                 'Android NDK path',
+                 default=android_ndk,
+                 validator=PathVariable.PathAccept),
+    PathVariable('ANDROID_GRADLE',
+                 'Gradle executable location',
+                 default=android_gradle,
+                 validator=PathVariable.PathIsFile),
+    PathVariable('ANDROID_HOME',
+                 'Android SDK path',
+                 default=android_sdk,
+                 validator=PathVariable.PathAccept),
+)
+help_vars.Update(env)
+Help(help_vars.GenerateHelpText(env, sort=cmp))
+
 Return('env')
index 144eb12..47c455d 100644 (file)
@@ -7,57 +7,30 @@ import subprocess
 
 Import('env')
 
+API_VER='21'
+
+# if paths for required Android pieces were not passed to scons,
+# work out the defaults by calling the appropriate scripts.
+# side effect: if the extlibs script is called, the piece
+# will be set up if it was not already, so may be quite slow
+# (sdk, ndk are huge)
 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-r10e')))
+android_ndk = env.get('ANDROID_NDK')
+msg = "\nANDROID_NDK=" + android_ndk
 
 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')))
+msg += "\nANDROID_GRADLE=" + env.get('ANDROID_GRADLE')
 
 if not env.get('ANDROID_HOME'):
     SConscript('#/extlibs/android/sdk/SConscript')
+msg += "\nANDROID_HOME=" + env.get('ANDROID_HOME')
 
-if env.get('ANDROID_NDK'):
-    android_ndk = env.get('ANDROID_NDK')
-else:
-    print '''
-*************************************** Info **********************************
-* Android NDK path not set, the default will be used. You can set
-* environment variable ANDROID_NDK or add it in the command line as:
-*      # scons ANDROID_NDK=<path to android NDK> ...
-*******************************************************************************
-'''
-    android_ndk = os.path.join(
-        env.get('SRC_DIR'), 'extlibs', 'android', 'ndk', 'android-ndk-r10e')
+# show the Android environment we will use:
+print msg
 
-if env.get('ANDROID_GRADLE'):
-    android_gradle = env.get('ANDROID_GRADLE')
-else:
-    print '''
-*************************************** Info **********************************
-* Android Gradle path not set, the default will be used. You can set
-* environment variable ANDROID_GRADLE or add it in the command line as:
-*      # scons ANDROID_GRADLE=<path to 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 host's don't agree with NDK
@@ -103,25 +76,6 @@ if not os.path.isfile(ndk_build_cmd):
 ''' % android_ndk
     Exit(msg)
 
-# 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= <path to Android SDK>
-*******************************************************************************
-'''
-
 target_arch = env.get('TARGET_ARCH')
 
 # Early Android ndk versions do not support C++11.
@@ -134,7 +88,7 @@ else:
 
 cmd = [ndk_build_cmd]
 cmd.append('APP_ABI=' + target_arch)
-cmd.append('APP_PLATFORM=android-21')
+cmd.append('APP_PLATFORM=android-' + API_VER)
 cmd.append('APP_STL=gnustl_shared')
 if env.get('RELEASE'):
     cmd.append('APP_OPTIM=release')
@@ -179,7 +133,7 @@ for flags in p.stdout.readlines():
         elif target_arch in ['arm64-v8a']:
             ndk_arch += 'arm64'
 
-        env.AppendUnique(CPPPATH=android_ndk + '/platforms/android-21/' + ndk_arch + '/usr/include')
+        env.AppendUnique(CPPPATH=android_ndk + '/platforms/android-' + API_VER + '/' + ndk_arch + '/usr/include')
         env.AppendUnique(CPPPATH=Split(flags.replace('CPPPATH=', '')))
 
     elif flags.startswith('SYSROOT='):
@@ -205,7 +159,7 @@ for flags in p.stdout.readlines():
             platform_ver = ''
 
 # Determine dependency faux SYS_ROOT
-dep_sys_root = os.path.join(env.get('SRC_DIR'), 'dep', 'android', target_arch, 'usr')
+dep_sys_root = os.path.join(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')
 
index 03a2c00..4837e08 100644 (file)
@@ -6,8 +6,6 @@
 import os
 Import('env')
 
-src_dir = env.get('SRC_DIR')
-
 # Add the default lib directory
 build_dir = env.get('BUILD_DIR')
 env.AppendUnique(LIBPATH=[build_dir])
index 6496d13..725335a 100644 (file)
@@ -6,7 +6,6 @@ import os
 import winreg
 import platform
 
-src_dir = env.get('SRC_DIR')
 build_dir = env.get('BUILD_DIR')
 
 def OpenRegKey(env, key, sub_key, reg_view_64bit=False):
index 15b8f21..f2ef5e8 100644 (file)
@@ -1,26 +1,24 @@
-import os, sys, platform, subprocess
+##
+# Make sure gradle exists
+# Note this script is only called if ANDROID_GRADLE was not set to begin with,
+# so we can safely set it here.
+
+import os
 
 Import('env')
 
-env = env.Clone()
-ndk_env = env.Clone()
+GRADLE_VER = '2.2.1'
 
-target_os = env.get('TARGET_OS')
-######################################################################
-# Build flags
-######################################################################
-src_dir = env.get('SRC_DIR')
+gradle_dir = 'gradle-' + GRADLE_VER
+gradle_zip_file = 'gradle-' + GRADLE_VER + '-bin.zip'
+gradle_url = 'https://services.gradle.org/distributions/' + gradle_zip_file
 
-path = os.path.join(src_dir, 'extlibs', 'android', 'gradle', 'gradle-2.2.1')
+if not os.path.exists(gradle_dir):
+    if not os.path.exists(gradle_zip_file):
+        print "Retrieving Android Gradle bundle"
+        gradle_zip = env.Download(gradle_zip_file, gradle_url)
+    gradle_unpacked = env.UnpackAll(gradle_dir, gradle_zip)
 
-# check 'gradle' library, if it doesn't exits, ask user to download it
-if not os.path.exists(path):
-    gradle_zip = env.Download(
-        'gradle2.2.1.zip',
-        'https://services.gradle.org/distributions/gradle-2.2.1-all.zip')
-    gradle_dir = env.UnpackAll('gradle-2.2.1', gradle_zip)
-    print( '''
-***********************************************************************
-* Downloading gradle:                                                 *
-***********************************************************************
-''')
+# export the location of the gradle script
+android_gradle = os.path.join(Dir('.').abspath, gradle_dir, 'bin/gradle')
+env.Replace(ANDROID_GRADLE=android_gradle)
index e6524a6..772a648 100644 (file)
@@ -1,47 +1,48 @@
-import os, string, sys, subprocess, struct
+##
+# Make sure Android NDK exists
+# Note this script is only called if ANDROID_NDK was not set to begin with,
+# so we can safely set it here.
 
-Import('env')
+import os
+import sys
 
-env = env.Clone()
-ndk_env = env.Clone()
+Import('env')
 
-target_os = env.get('TARGET_OS')
-target_arch = env.get('TARGET_ARCH')
+NDK_VER = 'r10e'
 
+ndk_dir = 'android-ndk-' + NDK_VER
+ndk_url_base = 'http://dl.google.com/android/ndk/android-ndk-' + NDK_VER
 host_os = sys.platform
 
-######################################################################
-# Build flags
-######################################################################
-src_dir = env.get('SRC_DIR')
-path = os.path.join(src_dir, 'extlibs', 'android', 'ndk', 'android-ndk-r10e')
-
-# check 'ndk' library, if it doesn't exits, ask user to download it
-if not os.path.exists(path):
-    ndk_env = Environment(ENV=os.environ)
-    if host_os.startswith("linux"):
-        archType = 8 * struct.calcsize("P")
-        if archType == 64:
-            env.Download(
-                'android-ndk-r10e.bin',
-                'http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin'
-            )
-        else:
-            env.Download(
-                'android-ndk-r10e.bin',
-                'http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86.bin'
-            )
+if host_os.startswith('linux'):
+    ndk_url = ndk_url_base + '-linux-x86_64.bin'
+    ndk_bundle = 'android-ndk-' + NDK_VER + '.bin'
+elif host_os == 'darwin':
+    ndk_url = ndk_url_base + '-darwin-x86_64.zip'
+    ndk_bundle = 'android-ndk-' + NDK_VER + '.zip'
+else:
+    if host_arch in ['x86_64']:
+        ndk_url = ndk_url_base + '-windows-x86_64.exe'
+    else:
+        ndk_url = ndk_url_base + '-windows-x86.exe'
+    ndk_bundle = 'android-ndk-' + NDK_VER + '.exe'
 
-        os.system("chmod a+x android-ndk-r10e.bin")
-        os.system("./android-ndk-r10e.bin")
+ndk_path = os.path.join(Dir('.').abspath, ndk_dir)
+if not os.path.exists(ndk_path):
+    if not os.path.exists(ndk_bundle):
+        print "Retrieving Android NDK bundle"
+        env.Download(ndk_bundle, ndk_url)
+    print "Unpacking Android NDK bundle"
+    if host_os.startswith('linux'):
+        # scons on Jenkins/android builder does not take 'a+x' mode, use octal
+        Execute(Chmod(ndk_bundle, 0755))
+        if Execute("./" + ndk_bundle):
+            Exit("Unpack %s failed" % ndk_bundle)
+    elif host_os == 'darwin':
+        env.UnpackAll(ndk_dir, ndk_bundle)
     else:
-        if target_arch in ['x86_64']:
-            env.Download(
-                'android-ndk-r10e',
-                'http://dl.google.com/android/ndk/android-ndk-r10e-windows-x86_64.exe'
-            )
-        if target_arch in ['x86']:
-            env.Download(
-                'android-ndk-r10e',
-                'http://dl.google.com/android/ndk/android-ndk-r10e-windows-x86.exe'
-            )
+        if Execute(ndk_bundle):
+            Exit("Unpack %s failed" % ndk_bundle)
+
+# export the location of the NDK
+env.Replace(ANDROID_NDK=ndk_path)
index 980d7c6..01a4f7a 100644 (file)
@@ -1,60 +1,53 @@
 ##
-# Script to install (if they do not exist) the Android SDK library (ie. Android JDK)
+# Script to download/install the Android SDK if it is not present
+# Only done if ANDROID_HOME is not set; if it is, assume just use that
+# ANDROID_HOME is set as a side effect
 ##
 
-import os, subprocess, struct
-import urllib2, urlparse
-import SCons.Errors
-import shutil
+import os
+import sys
 
 Import('env')
 
-target_os = env.get('TARGET_OS')
+SDK_VER = 'r24.2'
 src_dir = env.get('SRC_DIR')
 
-SConscript(src_dir + '/build_common/tools/UnpackAll.py')
-
-# Download
-if target_os == 'android':
-    android_home = env.get('ANDROID_HOME')
-    if not android_home:
-        print 'Creating ANDROID_HOME for Android SDK'
-
-        # older IoTivity versions expected the SDK at this position, this is left for backwards compatibility
-        androidlib_dir = src_dir + '/extlibs/android/sdk/android-sdk_r24.2'
-
-        if not os.path.exists(androidlib_dir):
-            from sys import platform as _platform
-            if _platform == "linux" or _platform == "linux2":
-                androidlib_zip_file = src_dir + '/extlibs/android/android-sdk_r24.2-linux.tgz'
-                androidlib_url = 'http://dl.google.com/android/android-sdk_r24.2-linux.tgz'
-                androidlib_dir = src_dir + '/extlibs/android/sdk/android-sdk-linux'
-            elif _platform == "darwin":
-                androidlib_zip_file = src_dir + '/extlibs/android/android-sdk_r24.2-macosx.zip'
-                androidlib_url = 'http://dl.google.com/android/android-sdk_r24.2-macosx.zip'
-                androidlib_dir = src_dir + '/extlibs/android/sdk/android-sdk-macosx'
-            elif _platform == "win32":
-                androidlib_zip_file = src_dir + '/extlibs/android/android-sdk_r24.2-windows.zip'
-                androidlib_url = 'http://dl.google.com/android/android-sdk_r24.2-windows.zip'
-                androidlib_dir = src_dir + '/extlibs/android/sdk/android-sdk-windows'
-
-        if not os.path.exists(androidlib_dir):
-            # If the zip file is not already present, download it
-            if not os.path.exists(androidlib_zip_file):
-                androidlib_zip = env.Download(androidlib_zip_file, androidlib_url)
-            else:
-                androidlib_zip = androidlib_zip_file
-
-            # Unzip the lib
-            print 'Unzipping android lib...'
-            env.UnpackAll(androidlib_dir, androidlib_zip)
-            print 'Unzipping android lib complete'
-
-            # Remove downloaded file
-            # os.remove(androidlib_zip_file)
-    else:
-        androidlib_dir = env.get('ANDROID_HOME')
-
-# Set the ANDROID_HOME
-env.Replace(ANDROID_HOME=androidlib_dir)
-print 'ANDROID_HOME = ' + env.get('ANDROID_HOME')
+SConscript('#/build_common/tools/UnpackAll.py')
+
+host_os = sys.platform
+
+if not env.get('ANDROID_HOME'):
+    # older IoTivity versions expected the SDK at this position.
+    # left for backwards compatibility (including hardcoded version)
+    androidlib_dir = src_dir + '/extlibs/android/sdk/android-sdk_' + SDK_VER
+
+    if not os.path.exists(androidlib_dir):
+        androidlib_bundle = os.path.join(src_dir, 'extlibs', 'android', 'sdk', 'android-sdk_' + SDK_VER)
+        androidlib_url = 'http://dl.google.com/android/android-sdk_' + SDK_VER
+        # if back-compat one didn't exist, redefine to new location
+        androidlib_dir = os.path.join(src_dir, 'extlibs', 'android', 'sdk', 'android-sdk')
+        if host_os.startswith("linux"):
+            androidlib_bundle += '-linux.tgz'
+            androidlib_url += '-linux.tgz'
+            androidlib_dir += '-linux'
+        elif host_os == "darwin":
+            androidlib_bundle += '-macosx.zip'
+            androidlib_url += '-macosx.zip'
+            androidlib_dir += '-macosx'
+        elif host_os == "win32":
+            androidlib_bundle += '-windows.zip'
+            androidlib_url += '-windows.zip'
+            androidlib_dir += '-windows'
+
+    if not os.path.exists(androidlib_dir):
+        if not os.path.exists(androidlib_bundle):
+            print "Retrieving Android SDK bundle"
+            androidlib_zip = env.Download(androidlib_bundle, androidlib_url)
+        else:
+            androidlib_zip = androidlib_bundle
+
+        print 'Unzipping Android lib...'
+        env.UnpackAll(androidlib_dir, androidlib_zip)
+        print 'Unzipping Android lib complete'
+    # export the location of the SDK
+    env.Replace(ANDROID_HOME=androidlib_dir)