From af4d848144d3e62a429528149dc33fd8d45ec9da Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 1 Feb 2017 15:59:27 -0600 Subject: [PATCH 1/2] Use the C Pre-Processor on GCC Linker scirpts This allows us to define parts of the linker script outside of the linker script itself. In particular, we are interested in restricting ROM to a subsection. --- tools/toolchains/gcc.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py index 3186cbb76ff..54fdbd567c5 100644 --- a/tools/toolchains/gcc.py +++ b/tools/toolchains/gcc.py @@ -15,7 +15,7 @@ limitations under the License. """ import re -from os.path import join, basename, splitext +from os.path import join, basename, splitext, dirname from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS from tools.hooks import hook_tool @@ -93,6 +93,7 @@ def __init__(self, target, notify=None, macros=None, self.flags['ld'] += self.cpu self.ld = [join(tool_path, "arm-none-eabi-gcc")] + self.flags['ld'] self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc"] + self.preproc = [join(tool_path, "arm-none-eabi-cpp"), "-E", "-P"] self.ar = join(tool_path, "arm-none-eabi-ar") self.elf2bin = join(tool_path, "arm-none-eabi-objcopy") @@ -213,6 +214,15 @@ def link(self, output, objects, libraries, lib_dirs, mem_map): libs.append("-l%s" % name[3:]) libs.extend(["-l%s" % l for l in self.sys_libs]) + # Preprocess + if mem_map: + preproc_output = join(dirname(output), ".link_script.ld") + cmd = (self.preproc + [mem_map] + self.ld[1:] + + [ "-o", preproc_output]) + self.cc_verbose("Preproc: %s" % ' '.join(cmd)) + self.default_cmd(cmd) + mem_map = preproc_output + # Build linker command map_file = splitext(output)[0] + ".map" cmd = self.ld + ["-o", output, "-Wl,-Map=%s" % map_file] + objects + ["-Wl,--start-group"] + libs + ["-Wl,--end-group"] From 3155e71786dc556cf1124fb458ad5a124949da88 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Wed, 8 Feb 2017 17:04:17 -0600 Subject: [PATCH 2/2] Add pre-processing of linker scripts to Make exporter For toolchains that do not implicitly run the C pre-processor on their linker scripts the toolchain is expected to define a `preproc` attribute. The Makefiles then pick up on this attribute and add another rule for pre-processing the linker script automatically. --- tools/export/makefile/Makefile.tmpl | 10 +++++++++- tools/export/makefile/__init__.py | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/export/makefile/Makefile.tmpl b/tools/export/makefile/Makefile.tmpl index 31316034d12..15d97f693de 100644 --- a/tools/export/makefile/Makefile.tmpl +++ b/tools/export/makefile/Makefile.tmpl @@ -67,6 +67,9 @@ CC = {{cc_cmd}} CPP = {{cppc_cmd}} LD = {{ld_cmd}} ELF2BIN = {{elf2bin_cmd}} +{% if pp_cmd -%} +PREPROC = {{pp_cmd}} +{%- endif %} {% if hex_files %} SREC_CAT = srec_cat {%- endif %} @@ -119,8 +122,13 @@ all: $(PROJECT).bin $(PROJECT).hex size +@echo "Compile: $(notdir $<)" @$(CPP) $(CXX_FLAGS) $(INCLUDE_PATHS) -o $@ $< +{% if pp_cmd %} +$(PROJECT).link_script{{link_script_ext}}: $(LINKER_SCRIPT) + @$(PREPROC) $< -o $@ +{% endif %} + {% block target_project_elf %} -$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS) $(LINKER_SCRIPT) +$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS) {% if pp_cmd -%} $(PROJECT).link_script{{link_script_ext}} {% else%} $(LINKER_SCRIPT) {% endif %} +@echo "link: $(notdir $@)" @$(LD) $(LD_FLAGS) {{link_script_option}} $(filter %{{link_script_ext}}, $^) $(LIBRARY_PATHS) --output $@ $(filter %.o, $^) $(LIBRARIES) $(LD_SYS_LIBS) {% endblock %} diff --git a/tools/export/makefile/__init__.py b/tools/export/makefile/__init__.py index d9c34a95b66..c6a1512094d 100644 --- a/tools/export/makefile/__init__.py +++ b/tools/export/makefile/__init__.py @@ -87,6 +87,14 @@ def generate(self): 'user_library_flag': self.USER_LIBRARY_FLAG, } + if hasattr(self.toolchain, "preproc"): + ctx['pp_cmd'] = " ".join(["\'" + part + "\'" for part + in ([basename(self.toolchain.preproc[0])] + + self.toolchain.preproc[1:] + + self.toolchain.ld[1:])]) + else: + ctx['pp_cmd'] = None + for key in ['include_paths', 'library_paths', 'linker_script', 'hex_files']: if isinstance(ctx[key], list):