Change rootstrap search option
[scm/meta/abs.git] / abs
1 #!/usr/bin/env python
2 # vim: ai ts=4 sts=4 et sw=4
3 #
4 # Copyright (c) 2014, 2015, 2016 Samsung Electronics.Co.Ltd.
5 #
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the Free
8 # Software Foundation; version 2 of the License
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 # for more details.
14 #
15
16 import sys
17 import os
18 import subprocess
19 import re
20 import argparse
21 from argparse import ArgumentParser
22 import ConfigParser
23 import glob
24 import fnmatch
25 import shutil
26 import zipfile
27 import errno
28
29 g_home = os.path.dirname(os.path.realpath(__file__))
30
31 class LocalError(Exception):
32     """Local error exception."""
33
34     pass
35
36 class Executor(object):
37     """Subprocess wrapper"""
38
39     def __init__(self, checker=None):
40         self.stdout = subprocess.PIPE
41         self.stderr = subprocess.STDOUT
42         self.checker = checker
43
44     def run(self, cmdline_or_args, show=False, checker=False):
45         """Execute external command"""
46
47         out = ''
48         try:
49             process = subprocess.Popen(cmdline_or_args, \
50                                        stdout=self.stdout, \
51                                        stderr=self.stderr, \
52                                        shell=True)
53             while True:
54                 line = process.stdout.readline()
55                 if show:
56                     print line.rstrip()
57                 out = out + '\n' + line.rstrip()
58                 if not line:
59                     break
60         except:
61             raise LocalError('Running process failed')
62
63         return out
64
65 def list_files(path, ext=None):
66
67     f_list = []
68     for root, dirnames, filenames in os.walk(path):
69         if ext is None:
70             for filename in filenames:
71                 f_list.append(os.path.join(root, filename))
72         else:
73             for filename in fnmatch.filter(filenames, '*.'+ext):
74                 f_list.append(os.path.join(root, filename))
75     return f_list
76
77 class FakeSecHead(object):
78
79     def __init__(self, fp):
80
81         self.fp = fp
82         self.sechead = '[ascection]\n'
83
84     def readline(self):
85
86         if self.sechead:
87             try:
88                 return self.sechead
89             finally:
90                 self.sechead = None
91         else:
92             return self.fp.readline()
93
94 class ErrorParser(object):
95     """Inspect specific error string"""
96
97     parsers = []
98
99     def __init__(self):
100
101         ErrorParser = {'GNU_LINKER':['(.*?):?\(\.\w+\+.*\): (.*)', \
102                                      '(.*[/\\\])?ld(\.exe)?: (.*)'], \
103                        'GNU_GCC':['(.*?):(\d+):(\d+:)? [Ee]rror: ([`\'"](.*)[\'"] undeclared .*)', \
104                                   '(.*?):(\d+):(\d+:)? [Ee]rror: (conflicting types for .*[`\'"](.*)[\'"].*)', \
105                                   '(.*?):(\d+):(\d+:)? (parse error before.*[`\'"](.*)[\'"].*)', \
106                                   '(.*?):(\d+):(\d+:)?\s*(([Ee]rror)|(ERROR)): (.*)'], \
107 #                                  '(.*?):(\d+):(\d+:)? (.*)'], \
108                        'GNU_GMAKE':['(.*):(\d*): (\*\*\* .*)', \
109                                     '.*make.*: \*\*\* .*', \
110                                     '.*make.*: Target (.*) not remade because of errors.', \
111                                     '.*[Cc]ommand not found.*', \
112                                     'Error:\s*(.*)'], \
113                        'TIZEN_NATIVE':['.*ninja: build stopped.*', \
114                                        'edje_cc: Error..(.*):(\d).*', \
115                                        'edje_cc: Error.*']}
116
117         for parser in ErrorParser:
118             parser_env = os.getenv('SDK_ERROR_'+parser)
119             if parser_env:
120                 self.parsers.append(parser_env)
121             else:
122                 for msg in ErrorParser[parser]:
123                     self.parsers.append(msg)
124
125     def check(self, full_log):
126         """Check error string line by line"""
127
128         #snipset_text = full_log[:full_log.rfind('PLATFORM_VER\t')].split('\n')
129         for line in full_log.split('\n'):
130             errline = re.search('|'.join(self.parsers), line[:1024])
131             if errline:
132                 return errline.string #Errors
133         return None #No error
134
135 class _Rootstrap(object):
136     """Tizen SDK rootstrap info.
137        Used only in Sdk class"""
138
139     rootstrap_list = None
140     sdk_path = None
141
142     def __init__(self, sdk_path=None, config=None, rootstrap_search=None):
143
144         self.tizen = sdk_path
145         self.list_rootstrap(rootstrap_search)
146         self.config_file = config
147
148     def list_rootstrap(self, rootstrap_search=None):
149         """List all the rootstraps"""
150
151         rs_prefix = 'mobile|wearable'
152         if rootstrap_search is not None:
153             rs_prefix = rootstrap_search
154         print 'Set rs_prefix: %s' % rs_prefix
155
156         if self.rootstrap_list != None:
157             return self.rootstrap_list
158
159         cmdline = self.tizen + ' list rootstrap'
160         ret = Executor().run(cmdline, show=False)
161         for x in ret.splitlines():
162             if re.search('(%s)-(2.4|3.0|4.0|5.0)-(device|emulator|device64|emulator64).core.*' % rs_prefix, x):
163                 if self.rootstrap_list == None:
164                     self.rootstrap_list = []
165                 self.rootstrap_list.append(x.split(' ')[0])
166             else:
167                 print 'No search result for %s' % '(%s)-(2.4|3.0|4.0|5.0)-(device|emulator|device64|emulator64).core.*' % rs_prefix
168         return self.rootstrap_list
169
170     def check_rootstrap(self, rootstrap, show=True):
171         """Specific rootstrap is in the SDK
172            Otherwise use default"""
173
174         if rootstrap == None:
175             rootstrap = 'mobile-3.0-emulator.core' #default
176         if rootstrap in self.rootstrap_list:
177             return rootstrap
178         else:
179             if show == True:
180                 print '  ERROR: Rootstrap [%s] does not exist' % rootstrap
181                 print '  Update your rootstrap or use one of:\n    %s' \
182                        % '\n    '.join(self.list_rootstrap())
183             return None
184
185 class Sdk(object):
186     """Tizen SDK related job"""
187
188     rs = None #_Rootstrap class instance
189     rootstrap_list = None
190     sdk_to_search = ['tizen-studio/tools/ide/bin/tizen', \
191                      'tizen-sdk/tools/ide/bin/tizen', \
192                      'tizen-sdk-ux/tools/ide/bin/tizen', \
193                      'tizen-sdk-cli/tools/ide/bin/tizen']
194
195     def __init__(self, sdkpath=None, rootstrap_search=None):
196
197         self.error_parser = ErrorParser()
198         self.runtool = Executor(checker=self.error_parser)
199
200         self.home = os.getenv('HOME')
201         self.config_file = os.path.join(g_home, '.abs')
202
203         if sdkpath is None:
204             self.tizen = self.get_user_root()
205             if self.tizen is None or self.tizen == '':
206                 for i in self.sdk_to_search:
207                     if os.path.isfile(os.path.join(self.home, i)):
208                         self.tizen = os.path.join(self.home, i)
209                         break
210         else:
211             self.tizen = os.path.join(sdkpath, 'tools/ide/bin/tizen')
212             self.update_user_root(self.tizen)
213
214         if not os.path.isfile(self.tizen):
215             print 'Cannot locate cli tool'
216             raise LocalError('Fail to locate cli tool')
217
218         self.rs = _Rootstrap(sdk_path=self.tizen, config=self.config_file, rootstrap_search=rootstrap_search)
219
220     def get_user_root(self):
221
222         if os.path.isfile(self.config_file):
223             config = ConfigParser.RawConfigParser()
224             config.read(self.config_file)
225             return config.get('Global', 'tizen')
226         return None
227
228     def update_user_root(self, path):
229
230         if not os.path.isfile(self.config_file):
231             with open(self.config_file, 'w') as f:
232                 f.write('[Global]\n')
233                 f.write('tizen = %s\n' % path)
234             return
235
236         config = ConfigParser.RawConfigParser()
237         config.read(self.config_file)
238         config.set('Global', 'tizen', path)
239         with open(self.config_file, 'wb') as cf:
240             config.write(cf)
241
242     def list_rootstrap(self):
243         return self.rs.list_rootstrap()
244
245     def check_rootstrap(self, rootstrap):
246         return self.rs.check_rootstrap(rootstrap)
247
248     def _run(self, command, args, show=True, checker=False):
249         """Run a tizen command"""
250
251         cmd = [self.tizen, command] + args
252         print '\nRunning command:\n    %s' % ' '.join(cmd)
253         return self.runtool.run(' '.join(cmd), show=show, checker=checker)
254
255     def copytree2(self, src, dst, symlinks=False, ignore=None):
256         """Copy with Ignore & Overwrite"""
257         names = os.listdir(src)
258         if ignore is not None:
259             ignored_names = ignore(src, names)
260         else:
261             ignored_names = set()
262
263         try:
264             os.makedirs(dst)
265         except:
266             pass
267
268         errors = []
269         for name in names:
270             if name in ignored_names:
271                 continue
272             srcname = os.path.join(src, name)
273             dstname = os.path.join(dst, name)
274             try:
275                 if symlinks and os.path.islink(srcname):
276                     linkto = os.readlink(srcname)
277                     os.symlink(linkto, dstname)
278                 elif os.path.isdir(srcname):
279                     self.copytree2(srcname, dstname, symlinks, ignore)
280                 else:
281                     # Will raise a SpecialFileError for unsupported file types
282                     shutil.copy2(srcname, dstname)
283             # catch the Error from the recursive copytree so that we can
284             # continue with other files
285             except shutil.Error, err:
286                 errors.extend(err.args[0])
287             except EnvironmentError, why:
288                 errors.append((srcname, dstname, str(why)))
289         try:
290             shutil.copystat(src, dst)
291         except OSError, why:
292             if WindowsError is not None and isinstance(why, WindowsError):
293                 # Copying file access times may fail on Windows
294                 pass
295             else:
296                 errors.append((src, dst, str(why)))
297         #if errors:
298          #   raise shutil.Error, errors
299
300     def _copy_build_output(self, src, dst):
301         if not os.path.isdir(src) :
302             return
303         try:
304             self.copytree2(src, dst, ignore=shutil.ignore_patterns('*.edc', '*.po', 'objs', '*.info', '*.so', 'CMakeLists.txt', '*.h', '*.c'))
305         except OSError as exc:
306             # File already exist
307             if exc.errno == errno.EEXIST:
308                 shutil.copy(src, dst)
309             if exc.errno == errno.ENOENT:
310                 shutil.copy(src, dst)
311             else:
312                 raise
313
314     def _package_sharedlib(self, project_path, conf, app_name):
315         """If -r option used for packaging, make zip file from copied files"""
316         #project_path=project['path']
317         project_build_output_path=os.path.join(project_path, conf)
318         package_path=os.path.join(project_build_output_path, '.pkg')
319
320         if os.path.isdir(package_path):
321             shutil.rmtree(package_path)
322         os.makedirs(package_path)
323         os.makedirs(os.path.join(package_path, 'lib'))
324
325         #Copy project resource
326         self._copy_build_output(os.path.join(project_path, 'lib'), os.path.join(package_path, 'lib'))
327         self._copy_build_output(os.path.join(project_path, 'res'), os.path.join(package_path, 'res'))
328
329         #Copy built res resource
330         self._copy_build_output(os.path.join(project_build_output_path, 'res'), os.path.join(package_path, 'res'))
331
332         #Copy so library file
333         for filename in list_files(project_build_output_path, 'so'):
334             shutil.copy(filename, os.path.join(package_path, 'lib'))
335
336         # Copy so library file
337         zipname=app_name + '.zip'
338         rsrc_zip = os.path.join(project_build_output_path, zipname)
339         myZipFile = zipfile.ZipFile(rsrc_zip, 'w')
340         for filename in list_files(package_path):
341             try:
342                 myZipFile.write(filename, filename.replace(package_path, ''))
343             except Exception, e:
344                 print str(e)
345         myZipFile.close()
346         return rsrc_zip
347
348     def build_native(self, source, rootstrap=None, arch=None, conf='Debug', jobs=None):
349         """SDK CLI build command"""
350
351         _rootstrap = self.check_rootstrap(rootstrap)
352         if _rootstrap == None:
353             raise LocalError('Rootstrap %s not exist' % rootstrap)
354
355         if rootstrap is None and arch is None:
356             rootstrap = _rootstrap
357             self.arch = 'x86'
358         elif arch is None:
359             if 'emulator64' in rootstrap: self.arch = 'x86_64'
360             elif 'device64' in rootstrap: self.arch = 'aarch64'
361             elif 'emulator' in rootstrap: self.arch = 'x86'
362             elif 'device' in rootstrap: self.arch = 'arm'
363         elif rootstrap is None:
364             if arch not in ['x86', 'arm', 'aarch64', 'x86_64']:
365                 raise LocalError('Architecture and rootstrap mismatch')
366
367             rootstrap = _rootstrap
368             if arch == 'x86_64': rootstrap = rootstrap.replace('emulator', 'emulator64')
369             elif arch == 'aarch64': rootstrap = rootstrap.replace('emulator', 'device64')
370             elif arch == 'arm': rootstrap = rootstrap.replace('emulator', 'device')
371
372         for x in source.project_list:
373             b_args = ['-r', rootstrap, '-a', self.arch, '-C', conf, '-c', 'gcc']
374             if jobs is not None: b_args.extend(['-j', jobs])
375             b_args.extend(['--', x['path']])
376             out = self._run('build-native', b_args, checker=True)
377             logpath = os.path.join(source.output_dir, \
378                                   'build_%s_%s' % (rootstrap, os.path.basename(x['path'])))
379             if not os.path.isdir(source.output_dir):
380                 os.makedirs(source.output_dir)
381             with open(logpath, 'w') as lf:
382                 lf.write(out)
383             ret = self.error_parser.check(out)
384             if True:
385                 with open(logpath+'.log', 'w') as lf:
386                     lf.write(out)
387             if ret:
388                 raise LocalError(ret)
389
390     def package(self, source, cert=None, pkg_type=None, conf=None):
391         """SDK CLI package command"""
392
393         if cert is None: cert = 'ABS'
394         if pkg_type is None: pkg_type = 'tpk'
395         if conf is None: conf = 'Debug'
396
397         final_app = ''
398         main_args = ['-t', pkg_type, '-s', cert]
399         out = '' #logfile
400
401         if conf == 'Release' :
402             main_args.extend(['--strip', 'on'])
403
404         for i, x in enumerate(source.project_list):
405             if x['type'] == 'app':
406                 out = '%s\n%s' % (out, \
407                       self._run('package', main_args + ['--',os.path.join(x['path'],conf)]))
408                 try:
409                     final_app = list_files(os.path.join(x['path'], conf), ext='tpk')[0]
410                 except:
411                     raise LocalError('TPK file not generated for %s.' % x['APPNAME'])
412                 x['out_package'] = final_app
413             elif x['type'] == 'sharedLib':
414                 self._package_sharedlib(x['path'], conf, x['APPNAME'])
415                 x['out_package'] = list_files(os.path.join(x['path'], conf), ext='zip')[0]
416             else:
417                 raise LocalError('Not supported project type %s' % x['type'])
418
419         if source.b_multi == True:
420             extra_args=[]
421             print 'THIS IS MULTI PROJECT'
422             for i, x in enumerate(source.project_list):
423                 if x['out_package'] != final_app and x['type'] == 'app':
424                     extra_args.extend(['-r', x['out_package']])
425                 elif x['type'] == 'sharedLib':
426                     extra_args.extend(['-r', x['out_package']])
427
428             extra_args.extend(['--', final_app])
429             out = self._run('package', main_args + extra_args)
430
431         #TODO: signature validation check failed : Invalid file reference. An unsigned file was found.
432         print 'Packaging final step again!'
433         out = self._run('package', main_args + ['--', final_app])
434
435         #Copy tpk to output directory
436         shutil.copy(final_app, source.output_dir)
437
438     def package_new(self, source, cert=None, pkg_type=None, conf=None, manual_strip=False):
439         """SDK CLI package command
440             IF Debug + Manual Strip off then generate package-name-debug.tpk
441             IF Debug + Manual Strip on then generate package-name.tpk with custom strip
442             IF Release then generate package-name.tpk with strip option
443         """
444
445         if cert is None: cert = 'ABS'
446         if pkg_type is None: pkg_type = 'tpk'
447         if conf is None: conf = 'Debug'
448
449         final_app = ''
450         main_args = ['-t', pkg_type, '-s', cert]
451         out = '' #logfile
452
453         # remove tpk or zip file on project path
454         package_list = []
455         for i, x in enumerate(source.project_list):
456             package_list.extend(list_files(os.path.join(x['path'], conf), ext='tpk'))
457             package_list.extend(list_files(os.path.join(x['path'], conf), ext='zip'))
458
459         for k in package_list :
460             print ' package list ' + k;
461             os.remove(k)
462
463         # Manual strip
464         if manual_strip == True :
465             strip_cmd='';
466             if self.arch == None:
467                 raise LocalError('Architecture is Noen')
468             elif self.arch == 'x86' :
469                 strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../i386-linux-gnueabi-gcc-4.9/bin/i386-linux-gnueabi-strip')
470             elif self.arch == 'arm' :
471                 strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../arm-linux-gnueabi-gcc-4.9/bin/arm-linux-gnueabi-strip')
472             elif self.arch == 'x86_64' :
473                 strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../x86_64-linux-gnu-gcc-4.9/bin/x86_64-linux-gnu-strip')
474             elif self.arch == 'aarch64' :
475                 strip_cmd = os.path.join(os.path.dirname(self.tizen), '../../aarch64-linux-gnu-gcc-4.9/bin/aarch64-linux-gnu-strip')
476
477             print strip_cmd
478
479             for i, x in enumerate(source.project_list):
480                 dir = os.path.join(x['path'], conf)
481                 files = [os.path.join(dir,f) for f in os.listdir(dir) if os.path.isfile(os.path.join(dir,f))]
482                 for k in files:
483                     cmdline = strip_cmd + ' ' + k;
484                     #print 'my command line ' + cmdline;
485                     Executor().run(cmdline, show=False)
486         elif conf == 'Release':
487             main_args.extend(['--strip', 'on'])
488
489         for i, x in enumerate(source.project_list):
490             if x['type'] == 'app':
491                 out = '%s\n%s' % (out, \
492                       self._run('package', main_args + ['--',os.path.join(x['path'],conf)]))
493                 try:
494                     final_app = list_files(os.path.join(x['path'], conf), ext='tpk')[0]
495                 except:
496                     raise LocalError('TPK file not generated for %s.' % x['APPNAME'])
497                 x['out_package'] = final_app
498             elif x['type'] == 'sharedLib':
499                 self._package_sharedlib(x['path'], conf, x['APPNAME'])
500                 x['out_package'] = list_files(os.path.join(x['path'], conf), ext='zip')[0]
501             else:
502                 raise LocalError('Not supported project type %s' % x['type'])
503
504         if source.b_multi == True:
505             extra_args=[]
506             print 'THIS IS MULTI PROJECT'
507             for i, x in enumerate(source.project_list):
508                 if x['out_package'] != final_app and x['type'] == 'app':
509                     extra_args.extend(['-r', x['out_package']])
510                 elif x['type'] == 'sharedLib':
511                     extra_args.extend(['-r', x['out_package']])
512
513             extra_args.extend(['--', final_app])
514             out = self._run('package', main_args + extra_args)
515
516         #TODO: signature validation check failed : Invalid file reference. An unsigned file was found.
517         print 'Packaging final step again!'
518         out = self._run('package', main_args + ['--', final_app])
519
520         #Copy tpk to output directory
521         if conf == 'Debug' and manual_strip == False :
522             basename = os.path.splitext(final_app)[0]
523             newname = basename +'-debug.tpk'
524             os.rename(final_app, newname)
525             shutil.copy(newname, source.output_dir)
526         else :
527             shutil.copy(final_app, source.output_dir)
528
529     def clean(self, source):
530         """SDK CLI clean command"""
531
532         if os.path.isdir(source.multizip_path):
533             shutil.rmtree(source.multizip_path)
534
535         if os.path.isfile(os.path.join(source.multizip_path, '.zip')):
536             os.remove(os.path.join(source.multizip_path, '.zip'))
537
538         for x in source.project_list:
539             self._run('clean', ['--', x['path']], show=False)
540
541 class Source(object):
542     """Project source related job"""
543
544     workspace = '' #Project root directory
545     project_list = []
546     b_multi = False
547     multi_conf_file = 'WORKSPACE' #Assume multi-project if this file exist.
548     multizip_path = '' #For multi-project packaging -r option
549     property_dict = {}
550     output_dir = '_abs_out_'
551
552     def __init__(self, src=None):
553
554         if src == None:
555             self.workspace = os.getcwd()
556         else:
557             self.workspace = os.path.abspath(src)
558         self.output_dir = os.path.join(self.workspace, self.output_dir)
559
560         os.environ['workspace_loc']=str(os.path.realpath(self.workspace))
561
562         self.multizip_path = os.path.join(self.workspace, 'multizip')
563         self.pre_process()
564
565     def set_properties(self, path):
566         """Fetch all properties from project_def.prop"""
567
568         mydict = {}
569         cp = ConfigParser.SafeConfigParser()
570         cp.optionxform = str
571         cp.readfp(FakeSecHead(open(os.path.join(path, 'project_def.prop'))))
572         for x in cp.items('ascection'):
573             mydict[x[0]] = x[1]
574         mydict['path'] = path
575         return mydict
576
577     def set_user_options(self, c_opts=None, cpp_opts=None, link_opts=None):
578         if c_opts is not None:
579             os.environ['USER_C_OPTS'] = c_opts
580             print 'Set USER_C_OPTS=[%s]' % os.getenv('USER_C_OPTS')
581         if cpp_opts is not None:
582             os.environ['USER_CPP_OPTS'] = cpp_opts
583             print 'Set USER_CPP_OPTS=[%s]' % os.getenv('USER_CPP_OPTS')
584         if link_opts is not None:
585             os.environ['USER_LINK_OPTS'] = link_opts
586             print 'Set USER_LINK_OPTS=[%s]' % os.getenv('USER_LINK_OPTS')
587
588     def pre_process(self):
589
590         if os.path.isfile(os.path.join(self.workspace, self.multi_conf_file)):
591             self.b_multi = True
592             with open(os.path.join(self.workspace, self.multi_conf_file)) as f:
593                 for line in f:
594                     file_path = os.path.join(self.workspace, line.rstrip())
595                     self.project_list.append(self.set_properties(file_path))
596         else:
597             self.b_multi = False
598             file_path = os.path.join(self.workspace)
599             self.project_list.append(self.set_properties(file_path))
600
601 def argument_parsing(argv):
602     """Any arguments passed from user"""
603
604     parser = argparse.ArgumentParser(description='ABS command line interface')
605
606     subparsers = parser.add_subparsers(dest='subcommands')
607
608     #### [subcommand - BUILD] ####
609     build = subparsers.add_parser('build')
610     build.add_argument('-w', '--workspace', action='store', dest='workspace', \
611                         help='source directory')
612     build.add_argument('-r', '--rootstrap', action='store', dest='rootstrap', \
613                         help='(ex, mobile-3.0-device.core) rootstrap name')
614     build.add_argument('-a', '--arch', action='store', dest='arch', \
615                         help='(x86|arm|x86_64|aarch64) Architecture to build')
616     build.add_argument('-t', '--type', action='store', dest='type', \
617                         help='(tpk|wgt) Packaging type')
618     build.add_argument('-s', '--cert', action='store', dest='cert', \
619                         help='(ex, ABS) Certificate profile name')
620     build.add_argument('-c', '--conf', action='store',default='Release', dest='conf', \
621                         help='(ex, Debug|Release) Build Configuration')
622     build.add_argument('-j', '--jobs', action='store', dest='jobs', \
623                         help='(number of jobs) The number of parallel builds')
624     build.add_argument('--sdkpath', action='store', dest='sdkpath', \
625                         help='Specify Tizen SDK installation root (one time init).' \
626                              ' ex) /home/yours/tizen-sdk/')
627     build.add_argument('--profile-to-search', action='store', dest='profiletosearch', \
628                         help='Rootstrap profile prefix.' \
629                              ' ex) (mobile|wearable|da-hfp)')
630     build.add_argument('--c-opts', action='store', dest='c_opts', \
631                         help='Extra compile options USER_C_OPTS')
632     build.add_argument('--cpp-opts', action='store', dest='cpp_opts', \
633                         help='Extra compile options USER_CPP_OPTS')
634     build.add_argument('--link-opts', action='store', dest='link_opts', \
635                         help='Extra linking options USER_LINK_OPTS')
636
637     return parser.parse_args(argv[1:])
638
639 def build_main(args):
640     """Command [build] entry point."""
641
642     my_source = Source(src=args.workspace)
643     my_source.set_user_options(c_opts=args.c_opts, cpp_opts=args.cpp_opts, link_opts=args.link_opts)
644     print '-------------------'
645     print '(%s)' % args.profiletosearch
646     print '-------------------'
647     my_sdk = Sdk(sdkpath=args.sdkpath, rootstrap_search=args.profiletosearch)
648     my_sdk.clean(my_source)
649     my_sdk.build_native(my_source, rootstrap=args.rootstrap, arch=args.arch, conf=args.conf, jobs=args.jobs)
650     if args.conf == 'Debug' :
651         my_sdk.package_new(my_source, pkg_type=args.type, cert=args.cert, conf=args.conf)
652         my_sdk.package_new(my_source, pkg_type=args.type, cert=args.cert, conf=args.conf, manual_strip=True)
653     else :
654         my_sdk.package_new(my_source, pkg_type=args.type, cert=args.cert, conf=args.conf)
655
656 def main(argv):
657     """Script entry point."""
658
659     print 'ABS SCRIPT FROM GIT'
660
661     args = argument_parsing(argv)
662
663     if args.subcommands == 'build':
664         return build_main(args)
665     else:
666         print 'Unsupported command %s' % args.subcommands
667         raise LocalError('Command %s not supported' % args.subcommands)
668
669 if __name__ == '__main__':
670
671     try:
672         sys.exit(main(sys.argv))
673     except Exception, e:
674         print 'Exception %s' % str(e)
675         sys.exit(1)