summaryrefslogtreecommitdiffstats
path: root/wscript
diff options
context:
space:
mode:
Diffstat (limited to 'wscript')
-rwxr-xr-xwscript647
1 files changed, 337 insertions, 310 deletions
diff --git a/wscript b/wscript
index 59ab96c43d..6c81083b2c 100755
--- a/wscript
+++ b/wscript
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (C) 2020 Hesham Almatary <Hesham.Almatary@cl.cam.ac.uk>
-# Copyright (C) 2019, 2020 embedded brains GmbH (http://www.embedded-brains.de)
+# Copyright (C) 2019, 2020 embedded brains GmbH & Co. KG
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -43,7 +43,13 @@ except:
from waflib.TaskGen import after, before_method, feature
is_windows_host = os.name == "nt" or sys.platform in ["msys", "cygwin"]
-default_prefix = "/opt/rtems/6"
+version = {
+ "__RTEMS_MAJOR__": "6",
+ "__RTEMS_MINOR__": "0",
+ "__RTEMS_REVISION__": "0",
+ "RTEMS_VERSION_CONTROL_KEY": "git"
+}
+default_prefix = "/opt/rtems/" + version["__RTEMS_MAJOR__"]
compilers = ["gcc", "clang"]
items = {}
bsps = {}
@@ -62,25 +68,28 @@ class VersionControlKeyHeader:
@staticmethod
def write(bld, filename):
- if VersionControlKeyHeader._content is None:
- from waflib.Build import Context
- from waflib.Errors import WafError
-
+ content = VersionControlKeyHeader._content
+ if content is None:
content = """/*
* Automatically generated. Do not edit.
*/
#if !defined(_RTEMS_VERSION_VC_KEY_H_)
#define _RTEMS_VERSION_VC_KEY_H_
"""
- try:
- rev = bld.cmd_and_log(
- "git rev-parse HEAD", quiet=Context.STDOUT
- ).strip()
- content += """#define RTEMS_VERSION_VC_KEY "{}"
-""".format(
- rev
- )
- except WafError:
+ key = bld.env.RTEMS_VERSION_CONTROL_KEY
+ if key == "git":
+ from waflib.Build import Context
+ from waflib.Errors import WafError
+
+ try:
+ key = bld.cmd_and_log("git rev-parse HEAD",
+ quiet=Context.STDOUT).strip()
+ except WafError:
+ key = ""
+ if key:
+ content += """#define RTEMS_VERSION_CONTROL_KEY "{}"
+""".format(key)
+ else:
content += """/* No version control key found; release? */
"""
content += """#endif
@@ -90,12 +99,13 @@ class VersionControlKeyHeader:
f.parent.mkdir()
try:
if content != f.read():
- f.write(VersionControlKeyHeader._content)
+ f.write(content)
except:
- f.write(VersionControlKeyHeader._content)
+ f.write(content)
class EnvWrapper(object):
+
def __init__(self, env):
self._env = env
@@ -112,7 +122,10 @@ class EnvWrapper(object):
class Template(string.Template):
- idpattern = "[_a-z][_a-z0-9:#]*"
+ idpattern = "[_A-Za-z][_A-Za-z0-9:#]*"
+
+
+_VAR_PATTERN = re.compile("\\$\\{?(" + Template.idpattern + ")\\}?$")
def _is_enabled_op_and(enabled, enabled_by):
@@ -152,9 +165,8 @@ def _is_enabled(enabled, enabled_by):
def _asm_explicit_target(self, node):
- task = self.create_task(
- "asm", node, self.bld.bldnode.make_node(self.target)
- )
+ task = self.create_task("asm", node,
+ self.bld.bldnode.make_node(self.target))
try:
self.compiled_tasks.append(task)
except AttributeError:
@@ -176,7 +188,17 @@ def process_start_files(self):
self.link_task.dep_nodes.extend(self.bld.start_files)
+def make_tar_info_reproducible(info):
+ info.uid = 0
+ info.gid = 0
+ info.mtime = 0
+ info.uname = "root"
+ info.gname = "root"
+ return info
+
+
class Item(object):
+
def __init__(self, uid, data):
self.uid = uid
self.data = data
@@ -189,8 +211,7 @@ class Item(object):
uid = link["uid"]
if not os.path.isabs(uid):
uid = os.path.normpath(
- os.path.join(os.path.dirname(self.uid), uid)
- )
+ os.path.join(os.path.dirname(self.uid), uid))
self._links.append(items[uid])
self.links = self._yield_links
for link in self._links:
@@ -203,27 +224,36 @@ class Item(object):
def get_enabled_by(self):
return self.data["enabled-by"]
- def defaults(self, enable, variant, family):
- if _is_enabled(enable, self.get_enabled_by()):
+ def defaults(self, enabled):
+ if _is_enabled(enabled, self.get_enabled_by()):
for p in self.links():
- p.defaults(enable, variant, family)
- self.do_defaults(variant, family)
+ p.defaults(enabled)
+ self.do_defaults(enabled)
def configure(self, conf, cic):
if _is_enabled(conf.env.ENABLE, self.get_enabled_by()):
self.prepare_configure(conf, cic)
for p in self.links():
p.configure(conf, cic)
- self.do_configure(conf, cic)
+ try:
+ self.do_configure(conf, cic)
+ except Exception as e:
+ raise type(e)(
+ "Configuration error related to item spec:{}: {}".format(
+ self.uid, str(e)))
def build(self, bld, bic):
if _is_enabled(bld.env.ENABLE, self.get_enabled_by()):
bic = self.prepare_build(bld, bic)
for p in self.links():
p.build(bld, bic)
- self.do_build(bld, bic)
+ try:
+ self.do_build(bld, bic)
+ except Exception as e:
+ raise type(e)("Build error related to item spec:{}: {}".format(
+ self.uid, str(e)))
- def do_defaults(self, variant, family):
+ def do_defaults(self, enabled):
return
def prepare_configure(self, conf, cic):
@@ -245,22 +275,24 @@ class Item(object):
except Exception as e:
ctx.fatal(
"In item '{}' substitution in '{}' failed: {}".format(
- self.uid, value, e
- )
- )
+ self.uid, value, e))
if isinstance(value, list):
- return [self.substitute(ctx, subvalue) for subvalue in value]
+ more = []
+ for item in value:
+ if isinstance(item, str):
+ m = _VAR_PATTERN.match(item)
+ else:
+ m = None
+ if m:
+ more.extend(ctx.env[m.group(1).strip("{}")])
+ else:
+ more.append(self.substitute(ctx, item))
+ return more
return value
def get(self, ctx, name):
return self.substitute(ctx, self.data[name])
- def get_values(self, ctx, name):
- more = []
- for value in self.data[name]:
- more.extend(self.substitute(ctx, value).split())
- return more
-
def install_target(self, bld):
install_path = self.data["install-path"]
if install_path:
@@ -275,9 +307,11 @@ class Item(object):
target = os.path.splitext(source)[0] + ".o"
bld(
asflags=self.substitute(bld, self.data["asflags"]),
- cppflags=self.substitute(bld, self.data["cppflags"]),
+ cppflags=bic.cppflags +
+ self.substitute(bld, self.data["cppflags"]),
features="asm_explicit_target asm c",
- includes=bic.includes + self.substitute(bld, self.data["includes"]),
+ includes=bic.includes +
+ self.substitute(bld, self.data["includes"]),
source=[source],
target=target,
)
@@ -287,11 +321,14 @@ class Item(object):
if target is None:
target = os.path.splitext(source)[0] + ".o"
bld(
- cflags=self.substitute(bld, self.data["cflags"]),
- cppflags=cppflags + self.substitute(bld, self.data["cppflags"]),
+ cflags=bic.cflags + self.substitute(bld, self.data["cflags"]),
+ cppflags=bic.cppflags + cppflags +
+ self.substitute(bld, self.data["cppflags"]),
features="c",
- includes=bic.includes + self.substitute(bld, self.data["includes"]),
- rule="${CC} ${CFLAGS} ${CPPFLAGS} ${DEFINES_ST:DEFINES} ${CPPPATH_ST:INCPATHS} -c ${SRC[0]} -o ${TGT}",
+ includes=bic.includes +
+ self.substitute(bld, self.data["includes"]),
+ rule=
+ "${CC} ${CFLAGS} ${CPPFLAGS} ${DEFINES_ST:DEFINES} ${CPPPATH_ST:INCPATHS} -c ${SRC[0]} -o ${TGT}",
source=[source] + deps,
target=target,
)
@@ -301,11 +338,15 @@ class Item(object):
if target is None:
target = os.path.splitext(source)[0] + ".o"
bld(
- cppflags=cppflags + self.substitute(bld, self.data["cppflags"]),
- cxxflags=self.substitute(bld, self.data["cxxflags"]),
+ cppflags=bic.cppflags + cppflags +
+ self.substitute(bld, self.data["cppflags"]),
+ cxxflags=bic.cxxflags +
+ self.substitute(bld, self.data["cxxflags"]),
features="cxx",
- includes=bic.includes + self.substitute(bld, self.data["includes"]),
- rule="${CXX} ${CXXFLAGS} ${CPPFLAGS} ${DEFINES_ST:DEFINES} ${CPPPATH_ST:INCPATHS} -c ${SRC[0]} -o ${TGT}",
+ includes=bic.includes +
+ self.substitute(bld, self.data["includes"]),
+ rule=
+ "${CXX} ${CXXFLAGS} ${CPPFLAGS} ${DEFINES_ST:DEFINES} ${CPPPATH_ST:INCPATHS} -c ${SRC[0]} -o ${TGT}",
source=[source] + deps,
target=target,
)
@@ -315,14 +356,14 @@ class Item(object):
from waflib.Task import Task
class link(Task):
- def __init__(self, item, bic, cmd, env):
+
+ def __init__(self, item, bic, cmd, env, ldflags):
super(link, self).__init__(self, env=env)
self.cmd = cmd
- self.ldflags = bic.ldflags + item.data["ldflags"]
+ self.ldflags = ldflags
self.stlib = item.data["stlib"]
- self.use = (
- item.data["use-before"] + bic.use + item.data["use-after"]
- )
+ self.use = (item.data["use-before"] + bic.use +
+ item.data["use-after"])
def run(self):
cmd = [self.cmd]
@@ -345,7 +386,8 @@ class Item(object):
[],
)
- tsk = link(self, bic, cmd, bld.env)
+ tsk = link(self, bic, cmd, bld.env,
+ bic.ldflags + self.substitute(bld, self.data["ldflags"]))
tsk.set_inputs([bld.bldnode.make_node(s) for s in source])
tsk.set_outputs(bld.bldnode.make_node(target))
bld.add_to_group(tsk)
@@ -361,6 +403,7 @@ class Item(object):
from waflib.Task import Task
class gnatmake(Task):
+
def __init__(self, bld, bic, objdir, objs, main, target, item):
super(gnatmake, self).__init__(self, env=bld.env)
self.objdir = objdir
@@ -375,9 +418,8 @@ class Item(object):
self.adaincludes.append(bld.path.make_node(i))
self.ldflags = bic.ldflags + item.data["ldflags"]
self.stlib = item.data["stlib"]
- self.use = (
- item.data["use-before"] + bic.use + item.data["use-after"]
- )
+ self.use = (item.data["use-before"] + bic.use +
+ item.data["use-after"])
def run(self):
cwd = self.get_cwd()
@@ -421,12 +463,14 @@ class Item(object):
return target
def ar(self, bld, source, target):
- bld(rule="${AR} ${ARFLAGS} ${TGT} ${SRC}", source=source, target=target)
+ bld(rule="${AR} ${ARFLAGS} ${TGT} ${SRC}",
+ source=source,
+ target=target)
return target
def gzip(self, bld, source):
target = source + ".gz"
- bld(rule="${GZIP} < ${SRC} > ${TGT}", source=source, target=target)
+ bld(rule="${GZIP} -n < ${SRC} > ${TGT}", source=source, target=target)
return target
def xz(self, bld, source):
@@ -435,12 +479,13 @@ class Item(object):
return target
def tar(self, bld, source, remove, target):
+
def run(task):
import tarfile
- tar = tarfile.TarFile(
- task.outputs[0].abspath(), "w", format=tarfile.USTAR_FORMAT
- )
+ tar = tarfile.TarFile(task.outputs[0].abspath(),
+ "w",
+ format=tarfile.USTAR_FORMAT)
srcpath = bld.path.abspath() + "/"
bldpath = bld.bldnode.abspath() + "/"
for src in task.inputs:
@@ -448,7 +493,7 @@ class Item(object):
dst = src
for r in remove:
dst = src.replace(srcpath + r, "").replace(bldpath + r, "")
- tar.add(src, dst)
+ tar.add(src, dst, filter=make_tar_info_reproducible)
tar.close()
return 0
@@ -456,6 +501,7 @@ class Item(object):
return target
def bin2c(self, bld, source, name=None, target=None):
+
def run(task):
cmd = [bld.env.BIN2C[0]]
if name is not None:
@@ -481,6 +527,7 @@ class Item(object):
return target
def rtems_rap(self, bld, base, objects, libs, target):
+
def run(task):
cmd = [
bld.env.RTEMS_LD[0],
@@ -507,14 +554,18 @@ class Item(object):
class GroupItem(Item):
+
def __init__(self, uid, data):
super(GroupItem, self).__init__(uid, data)
def prepare_build(self, bld, bic):
return BuildItemContext(
- bic.includes + self.get_values(bld, "includes"),
+ bic.includes + self.substitute(bld, self.data["includes"]),
+ bic.cppflags + self.substitute(bld, self.data["cppflags"]),
+ bic.cflags + self.substitute(bld, self.data["cflags"]),
+ bic.cxxflags + self.substitute(bld, self.data["cxxflags"]),
self.data["use-before"] + bic.use + self.data["use-after"],
- bic.ldflags + self.get_values(bld, "ldflags"),
+ bic.ldflags + self.substitute(bld, self.data["ldflags"]),
bic.objects,
)
@@ -523,14 +574,14 @@ class GroupItem(Item):
class ConfigFileItem(Item):
+
def __init__(self, uid, data):
super(ConfigFileItem, self).__init__(uid, data)
def do_configure(self, conf, cic):
content = self.substitute(conf, self.data["content"])
- f = conf.bldnode.make_node(
- conf.env.VARIANT + "/" + self.get(conf, "target")
- )
+ f = conf.bldnode.make_node(conf.env.VARIANT + "/" +
+ self.get(conf, "target"))
f.parent.mkdir()
f.write(content)
conf.env.append_value("cfg_files", f.abspath())
@@ -540,6 +591,7 @@ class ConfigFileItem(Item):
class ConfigHeaderItem(Item):
+
def __init__(self, uid, data):
super(ConfigHeaderItem, self).__init__(uid, data)
@@ -557,6 +609,7 @@ class ConfigHeaderItem(Item):
class StartFileItem(Item):
+
def __init__(self, uid, data):
super(StartFileItem, self).__init__(uid, data)
@@ -575,16 +628,28 @@ class StartFileItem(Item):
class ObjectsItem(Item):
+
def __init__(self, uid, data):
super(ObjectsItem, self).__init__(uid, data)
+ def prepare_build(self, bld, bic):
+ return BuildItemContext(
+ bic.includes + self.substitute(bld, self.data["includes"]),
+ bic.cppflags + self.substitute(bld, self.data["cppflags"]),
+ bic.cflags + self.substitute(bld, self.data["cflags"]),
+ bic.cxxflags + self.substitute(bld, self.data["cxxflags"]),
+ bic.use,
+ bic.ldflags,
+ bic.objects,
+ )
+
def do_build(self, bld, bic):
bld.objects(
- asflags=self.substitute(bld, self.data["cppflags"]),
- cflags=self.substitute(bld, self.data["cflags"]),
- cppflags=self.substitute(bld, self.data["cppflags"]),
- cxxflags=self.substitute(bld, self.data["cxxflags"]),
- includes=bic.includes + self.substitute(bld, self.data["includes"]),
+ asflags=bic.cppflags,
+ cflags=bic.cflags,
+ cppflags=bic.cppflags,
+ cxxflags=bic.cxxflags,
+ includes=bic.includes,
source=self.data["source"],
target=self.uid,
)
@@ -593,6 +658,7 @@ class ObjectsItem(Item):
class BSPItem(Item):
+
def __init__(self, uid, data):
super(BSPItem, self).__init__(uid, data)
arch_bsps = bsps.setdefault(data["arch"].strip(), {})
@@ -600,15 +666,22 @@ class BSPItem(Item):
def prepare_build(self, bld, bic):
return BuildItemContext(
- bic.includes + bld.env.BSP_INCLUDES.split(), [], [], []
+ bic.includes + bld.env.BSP_INCLUDES +
+ self.substitute(bld, self.data["includes"]),
+ self.substitute(bld, self.data["cppflags"]),
+ bld.env.BSP_CFLAGS + self.substitute(bld, self.data["cflags"]),
+ [],
+ [],
+ [],
+ [],
)
def do_build(self, bld, bic):
bld(
- cflags=self.substitute(bld, self.data["cflags"]),
- cppflags=self.substitute(bld, self.data["cppflags"]),
+ cflags=bic.cflags,
+ cppflags=bic.cppflags,
features="c cstlib",
- includes=bic.includes + self.substitute(bld, self.data["includes"]),
+ includes=bic.includes,
install_path="${BSP_LIBDIR}",
source=self.data["source"],
target="rtemsbsp",
@@ -618,19 +691,28 @@ class BSPItem(Item):
class LibraryItem(Item):
+
def __init__(self, uid, data):
super(LibraryItem, self).__init__(uid, data)
def prepare_build(self, bld, bic):
- return BuildItemContext(bic.includes, [], [], [])
+ return BuildItemContext(
+ bic.includes + self.substitute(bld, self.data["includes"]),
+ bic.cppflags + self.substitute(bld, self.data["cppflags"]),
+ bic.cflags + self.substitute(bld, self.data["cflags"]),
+ bic.cxxflags + self.substitute(bld, self.data["cxxflags"]),
+ bic.use,
+ bic.ldflags,
+ [],
+ )
def do_build(self, bld, bic):
bld(
- cflags=self.substitute(bld, self.data["cflags"]),
- cppflags=self.substitute(bld, self.data["cppflags"]),
- cxxflags=self.substitute(bld, self.data["cxxflags"]),
+ cflags=bic.cflags,
+ cppflags=bic.cppflags,
+ cxxflags=bic.cxxflags,
features="c cxx cstlib",
- includes=bic.includes + self.substitute(bld, self.data["includes"]),
+ includes=bic.includes,
install_path=self.data["install-path"],
source=self.data["source"],
target=self.get(bld, "target"),
@@ -640,6 +722,7 @@ class LibraryItem(Item):
class TestProgramItem(Item):
+
def __init__(self, uid, data):
super(TestProgramItem, self).__init__(uid, data)
name = uid.split("/")[-1].upper().replace("-", "_")
@@ -650,26 +733,36 @@ class TestProgramItem(Item):
return [{"and": [{"not": self.exclude}, self.data["enabled-by"]]}]
def prepare_build(self, bld, bic):
- return BuildItemContext(bic.includes, bic.use, bic.ldflags, [])
+ return BuildItemContext(
+ bic.includes + self.substitute(bld, self.data["includes"]),
+ bic.cppflags + bld.env[self.cppflags] +
+ self.substitute(bld, self.data["cppflags"]),
+ bic.cflags + self.substitute(bld, self.data["cflags"]),
+ bic.cxxflags + self.substitute(bld, self.data["cxxflags"]),
+ self.data["use-before"] + bic.use + self.data["use-after"],
+ bic.ldflags + self.substitute(bld, self.data["ldflags"]),
+ [],
+ )
def do_build(self, bld, bic):
bld(
- cflags=self.substitute(bld, self.data["cflags"]),
- cppflags=bld.env[self.cppflags] + self.substitute(bld, self.data["cppflags"]),
- cxxflags=self.substitute(bld, self.data["cxxflags"]),
+ cflags=bic.cflags,
+ cppflags=bic.cppflags,
+ cxxflags=bic.cxxflags,
features=self.data["features"],
- includes=bic.includes + self.substitute(bld, self.data["includes"]),
+ includes=bic.includes,
install_path=None,
- ldflags=bic.ldflags + self.substitute(bld, self.data["ldflags"]),
+ ldflags=bic.ldflags,
source=self.data["source"],
start_files=True,
stlib=self.data["stlib"],
target=self.get(bld, "target"),
- use=bic.objects + self.data["use-before"] + bic.use + self.data["use-after"],
+ use=bic.objects + bic.use,
)
class AdaTestProgramItem(TestProgramItem):
+
def __init__(self, uid, data):
super(AdaTestProgramItem, self).__init__(uid, data)
@@ -688,28 +781,16 @@ class AdaTestProgramItem(TestProgramItem):
class OptionItem(Item):
+
def __init__(self, uid, data):
super(OptionItem, self).__init__(uid, data)
- @staticmethod
- def _is_variant(variants, variant):
- for pattern in variants:
- if re.match(pattern + "$", variant):
- return True
- return False
-
- def default_value(self, variant, family):
- value = self.data["default"]
- for default in self.data["default-by-variant"]:
- if OptionItem._is_variant(default["variants"], variant):
+ def default_value(self, enabled):
+ value = None
+ for default in self.data["default"]:
+ if _is_enabled(enabled, default["enabled-by"]):
value = default["value"]
break
- else:
- family = "bsps/" + family
- for default in self.data["default-by-variant"]:
- if OptionItem._is_variant(default["variants"], family):
- value = default["value"]
- break
if value is None:
return value
if isinstance(value, list):
@@ -718,8 +799,8 @@ class OptionItem(Item):
return value
return self.data["format"].format(value)
- def do_defaults(self, variant, family):
- value = self.default_value(variant, family)
+ def do_defaults(self, enabled):
+ value = self.default_value(enabled)
if value is None:
return
description = self.data["description"]
@@ -736,56 +817,51 @@ class OptionItem(Item):
def _do_append_test_cppflags(self, conf, name, state):
conf.env.append_value(
- "TEST_" + name.upper().replace("-", "_") + "_CPPFLAGS", state
- )
+ "TEST_" + name.upper().replace("-", "_") + "_CPPFLAGS", state)
def _append_test_cppflags(self, conf, cic, value, arg):
self._do_append_test_cppflags(conf, arg, value)
return value
def _assert_aligned(self, conf, cic, value, arg):
- if value % arg != 0:
+ if value is not None and value % arg != 0:
conf.fatal(
"Value '{}' for option '{}' is not aligned by '{}'".format(
- value, self.data["name"], arg
- )
- )
+ value, self.data["name"], arg))
return value
def _assert_eq(self, conf, cic, value, arg):
- if value != arg:
- conf.fatal(
- "Value '{}' for option '{}' is not equal to {}".format(
- value, self.data["name"], arg
- )
- )
+ if value is not None and value != arg:
+ conf.fatal("Value '{}' for option '{}' is not equal to {}".format(
+ value, self.data["name"], arg))
return value
def _assert_ge(self, conf, cic, value, arg):
- if value < arg:
+ if value is not None and value < arg:
conf.fatal(
- "Value '{}' for option '{}' is not greater than or equal to {}".format(
- value, self.data["name"], arg
- )
- )
+ "Value '{}' for option '{}' is not greater than or equal to {}"
+ .format(value, self.data["name"], arg))
return value
def _assert_gt(self, conf, cic, value, arg):
- if value <= arg:
+ if value is not None and value <= arg:
conf.fatal(
"Value '{}' for option '{}' is not greater than {}".format(
- value, self.data["name"], arg
- )
- )
+ value, self.data["name"], arg))
+ return value
+
+ def _assert_in_set(self, conf, cic, value, arg):
+ if value is not None and value not in arg:
+ conf.fatal(
+ "Value '{}' for option '{}' is not an element of {}"
+ .format(value, self.data["name"], arg))
return value
def _assert_in_interval(self, conf, cic, value, arg):
- if value < arg[0] or value > arg[1]:
+ if value is not None and (value < arg[0] or value > arg[1]):
conf.fatal(
- "Value '{}' for option '{}' is not in closed interval [{}, {}]".format(
- value, self.data["name"], arg[0], arg[1]
- )
- )
+ "Value '{}' for option '{}' is not in closed interval [{}, {}]"
+ .format(value, self.data["name"], arg[0], arg[1]))
return value
def _assert_int8(self, conf, cic, value, arg):
@@ -795,49 +871,38 @@ class OptionItem(Item):
return self._assert_in_interval(conf, cic, value, [-32768, 32767])
def _assert_int32(self, conf, cic, value, arg):
- return self._assert_in_interval(
- conf, cic, value, [-2147483648, 2147483647]
- )
+ return self._assert_in_interval(conf, cic, value,
+ [-2147483648, 2147483647])
def _assert_int64(self, conf, cic, value, arg):
return self._assert_in_interval(
- conf, cic, value, [-9223372036854775808, 9223372036854775807]
- )
+ conf, cic, value, [-9223372036854775808, 9223372036854775807])
def _assert_le(self, conf, cic, value, arg):
- if value > arg:
+ if value is not None and value > arg:
conf.fatal(
- "Value '{}' for option '{}' is not less than or equal to {}".format(
- value, self.data["name"], arg
- )
- )
+ "Value '{}' for option '{}' is not less than or equal to {}".
+ format(value, self.data["name"], arg))
return value
def _assert_lt(self, conf, cic, value, arg):
- if value >= arg:
- conf.fatal(
- "Value '{}' for option '{}' is not less than {}".format(
- value, self.data["name"], arg
- )
- )
+ if value is not None and value >= arg:
+ conf.fatal("Value '{}' for option '{}' is not less than {}".format(
+ value, self.data["name"], arg))
return value
def _assert_ne(self, conf, cic, value, arg):
- if value == arg:
+ if value is not None and value == arg:
conf.fatal(
"Value '{}' for option '{}' is not unequal to {}".format(
- value, self.data["name"], arg
- )
- )
+ value, self.data["name"], arg))
return value
def _assert_power_of_two(self, conf, cic, value, arg):
- if value <= 0 or (value & (value - 1)) != 0:
+ if value is not None and (value <= 0 or (value & (value - 1)) != 0):
conf.fatal(
"Value '{}' for option '{}' is not a power of two".format(
- value, self.data["name"]
- )
- )
+ value, self.data["name"]))
return value
def _assert_uint8(self, conf, cic, value, arg):
@@ -850,9 +915,8 @@ class OptionItem(Item):
return self._assert_in_interval(conf, cic, value, [0, 4294967295])
def _assert_uint64(self, conf, cic, value, arg):
- return self._assert_in_interval(
- conf, cic, value, [0, 18446744073709551615]
- )
+ return self._assert_in_interval(conf, cic, value,
+ [0, 18446744073709551615])
def _check_cc(self, conf, cic, value, arg):
result = conf.check_cc(
@@ -926,11 +990,10 @@ class OptionItem(Item):
value = cic.cp.getboolean(conf.variant, name)
cic.add_option(name)
except configparser.NoOptionError:
- value = self.default_value(conf.env.ARCH_BSP, conf.env.ARCH_FAMILY)
+ value = self.default_value(conf.env.ENABLE)
except ValueError as ve:
- conf.fatal(
- "Invalid value for configuration option {}: {}".format(name, ve)
- )
+ conf.fatal("Invalid value for configuration option {}: {}".format(
+ name, ve))
return value
def _get_env(self, conf, cic, value, arg):
@@ -942,17 +1005,15 @@ class OptionItem(Item):
value = cic.cp.get(conf.variant, name)
cic.add_option(name)
except configparser.NoOptionError:
- value = self.default_value(conf.env.ARCH_BSP, conf.env.ARCH_FAMILY)
- if value is None:
- return value
+ value = self.default_value(conf.env.ENABLE)
+ if not value:
+ return None
try:
return eval(value)
except Exception as e:
conf.fatal(
- "Value '{}' for option '{}' is an invalid integer expression: {}".format(
- value, name, e
- )
- )
+ "Value '{}' for option '{}' is an invalid integer expression: {}"
+ .format(value, name, e))
def _get_string(self, conf, cic, value, arg):
name = self.data["name"]
@@ -961,39 +1022,33 @@ class OptionItem(Item):
cic.add_option(name)
value = no_unicode(value)
except configparser.NoOptionError:
- value = self.default_value(conf.env.ARCH_BSP, conf.env.ARCH_FAMILY)
- return value
-
- def _get_string_command_line(self, conf, cic, value, arg):
- name = self.data["name"]
- try:
- value = conf.rtems_options[name]
- del conf.rtems_options[name]
- except KeyError:
- value = arg[0]
+ value = self.default_value(conf.env.ENABLE)
return value
def _script(self, conf, cic, value, arg):
- exec(arg)
- return value
+ local_variables = {
+ "self": self,
+ "conf": conf,
+ "cic": cic,
+ "value": value
+ }
+ exec(arg, None, local_variables)
+ return local_variables["value"]
def _test_state_benchmark(self, conf, name):
self._do_append_test_cppflags(conf, name, "-DTEST_STATE_BENCHMARK=1")
def _test_state_exclude(self, conf, name):
conf.env.append_value(
- "ENABLE", "TEST_" + name.upper().replace("-", "_") + "_EXCLUDE"
- )
+ "ENABLE", "TEST_" + name.upper().replace("-", "_") + "_EXCLUDE")
def _test_state_expected_fail(self, conf, name):
- self._do_append_test_cppflags(
- conf, name, "-DTEST_STATE_EXPECTED_FAIL=1"
- )
+ self._do_append_test_cppflags(conf, name,
+ "-DTEST_STATE_EXPECTED_FAIL=1")
def _test_state_indeterminate(self, conf, name):
- self._do_append_test_cppflags(
- conf, name, "-DTEST_STATE_INDETERMINATE=1"
- )
+ self._do_append_test_cppflags(conf, name,
+ "-DTEST_STATE_INDETERMINATE=1")
def _test_state_user_input(self, conf, name):
self._do_append_test_cppflags(conf, name, "-DTEST_STATE_USER_INPUT=1")
@@ -1006,8 +1061,9 @@ class OptionItem(Item):
"indeterminate": self._test_state_indeterminate,
"user-input": self._test_state_user_input,
}
- for k, v in arg.items():
- actions[v](conf, k)
+ action = actions[arg["state"]]
+ for test in arg["tests"]:
+ action(conf, test)
return value
def _set_value(self, conf, cic, value, arg):
@@ -1029,6 +1085,7 @@ class OptionItem(Item):
"assert-eq": self._assert_eq,
"assert-ge": self._assert_ge,
"assert-gt": self._assert_gt,
+ "assert-in-set": self._assert_in_set,
"assert-int8": self._assert_int8,
"assert-int16": self._assert_int16,
"assert-int32": self._assert_int32,
@@ -1055,7 +1112,6 @@ class OptionItem(Item):
"get-env": self._get_env,
"get-integer": self._get_integer,
"get-string": self._get_string,
- "get-string-command-line": self._get_string_command_line,
"script": self._script,
"set-test-state": self._set_test_state,
"set-value": self._set_value,
@@ -1069,6 +1125,7 @@ class OptionItem(Item):
class ScriptItem(Item):
+
def __init__(self, uid, data):
super(ScriptItem, self).__init__(uid, data)
@@ -1095,6 +1152,7 @@ class ScriptItem(Item):
class ConfigItemContext(object):
+
def __init__(self, cp, path_list):
self.cp = cp
self.options = set()
@@ -1105,8 +1163,13 @@ class ConfigItemContext(object):
class BuildItemContext(object):
- def __init__(self, includes, use, ldflags, objects):
+
+ def __init__(self, includes, cppflags, cflags, cxxflags, use, ldflags,
+ objects):
self.includes = includes
+ self.cppflags = cppflags
+ self.cflags = cflags
+ self.cxxflags = cxxflags
self.use = use
self.ldflags = ldflags
self.objects = objects
@@ -1237,74 +1300,81 @@ def options(ctx):
rg.add_option(
"--rtems-bsps",
metavar="REGEX,...",
- help="a comma-separated list of Python regular expressions which select the desired BSP variants (e.g. 'sparc/erc32'); it may be used in the bsp_defaults and bsp_list commands",
+ help=
+ "a comma-separated list of Python regular expressions which select the desired BSP variants (e.g. 'sparc/erc32'); it may be used in the bspdefaults and bsps commands",
)
rg.add_option(
"--rtems-compiler",
metavar="COMPILER",
- help="determines which compiler is used to list the BSP option defaults [default: 'gcc']; it may be used in the bsp_defaults command; valid compilers are: {}".format(
- ", ".join(compilers)
- ),
+ help=
+ "determines which compiler is used to list the BSP option defaults [default: 'gcc']; it may be used in the bspdefaults command; valid compilers are: {}"
+ .format(", ".join(compilers)),
)
rg.add_option(
"--rtems-config",
metavar="CONFIG.INI,...",
- help="a comma-separated list of paths to the BSP configuration option files [default: 'config.ini']; default option values can be obtained via the bsp_defaults command; it may be used in the configure command",
+ help=
+ "a comma-separated list of paths to the BSP configuration option files [default: 'config.ini']; default option values can be obtained via the bspdefaults command; it may be used in the configure command",
)
rg.add_option(
"--rtems-specs",
metavar="SPECDIRS,...",
- help="a comma-separated list of directory paths to build specification items [default: 'spec/build']; it may be used in the bsp_defaults, bsp_list, and configure commands",
+ help=
+ "a comma-separated list of directory paths to build specification items [default: 'spec/build']; it may be used in the bspdefaults, bsps, and configure commands",
)
rg.add_option(
"--rtems-tools",
metavar="PREFIX,...",
- help="a comma-separated list of prefix paths to tools, e.g. compiler, linker, etc. [default: the installation prefix]; tools are searched in the prefix path and also in a 'bin' subdirectory of the prefix path; it may be used in the configure command",
+ help=
+ "a comma-separated list of prefix paths to tools, e.g. compiler, linker, etc. [default: the installation prefix]; tools are searched in the prefix path and also in a 'bin' subdirectory of the prefix path; it may be used in the configure command",
)
rg.add_option(
"--rtems-top-group",
metavar="UID",
- help="the UID of the top-level group [default: '/grp']; it may be used in the bsp_defaults and configure commands",
- )
- rg.add_option(
- "--rtems-version",
- metavar="VALUE",
- help="sets the RTEMS major version number; it is intended for RTEMS maintainers and may be used in the bsp_defaults and configure commands",
- )
- rg.add_option(
- "--rtems-option",
- metavar="KEY=VALUE",
- action="append",
- dest="rtems_options",
- default=[],
- help="sets the option identified by KEY to the VALUE in the build specification; it is intended for RTEMS maintainers and may be used in the bsp_defaults and configure commands",
+ help=
+ "the UID of the top-level group [default: '/grp']; it may be used in the bspdefaults and configure commands",
)
def check_environment(conf):
for ev in [
- "AR",
- "AS",
- "ASFLAGS",
- "CC",
- "CFLAGS",
- "CPPFLAGS",
- "CXX",
- "CXXFLAGS",
- "IFLAGS",
- "LD",
- "LIB",
- "LINK_CC",
- "LINK_CXX",
- "LINKFLAGS",
- "MFLAGS",
- "RFLAGS",
- "WFLAGS",
+ "AR",
+ "AS",
+ "ASFLAGS",
+ "CC",
+ "CFLAGS",
+ "CPPFLAGS",
+ "CXX",
+ "CXXFLAGS",
+ "IFLAGS",
+ "LD",
+ "LIB",
+ "LINK_CC",
+ "LINK_CXX",
+ "LINKFLAGS",
+ "MFLAGS",
+ "RFLAGS",
+ "WFLAGS",
]:
if ev in os.environ:
conf.msg("Environment variable set", ev, color="RED")
+def configure_version(conf):
+ cp = configparser.ConfigParser()
+ version_file = "VERSION"
+ if cp.read([version_file]):
+ conf.msg("Configure RTEMS version from file",
+ version_file,
+ color="YELLOW")
+ for key in version:
+ try:
+ value = cp.get("RTEMS_VERSION", key)
+ version[key] = no_unicode(value)
+ except configparser.NoOptionError:
+ pass
+
+
def load_config_files(ctx):
cp = configparser.ConfigParser()
files = ctx.options.rtems_config
@@ -1338,10 +1408,8 @@ def inherit(conf, cp, bsp_map, arch, bsp, path):
if not cp.has_section(base_variant):
if (not arch in bsps) or (not base in bsps[arch]):
conf.fatal(
- "BSP variant '{}' cannot inherit options from not existing variant '{}'".format(
- variant, base_variant
- )
- )
+ "BSP variant '{}' cannot inherit options from not existing variant '{}'"
+ .format(variant, base_variant))
bsp_map[bsp] = base
return base
top = inherit(conf, cp, bsp_map, arch, base, path + [variant])
@@ -1364,20 +1432,15 @@ def resolve_option_inheritance(conf, cp):
except:
conf.fatal(
"Section name '{}' is a malformed 'arch/bsp' tuple".format(
- variant
- )
- )
+ variant))
inherit(conf, cp, bsp_map, arch, bsp, [])
return bsp_map
def check_compiler(ctx, compiler):
if compiler not in compilers:
- ctx.fatal(
- "Specified compiler '{}' is not one of {}".format(
- compiler, compilers
- )
- )
+ ctx.fatal("Specified compiler '{}' is not one of {}".format(
+ compiler, compilers))
def get_compiler(conf, cp, variant):
@@ -1408,6 +1471,9 @@ def configure_variant(conf, cp, bsp_map, path_list, top_group, variant):
arch_bsp = arch + "/" + bsp_base
arch_family = arch + "/" + family
+ for key, value in version.items():
+ conf.env[key] = value
+
conf.env["ARCH"] = arch
conf.env["ARCH_BSP"] = arch_bsp
conf.env["ARCH_FAMILY"] = arch_family
@@ -1429,7 +1495,6 @@ def configure_variant(conf, cp, bsp_map, path_list, top_group, variant):
conf.env["TOPGROUP"] = top_group
conf.env["VARIANT"] = variant
- prepare_rtems_options(conf)
cic = ConfigItemContext(cp, path_list)
items[conf.env.TOPGROUP].configure(conf, cic)
bsp_item.configure(conf, cic)
@@ -1437,18 +1502,14 @@ def configure_variant(conf, cp, bsp_map, path_list, top_group, variant):
options = set([o[0].upper() for o in cp.items(variant)])
for o in options.difference(cic.options):
conf.msg("Unknown configuration option", o.upper(), color="RED")
- for key in conf.rtems_options:
- conf.msg("Unknown command line RTEMS option", key, color="RED")
def check_forbidden_options(ctx, opts):
for o in opts:
if getattr(ctx.options, "rtems_" + o):
ctx.fatal(
- "The --rtems-{} command line option is not allowed in the {} command".format(
- o.replace("_", "-"), ctx.cmd
- )
- )
+ "The --rtems-{} command line option is not allowed in the {} command"
+ .format(o.replace("_", "-"), ctx.cmd))
def get_path_list(conf):
@@ -1468,35 +1529,14 @@ def get_top_group(ctx):
top_group = "/grp"
if top_group not in items:
ctx.fatal(
- "There is no top-level group with UID '{}' in the specification".format(
- top_group
- )
- )
+ "There is no top-level group with UID '{}' in the specification".
+ format(top_group))
return top_group
-def prepare_rtems_options(conf):
- conf.rtems_options = {}
- for x in conf.options.rtems_options:
- try:
- k, v = x.split("=", 1)
- conf.rtems_options[k] = v
- except:
- conf.fatal(
- "The RTEMS option '{}' is not in KEY=VALUE format".format(x)
- )
- version = conf.options.rtems_version
- if version is not None:
- key = "__RTEMS_MAJOR__"
- if conf.rtems_options.get(key, version) != version:
- conf.fatal(
- "Conflicting RTEMS major versions specified at the command line"
- )
- conf.rtems_options[key] = version
-
-
def configure(conf):
check_forbidden_options(conf, ["compiler"])
+ configure_version(conf)
check_environment(conf)
conf.env["SPECS"] = load_items_from_options(conf)
top_group = get_top_group(conf)
@@ -1522,7 +1562,8 @@ def append_variant_builds(bld):
)
for var in bld.env["VARIANTS"]:
- for c in (BuildContext, CleanContext, InstallContext, UninstallContext):
+ for c in (BuildContext, CleanContext, InstallContext,
+ UninstallContext):
name = c.__name__.replace("Context", "").lower()
class magic(c):
@@ -1541,21 +1582,14 @@ def build(bld):
if not bld.variant:
check_forbidden_options(
bld,
- [
- "compiler",
- "config",
- "options",
- "specs",
- "tools",
- "top_group",
- "version",
- ],
+ ["compiler", "config", "specs", "tools", "top_group"],
)
load_items(bld, bld.env.SPECS)
append_variant_builds(bld)
return
long_command_line_workaround(bld)
- bic = BuildItemContext(bld.env.ARCH_INCLUDES.split(), [], [], [])
+ bic = BuildItemContext(bld.env.ARCH_INCLUDES.split(), [], [], [], [], [],
+ [])
bsps[bld.env.ARCH][bld.env.BSP_BASE].build(bld, bic)
items[bld.env.TOPGROUP].build(bld, bic)
@@ -1564,6 +1598,7 @@ def add_log_filter(name):
msg = "'" + name + "' finished successfully"
class Filter:
+
def filter(self, rec):
return not msg in rec.getMessage()
@@ -1590,16 +1625,13 @@ def is_in_white_list(variant, white_list):
def no_matches_error(ctx, white_list):
if white_list:
- ctx.fatal(
- "No BSP matches with the specified patterns: '{}'".format(
- "', '".join(white_list)
- )
- )
+ ctx.fatal("No BSP matches with the specified patterns: '{}'".format(
+ "', '".join(white_list)))
else:
ctx.fatal("The build specification contains no BSPs")
-def bsp_defaults(ctx):
+def bspdefaults(ctx):
"""get all options with default values for base BSP variants"""
check_forbidden_options(ctx, ["config", "tools"])
add_log_filter(ctx.cmd)
@@ -1619,32 +1651,27 @@ def bsp_defaults(ctx):
if not first:
print("")
first = False
- print(
- """[{}]
+ print("""[{}]
# Selects the compiler used to build the BSP (allowed values are "gcc" and
# "clang"). Please note that the values of some options depend on the compiler
# selection and changing the compiler may lead to unpredictable behaviour if
# these options are not adjusted as well. Use the --rtems-compiler command line
# option to get the default values for a particular compiler via
-# ./waf bsp_defaults.
-COMPILER = {}""".format(
- variant, compiler
- )
- )
+# ./waf bspdefaults.
+COMPILER = {}""".format(variant, compiler))
enable = [compiler, arch, variant]
bsp_item = bsps[arch][bsp]
- family = arch + "/" + bsp_item.data["family"]
- items[top_group].defaults(enable, variant, family)
- bsp_item.defaults(enable, variant, family)
+ family = "bsps/" + arch + "/" + bsp_item.data["family"]
+ enabled = [compiler, arch, family, variant]
+ items[top_group].defaults(enabled)
+ bsp_item.defaults(enabled)
if first:
no_matches_error(ctx, white_list)
-def bsp_list(ctx):
+def bsplist(ctx):
"""lists base BSP variants"""
- check_forbidden_options(
- ctx, ["compiler", "config", "options", "tools", "top_group", "version"]
- )
+ check_forbidden_options(ctx, ["compiler", "config", "tools", "top_group"])
add_log_filter(ctx.cmd)
load_items_from_options(ctx)
white_list = get_white_list(ctx)