Fixed config-related options for the IAR assembler

The IAR assembler doesn't accept '--preinclude', but it accepts -D.
This commit changes the way the config-related macros are propagated
to the IAR assembler to use '-D' instead of '--preinclude'. This is
the only change related to functionality, the others are small,
backward compatible changes to the config code to make passing arguments
to the toolchain instances easier.

Tested by compiled blinky with IAR, GCC_ARM and ARM for K64F.
pull/2020/head
Bogdan Marinescu 2016-06-27 15:17:03 +03:00
parent 703aee4f61
commit b4e8cf655d
4 changed files with 50 additions and 26 deletions

View File

@ -217,8 +217,8 @@ def build_project(src_path, build_path, target, toolchain_name,
# Load resources into the config system which might expand/modify resources based on config data # Load resources into the config system which might expand/modify resources based on config data
resources = config.load_resources(resources) resources = config.load_resources(resources)
# Set the toolchain's config header with the config data # Set the toolchain's configuration data
toolchain.set_config_header_content(config.get_config_data_header()) toolchain.set_config_data(config.get_config_data())
# Compile Sources # Compile Sources
objects = toolchain.compile_sources(resources, build_path, resources.inc_dirs) objects = toolchain.compile_sources(resources, build_path, resources.inc_dirs)
@ -361,8 +361,8 @@ def build_library(src_paths, build_path, target, toolchain_name,
# Load resources into the config system which might expand/modify resources based on config data # Load resources into the config system which might expand/modify resources based on config data
resources = config.load_resources(resources) resources = config.load_resources(resources)
# Set the toolchain's config header with the config data # Set the toolchain's configuration data
toolchain.set_config_header_content(config.get_config_data_header()) toolchain.set_config_data(config.get_config_data())
# Copy headers, objects and static libraries - all files needed for static lib # Copy headers, objects and static libraries - all files needed for static lib
toolchain.copy_files(resources.headers, build_path, resources=resources) toolchain.copy_files(resources.headers, build_path, resources=resources)

View File

@ -354,7 +354,8 @@ class Config:
return all_params, macros return all_params, macros
# Helper: verify if there are any required parameters without a value in 'params' # Helper: verify if there are any required parameters without a value in 'params'
def _check_required_parameters(self, params): @staticmethod
def _check_required_parameters(params):
for p in params.values(): for p in params.values():
if p.required and (p.value is None): 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)) raise ConfigException("Required parameter '%s' defined by '%s' doesn't have a value" % (p.name, p.defined_by))
@ -371,11 +372,18 @@ class Config:
def config_macros_to_macros(macros): def config_macros_to_macros(macros):
return [m.name for m in macros.values()] return [m.name for m in macros.values()]
# Return the configuration data converted to a list of C macros
# config - configuration data as (ConfigParam instances, ConfigMacro instances) tuple
# (as returned by get_config_data())
@staticmethod
def config_to_macros(config):
params, macros = config[0], config[1]
Config._check_required_parameters(params)
return Config.config_macros_to_macros(macros) + Config.parameters_to_macros(params)
# Return the configuration data converted to a list of C macros # Return the configuration data converted to a list of C macros
def get_config_data_macros(self): def get_config_data_macros(self):
params, macros = self.get_config_data() return self.config_to_macros(self.get_config_data())
self._check_required_parameters(params)
return self.config_macros_to_macros(macros) + self.parameters_to_macros(params)
# Returns any features in the configuration data # Returns any features in the configuration data
def get_features(self): def get_features(self):
@ -419,14 +427,16 @@ class Config:
return resources return resources
# Return the configuration data converted to the content of a C header file, # Return the configuration data converted to the content of a C header file,
# meant to be included to a C/C++ file. The content is returned as a string. # meant to be included to a C/C++ file. The content is returned as a string.
# If 'fname' is given, the content is also written to the file called "fname". # If 'fname' is given, the content is also written to the file called "fname".
# WARNING: if 'fname' names an existing file, that file will be overwritten! # WARNING: if 'fname' names an existing file, that file will be overwritten!
def get_config_data_header(self, fname = None): # config - configuration data as (ConfigParam instances, ConfigMacro instances) tuple
params, macros = self.get_config_data() # (as returned by get_config_data())
self._check_required_parameters(params) @staticmethod
def config_to_header(config, fname = None):
params, macros = config[0], config[1]
Config._check_required_parameters(params)
header_data = "// Automatically generated configuration file.\n" header_data = "// Automatically generated configuration file.\n"
header_data += "// DO NOT EDIT, content will be overwritten.\n\n" header_data += "// DO NOT EDIT, content will be overwritten.\n\n"
header_data += "#ifndef __MBED_CONFIG_DATA__\n" header_data += "#ifndef __MBED_CONFIG_DATA__\n"
@ -459,3 +469,10 @@ class Config:
with open(fname, "wt") as f: with open(fname, "wt") as f:
f.write(header_data) f.write(header_data)
return header_data return header_data
# Return the configuration data converted to the content of a C header file,
# meant to be included to a C/C++ file. The content is returned as a string.
# If 'fname' is given, the content is also written to the file called "fname".
# WARNING: if 'fname' names an existing file, that file will be overwritten!
def get_config_data_header(self, fname = None):
return self.config_to_header(self.get_config_data(), fname)

View File

@ -25,6 +25,7 @@ from shutil import copyfile
from os.path import join, splitext, exists, relpath, dirname, basename, split, abspath from os.path import join, splitext, exists, relpath, dirname, basename, split, abspath
from inspect import getmro from inspect import getmro
from copy import deepcopy from copy import deepcopy
from tools.config import Config
from multiprocessing import Pool, cpu_count from multiprocessing import Pool, cpu_count
from tools.utils import run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path from tools.utils import run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path
@ -245,8 +246,8 @@ class mbedToolchain:
# Labels generated from toolchain and target rules/features (used for selective build) # Labels generated from toolchain and target rules/features (used for selective build)
self.labels = None self.labels = None
# config_header_content will hold the content of the config header (if used) # This will hold the configuration data (as returned by Config.get_config_data())
self.config_header_content = None self.config_data = None
# Non-incremental compile # Non-incremental compile
self.build_all = False self.build_all = False
@ -892,11 +893,9 @@ class mbedToolchain:
map_csv = splitext(map)[0] + "_map.csv" map_csv = splitext(map)[0] + "_map.csv"
memap.generate_output('csv-ci', map_csv) memap.generate_output('csv-ci', map_csv)
# "Prefix headers" are automatically included by the compiler at the beginning of # Set the configuration data
# each source file. They are used to provide configuration data. def set_config_data(self, config_data):
# header_content - the content of the config header file. self.config_data = config_data
def set_config_header_content(self, header_content):
self.config_header_content = header_content
# Return the location of the config header. This function will create the config # Return the location of the config header. This function will create the config
# header first if needed. The header will be written in a file called "mbed_conf.h" # header first if needed. The header will be written in a file called "mbed_conf.h"
@ -904,14 +903,17 @@ class mbedToolchain:
# If config headers are not used (self.config_header_content is None), the function # If config headers are not used (self.config_header_content is None), the function
# returns None # returns None
def get_config_header(self): def get_config_header(self):
if self.config_header_content is None: if self.config_data is None:
return None return None
config_file = join(self.build_dir, "mbed_config.h") config_file = join(self.build_dir, "mbed_config.h")
if not exists(config_file): if not exists(config_file):
with open(config_file, "wt") as f: with open(config_file, "wt") as f:
f.write(self.config_header_content) f.write(Config.config_to_header(self.config_data))
return config_file return config_file
# Return the list of macros geenrated by the build system
def get_config_macros(self):
return Config.config_to_macros(self.config_data) if self.config_data else []
from tools.settings import ARM_BIN from tools.settings import ARM_BIN
from tools.settings import GCC_ARM_PATH, GCC_CR_PATH from tools.settings import GCC_ARM_PATH, GCC_CR_PATH

View File

@ -126,17 +126,22 @@ class IAR(mbedToolchain):
base, _ = splitext(object) base, _ = splitext(object)
return ["-l", base + '.s.txt'] return ["-l", base + '.s.txt']
def get_compile_options(self, defines, includes): def get_compile_options(self, defines, includes, for_asm=False):
opts = ['-D%s' % d for d in defines] + ['-f', self.get_inc_file(includes)] opts = ['-D%s' % d for d in defines] + ['-f', self.get_inc_file(includes)]
config_header = self.get_config_header() if for_asm:
if config_header is not None: # The assembler doesn't support '--preinclude', so we need to add
opts = opts + ['--preinclude', config_header] # the macros directly
opts = opts + ['-D%s' % d for d in self.get_config_macros()]
else:
config_header = self.get_config_header()
if config_header is not None:
opts = opts + ['--preinclude', config_header]
return opts return opts
@hook_tool @hook_tool
def assemble(self, source, object, includes): def assemble(self, source, object, includes):
# Build assemble command # Build assemble command
cmd = self.asm + self.get_compile_options(self.get_symbols(), includes) + ["-o", object, source] cmd = self.asm + self.get_compile_options(self.get_symbols(), includes, for_asm=True) + ["-o", object, source]
# Call cmdline hook # Call cmdline hook
cmd = self.hook.get_cmdline_assembler(cmd) cmd = self.hook.get_cmdline_assembler(cmd)