2 sys
.path
.append("tools") # Allow us to import bootimg.py
3 #sys.path.append("tools/pyelf")
4 #sys.path = ["tools/pexpect"] + sys.path # Allow us to import pexpect.py
12 from types
import TupleType
13 from util
import contains_any
, identity_mapping
14 from xml
.dom
import minidom
15 from optparse
import OptionParser
17 # Make it easier to raise UserErrors
18 from SCons
.Errors
import UserError
20 # We want the SConsign file (where it stores
21 # information on hashs and times
22 SConsignFile(".sconsign")
25 # Work make the scons version easy to test
26 scons_version
= tuple([int(x
) for x
in SCons
.__version
__.split(".")])
28 # Make sure that we have a decent version of SCons
29 if scons_version
<= (0, 95):
30 raise UserError
, "Support for SCons 0.95 has been dropped. " + \
31 "Please upgrade to at least 0.96"
33 # We check we have at least version 2.3, If we don't we are in trouble!
34 if sys
.version_info
< (2, 3):
35 raise UserError
, "To use the Kenge build system you need Python2.3 " + \
36 "including the python devel packages."
39 def src_glob(search
, replacement
= {}):
40 """Src glob is used to find source files easily e.g: src_glob("src/*.c"),
41 the reason we can't just use glob is due to the way SCons handles out
42 of directory builds."""
43 if search
.startswith('#'):
44 # what does '#' signify?
46 dir = os
.path
.dirname(search
)
48 dir = '#' + dir + os
.sep
49 #is the below any different from Dir('.').srcnode.abspath ??
50 src_path
= Dir('#').srcnode().abspath
51 elif search
.startswith(os
.sep
):
52 # we have been given an absolute path
53 dir = os
.path
.dirname(search
)
58 dir = os
.path
.dirname(search
)
61 src_path
= Dir('.').srcnode().abspath
63 src_path
= src_path
% replacement
64 search
= search
% replacement
65 files
= glob
.glob(os
.path
.join(src_path
, search
))
66 files
= map(os
.path
.basename
, files
)
69 ret_files
.append(dir + file)
70 # Sort the files so the linkers get the same list of objects
71 # and hence deterministic builds
75 ################################################################################
76 # Read configuration files
77 ################################################################################
80 """Class to hold a set of configuration options. This works as a
81 recursive dictionary, with access through the "." method. This allows
82 settings things such as:
87 And all intermediate level will be created automagically."""
90 """Create a new instance."""
91 self
.__dict
__["dict"] = {}
93 def __getattr__(self
, attr
):
94 """Magic getattr method to implement accessing dictionary
95 members through the . syntax. Will create a new Options dictionary
96 when accessing new names. This method is only called in cases
97 when the attribute doesn't already exist."""
98 if attr
.startswith("__"): # Disallow access to "__" names
100 self
.__dict
__[attr
] = Options()
101 return self
.__dict
__[attr
]
103 def __setattr__(self
, attr
, value
):
104 """Sets a new value in the dictionary"""
105 self
.dict[attr
.upper()] = value
109 # First read options from the .conf file
110 if os
.path
.exists(".conf"):
111 execfile(".conf", locals())
113 # Then take values from the commands line options
114 for (key
, value
) in args
.items():
115 parts
= key
.split(".")
117 while len(parts
) > 1:
118 c
= getattr(c
, parts
[0])
120 setattr(c
, parts
[0], value
)
123 def load_cross(conf
):
127 cross
.SConsignFile
= SConsignFile
128 cross
.Environment
= Environment
129 cross
.Scanner
= Scanner
131 cross
.Builder
= Builder
132 cross
.Action
= Action
133 cross
.SConscript
= SConscript
134 cross
.Flatten
= Flatten
135 cross
.src_glob
= src_glob
137 cross
.Command
= Command
140 cross
.Depends
= Depends
142 cross
.AlwaysBuild
= AlwaysBuild
145 ############################################################################
147 ############################################################################
150 # Determine if the user is trying to clean
151 cleaning
= contains_any(["--clean", "--remove", "-c"], sys
.argv
)
153 # Clean out any .pyc from tool
157 # Option processing functions.
159 def get_bool_arg(build
, name
, default
):
160 """Get the boolean value of an option."""
161 if type(build
) == dict:
165 x
= args
.get(name
, default
)
166 if type(x
) is type(""):
168 if x
in [1, True, "1", "true", "yes", "True"]:
170 elif x
in [0, False, "0", "false", "no", "False"]:
173 raise UserError
, "%s is not a valid argument for option %s. It should be True or False" % (x
, name
)
177 def get_arg(build
, name
, default
):
178 if type(build
) == dict:
182 return args
.get(name
, default
)
184 def get_int_arg(build
, name
, default
):
185 val
= get_arg(build
, name
, default
)
192 def get_option_arg(build
, name
, default
, options
, as_list
= False):
193 """Get the value of an option, which must be one of the supplied set"""
194 if type(build
) == dict:
199 arg
= args
.get(name
, def_val
)
201 if options
and type(options
[0]) == TupleType
:
202 # This means a user has specified a list like:
203 # [("foo", foo_object), ("bar", bar_object)]
204 mapping
= dict(options
)
205 options
= [x
[0] for x
in options
]
207 mapping
= dict([(str(x
), x
) for x
in options
])
210 if str(arg
) not in mapping
:
211 raise UserError
, "need argument for option %s. Valid options are: %s" % (name
, options
)
212 return mapping
[str(arg
)]
214 if not isinstance(arg
, str): #Assuming integer
215 if arg
not in options
:
216 raise UserError
, "%s is not a valid argument for option %s. Valid options are: %s" % (x
, name
, options
)
221 raise UserError
, "%s is not a valid argument for option %s. Valid options are: %s" % (x
, name
, options
)
226 return mapping
[arg
[0]]
229 def get_rtos_example_args(xml_file
, example_cmd_line
):
230 """Read the given rtos tests configuration xml file and return a dictionary
231 containing the values read"""
233 for example
in example_cmd_line
:
234 if not example
== "all":
235 rtos_args
[example
] = {}
236 rtos_args
[example
]["nb_copies"] = 1
237 rtos_args
[example
]["extra_arg"] = 1
238 xmltree
= minidom
.parse("tools/unittest/" + xml_file
).documentElement
239 rtos_args
["server"] = xmltree
.getAttribute("server")
240 example_nodes
= xmltree
.getElementsByTagName("example")
241 for example_node
in example_nodes
:
242 example_name
= example_node
.getAttribute("name")
243 if example_name
in example_cmd_line
or example_cmd_line
== ["all"]:
244 if example_cmd_line
== ["all"]:
245 rtos_args
[example_name
] = {}
246 rtos_args
[example_name
]["nb_copies"] = example_node
.getAttribute("nb_copies")
247 rtos_args
[example_name
]["extra_arg"] = example_node
.getAttribute("extra_arg")
250 ################################################################################
251 # Now find the project SConstruct file to use.
252 ################################################################################
254 def get_sconstruct_path(conf
):
255 # Find the project from the arguments.
256 project
= conf
.dict.get("PROJECT", None)
257 if "PROJECT" in conf
.dict: del conf
.dict["PROJECT"]
259 # Provide useful message if it doesn't exist
261 raise UserError
, "You must specify the PROJECT you want to build."
263 cust
= conf
.dict.get('CUST', None)
264 sconstruct_path
= "cust/%s/projects/%s/SConstruct" % (cust
, project
)
265 if not os
.path
.exists(sconstruct_path
):
266 sconstruct_path
= "projects/%s/SConstruct" % project
267 if not os
.path
.exists(sconstruct_path
):
268 raise UserError
, "%s is not a valid project" % project
270 # liunote add for project import
271 project_path
= "projects/%s/" % project
273 sys
.path
.append(project_path
)
275 return sconstruct_path
278 scons_version
= get_version()
279 conf
= get_conf(ARGUMENTS
)
282 sconstruct_path
= get_sconstruct_path(conf
)
285 Export("scons_version")
288 Export("get_bool_arg")
289 Export("get_int_arg")
291 # Execute the SConstruct
292 execfile(sconstruct_path
)