summaryrefslogtreecommitdiffhomepage
path: root/digital/ucoolib/build
diff options
context:
space:
mode:
Diffstat (limited to 'digital/ucoolib/build')
-rw-r--r--digital/ucoolib/build/config.mk3
-rwxr-xr-xdigital/ucoolib/build/tools/config-gen85
-rw-r--r--digital/ucoolib/build/tools/test/Config-nok-badtarget5
-rw-r--r--digital/ucoolib/build/tools/test/Config-nok-missdefault2
-rw-r--r--digital/ucoolib/build/tools/test/Config-nok-nodefault2
-rw-r--r--digital/ucoolib/build/tools/test/Config-nok-toomany8
-rw-r--r--digital/ucoolib/build/tools/test/Config-nok-unknown2
-rw-r--r--digital/ucoolib/build/tools/test/Config-ok5
-rw-r--r--digital/ucoolib/build/tools/test/Makefile16
-rw-r--r--digital/ucoolib/build/tools/test/a-Config3
-rw-r--r--digital/ucoolib/build/tools/test/b-Config2
-rw-r--r--digital/ucoolib/build/top.mk3
12 files changed, 124 insertions, 12 deletions
diff --git a/digital/ucoolib/build/config.mk b/digital/ucoolib/build/config.mk
index cdffc16e..ff3fa568 100644
--- a/digital/ucoolib/build/config.mk
+++ b/digital/ucoolib/build/config.mk
@@ -28,7 +28,8 @@ clean: config-clean
$(OBJDIR)/config.list: $(CONFIG_LIST) $(CONFIG_FORCE) | $(OBJDIR)
@echo "CONF $(PROJECT_CONFIG)"
$Q$(BASE)/build/tools/config-gen -H $(OBJDIR)/config/%.hh \
- -p $(PROJECT_CONFIG) $(MODULES_CONFIG)
+ -p $(PROJECT_CONFIG) -T '$(TARGETS_SUBTARGETS)' \
+ $(MODULES_CONFIG)
$Qecho "CONFIG_LIST_OLD = $(CONFIG_LIST)" > $@
config-clean:
diff --git a/digital/ucoolib/build/tools/config-gen b/digital/ucoolib/build/tools/config-gen
index 3feffbe8..9bc578bc 100755
--- a/digital/ucoolib/build/tools/config-gen
+++ b/digital/ucoolib/build/tools/config-gen
@@ -2,6 +2,7 @@
"""Read build configuration and generate header files."""
import optparse
import ConfigParser
+import collections
import sys
import re
import os
@@ -21,7 +22,7 @@ def read_config(modules_configs, project_config):
parser.readfp(mcf)
# Save the list of existing items for later check.
def config_items(parser):
- return set('%s:%s' % (section, item)
+ return set('%s:%s' % (section.split(':')[0], item)
for section in parser.sections()
for item in parser.options(section))
modules_items = config_items(parser)
@@ -40,24 +41,81 @@ def read_config(modules_configs, project_config):
if unknown_items:
raise RuntimeError("unknown configuration item: "
+ " ".join(unknown_items))
- # Check for items with no default value.
- for section in parser.sections():
- for key, value in parser.items(section):
- if value == '':
+ # OK, convert to more natural structure.
+ config = collections.defaultdict (lambda: collections.defaultdict(dict))
+ for section in parser.sections():
+ items = parser.items(section)
+ if ':' in section:
+ section, target = section.split(':', 1)
+ else:
+ target = None
+ for k, v in items:
+ config[section][k][target] = v
+ return config
+
+def check_config(config, targets, subtargets):
+ """Run consistency checks on configuration."""
+ for section, section_dict in config.iteritems():
+ for key, values in section_dict.iteritems():
+ # Check targets.
+ for ts in values:
+ if ts is not None and ts not in subtargets:
+ raise RuntimeError("unknown target %s" % ts)
+ values_targets = reduce(lambda a, b: a + b, (subtargets[ts]
+ for ts in values if ts is not None), [ ])
+ values_targets_set = set(values_targets)
+ # Check for items with no default value.
+ if values[None] == '':
+ if not values_targets:
raise RuntimeError("no value given for %s:%s"
% (section, key))
- # OK, convert to more natural structure.
- return dict((section, parser.items(section))
- for section in parser.sections())
+ else:
+ if values_targets_set < targets:
+ raise RuntimeError("no value given for %s:%s for"
+ " targets: %s" % (section, key,
+ ', '.join (targets - values_targets_set)))
+ # Check for items overridden several times for the same target.
+ if len(values_targets) != len(values_targets_set):
+ raise RuntimeError("several values given for %s:%s for the"
+ " same target" % (section, key))
+
+def parse_targets(targets_option):
+ """Parse a space separated target:subtarget list. Return a set of
+ targets, and a mapping of each subtarget to a list of target."""
+ if targets_option is None:
+ targets_option = ''
+ targets = set()
+ subtargets = collections.defaultdict(list)
+ for tpair in targets_option.split():
+ tpairl = tpair.split(':')
+ if len(tpairl) != 2:
+ raise RuntimeError("bad target:subtarget pair %s" % tpair)
+ target, subtarget = tpairl
+ targets.add(target)
+ subtargets[subtarget].append(target)
+ return targets, dict(subtargets)
def write_header(filename, section, section_dict):
"""Write (update) a section to a C header file."""
# Prepare new content.
items = [ ]
section = section.replace('/', '_').upper()
- for key, value in section_dict:
- items.append('#define UCOO_CONFIG_%s_%s (%s)'
- % (section, key.upper(), value))
+ for key, values in section_dict.iteritems():
+ cond = False
+ for target, value in values.iteritems():
+ if target is None: continue
+ item_fmt = ('#ifdef TARGET_{target}\n'
+ '# define UCOO_CONFIG_{section}_{key} ({value})\n'
+ '#endif')
+ items.append(item_fmt.format(section=section, key=key.upper(),
+ target=target, value=value))
+ cond = True
+ item_fmt = '#define UCOO_CONFIG_{section}_{key} ({value})'
+ if cond:
+ item_fmt = '#ifndef UCOO_CONFIG_{section}_{key}\n# ' \
+ + item_fmt[1:] + '\n#endif'
+ items.append(item_fmt.format(section=section, key=key.upper(),
+ value=values[None]))
guard = re.sub(r'\W', '_', filename)
content = '\n'.join([
'#ifndef %s' % guard,
@@ -99,10 +157,15 @@ if __name__ == '__main__':
parser.add_option('-H', '--c-header-template', metavar='TEMPLATE',
help="name template for C header files"
+ " (use % as section placeholder)")
+ parser.add_option('-T', '--targets', metavar='"LIST"',
+ help="space separated list of target:subtarget pairs (used for"
+ + " error checking)")
options, modules_configs = parser.parse_args()
try:
+ targets, subtargets = parse_targets(options.targets)
config = read_config(modules_configs, options.project_config)
+ check_config(config, targets, subtargets)
if options.c_header_template:
write_headers(options.c_header_template, config)
except RuntimeError, e:
diff --git a/digital/ucoolib/build/tools/test/Config-nok-badtarget b/digital/ucoolib/build/tools/test/Config-nok-badtarget
new file mode 100644
index 00000000..d3aef600
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/Config-nok-badtarget
@@ -0,0 +1,5 @@
+[a]
+bar = 2
+
+[a:plop]
+bar = 3
diff --git a/digital/ucoolib/build/tools/test/Config-nok-missdefault b/digital/ucoolib/build/tools/test/Config-nok-missdefault
new file mode 100644
index 00000000..fb2bc0bf
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/Config-nok-missdefault
@@ -0,0 +1,2 @@
+[a:host]
+bar = 2
diff --git a/digital/ucoolib/build/tools/test/Config-nok-nodefault b/digital/ucoolib/build/tools/test/Config-nok-nodefault
new file mode 100644
index 00000000..384ce663
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/Config-nok-nodefault
@@ -0,0 +1,2 @@
+[a]
+foo = 2
diff --git a/digital/ucoolib/build/tools/test/Config-nok-toomany b/digital/ucoolib/build/tools/test/Config-nok-toomany
new file mode 100644
index 00000000..13549e94
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/Config-nok-toomany
@@ -0,0 +1,8 @@
+[a]
+bar = 2
+
+[a:stm32f4]
+bar = 3
+
+[a:arm]
+bar = 4
diff --git a/digital/ucoolib/build/tools/test/Config-nok-unknown b/digital/ucoolib/build/tools/test/Config-nok-unknown
new file mode 100644
index 00000000..7df223d7
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/Config-nok-unknown
@@ -0,0 +1,2 @@
+[a]
+bazar = 2
diff --git a/digital/ucoolib/build/tools/test/Config-ok b/digital/ucoolib/build/tools/test/Config-ok
new file mode 100644
index 00000000..19b46141
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/Config-ok
@@ -0,0 +1,5 @@
+[a]
+bar = 2
+
+[a:host]
+bar = 3
diff --git a/digital/ucoolib/build/tools/test/Makefile b/digital/ucoolib/build/tools/test/Makefile
new file mode 100644
index 00000000..59bd2da0
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/Makefile
@@ -0,0 +1,16 @@
+CONFIG_GEN = ../config-gen
+MODULES_CONFIG = a-Config b-Config
+
+TARGETS := host:host stm32f4:stm32f4 stm32f4:arm
+
+TESTS = ok nok-unknown nok-nodefault nok-missdefault nok-toomany nok-badtarget
+
+all: $(TESTS:%=test-%)
+
+test-%: Config-% $(MODULES_CONFIG) $(CONFIG_GEN)
+ expect=$(if $(filter ok,$*),0,1); \
+ $(CONFIG_GEN) -p $< -H out-$*/%.hh -T "$(TARGETS)" $(MODULES_CONFIG); \
+ test $$expect -eq $$?
+
+clean:
+ rm -rf $(TESTS:%=out-%)
diff --git a/digital/ucoolib/build/tools/test/a-Config b/digital/ucoolib/build/tools/test/a-Config
new file mode 100644
index 00000000..ed66ccc4
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/a-Config
@@ -0,0 +1,3 @@
+[a]
+foo = 1
+bar =
diff --git a/digital/ucoolib/build/tools/test/b-Config b/digital/ucoolib/build/tools/test/b-Config
new file mode 100644
index 00000000..b0bb7535
--- /dev/null
+++ b/digital/ucoolib/build/tools/test/b-Config
@@ -0,0 +1,2 @@
+[b]
+foobar = "hello"
diff --git a/digital/ucoolib/build/top.mk b/digital/ucoolib/build/top.mk
index a944b2c7..71fe1be0 100644
--- a/digital/ucoolib/build/top.mk
+++ b/digital/ucoolib/build/top.mk
@@ -63,3 +63,6 @@ define TARGETS_template
include $$(BASE)/build/$1.mk
endef
$(foreach target,$(TARGETS),$(eval $(call TARGETS_template,$(target))))
+
+TARGETS_SUBTARGETS := $(foreach target,$(TARGETS),$(target):$(target) \
+ $(foreach subtarget,$($(target)_SUBTARGETS),$(target):$(subtarget)))