ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

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
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     def generate (self):
00039         """Generate the makefile
00040 
00041         Note: subclasses should not need to override this method
00042         """
00043         if not self.resources.linker_script:
00044             raise NotSupportedException("No linker script found.")
00045 
00046         self.resources.win_to_unix()
00047 
00048         to_be_compiled = [splitext(src)[0] + ".o" for src in
00049                           self.resources.s_sources +
00050                           self.resources.c_sources +
00051                           self.resources.cpp_sources]
00052 
00053         libraries = [self.prepare_lib(basename(lib)) for lib
00054                      in self.resources.libraries]
00055 
00056         ctx = {
00057             'name': self.project_name,
00058             'to_be_compiled': to_be_compiled,
00059             'object_files': self.resources.objects,
00060             'include_paths': list(set(self.resources.inc_dirs)),
00061             'library_paths': self.resources.lib_dirs,
00062             'linker_script': self.resources.linker_script,
00063             'libraries': libraries,
00064             'hex_files': self.resources.hex_files,
00065             'vpath': (["../../.."]
00066                       if (basename(dirname(dirname(self.export_dir)))
00067                           == "projectfiles")
00068                       else [".."]),
00069             'cc_cmd': " ".join(["\'" + part + "\'" for part
00070                                 in ([basename(self.toolchain.cc[0])] +
00071                                     self.toolchain.cc[1:])]),
00072             'cppc_cmd': " ".join(["\'" + part + "\'" for part
00073                                   in ([basename(self.toolchain.cppc[0])] +
00074                                       self.toolchain.cppc[1:])]),
00075             'asm_cmd': " ".join(["\'" + part + "\'" for part
00076                                 in ([basename(self.toolchain.asm[0])] +
00077                                     self.toolchain.asm[1:])]),
00078             'ld_cmd': " ".join(["\'" + part + "\'" for part
00079                                 in ([basename(self.toolchain.ld[0])] +
00080                                     self.toolchain.ld[1:])]),
00081             'elf2bin_cmd': "\'" + basename(self.toolchain.elf2bin) + "\'",
00082             'link_script_ext': self.toolchain.LINKER_EXT,
00083             'link_script_option': self.LINK_SCRIPT_OPTION,
00084             'user_library_flag': self.USER_LIBRARY_FLAG,
00085         }
00086 
00087         for key in ['include_paths', 'library_paths', 'linker_script',
00088                     'hex_files']:
00089             if isinstance(ctx[key], list):
00090                 ctx[key] = [ctx['vpath'][0] + "/" + t for t in ctx[key]]
00091             else:
00092                 ctx[key] = ctx['vpath'][0] + "/" + ctx[key]
00093         if "../." not in ctx["include_paths"]:
00094             ctx["include_paths"] += ['../.']
00095         for key in ['include_paths', 'library_paths', 'hex_files',
00096                     'to_be_compiled']:
00097             ctx[key] = sorted(ctx[key])
00098         ctx.update(self.flags)
00099 
00100         for templatefile in \
00101             ['makefile/%s_%s.tmpl' % (self.TEMPLATE,
00102                                       self.target.lower())] + \
00103             ['makefile/%s_%s.tmpl' % (self.TEMPLATE,
00104                                       label.lower()) for label
00105              in self.toolchain.target.extra_labels] +\
00106             ['makefile/%s.tmpl' % self.TEMPLATE]:
00107             try:
00108                 self.gen_file(templatefile, ctx, 'Makefile')
00109                 break
00110             except TemplateNotFound:
00111                 pass
00112         else:
00113             raise NotSupportedException("This make tool is in development")
00114 
00115     @staticmethod
00116     def build (project_name, log_name="build_log.txt", cleanup=True):
00117         """ Build Make project """
00118         # > Make -j
00119         cmd = ["make", "-j"]
00120 
00121         # Build the project
00122         p = Popen(cmd, stdout=PIPE, stderr=PIPE)
00123         out, err = p.communicate()
00124         ret_code = p.returncode
00125 
00126         out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
00127         out_string += out
00128         out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
00129         out_string += err
00130 
00131         if ret_code == 0:
00132             out_string += "SUCCESS"
00133         else:
00134             out_string += "FAILURE"
00135 
00136         print out_string
00137 
00138         if log_name:
00139             # Write the output to the log file
00140             with open(log_name, 'w+') as f:
00141                 f.write(out_string)
00142 
00143         # Cleanup the exported and built files
00144         if cleanup:
00145             remove("Makefile")
00146             remove(log_name)
00147             # legacy .build directory cleaned if exists
00148             if exists('.build'):
00149                 shutil.rmtree('.build')
00150             if exists('BUILD'):
00151                 shutil.rmtree('BUILD')
00152 
00153         if ret_code != 0:
00154             # Seems like something went wrong.
00155             return -1
00156         else:
00157             return 0
00158 
00159 
00160 class GccArm (Makefile ):
00161     """GCC ARM specific makefile target"""
00162     TARGETS = [target for target, obj in TARGET_MAP.iteritems()
00163                if "GCC_ARM" in obj.supported_toolchains]
00164     NAME = 'Make-GCC-ARM'
00165     TEMPLATE = 'make-gcc-arm'
00166     TOOLCHAIN = "GCC_ARM"
00167     LINK_SCRIPT_OPTION = "-T"
00168     USER_LIBRARY_FLAG = "-L"
00169 
00170     @staticmethod
00171     def prepare_lib(libname):
00172         return "-l:" + libname
00173 
00174 
00175 class Armc5 (Makefile ):
00176     """ARM Compiler 5 specific makefile target"""
00177     TARGETS = [target for target, obj in TARGET_MAP.iteritems()
00178                if "ARM" in obj.supported_toolchains]
00179     NAME = 'Make-ARMc5'
00180     TEMPLATE = 'make-armc5'
00181     TOOLCHAIN = "ARM"
00182     LINK_SCRIPT_OPTION = "--scatter"
00183     USER_LIBRARY_FLAG = "--userlibpath "
00184 
00185     @staticmethod
00186     def prepare_lib(libname):
00187         return libname
00188 
00189 
00190 class IAR (Makefile ):
00191     """IAR specific makefile target"""
00192     TARGETS = [target for target, obj in TARGET_MAP.iteritems()
00193                if "IAR" in obj.supported_toolchains]
00194     NAME = 'Make-IAR'
00195     TEMPLATE = 'make-iar'
00196     TOOLCHAIN = "IAR"
00197     LINK_SCRIPT_OPTION = "--config"
00198     USER_LIBRARY_FLAG = "-L"
00199 
00200     @staticmethod
00201     def prepare_lib(libname):
00202         if "lib" == libname[:3]:
00203             libname = libname[3:]
00204         return "-l" + splitext(libname)[0]