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 iar.py Source File

iar.py

00001 """
00002 mbed SDK
00003 Copyright (c) 2011-2015 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 import re
00018 import os
00019 from project_generator_definitions.definitions import ProGenDef
00020 
00021 from tools.export.exporters import Exporter, ExporterTargetsProperty
00022 from tools.targets import TARGET_MAP, TARGET_NAMES
00023 
00024 # If you wish to add a new target, add it to project_generator_definitions, and then
00025 # define progen_target name in the target class (`` self.progen_target = 'my_target_name' ``)
00026 class IAREmbeddedWorkbench (Exporter):
00027     """
00028     Exporter class for IAR Systems. This class uses project generator.
00029     """
00030     # These 2 are currently for exporters backward compatiblity
00031     NAME = 'IAR'
00032     TOOLCHAIN = 'IAR'
00033     # PROGEN_ACTIVE contains information for exporter scripts that this is using progen
00034     PROGEN_ACTIVE = True
00035 
00036     MBED_CONFIG_HEADER_SUPPORTED = True
00037 
00038     @ExporterTargetsProperty
00039     def TARGETS(cls):
00040         if not hasattr(cls, "_targets_supported"):
00041             cls._targets_supported = []
00042             progendef = ProGenDef('iar')
00043             for target in TARGET_NAMES:
00044                 try:
00045                     if (progendef.is_supported(str(TARGET_MAP[target])) or
00046                         progendef.is_supported(TARGET_MAP[target].progen['target'])):
00047                         cls._targets_supported.append(target)
00048                 except AttributeError:
00049                     # target is not supported yet
00050                     continue
00051         return cls._targets_supported
00052 
00053     def generate (self, progen_build=False):
00054         """ Generates the project files """
00055         project_data = self.progen_get_project_data()
00056         tool_specific = {}
00057         # Expand tool specific settings by IAR specific settings which are required
00058         try:
00059             if TARGET_MAP[self.target].progen['iar']['template']:
00060                 tool_specific['iar'] = TARGET_MAP[self.target].progen['iar']
00061         except KeyError:
00062             # use default template
00063             # by the mbed projects
00064             tool_specific['iar'] = {
00065                     # We currently don't use misc, template sets those for us
00066                     # 'misc': {
00067                     #     'cxx_flags': ['--no_rtti', '--no_exceptions'],
00068                     #     'c_flags': ['--diag_suppress=Pa050,Pa084,Pa093,Pa082'],
00069                     #     'ld_flags': ['--skip_dynamic_initialization'],
00070                     # },
00071                     'template': [os.path.join(os.path.dirname(__file__),  'iar_template.ewp.tmpl')],
00072             }
00073 
00074         project_data['tool_specific'] = {}
00075         project_data['tool_specific'].setdefault("iar", {})
00076         project_data['tool_specific']['iar'].setdefault("misc", {})
00077         project_data['tool_specific']['iar'].update(tool_specific['iar'])
00078         project_data['tool_specific']['iar']['misc'].update(self.progen_flags)
00079         # VLA is enabled via template IccAllowVLA
00080         project_data['tool_specific']['iar']['misc']['c_flags'].remove("--vla")
00081         project_data['common']['build_dir'] = os.path.join(project_data['common']['build_dir'], 'iar_arm')
00082         if progen_build:
00083             self.progen_gen_file('iar_arm', project_data, True)
00084         else:
00085             self.progen_gen_file('iar_arm', project_data)
00086 
00087 # Currently not used, we should reuse folder_name to create virtual folders
00088 class IarFolder ():
00089     """
00090     This is a recursive folder object.
00091     To present the folder structure in the IDE as it is presented on the disk.
00092     This can be used for uvision as well if you replace the __str__ method.
00093     Example:
00094     files: ./main.cpp, ./apis/I2C.h, ./mbed/common/I2C.cpp
00095     in the project this would look like:
00096     main.cpp
00097     common/I2C.cpp
00098     input:
00099     folder_level : folder path to current folder
00100     folder_name : name of current folder
00101     source_files : list of source_files (all must be in same directory)
00102     """
00103     def __init__(self, folder_level, folder_name, source_files):
00104         self.folder_level  = folder_level
00105         self.folder_name  = folder_name
00106         self.source_files  = source_files
00107         self.sub_folders  = {}
00108 
00109     def __str__ (self):
00110         """
00111         converts the folder structue to IAR project format.
00112         """
00113         group_start = ""
00114         group_end = ""
00115         if self.folder_name  != "":
00116             group_start = "<group>\n<name>%s</name>\n" %(self.folder_name )
00117             group_end = "</group>\n"
00118 
00119         str_content = group_start
00120         #Add files in current folder
00121         if self.source_files :
00122             for src in self.source_files :
00123                 str_content += "<file>\n<name>$PROJ_DIR$/%s</name>\n</file>\n" % src
00124         #Add sub folders
00125         if self.sub_folders :
00126             for folder_name in self.sub_folders .iterkeys():
00127                 str_content += self.sub_folders [folder_name].__str__()
00128 
00129         str_content += group_end
00130         return str_content
00131 
00132     def insert_file (self, source_input):
00133         """
00134         Inserts a source file into the folder tree
00135         """
00136         if self.source_files :
00137             #All source_files in a IarFolder must be in same directory.
00138             dir_sources = IarFolder.get_directory(self.source_files [0])
00139             #Check if sources are already at their deepest level.
00140             if not self.folder_level  == dir_sources:
00141                 _reg_exp = r"^" + re.escape(self.folder_level ) + r"[/\\]?([^/\\]+)"
00142                 folder_name = re.match(_reg_exp, dir_sources).group(1)
00143                 self.sub_folders [folder_name] = IarFolder(os.path.join(self.folder_level , folder_name), folder_name, self.source_files )
00144                 self.source_files  = []
00145 
00146         dir_input = IarFolder.get_directory(source_input)
00147         if dir_input == self.folder_level :
00148             self.source_files .append(source_input)
00149         else:
00150             _reg_exp = r"^" + re.escape(self.folder_level ) + r"[/\\]?([^/\\]+)"
00151             folder_name = re.match(_reg_exp, dir_input).group(1)
00152             if self.sub_folders .has_key(folder_name):
00153                 self.sub_folders [folder_name].insert_file(source_input)
00154             else:
00155                 if self.folder_level  == "":
00156                     #Top level exception
00157                     self.sub_folders [folder_name] = IarFolder(folder_name, folder_name, [source_input])
00158                 else:
00159                     self.sub_folders [folder_name] = IarFolder(os.path.join(self.folder_level , folder_name), folder_name, [source_input])
00160 
00161     @staticmethod
00162     def get_directory (file_path):
00163         """
00164         Returns the directory of the file
00165         """
00166         return os.path.dirname(file_path)