From ead1b5aaaf08047ac99b5959202e55d34ec529d3 Mon Sep 17 00:00:00 2001 From: George Nash Date: Tue, 11 Apr 2017 13:23:54 -0700 Subject: [PATCH] [IOT-2029] split scons builder code out of external_libs.scons This splits the contents of the external_libs.scons into two files: external_builders.scons external_libs.scons The external_libs.scons script added scons Psuedo-Builders 'PrepareLib', 'Download', 'UnpackAll', 'Configure', 'InstallHeadFile' and 'InstalLib' to the scons environment The builder scripts are responsible for downloading, unpacking, and installing different items throughout the build process. Additionally the external_libs.scons was also responsible for building and setting up compilar flags and building external libraries. The external_libs.scons used to be called before and after the android build. Once to setup the Psuedo-Builders and again to set the compiler flags for the external libraries. Due to some cleanup for a recent change. The script can no longer be called multiple times without a scons error. see: https://gerrit.iotivity.org/gerrit/#/c/18381 Now the Psuedo-Builders are added to the scons environment by calling external_builders.scons. The external_libs.scons is used to build the external libraries. This allows adding the builders that are required for the android build. While still setting up the build environment for the external libraries. Due to the UnpackAll builder using the system path on windows the external_builders.scons script must be called twice. Additional Whitespace cleanup changed tabs into spaces to follow convention of other scons scripts. Change-Id: I070224425bfd2d4279cd6c9b0c329e393250770a Signed-off-by: George Nash Reviewed-on: https://gerrit.iotivity.org/gerrit/18739 Tested-by: jenkins-iotivity Reviewed-by: Uze Choi Tested-by: Uze Choi --- build_common/SConscript | 7 ++ build_common/external_builders.scons | 106 ++++++++++++++++++++++++++ build_common/external_libs.scons | 141 ++++++----------------------------- 3 files changed, 134 insertions(+), 120 deletions(-) create mode 100644 build_common/external_builders.scons diff --git a/build_common/SConscript b/build_common/SConscript index 4e0a3fc..ed60ae4 100755 --- a/build_common/SConscript +++ b/build_common/SConscript @@ -526,6 +526,9 @@ if 'SERVER' in rd_mode: if with_ra_ibb: env.AppendUnique(CPPDEFINES = ['RA_ADAPTER_IBB']) + +env.SConscript('external_builders.scons') + ###################################################################### # Link scons to Yocto cross-toolchain ONLY when target_os is yocto ###################################################################### @@ -622,5 +625,9 @@ conf.CheckPThreadsSupport() env = conf.Finish() ###################################################################### +# must call external_builders.scons second time to properly setup +# UnpackAll builder this is due to the system path not being pulled +# in for windows till after the windows target has run. +env.SConscript('external_builders.scons') env.SConscript('external_libs.scons') Return('env') diff --git a/build_common/external_builders.scons b/build_common/external_builders.scons new file mode 100644 index 0000000..ea041ec --- /dev/null +++ b/build_common/external_builders.scons @@ -0,0 +1,106 @@ +## +# Add external Pseudo-Builders +# +# Some methods are added to manage external packages: +# 'PrepareLib': Checks the existence of an external library, if it +# doesn't exist, calls the script user provided to download(if required) +# and build the source code of the external library or notify user to +# install the library. +# 'Download': Download package from specify URL +# 'UnpackAll': Unpack the package +# 'Configure': Execute specify script(configure, bootstrap etc) +# 'InstallHeadFile': Install head files +# 'InstallLib': Install library binaries(.so, .a etc) +# +# for more on Pseudo-Builders see scons offical documentation +# 'Pseudo-Builders: the AddMethod function' +## +import os, subprocess +import urllib2, urlparse +import SCons.Errors + +Import('env') + +# Check whether a library exists, if not, notify user to install it or try to +# download the source code and build it +# @param libname - the name of the library try to prepare +# @param lib - the lib(.so, .a etc) to check (a library may include more then +# one lib, e.g. boost, includes boost_thread, boost_system ... +# @param path - the directory of the library building script, if it's not set, +# by default, it's /extlibs// +# @param script - the building script, by default, it's 'SConscript' +# +def __prepare_lib(ienv, libname, lib = None, path = None, script = None): + p_env = ienv.Clone(LIBS = []) + if p_env.GetOption('clean') or p_env.GetOption('help'): + return + + conf = Configure(p_env) + + if not lib: + lib = libname + if not conf.CheckLib(lib): + if path: + dir = path + else: + dir = os.path.join(env.get('SRC_DIR'), 'extlibs', libname) + + # Execute the script to download(if required) and build source code + if script: + st = os.path.join(dir, script) + else: + st = os.path.join(dir, 'SConscript') + + if os.path.exists(st): + SConscript(st) + else: + if target_os in ['linux', 'darwin', 'tizen']: + print 'Don\'t find library(%s), please intall it, exit ...' % libname + else: + print 'Don\'t find library(%s) and don\'t find the process script (%s), exit ...' % (libname, st) + Exit(1) + + conf.Finish() + +# Run configure command (usually it's done before build a library) +def __configure(env, cwd, cmd) : + print "Configuring using [%s/%s] ..." % (cwd, cmd) + # build it now (we need the shell, because some programs need it) + devnull = open(os.devnull, "wb") + handle = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=devnull) + + if handle.wait() <> 0 : + raise SCons.Errors.BuildError( "Run configuring script [%s]" % (cmd) ) + +# Download from URL 'url', will save as 'target' +def __download(ienv, target, url) : + if os.path.exists(target) : + return target + + try : + print "Download %s from %s" % (target, url) + print "Downloading ..." + stream = urllib2.urlopen(url) + file = open(target, 'wb') + file.write(stream.read()) + file.close() + print "Download %s from %s complete" % (target, url) + return target + except Exception, e : + raise SCons.Errors.StopError( '%s [%s]' % (e, url) ) + +# Install header file(s) to /deps//include +def __install_head_file(ienv, file): + return ienv.Install(os.path.join(env.get('SRC_DIR'), 'dep', target_os, target_arch, 'usr', 'include'), file) + +# Install library binaries to /deps//lib/ +def __install_lib(ienv, lib): + return ienv.Install(os.path.join(env.get('SRC_DIR'), 'dep', target_os, target_arch, 'usr', 'lib'), lib) + +SConscript('tools/UnpackAll.py') + +env.AddMethod(__prepare_lib, "PrepareLib") +env.AddMethod(__configure, "Configure") +env.AddMethod(__download, "Download") +env.AddMethod(__install_head_file, "InstallHeadFile") +env.AddMethod(__install_lib, "InstallLib") diff --git a/build_common/external_libs.scons b/build_common/external_libs.scons index c43a29e..0fa9ad8 100644 --- a/build_common/external_libs.scons +++ b/build_common/external_libs.scons @@ -1,28 +1,15 @@ ## # This script manages external libraries # -# Some methods are added to manage external packages: -# 'PrepareLib': Checks the existence of an external library, if it -# doesn't exist, calls the script user provided to download(if required) -# and build the source code of the external library or notify user to -# install the library. -# 'Download': Download package from specify URL -# 'UnpackAll': Unpack the package -# 'Configure': Execute specify script(configure, bootstrap etc) -# 'InstallHeadFile': Install head files -# 'InstallLib': Install library binaries(.so, .a etc) -# # By default, assume the script for an exteranl library is: -# /extlibs//SConscript +# /extlibs//SConscript # # Note: After the external library is built: # Head files should be installed to /deps//include # lib(e.g .so, .a) should be installed to /deps//lib/ # ## -import os, subprocess -import urllib2, urlparse -import SCons.Errors +import os Import('env') @@ -32,108 +19,29 @@ rd_mode = env.get('RD_MODE') # for android, doesn't distinguish 'armeabi-v7a-hard' and 'armeabi-v7a' library if target_os == 'android': - if target_arch == 'armeabi-v7a-hard': - target_arch = 'armeabi-v7a' - env.AppendUnique(CCFLAGS = ['-D__JAVA__']) + if target_arch == 'armeabi-v7a-hard': + target_arch = 'armeabi-v7a' + env.AppendUnique(CCFLAGS = ['-D__JAVA__']) if target_os == 'darwin': - env.AppendUnique(CPPPATH = ['/usr/local/include']) - env.AppendUnique(LIBPATH = ['/usr/local/lib']) + env.AppendUnique(CPPPATH = ['/usr/local/include']) + env.AppendUnique(LIBPATH = ['/usr/local/lib']) if env.get('BUILD_JAVA') == True and target_os != 'android': - if env.get('JAVA_HOME') != None: - env.AppendUnique(CCFLAGS = ['-D__JAVA__']) - env.AppendUnique(CPPPATH = [ - env.get('JAVA_HOME') + '/include', - env.get('JAVA_HOME') + '/include/' + target_os - ]) - else: - raise SCons.Errors.StopError( 'BUILD_JAVA is specified, but JAVA_HOME is not set.') - + if env.get('JAVA_HOME') != None: + env.AppendUnique(CCFLAGS = ['-D__JAVA__']) + env.AppendUnique(CPPPATH = [ + env.get('JAVA_HOME') + '/include', + env.get('JAVA_HOME') + '/include/' + target_os + ]) + else: + raise SCons.Errors.StopError( 'BUILD_JAVA is specified, but JAVA_HOME is not set.') # External library include files are in /deps//include # the library binaries are in /deps//lib/ if target_os not in ['windows']: - env.AppendUnique(CPPPATH = [os.path.join(env.get('SRC_DIR'), 'deps', target_os, 'include')]) - env.AppendUnique(LIBPATH = [os.path.join(env.get('SRC_DIR'), 'deps', target_os, 'lib', target_arch)]) - -# Check whether a library exists, if not, notify user to install it or try to -# download the source code and build it -# @param libname - the name of the library try to prepare -# @param lib - the lib(.so, .a etc) to check (a library may include more then -# one lib, e.g. boost, includes boost_thread, boost_system ... -# @param path - the directory of the library building script, if it's not set, -# by default, it's /extlibs// -# @param script - the building script, by default, it's 'SConscript' -# -def __prepare_lib(ienv, libname, lib = None, path = None, script = None): - p_env = ienv.Clone(LIBS = []) - if p_env.GetOption('clean') or p_env.GetOption('help'): - return - - conf = Configure(p_env) - - if not lib: - lib = libname - if not conf.CheckLib(lib): - if path: - dir = path - else: - dir = os.path.join(env.get('SRC_DIR'), 'extlibs', libname) - - # Execute the script to download(if required) and build source code - if script: - st = os.path.join(dir, script) - else: - st = os.path.join(dir, 'SConscript') - - if os.path.exists(st): - SConscript(st) - else: - if target_os in ['linux', 'darwin', 'tizen']: - print 'Don\'t find library(%s), please intall it, exit ...' % libname - else: - print 'Don\'t find library(%s) and don\'t find the process script (%s), exit ...' % (libname, st) - Exit(1) - - conf.Finish() - -# Run configure command (usually it's done before build a library) -def __configure(env, cwd, cmd) : - print "Configuring using [%s/%s] ..." % (cwd, cmd) - # build it now (we need the shell, because some programs need it) - devnull = open(os.devnull, "wb") - handle = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=devnull) - - if handle.wait() <> 0 : - raise SCons.Errors.BuildError( "Run configuring script [%s]" % (cmd) ) - -# Download from URL 'url', will save as 'target' -def __download(ienv, target, url) : - if os.path.exists(target) : - return target - - try : - print "Download %s from %s" % (target, url) - print "Downloading ..." - stream = urllib2.urlopen(url) - file = open(target, 'wb') - file.write(stream.read()) - file.close() - print "Download %s from %s complete" % (target, url) - return target - except Exception, e : - raise SCons.Errors.StopError( '%s [%s]' % (e, url) ) - -# Install header file(s) to /deps//include -def __install_head_file(ienv, file): - return ienv.Install(os.path.join(env.get('SRC_DIR'), 'dep', target_os, target_arch, 'usr', 'include'), file) - -# Install library binaries to /deps//lib/ -def __install_lib(ienv, lib): - return ienv.Install(os.path.join(env.get('SRC_DIR'), 'dep', target_os, target_arch, 'usr', 'lib'), lib) - -SConscript('tools/UnpackAll.py') + env.AppendUnique(CPPPATH = [os.path.join(env.get('SRC_DIR'), 'deps', target_os, 'include')]) + env.AppendUnique(LIBPATH = [os.path.join(env.get('SRC_DIR'), 'deps', target_os, 'lib', target_arch)]) # tinycbor build/fetch SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'tinycbor', 'SConscript')) @@ -143,19 +51,12 @@ SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'cjson', 'SConscript')) with_ra = env.get('WITH_RA') if with_ra: - SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'raxmpp', 'SConscript')) + SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'raxmpp', 'SConscript')) with_ra_ibb = env.get('WITH_RA_IBB') if with_ra_ibb: - SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'wksxmppxep', 'SConscript')) - - -env.AddMethod(__prepare_lib, "PrepareLib") -env.AddMethod(__configure, "Configure") -env.AddMethod(__download, "Download") -env.AddMethod(__install_head_file, "InstallHeadFile") -env.AddMethod(__install_lib, "InstallLib") + SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'wksxmppxep', 'SConscript')) if env.get('SECURED') == '1' or 'SERVER' in rd_mode: - if target_os not in ['linux', 'tizen']: - SConscript('#extlibs/sqlite3/SConscript') + if target_os not in ['linux', 'tizen']: + SConscript('#extlibs/sqlite3/SConscript') -- 2.7.4