Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers __init__.py Source File

__init__.py

00001 """
00002 mbed SDK
00003 Copyright (c) 2011-2016 ARM Limited
00004 
00005 Licensed under the Apache License, Version 2.0 (the "License");
00006 you may not use this file except in compliance with the License.
00007 You may obtain a copy of the License at
00008 
00009     http://www.apache.org/licenses/LICENSE-2.0
00010 
00011 Unless required by applicable law or agreed to in writing, software
00012 distributed under the License is distributed on an "AS IS" BASIS,
00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 See the License for the specific language governing permissions and
00015 limitations under the License.
00016 """
00017 from os.path import splitext, basename, relpath, join, abspath, dirname,\
00018     exists
00019 from os import remove
00020 import sys
00021 from subprocess import check_output, CalledProcessError, Popen, PIPE
00022 import shutil
00023 from jinja2.exceptions import TemplateNotFound
00024 from tools.export.exporters import Exporter, apply_supported_whitelist
00025 from tools.utils import NotSupportedException
00026 from tools.targets import TARGET_MAP
00027 
00028 
00029 class Makefile (Exporter ):
00030     """Generic Makefile template that mimics the behavior of the python build
00031     system
00032     """
00033 
00034     DOT_IN_RELATIVE_PATH = True
00035 
00036     MBED_CONFIG_HEADER_SUPPORTED = True
00037 
00038     PREPROCESS_ASM = False
00039 
00040     POST_BINARY_WHITELIST = set([
00041         "MCU_NRF51Code.binary_hook",
00042         "TEENSY3_1Code.binary_hook",
00043         "LPCTargetCode.lpc_patch",
00044         "LPC4088Code.binary_hook"
00045     ])
00046 
00047     @classmethod
00048     def is_target_supported (cls, target_name):
00049         target = TARGET_MAP[target_name]
00050         return apply_supported_whitelist(
00051             cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target)
00052 
00053     def generate (self):
00054         """Generate the makefile
00055 
00056         Note: subclasses should not need to override this method
00057         """
00058         if not self.resources.linker_script:
00059             raise NotSupportedException("No linker script found.")
00060 
00061         self.resources.win_to_unix()
00062 
00063         to_be_compiled = [splitext(src)[0] + ".o" for src in
00064                           self.resources.s_sources +
00065                           self.resources.c_sources +
00066                           self.resources.cpp_sources]
00067 
00068         libraries = [self.prepare_lib(basename(lib)) for lib
00069                      in self.resources.libraries]
00070         sys_libs = [self.prepare_sys_lib(lib) for lib
00071                     in self.toolchain.sys_libs]
00072 
00073         ctx = {
00074             'name': self.project_name,
00075             'to_be_compiled': to_be_compiled,
00076             'object_files': self.resources.objects,
00077             'include_paths': list(set(self.resources.inc_dirs)),
00078             'library_paths': self.resources.lib_dirs,
00079             'linker_script': self.resources.linker_script,
00080             'libraries': libraries,
00081             'ld_sys_libs': sys_libs,
00082             'hex_files': self.resources.hex_files,
00083             'vpath': (["../../.."]
00084                       if (basename(dirname(dirname(self.export_dir)))
00085                           == "projectfiles")
00086                       else [".."]),
00087             'cc_cmd': " ".join(["\'" + part + "\'" for part
00088                                 in ([basename(self.toolchain.cc[0])] +
00089                                     self.toolchain.cc[1:])]),
00090             'cppc_cmd': " ".join(["\'" + part + "\'" for part
00091                                   in ([basename(self.toolchain.cppc[0])] +
00092                                       self.toolchain.cppc[1:])]),
00093             'asm_cmd': " ".join(["\'" + part + "\'" for part
00094                                 in ([basename(self.toolchain.asm[0])] +
00095                                     self.toolchain.asm[1:])]),
00096             'ld_cmd': "\'" + basename(self.toolchain.ld[0]) + "\'",
00097             'elf2bin_cmd': "\'" + basename(self.toolchain.elf2bin) + "\'",
00098             'link_script_ext': self.toolchain.LINKER_EXT,
00099             'link_script_option': self.LINK_SCRIPT_OPTION,
00100             'user_library_flag': self.USER_LIBRARY_FLAG,
00101             'needs_asm_preproc': self.PREPROCESS_ASM ,
00102         }
00103 
00104         if hasattr(self.toolchain, "preproc"):
00105             ctx['pp_cmd'] = " ".join(["\'" + part + "\'" for part
00106                                       in ([basename(self.toolchain.preproc[0])] +
00107                                           self.toolchain.preproc[1:] + 
00108                                           self.toolchain.ld[1:])])
00109         else:
00110             ctx['pp_cmd'] = None
00111 
00112         for key in ['include_paths', 'library_paths', 'linker_script',
00113                     'hex_files']:
00114             if isinstance(ctx[key], list):
00115                 ctx[key] = [ctx['vpath'][0] + "/" + t for t in ctx[key]]
00116             else:
00117                 ctx[key] = ctx['vpath'][0] + "/" + ctx[key]
00118         if "../." not in ctx["include_paths"]:
00119             ctx["include_paths"] += ['../.']
00120         for key in ['include_paths', 'library_paths', 'hex_files',
00121                     'to_be_compiled']:
00122             ctx[key] = sorted(ctx[key])
00123         ctx.update(self.format_flags ())
00124 
00125         for templatefile in \
00126             ['makefile/%s_%s.tmpl' % (self.TEMPLATE,
00127                                       self.target.lower())] + \
00128             ['makefile/%s_%s.tmpl' % (self.TEMPLATE,
00129                                       label.lower()) for label
00130              in self.toolchain.target.extra_labels] +\
00131             ['makefile/%s.tmpl' % self.TEMPLATE]:
00132             try:
00133                 self.gen_file(templatefile, ctx, 'Makefile')
00134                 break
00135             except TemplateNotFound:
00136                 pass
00137         else:
00138             raise NotSupportedException("This make tool is in development")
00139 
00140     def format_flags (self):
00141         """Format toolchain flags for Makefile"""
00142         flags = {}
00143         for k, v in self.flags.iteritems():
00144             if k in ['asm_flags', 'c_flags', 'cxx_flags']:
00145                 flags[k] = map(lambda x: x.replace('"', '\\"'), v)
00146             else:
00147                 flags[k] = v
00148 
00149         return flags
00150 
00151     @staticmethod
00152     def build (project_name, log_name="build_log.txt", cleanup=True):
00153         """ Build Make project """
00154         # > Make -j
00155         cmd = ["make", "-j"]
00156 
00157         # Build the project
00158         p = Popen(cmd, stdout=PIPE, stderr=PIPE)
00159         out, err = p.communicate()
00160         ret_code = p.returncode
00161 
00162         out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
00163         out_string += out
00164         out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
00165         out_string += err
00166 
00167         if ret_code == 0:
00168             out_string += "SUCCESS"
00169         else:
00170             out_string += "FAILURE"
00171 
00172         print out_string
00173 
00174         if log_name:
00175             # Write the output to the log file
00176             with open(log_name, 'w+') as f:
00177                 f.write(out_string)
00178 
00179         # Cleanup the exported and built files
00180         if cleanup:
00181             remove("Makefile")
00182             remove(log_name)
00183             # legacy .build directory cleaned if exists
00184             if exists('.build'):
00185                 shutil.rmtree('.build')
00186             if exists('BUILD'):
00187                 shutil.rmtree('BUILD')
00188 
00189         if ret_code != 0:
00190             # Seems like something went wrong.
00191             return -1
00192         else:
00193             return 0
00194 
00195 
00196 class GccArm (Makefile ):
00197     """GCC ARM specific makefile target"""
00198     NAME = 'Make-GCC-ARM'
00199     TEMPLATE = 'make-gcc-arm'
00200     TOOLCHAIN = "GCC_ARM"
00201     LINK_SCRIPT_OPTION = "-T"
00202     USER_LIBRARY_FLAG = "-L"
00203 
00204     @staticmethod
00205     def prepare_lib(libname):
00206         if "lib" == libname[:3]:
00207             libname = libname[3:-2]
00208         return "-l" + libname
00209 
00210     @staticmethod
00211     def prepare_sys_lib(libname):
00212         return "-l" + libname
00213 
00214 
00215 class Arm (Makefile ):
00216     """ARM Compiler generic makefile target"""
00217     LINK_SCRIPT_OPTION = "--scatter"
00218     USER_LIBRARY_FLAG = "--userlibpath "
00219     TEMPLATE = 'make-arm'
00220 
00221     @staticmethod
00222     def prepare_lib(libname):
00223         return libname
00224 
00225     @staticmethod
00226     def prepare_sys_lib(libname):
00227         return libname
00228 
00229     def generate (self):
00230         if self.resources.linker_script:
00231             new_script = self.toolchain.correct_scatter_shebang(
00232                 self.resources.linker_script)
00233             if new_script is not self.resources.linker_script:
00234                 self.resources.linker_script = new_script
00235                 self.generated_files.append(new_script)
00236         return super(Arm, self).generate()
00237 
00238 class Armc5 (Arm ):
00239     """ARM Compiler 5 (armcc) specific makefile target"""
00240     NAME = 'Make-ARMc5'
00241     TOOLCHAIN = "ARM"
00242     PREPROCESS_ASM = True
00243 
00244 class Armc6 (Arm ):
00245     """ARM Compiler 6 (armclang) specific generic makefile target"""
00246     NAME = 'Make-ARMc6'
00247     TOOLCHAIN = "ARMC6"
00248 
00249 
00250 class IAR (Makefile ):
00251     """IAR specific makefile target"""
00252     NAME = 'Make-IAR'
00253     TEMPLATE = 'make-iar'
00254     TOOLCHAIN = "IAR"
00255     LINK_SCRIPT_OPTION = "--config"
00256     USER_LIBRARY_FLAG = "-L"
00257 
00258     @staticmethod
00259     def prepare_lib(libname):
00260         if "lib" == libname[:3]:
00261             libname = libname[3:]
00262         return "-l" + splitext(libname)[0]
00263 
00264     @staticmethod
00265     def prepare_sys_lib(libname):
00266         if "lib" == libname[:3]:
00267             libname = libname[3:]
00268         return "-l" + splitext(libname)[0]