Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
__init__.py
00001 from __future__ import print_function, absolute_import 00002 from builtins import str 00003 00004 import os 00005 import copy 00006 import shutil 00007 00008 from os.path import relpath, join, exists, dirname, basename 00009 from os import makedirs, remove 00010 from json import load 00011 00012 from tools.export.exporters import Exporter, apply_supported_whitelist 00013 from tools.targets import TARGET_MAP 00014 from tools.utils import NotSupportedException 00015 from tools.build_api import prepare_toolchain 00016 00017 POST_BINARY_WHITELIST = set([ 00018 "TEENSY3_1Code.binary_hook", 00019 "MCU_NRF51Code.binary_hook", 00020 "LPCTargetCode.lpc_patch", 00021 "LPC4088Code.binary_hook" 00022 ]) 00023 00024 00025 class GNUARMNetbeans(Exporter): 00026 NAME = 'GNU ARM Netbeans' 00027 TOOLCHAIN = 'GCC_ARM' 00028 00029 @classmethod 00030 def is_target_supported(cls, target_name): 00031 target = TARGET_MAP[target_name] 00032 return apply_supported_whitelist( 00033 cls.TOOLCHAIN, POST_BINARY_WHITELIST, target) 00034 00035 @staticmethod 00036 def prepare_sys_lib(libname): 00037 return "-l" + libname 00038 00039 @staticmethod 00040 def get_defines_and_remove_from_flags(flags_in, str_key): 00041 defines = [] 00042 flags_temp = copy.deepcopy(flags_in) 00043 for f in flags_temp[str_key]: 00044 f = f.strip() 00045 if f.startswith('-D'): 00046 defines.append(f[2:]) 00047 flags_in[str_key].remove(f) 00048 00049 return defines 00050 00051 @staticmethod 00052 def get_includes_and_remove_from_flags(flags_in, str_key): 00053 includes = [] 00054 flags_temp = copy.deepcopy(flags_in) 00055 next_is_include = False 00056 for f in flags_temp[str_key]: 00057 f = f.strip() 00058 if next_is_include: 00059 includes.append(f) 00060 flags_in[str_key].remove(f) 00061 next_is_include = False 00062 continue 00063 if f == "-include": 00064 flags_in[str_key].remove(f) 00065 next_is_include = True 00066 00067 return includes 00068 00069 @staticmethod 00070 def get_c_std_and_remove_from_flag(flags_in, str_key): 00071 comp_std = '' 00072 c_std = { 00073 'c90': 'c90', 'c89': 'c90', 'gnu90': 'gnu90', 'gnu89': 'gnu90', 00074 'c99': 'c99', 'c9x': 'c99', 'gnu99': 'gnu99', 'gnu9x': 'gnu98', 00075 'c11': 'c11', 'c1x': 'c11', 'gnu11': 'gnu11', 'gnu1x': 'gnu11' 00076 } 00077 cpp_std = { 00078 'c++98': 'cpp98', 'c++03': 'cpp98', 00079 'gnu++98': 'gnucpp98', 'gnu++03': 'gnucpp98', 00080 'c++0x': 'cpp0x', 'gnu++0x': 'gnucpp0x', 00081 'c++11': 'cpp11', 'gnu++11': 'gnucpp11', 00082 'c++1y': 'cpp1y', 'gnu++1y': 'gnucpp1y', 00083 'c++14': 'cpp14', 'gnu++14': 'gnucpp14', 00084 'c++1z': 'cpp1z', 'gnu++1z': 'gnucpp1z', 00085 } 00086 00087 flags_temp = copy.deepcopy(flags_in) 00088 for f in flags_temp[str_key]: 00089 f = f.strip() 00090 if f.startswith('-std='): 00091 comp_std = f[len('-std='):] 00092 flags_in[str_key].remove(f) 00093 elif f.startswith('-'): 00094 std = f[len('-'):] 00095 if std in c_std or std in cpp_std: 00096 comp_std = std 00097 flags_in[str_key].remove(f) 00098 return comp_std 00099 00100 def validate_resources(self): 00101 if not self.resources.linker_script: 00102 raise NotSupportedException("No linker script found.") 00103 00104 def create_jinja_ctx(self): 00105 self.options = {} 00106 flags = {} 00107 self.validate_resources() 00108 # Convert all Backslashes to Forward Slashes 00109 self.resources.win_to_unix() 00110 00111 self.ld_script = self.filter_dot( 00112 self.resources.linker_script) 00113 00114 # Read in all profiles, we'll extract compiler options. 00115 profiles = self.get_all_profiles() 00116 00117 profile_ids = [s.lower() for s in profiles] 00118 profile_ids.sort() 00119 for prof_id in profile_ids: 00120 # There are 4 categories of options, a category common too 00121 # all tools and a specific category for each of the tools. 00122 opts = {} 00123 opts['defines'] = {} 00124 opts['common'] = {} 00125 opts['as'] = {} 00126 opts['c'] = {} 00127 opts['cpp'] = {} 00128 opts['ld'] = {} 00129 00130 opts['id'] = prof_id 00131 opts['name'] = opts['id'].capitalize() 00132 00133 profile = profiles[prof_id] 00134 00135 # A small hack, do not bother with src_path again, 00136 # pass an empty string to avoid crashing. 00137 src_paths = [''] 00138 target_name = self.toolchain.target.name 00139 00140 toolchain = prepare_toolchain( 00141 src_paths, "", target_name, self.TOOLCHAIN, build_profile=[profile]) 00142 00143 flags = self.toolchain_flags(toolchain) 00144 00145 opts['defines'] = self.get_defines_and_remove_from_flags(flags, 'common_flags') 00146 opts['forced_includes'] = self.get_includes_and_remove_from_flags(flags, 'common_flags') 00147 opts['common'] = flags['common_flags'] 00148 opts['as'] = flags['asm_flags'] 00149 opts['c'] = flags['c_flags'] 00150 opts['cpp'] = flags['cxx_flags'] 00151 opts['ld'] = flags['ld_flags'] 00152 00153 self.options[prof_id] = opts 00154 00155 sources = [] # list of strings 00156 00157 forced_includes = self.get_includes_and_remove_from_flags(flags, 'c_flags') 00158 forced_includes += self.get_includes_and_remove_from_flags(flags, 'cxx_flags') 00159 00160 # Remove Duplicates 00161 forced_includes = list(set(forced_includes)) 00162 00163 c_std = self.get_c_std_and_remove_from_flag(flags, 'c_flags') 00164 cpp_std = self.get_c_std_and_remove_from_flag(flags, 'cxx_flags') 00165 00166 # Make one list of all resources 00167 for r_type in ['c_sources', 's_sources', 'cpp_sources']: 00168 sources.extend(getattr(self.resources, r_type)) 00169 00170 # Remove all leading './' 00171 c_sources = [self.filter_dot(field) for field in self.resources.c_sources] 00172 cpp_sources = [self.filter_dot(field) for field in self.resources.cpp_sources] 00173 s_sources = [self.filter_dot(field) for field in self.resources.s_sources] 00174 headers = [self.filter_dot(field) for field in self.resources.headers] 00175 sources = [self.filter_dot(field) for field in sources] 00176 include_paths = [self.filter_dot(field) for field in self.resources.inc_dirs] 00177 00178 sys_libs = [self.prepare_sys_lib(lib) for lib 00179 in self.toolchain.sys_libs] 00180 preproc = " ".join([basename(self.toolchain.preproc[0])] + 00181 self.toolchain.preproc[1:] + 00182 self.toolchain.ld[1:]) 00183 00184 if 'nbproject' in include_paths: 00185 include_paths.remove('nbproject') 00186 00187 jinja_ctx = { 00188 'name': self.project_name, 00189 'target': self.toolchain.target.name, 00190 'elf_location': join('BUILD', self.project_name) + '.elf', 00191 'c_symbols': self.toolchain.get_symbols(), 00192 'asm_symbols': self.toolchain.get_symbols(True), 00193 'c_flags': flags['c_flags'], 00194 'cxx_flags': flags['cxx_flags'], 00195 'ld_flags': self.flags['ld_flags'], 00196 'asm_flags': self.flags['asm_flags'], 00197 'common_flags': self.flags['common_flags'], 00198 'include_paths': include_paths, 00199 'forced_includes': forced_includes, 00200 'c_sources': c_sources, 00201 'cpp_sources': cpp_sources, 00202 's_sources': s_sources, 00203 'headers': headers, 00204 'headers_folder': self.get_netbeans_file_list(sorted(headers)), 00205 'sources_folder': self.get_netbeans_file_list(sorted(sources)), 00206 'options': self.options, 00207 'c_std': self.get_netbeans_c_std(c_std), 00208 'cpp_std': self.get_netbeans_cpp_std(cpp_std), 00209 'linker_script': self.ld_script, 00210 'linker_libs': sys_libs, 00211 'pp_cmd': preproc, 00212 'cc_cmd': self.toolchain.cc[0], 00213 'cppc_cmd': self.toolchain.cppc[0], 00214 'asm_cmd': self.toolchain.asm[0], 00215 'ld_cmd': self.toolchain.ld[0], 00216 'elf2bin_cmd': self.toolchain.elf2bin 00217 } 00218 return jinja_ctx 00219 00220 def generate(self): 00221 """Generate Makefile, configurations.xml & project.xml Netbeans project file 00222 """ 00223 jinja_ctx = self.create_jinja_ctx() 00224 00225 if not exists(join(self.export_dir, 'nbproject')): 00226 makedirs(join(self.export_dir, 'nbproject')) 00227 00228 self.gen_file('nb/configurations.tmpl', jinja_ctx, 'nbproject/configurations.xml') 00229 self.gen_file('nb/project.tmpl', jinja_ctx, 'nbproject/project.xml') 00230 self.gen_file_nonoverwrite('nb/mbedignore.tmpl', jinja_ctx, 00231 '.mbedignore') 00232 self.gen_file('nb/Makefile.tmpl', jinja_ctx, 'Makefile') 00233 00234 print('Done. Import the \'{0}\' project in Netbeans.'.format(self.project_name)) 00235 00236 @staticmethod 00237 def clean(_): 00238 shutil.rmtree("nbproject") 00239 remove("Makefile") 00240 00241 # ------------------------------------------------------------------------- 00242 00243 @staticmethod 00244 def filter_dot(str_in): 00245 """ 00246 Remove the './' prefix, if present. 00247 This function assumes that resources.win_to_unix() 00248 replaced all windows backslashes with slashes. 00249 """ 00250 if str_in is None: 00251 return None 00252 if str_in[:2] == './': 00253 return str_in[2:] 00254 return str_in 00255 00256 # ------------------------------------------------------------------------- 00257 00258 @staticmethod 00259 def get_all_profiles(): 00260 tools_path = dirname(dirname(dirname(__file__))) 00261 file_names = [join(tools_path, "profiles", fn) for fn in os.listdir( 00262 join(tools_path, "profiles")) if fn.endswith(".json")] 00263 00264 profiles = {} 00265 00266 for fn in file_names: 00267 content = load(open(fn)) 00268 profile_name = basename(fn).replace(".json", "") 00269 profiles[profile_name] = content 00270 00271 return profiles 00272 00273 @staticmethod 00274 def get_netbeans_file_list(file_list): 00275 cur_dir = '' 00276 prev_dir = '' 00277 output = [] 00278 folder_count = 1 00279 dir_depth = 0 00280 for item in file_list: 00281 cur_dir = os.path.dirname(item) 00282 dir_temp = os.path.normpath(cur_dir) 00283 prev_dir_temp = os.path.normpath(prev_dir) 00284 dir_list = dir_temp.split(os.sep) 00285 prev_dir_list = prev_dir_temp.split(os.sep) 00286 dir_depth = len(dir_list) 00287 00288 # Current File is in Directory: Compare the given dir with previous Dir 00289 if cur_dir and prev_dir != cur_dir: 00290 # evaluate all matched items (from current and previous list) 00291 matched = [] 00292 # Compare the Element in Previous Dir with the Elements in Current Dir 00293 # and add the equal Elements to the match-List 00294 for elem_prev_dir, elem_cur_dir in zip(prev_dir_list, dir_list): 00295 if elem_prev_dir == elem_cur_dir: 00296 matched.append(elem_cur_dir) 00297 00298 # calculate difference between matched and length 00299 diff = dir_depth - len(matched) 00300 00301 # if previous dir was not root 00302 if prev_dir != '': 00303 # if the elements count is not equal we calculate the difference 00304 if len(dir_list) != len(prev_dir_list): 00305 dir_depth_prev = len(prev_dir_list) 00306 delta = dir_depth_prev - len(matched) 00307 00308 for i in range(dir_depth_prev - delta, dir_depth_prev): 00309 output.append('</logicalFolder>') 00310 00311 # if the elements count is equal, we subtract the matched length from the total length 00312 else: 00313 for i in range(len(matched), len(dir_list)): 00314 output.append('</logicalFolder>') 00315 00316 for i in range(dir_depth - diff, dir_depth): 00317 output.append('<logicalFolder name="f' + str(folder_count) + '" displayName="' + str( 00318 dir_list[i]) + '" projectFiles="true">') 00319 folder_count += 1 00320 00321 # Current File is in root 00322 else: 00323 # Close Tag if we are in root and the previous dir wasn't 00324 if cur_dir == '' and prev_dir != '': 00325 for i in range(0, len(prev_dir_list)): 00326 output.append('</logicalFolder>') 00327 00328 # Save the Current Dir 00329 prev_dir = cur_dir 00330 output.append('<itemPath>' + str(item) + '</itemPath>') 00331 00332 if cur_dir != '': 00333 # close all open tags 00334 output.append('</logicalFolder>' * dir_depth) 00335 00336 return output 00337 00338 @staticmethod 00339 def get_netbeans_c_std(c_std): 00340 c_std_netbeans = 0 00341 if '89' in c_std: 00342 c_std_netbeans = 2 00343 elif '99' in c_std: 00344 c_std_netbeans = 3 00345 elif '11' in c_std: 00346 c_std_netbeans = 10 00347 return c_std_netbeans 00348 00349 @staticmethod 00350 def get_netbeans_cpp_std(cpp_std): 00351 cpp_std_netbeans = 0 00352 if '98' in cpp_std: 00353 cpp_std_netbeans = 4 00354 elif '11' in cpp_std: 00355 cpp_std_netbeans = 8 00356 elif '14' in cpp_std: 00357 cpp_std_netbeans = 11 00358 return cpp_std_netbeans
Generated on Tue Jul 12 2022 17:12:47 by
