sbsv2/raptor/python/raptor_cli.py
changeset 0 044383f39525
child 3 e1eecf4d390d
child 590 360bd6b35136
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 #
       
     2 # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 # raptor_cli module
       
    16 # This module represents a Command Line Interpreter (CLI) for Raptor.
       
    17 # The interface with Raptor is the GetArgs() function, which is called
       
    18 # by a raptor.Raptor object.
       
    19 #
       
    20 
       
    21 import re
       
    22 import types
       
    23 import raptor
       
    24 import os
       
    25 import sys
       
    26 import tempfile
       
    27 from raptor_utilities import getOSPlatform
       
    28 
       
    29 from optparse import OptionParser # for parsing command line parameters
       
    30 
       
    31 fullCommandOption = "--command"
       
    32 miniCommandOption = "--co"  # update this if another "co" option is added
       
    33 
       
    34 # raptor_cli module attributes
       
    35 
       
    36 parser = OptionParser(prog = raptor.name,
       
    37 					  usage = """%prog [--help] [options] [variable=value] [target] ...
       
    38 
       
    39 Targets:
       
    40 
       
    41 BITMAP         Create bitmap files
       
    42 CLEAN          Remove built files and intermediates, but not exported files
       
    43 CLEANEXPORT    Remove exported files
       
    44 EXPORT         Copy exported files to destinations
       
    45 FINAL          Allow extension makefiles to execute final commands
       
    46 FREEZE         Freeze exported functions in a .DEF file
       
    47 LIBRARY        Create import libraries from frozen .DEF files
       
    48 LISTING        Create assembler listing files for source files
       
    49 REALLYCLEAN    Same as CLEAN but also remove exported files
       
    50 RESOURCE       Create resource files and AIFs
       
    51 ROMFILE        Create an IBY file to be included in a ROM
       
    52 TARGET         Create main executables
       
    53 WHAT           List all releaseable targets
       
    54 
       
    55 Examples:
       
    56 
       
    57 sbs -b my/group/bld.inf -c armv5        # build my component for target ARMV5
       
    58 sbs -b my/group/bld.inf -c armv5.test   # build my tests for target ARMV5
       
    59 
       
    60 sbs -c winscw CLEAN                     # clean emulator files
       
    61 sbs REALLYCLEAN                         # delete everything""")
       
    62 
       
    63 parser.add_option("-a","--sysdefbase",action="store",dest="sys_def_base",
       
    64 				help="Root directory for relative paths in the System Definition XML file.")
       
    65 
       
    66 parser.add_option("-b","--bldinf",action="append",dest="bld_inf_file",
       
    67 				help="Build information filename. Multiple -b options can be given.")
       
    68 
       
    69 parser.add_option("-c","--config",action="append",dest="config_name",
       
    70 				help="Configuration name to build. Multiple -c options can be given. The standard configs are all, armv5, armv7, default, tools, tools2 and winscw.")
       
    71 
       
    72 parser.add_option("--configpath", action="append",dest="config_list",
       
    73 				help="Append a list of paths to the default list of XML configuration folders. Use ';' as the separator on Windows, and ':' on Linux. Multiple --configpath options can be given.")
       
    74 
       
    75 parser.add_option("--check",action="store_true",dest="check",
       
    76 				help="Test for the existence of files created by the build, printing the ones which are missing. Do not build anything.")
       
    77 
       
    78 parser.add_option("--command",action="append",dest="command_file",
       
    79 				help="Provide a set of command-line options in a file.")
       
    80 
       
    81 parser.add_option("-d","--debug",action="store_true",dest="debugoutput",
       
    82 				help="Display information useful for debugging.")
       
    83 
       
    84 parser.add_option("-e","--engine",action="store",dest="make_engine",
       
    85 				help="Name of the make engine which runs the build.")
       
    86 
       
    87 parser.add_option("--export-only",action="store_true",dest="doExportOnly",
       
    88 				help="Generate exports only and do not create any make files.")
       
    89 
       
    90 parser.add_option("-f","--logfile",action="store",dest="logfile",
       
    91 				help="Name of the log file, or '-' for stdout.")
       
    92 
       
    93 parser.add_option("--filters",action="store",dest="filter_list",
       
    94 				help="Comma-separated list of names of the filters to use (case sensitive).")
       
    95 
       
    96 parser.add_option("-i","--ignore-os-detection",action="store_true",dest="ignore_os_detection",
       
    97 				help="Disables automatic application of OS variant based upon the OS version detected from each epoc32 tree.")
       
    98 
       
    99 parser.add_option("-j","--jobs",action="store",dest="number_of_jobs",
       
   100                 help="The maximum number of jobs that make should try and run in parallel (on a single machine).")
       
   101 
       
   102 parser.add_option("-k","--keepgoing",action="store_true",dest="keepgoing",
       
   103 				help="Continue building, even if some build commands fail.")
       
   104 
       
   105 parser.add_option("-l","--layer",action="append",dest="sys_def_layer",
       
   106                 help="Build a specific layer in the System Definition XML File. Multiple -l options can be given.")
       
   107 
       
   108 parser.add_option("-m","--makefile",action="store",dest="makefile",
       
   109 				help="Top-level makefile to be created.")
       
   110 
       
   111 parser.add_option("--mo",action="append",dest="make_option",
       
   112 				help="Option that must be passed through to the make engine. Multiple --mo options can be given.")
       
   113 
       
   114 parser.add_option("-n","--nobuild",action="store_true",dest="nobuild",
       
   115 				help="Just create makefiles, do not build anything.")
       
   116 
       
   117 parser.add_option("--no-depend-include",action="store_true",dest="noDependInclude",
       
   118 				help="Do not include generated dependency files. This is only useful for extremely large non-incremental builds.")
       
   119 				
       
   120 parser.add_option("-o","--orderlayers",action="store_true",dest="sys_def_order_layers",
       
   121 				help="Build layers in the System Definition XML file in the order listed or, if given, in the order of -l options.")
       
   122 
       
   123 parser.add_option("-p","--project",action="append",dest="project_name",
       
   124                 help="Build a specific project (mmp or extension) in the given bld.inf file. Multiple -p options can be given.")
       
   125 
       
   126 parser.add_option("-q","--quiet",action="store_true",dest="quiet",
       
   127 				help="Run quietly, not generating output messages.")
       
   128 
       
   129 parser.add_option("-s","--sysdef",action="store",dest="sys_def_file",
       
   130 				help="System Definition XML filename.")
       
   131 
       
   132 parser.add_option("--source-target",action="append",dest="source_target",
       
   133 				help="Build the listed source or resource file in isolation - do not perform any dependent processing. Multiple --source-target options can be given.")
       
   134 
       
   135 parser.add_option("-t","--tries",action="store",dest="tries",
       
   136 				help="How many times to run a command before recording an error. The default is 1. This is useful for builds where transient failures can occur.")
       
   137 
       
   138 parser.add_option("--toolcheck",action="store",dest="toolcheck",
       
   139 			help= \
       
   140 				"""Possible values are:
       
   141 				  "on"     -  Check the versions of tools that will be used in the build. Use cached results from previous builds to save time. This is the default.
       
   142 
       
   143   				  "off"    -  Do not check tool versions whatsoever.
       
   144 
       
   145 				  "forced" -  Check all tool versions. Don't use cached results.
       
   146 			""")
       
   147 parser.add_option("--pp",action="store",dest="parallel_parsing",
       
   148 				help="""Controls how metadata (e.g. bld.infs) are parsed in Parallel.
       
   149 					Possible values are:
       
   150 					"on"  - Parse bld.infs in parallel (should be faster on clusters/multicore machines)
       
   151 					"off" - Parse bld.infs serially 
       
   152 				     """)
       
   153 
       
   154 parser.add_option("-v","--version",action="store_true",dest="version",
       
   155 				help="Print the version number and exit.")
       
   156 
       
   157 parser.add_option("--what",action="store_true",dest="what",
       
   158 				help="Print out the names of the files created by the build. Do not build anything.")
       
   159 
       
   160 def GetArgs(Raptor, args):
       
   161 	"Process command line arguments for a Raptor object"
       
   162 	return DoRaptor(Raptor,args)
       
   163 
       
   164 def ReadCommandFile(filename, used):
       
   165 	if filename in used:
       
   166 		raise IOError("command file '%s' refers to itself" % filename)
       
   167 
       
   168 	args = []
       
   169 	try:
       
   170 		file = open(filename, "r")
       
   171 		for line in file.readlines():
       
   172 			args.extend(line.split())
       
   173 		file.close()
       
   174 	except:
       
   175 		raise IOError("couldn't read command file '%s'" % filename)
       
   176 
       
   177 	# expand any command files in the options we just read.
       
   178 	# making sure we don't get stuck in a loop.
       
   179 	usedPlusThis = used[:]
       
   180 	usedPlusThis.append(filename)
       
   181 	return ExpandCommandOptions(args, usedPlusThis)
       
   182 
       
   183 def ExpandCommandOptions(args, files = []):
       
   184 	"""recursively expand --command options."""
       
   185 	expanded = []
       
   186 	previousWasOpt = False
       
   187 
       
   188 	for a in args:
       
   189 		if previousWasOpt: # then this one is the filename
       
   190 			expanded.extend(ReadCommandFile(a, files))
       
   191 			previousWasOpt = False
       
   192 			continue
       
   193 
       
   194 		if a.startswith(miniCommandOption):
       
   195 			if "=" in a: # then this is opt=filename
       
   196 				opt = a.split("=")
       
   197 				if fullCommandOption.startswith(opt[0]):
       
   198 					expanded.extend(ReadCommandFile(opt[1], files))
       
   199 					continue
       
   200 			else: # the next one is the filename
       
   201 				if fullCommandOption.startswith(a):
       
   202 					previousWasOpt = True
       
   203 					continue
       
   204 
       
   205 		expanded.append(a) # an ordinary arg, nothing to do with command files
       
   206 
       
   207 	return expanded
       
   208 
       
   209 def DoRaptor(Raptor, args):
       
   210 	"Process raptor arguments"
       
   211 	#
       
   212 	# This should parse the args list and call methods on
       
   213 	# the Raptor object to store the appropriate data.
       
   214 
       
   215 	# Expand --command=file options, replacing them with the contents of the
       
   216 	# command file.
       
   217 
       
   218 	non_ascii_error = "Non-ASCII character in argument or command file"
       
   219 
       
   220 	try:
       
   221 		expanded_args = ExpandCommandOptions(args)
       
   222 		for arg in expanded_args:
       
   223 			for c in arg:
       
   224 				if ord(c) > 127:
       
   225 					Raptor.Error(non_ascii_error)
       
   226 					return False
       
   227 	except IOError, e:
       
   228 		Raptor.Error(str(e))
       
   229 		return False
       
   230 	except UnicodeDecodeError:
       
   231 		Raptor.Error(non_ascii_error)
       
   232 		return False
       
   233 
       
   234 	# parse the full set of arguments
       
   235 	(options, leftover_args) = parser.parse_args(expanded_args)
       
   236 
       
   237 	# the leftover_args are either variable assignments of the form a=b
       
   238 	# or target names.
       
   239 	regex = re.compile("^(.+)=(.*)$")
       
   240 	for leftover in leftover_args:
       
   241 		assignment = regex.findall(leftover)
       
   242 		if len(assignment) > 0:
       
   243 			Raptor.SetEnv(assignment[0][0],assignment[0][1])
       
   244 		else:
       
   245 			Raptor.AddTarget(leftover)
       
   246 
       
   247 	# Define the dictionary of functions to be used.
       
   248 	# Attributes and function names can be added easily.
       
   249 	# The calling attribute should be the same
       
   250 	# as specified when creating the add_option
       
   251 	functions = {'config_name': Raptor.AddConfigName,
       
   252 				 'config_list':Raptor.AddConfigList,
       
   253 				 'sys_def_file' : Raptor.SetSysDefFile,
       
   254 				 'sys_def_base' : Raptor.SetSysDefBase,
       
   255 				 'sys_def_layer' : Raptor.AddSysDefLayer,
       
   256 				 'sys_def_order_layers' : Raptor.SetSysDefOrderLayers,
       
   257 				 'bld_inf_file' : Raptor.AddBuildInfoFile,
       
   258 				 'logfile' : Raptor.SetLogFileName,
       
   259 				 'makefile' : Raptor.SetTopMakefile,
       
   260 				 'quiet' : Raptor.RunQuietly,
       
   261 				 'debugoutput' : Raptor.SetDebugOutput,
       
   262 				 'doExportOnly' : Raptor.SetExportOnly,
       
   263 				 'keepgoing': Raptor.SetKeepGoing,
       
   264 				 'nobuild' : Raptor.SetNoBuild,
       
   265 				 'make_engine': Raptor.SetMakeEngine,
       
   266 				 'make_option': Raptor.AddMakeOption,
       
   267 				 'noDependInclude': Raptor.SetNoDependInclude,
       
   268 				 'number_of_jobs': Raptor.SetJobs,
       
   269 				 'project_name' :  Raptor.AddProject,
       
   270 				 'filter_list' : Raptor.FilterList,
       
   271 				 'ignore_os_detection': Raptor.IgnoreOsDetection,
       
   272 				 'check' :  Raptor.SetCheck,
       
   273 				 'what' :  Raptor.SetWhat,
       
   274 				 'tries' : Raptor.SetTries,
       
   275 				 'toolcheck' : Raptor.SetToolCheck,
       
   276 				 'source_target' : Raptor.AddSourceTarget,
       
   277 				 'command_file' : CommandFile,
       
   278 				'parallel_parsing' : Raptor.SetParallelParsing,
       
   279 			 	'version' : Raptor.PrintVersion
       
   280 				}
       
   281 
       
   282 	# Check if Quiet mode has been specified (otherwise we will make noise)
       
   283 	if parser.values.quiet:
       
   284 		Raptor.RunQuietly(True)
       
   285 
       
   286 	# some options imply that Raptor should exit immediately (e.g. --version)
       
   287 	keepGoing = True
       
   288 
       
   289 	if parser.values.version:
       
   290 		keepGoing = False
       
   291 
       
   292 	# Parse through the command line arguments passed, and call the
       
   293 	# corresponding function with the correct parameter.
       
   294 	# Since options is a OptParse.Value instance, it can be iterated over.
       
   295 	# This implementation helps avoid lengthy if-else statements
       
   296 	for opt in options.__dict__.items():
       
   297 		call_function = functions[str(opt[0])]
       
   298 		values = opt[1]
       
   299 		if not values:
       
   300 			pass
       
   301 		else:
       
   302 			if type(values) == types.ListType: # Check if the argument type is a list or a string. If list, then iterate through it and call the functions
       
   303 				for val in values:
       
   304 					keepGoing = (call_function(val) and keepGoing)
       
   305 			else:
       
   306 					keepGoing = (call_function(values) and keepGoing)
       
   307 
       
   308 	return keepGoing
       
   309 
       
   310 def CommandFile(file):
       
   311 	"this should never be called because we expand --command in this module."
       
   312 	print raptor.name + ": error: command file '%s' was not expanded" % file
       
   313 	return False
       
   314 
       
   315 
       
   316 
       
   317 
       
   318 # end of the raptor_cli module
       
   319 
       
   320