From 6f1298b02b5f691ed4a9446121d7ea458b353231 Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Fri, 3 Jun 2016 12:54:04 +0300 Subject: [PATCH] Added support for viewing the configuration get_config.py can be used to view the configuration of the mbed project that's being compiled: - without '-v' it displays a simple list of configuration parameters and their values - with '-v' it displays additional data for each configuration parameter (like the place of definition and the last place that set a value for the configuration parameter). Tested by running "get_config.py" on a few tests from tools/test/config_test. --- tools/config.py | 25 +++++++++++- tools/get_config.py | 94 +++++++++++++++++++++++++++++++++++++++++++++ tools/options.py | 12 +++--- 3 files changed, 124 insertions(+), 7 deletions(-) create mode 100755 tools/get_config.py diff --git a/tools/config.py b/tools/config.py index 46cb42a1a1..a152e62cd1 100644 --- a/tools/config.py +++ b/tools/config.py @@ -103,7 +103,22 @@ class ConfigParameter: # Return the string representation of this configuration parameter def __str__(self): - return '"%s" = %s (set in "%s", defined in "%s")' % (self.name, self.value, self.set_by, self.defined_by) + if self.value is not None: + return '%s = %s (macro name: "%s")' % (self.name, self.value, self.macro_name) + else: + return '%s has no value' % self.name + + # Return a verbose description of this configuration paramater as a string + def get_verbose_description(self): + desc = "Name: %s%s\n" % (self.name, " (required parameter)" if self.required else "") + if self.help_text: + desc += " Description: %s\n" % self.help_text + desc += " Defined by: %s\n" % self.defined_by + if not self.value: + return desc + " No value set" + desc += " Macro name: %s\n" % self.macro_name + desc += " Value: %s (set by %s)" % (self.value, self.set_by) + return desc # A representation of a configuration macro. It handles both macros without a value (MACRO) # and with a value (MACRO=VALUE) @@ -297,8 +312,14 @@ class Config: if p.required and (p.value is None): raise ConfigException("Required parameter '%s' defined by '%s' doesn't have a value" % (p.name, p.defined_by)) + # Return the macro definitions generated for a dictionary of configuration parameters + # params: a dictionary of (name, ConfigParameters instance) mappings + @staticmethod + def parameters_to_macros(params): + return ['%s=%s' % (m.macro_name, m.value) for m in params.values() if m.value is not None] + # Return the configuration data converted to a list of C macros def get_config_data_macros(self): params, macros = self.get_config_data() self._check_required_parameters(params) - return macros + ['%s=%s' % (m.macro_name, m.value) for m in params.values() if m.value is not None] + return macros + self.parameters_to_macros(params) diff --git a/tools/get_config.py b/tools/get_config.py new file mode 100755 index 0000000000..6d8af83817 --- /dev/null +++ b/tools/get_config.py @@ -0,0 +1,94 @@ +#! /usr/bin/env python2 +""" +mbed SDK +Copyright (c) 2011-2013 ARM Limited + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +""" +import sys +from os.path import isdir, abspath, dirname, join +from os import _exit + +# Be sure that the tools directory is in the search path +ROOT = abspath(join(dirname(__file__), "..")) +sys.path.insert(0, ROOT) + +from tools.utils import args_error +from tools.options import get_default_options_parser +from tools.build_api import get_config +from config import Config +try: + import tools.private_settings as ps +except: + ps = object() + +if __name__ == '__main__': + # Parse Options + parser = get_default_options_parser(add_clean=False, add_options=False) + parser.add_option("--source", dest="source_dir", + default=None, help="The source (input) directory", action="append") + parser.add_option("--prefix", dest="prefix", action="append", + default=None, help="Restrict listing to parameters that have this prefix") + parser.add_option("-v", "--verbose", action="store_true", dest="verbose", + default=False, help="Verbose diagnostic output") + + (options, args) = parser.parse_args() + + for path in options.source_dir : + if not isdir(path) : + args_error(parser, "[ERROR] you passed \"{}\" to --source, which does not exist". + format(path)) + # Target + if options.mcu is None : + args_error(parser, "[ERROR] You should specify an MCU") + target = options.mcu + + # Toolchain + if options.tool is None: + args_error(parser, "[ERROR] You should specify a TOOLCHAIN") + toolchain = options.tool + + options.prefix = options.prefix or [""] + + try: + params, macros = get_config(options.source_dir, target, toolchain) + if not params and not macros: + print "No configuration data available." + _exit(0) + if params: + print "Configuration parameters" + print "------------------------" + for p in params: + for s in options.prefix: + if p.startswith(s): + print(str(params[p]) if not options.verbose else params[p].get_verbose_description()) + break + print "" + + print "Macros" + print "------" + if macros: + print 'Defined with "macros":', macros + print "Generated from configuration parameters:", Config.parameters_to_macros(params) + + except KeyboardInterrupt, e: + print "\n[CTRL+c] exit" + except Exception,e: + if options.verbose: + import traceback + traceback.print_exc(file=sys.stdout) + else: + print "[ERROR] %s" % str(e) + + sys.exit(1) diff --git a/tools/options.py b/tools/options.py index cf146c47bd..250e8e1948 100644 --- a/tools/options.py +++ b/tools/options.py @@ -19,7 +19,7 @@ from tools.toolchains import TOOLCHAINS from tools.targets import TARGET_NAMES -def get_default_options_parser(): +def get_default_options_parser(add_clean=True, add_options=True): parser = OptionParser() targetnames = TARGET_NAMES @@ -35,10 +35,12 @@ def get_default_options_parser(): help="build using the given TOOLCHAIN (%s)" % ', '.join(toolchainlist), metavar="TOOLCHAIN") - parser.add_option("-c", "--clean", action="store_true", default=False, - help="clean the build directory") + if add_clean: + parser.add_option("-c", "--clean", action="store_true", default=False, + help="clean the build directory") - parser.add_option("-o", "--options", action="append", - help='Add a build option ("save-asm": save the asm generated by the compiler, "debug-info": generate debugging information, "analyze": run Goanna static code analyzer")') + if add_options: + parser.add_option("-o", "--options", action="append", + help='Add a build option ("save-asm": save the asm generated by the compiler, "debug-info": generate debugging information, "analyze": run Goanna static code analyzer")') return parser