the other jimmy / mbed-sdk-tools

Fork of mbed-sdk-tools by mbed official

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