X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=abs;h=487f57f9290b3bc9987cb464dfe121c2d35e6072;hb=5d05e7c56bae3be51b5e0a371d509883ecabd569;hp=d2b5312f2c9c4282c15d620d1587988a05e6ffd5;hpb=42eb48064b15cc43d79d9c417d781d7683c8551e;p=scm%2Fmeta%2Fabs.git diff --git a/abs b/abs index d2b5312..487f57f 100755 --- a/abs +++ b/abs @@ -27,7 +27,6 @@ import zipfile import errno g_home = os.path.dirname(os.path.realpath(__file__)) - class LocalError(Exception): """Local error exception.""" @@ -109,7 +108,7 @@ class ErrorParser(object): '.*make.*: \*\*\* .*', \ '.*make.*: Target (.*) not remade because of errors.', \ '.*[Cc]ommand not found.*', \ - 'Error:\s*(.*)'], \ + '^Error:\s*(.*)'], \ 'TIZEN_NATIVE':['.*ninja: build stopped.*', \ 'edje_cc: Error..(.*):(\d).*', \ 'edje_cc: Error.*']} @@ -139,25 +138,32 @@ class _Rootstrap(object): rootstrap_list = None sdk_path = None - def __init__(self, sdk_path=None, config=None): + def __init__(self, sdk_path=None, config=None, rootstrap_search=None): self.tizen = sdk_path - self.list_rootstrap() + self.list_rootstrap(rootstrap_search) self.config_file = config - def list_rootstrap(self): + def list_rootstrap(self, rootstrap_search=None): """List all the rootstraps""" + rs_prefix = 'mobile|wearable|tizeniot' + if rootstrap_search is not None: + rs_prefix = rootstrap_search + print 'Set rs_prefix: %s' % rs_prefix + if self.rootstrap_list != None: return self.rootstrap_list cmdline = self.tizen + ' list rootstrap' ret = Executor().run(cmdline, show=False) for x in ret.splitlines(): - if re.search('(mobile|wearable)-(2.4|3.0|4.0)-(device|emulator|device64|emulator64).core.*', x): + if re.search('(%s)-([0-9.]*)-(device.*|emulator.*).core.*' % rs_prefix, x): if self.rootstrap_list == None: self.rootstrap_list = [] self.rootstrap_list.append(x.split(' ')[0]) + else: + print 'No search result for %s' % '(%s)-([0-9.]*)-(device.*|emulator.*).core.*' % rs_prefix return self.rootstrap_list def check_rootstrap(self, rootstrap, show=True): @@ -185,13 +191,13 @@ class Sdk(object): 'tizen-sdk-ux/tools/ide/bin/tizen', \ 'tizen-sdk-cli/tools/ide/bin/tizen'] - def __init__(self, sdkpath=None): + def __init__(self, sdkpath=None, rootstrap_search=None, no_dbus=False): self.error_parser = ErrorParser() self.runtool = Executor(checker=self.error_parser) self.home = os.getenv('HOME') - self.config_file = os.path.join(g_home, '.abs') + self.config_file = os.path.join(g_home, '.absconfig') if sdkpath is None: self.tizen = self.get_user_root() @@ -208,7 +214,11 @@ class Sdk(object): print 'Cannot locate cli tool' raise LocalError('Fail to locate cli tool') - self.rs = _Rootstrap(sdk_path=self.tizen, config=self.config_file) + self.rs = _Rootstrap(sdk_path=self.tizen, config=self.config_file, rootstrap_search=rootstrap_search) + if no_dbus != False: + self.no_dbus = True + else: + self.no_dbus = False def get_user_root(self): @@ -242,8 +252,14 @@ class Sdk(object): """Run a tizen command""" cmd = [self.tizen, command] + args + if command == 'package': + dbus_command = 'dbus-run-session -- bash; echo build | gnome-keyring-daemon --unlock; ' + if self.no_dbus == True: + dbus_command = ' ' + cmd = ['{} '.format(dbus_command)] + cmd print '\nRunning command:\n %s' % ' '.join(cmd) - return self.runtool.run(' '.join(cmd), show=show, checker=checker) + return self.runtool.run('{}'.format(' '.join(cmd)), \ + show=show, checker=checker) def copytree2(self, src, dst, symlinks=False, ignore=None): """Copy with Ignore & Overwrite""" @@ -338,7 +354,7 @@ class Sdk(object): myZipFile.close() return rsrc_zip - def build_native(self, source, rootstrap=None, arch=None, conf='Debug', jobs=None): + def build_tizen(self, source, rootstrap=None, arch=None, conf='Debug', jobs=None): """SDK CLI build command""" _rootstrap = self.check_rootstrap(rootstrap) @@ -363,10 +379,18 @@ class Sdk(object): elif arch == 'arm': rootstrap = rootstrap.replace('emulator', 'device') for x in source.project_list: - b_args = ['-r', rootstrap, '-a', self.arch, '-C', conf, '-c', 'gcc'] - if jobs is not None: b_args.extend(['-j', jobs]) - b_args.extend(['--', x['path']]) - out = self._run('build-native', b_args, checker=True) + b_args = [] + if x['web_app'] == True: + print '\n\n BUILD WEB\n' + b_args.extend(['--', x['path']]) + out = self._run('build-web ', b_args, checker=True) + else: + print '\n\n BUILD NATIVE\n' + if jobs is not None: + b_args.extend(['-j', jobs]) + b_args.extend(['-r', rootstrap, '-a', self.arch, '-C', conf]) + b_args.extend(['--', x['path']]) + out = self._run('build-native', b_args, checker=True) logpath = os.path.join(source.output_dir, \ 'build_%s_%s' % (rootstrap, os.path.basename(x['path']))) if not os.path.isdir(source.output_dir): @@ -374,72 +398,38 @@ class Sdk(object): with open(logpath, 'w') as lf: lf.write(out) ret = self.error_parser.check(out) - if ret: + if True: with open(logpath+'.log', 'w') as lf: lf.write(out) + if ret: raise LocalError(ret) - def package(self, source, cert=None, pkg_type=None, conf=None): - """SDK CLI package command""" - - if cert is None: cert = 'ABS' - if pkg_type is None: pkg_type = 'tpk' - if conf is None: conf = 'Debug' - - final_app = '' - main_args = ['-t', pkg_type, '-s', cert] - out = '' #logfile - - if conf == 'Release' : - main_args.extend(['--strip', 'on']) - - for i, x in enumerate(source.project_list): - if x['type'] == 'app': - out = '%s\n%s' % (out, \ - self._run('package', main_args + ['--',os.path.join(x['path'],conf)])) - try: - final_app = list_files(os.path.join(x['path'], conf), ext='tpk')[0] - except: - raise LocalError('TPK file not generated for %s.' % x['APPNAME']) - x['out_package'] = final_app - elif x['type'] == 'sharedLib': - self._package_sharedlib(x['path'], conf, x['APPNAME']) - x['out_package'] = list_files(os.path.join(x['path'], conf), ext='zip')[0] - else: - raise LocalError('Not supported project type %s' % x['type']) - - if source.b_multi == True: - extra_args=[] - print 'THIS IS MULTI PROJECT' - for i, x in enumerate(source.project_list): - if x['out_package'] != final_app and x['type'] == 'app': - extra_args.extend(['-r', x['out_package']]) - elif x['type'] == 'sharedLib': - extra_args.extend(['-r', x['out_package']]) - - extra_args.extend(['--', final_app]) - out = self._run('package', main_args + extra_args) - - #TODO: signature validation check failed : Invalid file reference. An unsigned file was found. - print 'Packaging final step again!' - out = self._run('package', main_args + ['--', final_app]) - - #Copy tpk to output directory - shutil.copy(final_app, source.output_dir) - - def package_new(self, source, cert=None, pkg_type=None, conf=None, manual_strip=False): + def raise_package_exception(self, out, output_dir, i, bname, appname): + logpath = os.path.join(output_dir, \ + 'package_%d_%s' % (i, bname)) + if not os.path.isdir(output_dir): + os.makedirs(output_dir) + with open(logpath + '.log', 'w') as lf: + lf.write(out) + if 'keystore password was incorrect' in out \ + or 'Sequence tag error' in out \ + or 'Signing... java.io.IOException: ' in out: + raise LocalError('signing error for %s.' % appname) + raise LocalError('TPK/WGT file not generated for %s.' % appname) + + def package(self, source, cert=None, pkg_type=None, conf='Debug', manual_strip=False): """SDK CLI package command IF Debug + Manual Strip off then generate package-name-debug.tpk IF Debug + Manual Strip on then generate package-name.tpk with custom strip IF Release then generate package-name.tpk with strip option """ - if cert is None: cert = 'ABS' if pkg_type is None: pkg_type = 'tpk' if conf is None: conf = 'Debug' final_app = '' main_args = ['-t', pkg_type, '-s', cert] + main_args_web = ['-t', 'wgt', '-s', cert] out = '' #logfile # remove tpk or zip file on project path @@ -447,6 +437,7 @@ class Sdk(object): for i, x in enumerate(source.project_list): package_list.extend(list_files(os.path.join(x['path'], conf), ext='tpk')) package_list.extend(list_files(os.path.join(x['path'], conf), ext='zip')) + package_list.extend(list_files(x['path'], ext='wgt')) for k in package_list : print ' package list ' + k; @@ -454,70 +445,119 @@ class Sdk(object): # Manual strip if manual_strip == True : + main_args.extend(['--strip', 'on']) strip_cmd=''; if self.arch == None: - raise LocalError('Architecture is Noen') - elif self.arch == 'x86' : - strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../i386-linux-gnueabi-gcc-4.9/bin/i386-linux-gnueabi-strip') - elif self.arch == 'arm' : - strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../arm-linux-gnueabi-gcc-4.9/bin/arm-linux-gnueabi-strip') - elif self.arch == 'x86_64' : - strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../x86_64-linux-gnu-gcc-4.9/bin/x86_64-linux-gnu-strip') - elif self.arch == 'aarch64' : - strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../aarch64-linux-gnu-gcc-4.9/bin/aarch64-linux-gnu-strip') - - print strip_cmd + raise LocalError('Architecture is None') for i, x in enumerate(source.project_list): dir = os.path.join(x['path'], conf) + if not os.path.isdir(dir): + continue files = [os.path.join(dir,f) for f in os.listdir(dir) if os.path.isfile(os.path.join(dir,f))] + + # dir must be "project/Debug directory" + info_path = os.path.join(dir, "build.info") + # Default Strip gcc version is 6.2 + gcc_version = "6.2" + # Parsing GCC version from build.info inside Debug directory in Project to each project + if os.path.exists(info_path) : + with open(info_path) as fp : + for line in fp : + if line.startswith("toolchain=") : + line = line.strip() + gcc_version = re.findall("\d+\.\d+", line)[0] + else : + print "Cannot find Debug/build.info. The default gcc will strip tpk" + + print "gcc version:" + gcc_version + + if self.arch == 'x86' : + if(gcc_version == "4.9"): + strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../i386-linux-gnueabi-gcc-' + gcc_version + '/bin/i386-linux-gnueabi-strip') + else: + strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../i586-linux-gnueabi-gcc-' + gcc_version + '/bin/i586-linux-gnueabi-strip') + elif self.arch == 'arm' : + strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../arm-linux-gnueabi-gcc-' + gcc_version + '/bin/arm-linux-gnueabi-strip') + elif self.arch == 'x86_64' : + strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../x86_64-linux-gnu-gcc-' + gcc_version + '/bin/x86_64-linux-gnu-strip') + elif self.arch == 'aarch64' : + strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../aarch64-linux-gnu-gcc-' + gcc_version + '/bin/aarch64-linux-gnu-strip') + + print strip_cmd + for k in files: cmdline = strip_cmd + ' ' + k; - #print 'my command line ' + cmdline; Executor().run(cmdline, show=False) + elif conf == 'Release': main_args.extend(['--strip', 'on']) for i, x in enumerate(source.project_list): - if x['type'] == 'app': + if x['web_app'] == False: + if x['type'] == 'app': + print '\n\n PACKAGE NATIVE\n' + out = '%s\n%s' % (out, \ + self._run('package', main_args + ['--',os.path.join(x['path'],conf)])) + try: + final_app = list_files(os.path.join(x['path'], conf), ext='tpk')[0] + except: + self.raise_package_exception(out, source.output_dir, i, os.path.basename(x['path']), x['APPNAME']) + x['out_package'] = final_app + elif x['type'] == 'sharedLib': + self._package_sharedlib(x['path'], conf, x['APPNAME']) + x['out_package'] = list_files(os.path.join(x['path'], conf), ext='zip')[0] + else: + raise LocalError('Not supported project type %s' % x['type']) + elif x['web_app'] == True: + print '\n\n PACKAGE WEB\n' out = '%s\n%s' % (out, \ - self._run('package', main_args + ['--',os.path.join(x['path'],conf)])) + self._run('package', main_args_web + ['--', os.path.join(x['path'], '.buildResult')])) try: - final_app = list_files(os.path.join(x['path'], conf), ext='tpk')[0] + final_app = list_files(os.path.join(x['path'], '.buildResult'), ext='wgt')[0] except: - raise LocalError('TPK file not generated for %s.' % x['APPNAME']) + self.raise_package_exception(out, source.output_dir, i, os.path.basename(x['path']), x['APPNAME']) x['out_package'] = final_app - elif x['type'] == 'sharedLib': - self._package_sharedlib(x['path'], conf, x['APPNAME']) - x['out_package'] = list_files(os.path.join(x['path'], conf), ext='zip')[0] - else: - raise LocalError('Not supported project type %s' % x['type']) if source.b_multi == True: extra_args=[] print 'THIS IS MULTI PROJECT' for i, x in enumerate(source.project_list): - if x['out_package'] != final_app and x['type'] == 'app': - extra_args.extend(['-r', x['out_package']]) - elif x['type'] == 'sharedLib': - extra_args.extend(['-r', x['out_package']]) + if x['out_package'] != final_app and x.get('type') == 'app': + extra_args.extend(['-r', '"%s"' % x['out_package']]) + elif x.get('type') == 'sharedLib': + extra_args.extend(['-r', '"%s"' % x['out_package']]) - extra_args.extend(['--', final_app]) - out = self._run('package', main_args + extra_args) + extra_args.extend(['--', '"%s"' % final_app]) + if final_app.endswith('.tpk'): + out = '%s\n\n%s' % (out, self._run('package', main_args + extra_args)) + elif final_app.endswith('.wgt'): + out = '%s\n\n%s' % (out, self._run('package', main_args_web + extra_args)) #TODO: signature validation check failed : Invalid file reference. An unsigned file was found. - print 'Packaging final step again!' - out = self._run('package', main_args + ['--', final_app]) + if final_app.endswith('.tpk'): + print 'Packaging final step again!' + out = '%s\n\n%s' % (out, self._run('package', main_args + ['--', '"%s"' % final_app])) + + #Append arch to web binary + #if final_app.endswith('.wgt'): + # final_app_with_arch = final_app.replace('.wgt', '-%s.wgt' % self.arch) + # os.rename(final_app, final_app_with_arch) + # final_app = final_app_with_arch #Copy tpk to output directory if conf == 'Debug' and manual_strip == False : basename = os.path.splitext(final_app)[0] - newname = basename +'-debug.tpk' + if final_app.endswith('.tpk'): + newname = basename +'-debug.tpk' + elif final_app.endswith('.wgt'): + newname = basename +'-debug.wgt' os.rename(final_app, newname) shutil.copy(newname, source.output_dir) else : shutil.copy(final_app, source.output_dir) + def clean(self, source): """SDK CLI clean command""" @@ -560,18 +600,40 @@ class Source(object): mydict = {} cp = ConfigParser.SafeConfigParser() cp.optionxform = str - cp.readfp(FakeSecHead(open(os.path.join(path, 'project_def.prop')))) - for x in cp.items('ascection'): - mydict[x[0]] = x[1] + if self.is_web_app(path): + mydict['web_app'] = True + else: + mydict['web_app'] = False + cp.readfp(FakeSecHead(open(os.path.join(path, 'project_def.prop')))) + for x in cp.items('ascection'): + mydict[x[0]] = x[1] mydict['path'] = path return mydict + def set_user_options(self, c_opts=None, cpp_opts=None, link_opts=None): + if c_opts is not None: + os.environ['USER_C_OPTS'] = c_opts + print 'Set USER_C_OPTS=[%s]' % os.getenv('USER_C_OPTS') + if cpp_opts is not None: + os.environ['USER_CPP_OPTS'] = cpp_opts + print 'Set USER_CPP_OPTS=[%s]' % os.getenv('USER_CPP_OPTS') + if link_opts is not None: + os.environ['USER_LINK_OPTS'] = link_opts + print 'Set USER_LINK_OPTS=[%s]' % os.getenv('USER_LINK_OPTS') + + def is_web_app(self, project_directory): + if os.path.isfile(os.path.join(project_directory, 'config.xml')): + return True + return False + def pre_process(self): if os.path.isfile(os.path.join(self.workspace, self.multi_conf_file)): self.b_multi = True with open(os.path.join(self.workspace, self.multi_conf_file)) as f: for line in f: + if not line.strip(): + continue file_path = os.path.join(self.workspace, line.rstrip()) self.project_list.append(self.set_properties(file_path)) else: @@ -605,27 +667,50 @@ def argument_parsing(argv): build.add_argument('--sdkpath', action='store', dest='sdkpath', \ help='Specify Tizen SDK installation root (one time init).' \ ' ex) /home/yours/tizen-sdk/') + build.add_argument('--profile-to-search', action='store', dest='profiletosearch', \ + help='Rootstrap profile prefix.' \ + ' ex) (mobile|wearable|da-hfp)') + build.add_argument('--c-opts', action='store', dest='c_opts', \ + help='Extra compile options USER_C_OPTS') + build.add_argument('--cpp-opts', action='store', dest='cpp_opts', \ + help='Extra compile options USER_CPP_OPTS') + build.add_argument('--link-opts', action='store', dest='link_opts', \ + help='Extra linking options USER_LINK_OPTS') + build.add_argument('--no-dbus', action='store', dest='no_dbus', default=False, \ + help='Do not run dbus session before packaging') return parser.parse_args(argv[1:]) def build_main(args): """Command [build] entry point.""" - my_source = Source(src=args.workspace) - my_sdk = Sdk(sdkpath=args.sdkpath) - my_sdk.clean(my_source) - my_sdk.build_native(my_source, rootstrap=args.rootstrap, arch=args.arch, conf=args.conf, jobs=args.jobs) - if args.conf == 'Debug' : - my_sdk.package_new(my_source, pkg_type=args.type, cert=args.cert, conf=args.conf) - my_sdk.package_new(my_source, pkg_type=args.type, cert=args.cert, conf=args.conf, manual_strip=True) - else : - my_sdk.package_new(my_source, pkg_type=args.type, cert=args.cert, conf=args.conf) + try: + my_source = Source(src=args.workspace) + + my_source.set_user_options(c_opts=args.c_opts, cpp_opts=args.cpp_opts, link_opts=args.link_opts) + print '-------------------' + print '(%s)' % args.profiletosearch + print '-------------------' + my_sdk = Sdk(sdkpath=args.sdkpath, rootstrap_search=args.profiletosearch, no_dbus=args.no_dbus) + my_sdk.clean(my_source) + my_sdk.build_tizen(my_source, rootstrap=args.rootstrap, arch=args.arch, jobs=args.jobs) + if args.conf == 'Debug' : + my_sdk.package(my_source, pkg_type=args.type, cert=args.cert) + my_sdk.package(my_source, pkg_type=args.type, cert=args.cert, manual_strip=True) + else : + my_sdk.package(my_source, pkg_type=args.type, cert=args.cert, manual_strip=True) + + except Exception as err: + wrk = os.path.join(os.path.abspath(args.workspace), '_abs_out_') + if not os.path.isdir(wrk): + os.makedirs(wrk) + with open(os.path.join(wrk, 'build_EXCEPTION.log'), 'w') as ef: + ef.write('Exception %s' % str(err)) + raise err def main(argv): """Script entry point.""" - print 'ABS SCRIPT FROM GIT' - args = argument_parsing(argv) if args.subcommands == 'build': @@ -640,4 +725,11 @@ if __name__ == '__main__': sys.exit(main(sys.argv)) except Exception, e: print 'Exception %s' % str(e) - sys.exit(1) + #FIXME: Remove hard-coded output directory. + if not os.path.isdir('_abs_out_'): + os.makedirs('_abs_out_') + with open(os.path.join('_abs_out_', 'build_EXCEPTION.log'), 'w') as ef: + ef.write('Exception %s' % repr(e)) + if 'keystore password was incorrect' in repr(e): + sys.exit(99) + sys.exit(77)