From b112ad7da44b46ce85b7fad79c191c2d572d6046 Mon Sep 17 00:00:00 2001 From: "c.mandl" Date: Fri, 24 Nov 2017 09:45:46 +0100 Subject: [PATCH] Refactoring of Netbeans Exporter...still some more work to do, because linking still not works --- tools/export/__init__.py | 6 +- tools/export/nb/Makefile.tmpl | 128 ++++++++ tools/export/nb/__init__.py | 434 ++++++++++++++++++++-------- tools/export/nb/configurations.tmpl | 204 ++++++------- tools/export/nb/project.tmpl | 4 +- 5 files changed, 531 insertions(+), 245 deletions(-) create mode 100644 tools/export/nb/Makefile.tmpl diff --git a/tools/export/__init__.py b/tools/export/__init__.py index c70c762047..c15669618f 100644 --- a/tools/export/__init__.py +++ b/tools/export/__init__.py @@ -58,14 +58,12 @@ EXPORTERS = { 'eclipse_iar' : cdt.EclipseIAR, 'eclipse_armc5' : cdt.EclipseArmc5, 'gnuarmeclipse': gnuarmeclipse.GNUARMEclipse, + 'netbeans': nb.GNUARMNetbeans, 'mcuxpresso': mcuxpresso.MCUXpresso, 'qtcreator': qtcreator.QtCreator, 'vscode_gcc_arm' : vscode.VSCodeGcc, 'vscode_iar' : vscode.VSCodeIAR, - 'vscode_armc5' : vscode.VSCodeArmc5, - 'netbeans_gcc_arm' : nb.NetbeansGcc, - 'netbeans_iar' : nb.NetbeansIAR, - 'netbeans_armc5' : nb.NetbeansArmc5 + 'vscode_armc5' : vscode.VSCodeArmc5 } ERROR_MESSAGE_UNSUPPORTED_TOOLCHAIN = """ diff --git a/tools/export/nb/Makefile.tmpl b/tools/export/nb/Makefile.tmpl new file mode 100644 index 0000000000..05de621e85 --- /dev/null +++ b/tools/export/nb/Makefile.tmpl @@ -0,0 +1,128 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_PLATFORM_${CONF} platform name (current configuration) +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# build tests +build-tests: .build-tests-post + +.build-tests-pre: +# Add your pre 'build-tests' code here... + +.build-tests-post: .build-tests-impl +# Add your post 'build-tests' code here... + + +# run tests +test: .test-post + +.test-pre: build-tests +# Add your pre 'test' code here... + +.test-post: .test-impl +# Add your post 'test' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/tools/export/nb/__init__.py b/tools/export/nb/__init__.py index cdfee42fbe..2a3357d986 100644 --- a/tools/export/nb/__init__.py +++ b/tools/export/nb/__init__.py @@ -1,20 +1,34 @@ -import re import os import copy -from os.path import relpath, join, exists +from os.path import relpath, join, exists, dirname, basename from os import makedirs +from json import load -from tools.export.makefile import Makefile, GccArm, Armc5, IAR +from tools.export.exporters import Exporter, apply_supported_whitelist +from tools.targets import TARGET_MAP +from tools.utils import NotSupportedException +from tools.build_api import prepare_toolchain + +POST_BINARY_WHITELIST = set([ + "TEENSY3_1Code.binary_hook", + "MCU_NRF51Code.binary_hook", + "LPCTargetCode.lpc_patch", + "LPC4088Code.binary_hook" +]) -class Netbeans(Makefile): - """Generic Netbeans project. Intended to be subclassed by classes that - specify a type of Makefile. - """ +class GNUARMNetbeans(Exporter): + NAME = 'GNU ARM Netbeans' + TOOLCHAIN = 'GCC_ARM' - @property - def flags(self): + @classmethod + def is_target_supported(cls, target_name): + target = TARGET_MAP[target_name] + return apply_supported_whitelist( + cls.TOOLCHAIN, POST_BINARY_WHITELIST, target) + + def toolchain_flags(self, toolchain): """Returns a dictionary of toolchain flags. Keys of the dictionary are: cxx_flags - c++ flags @@ -23,168 +37,352 @@ class Netbeans(Makefile): asm_flags - assembler flags common_flags - common options - The difference from the parent function is that it does not - add macro definitions, since they are passed separately. + The difference from the above is that it takes a parameter. """ + # Note: use the config options from the currently selected toolchain. config_header = self.toolchain.get_config_header() + flags = {key + "_flags": copy.deepcopy(value) for key, value - in self.toolchain.flags.iteritems()} + in toolchain.flags.iteritems()} if config_header: config_header = relpath(config_header, self.resources.file_basepath[config_header]) - flags['c_flags'] += self.toolchain.get_config_option(config_header) - flags['cxx_flags'] += self.toolchain.get_config_option( - config_header) + header_options = self.toolchain.get_config_option(config_header) + flags['c_flags'] += header_options + flags['cxx_flags'] += header_options return flags - def generate(self): - """Generate Makefile, configurations.xml & project.xml Netbeans project file - """ - super(Netbeans, self).generate() + @staticmethod + def get_defines_and_remove_from_flags(flags_in, str_key): + defines = [] + flags_temp = copy.deepcopy(flags_in) + for f in flags_temp[str_key]: + f = f.strip() + if f.startswith('-D'): + defines.append(f[2:]) + flags_in[str_key].remove(f) - defines = [] # list of tuples ('D'/'U', [key, value]) (value is optional) - forced_includes = [] # list of strings - sources = [] # list of strings - headers = [] # list of strings + return defines + @staticmethod + def get_includes_and_remove_from_flags(flags_in, str_key): + includes = [] + flags_temp = copy.deepcopy(flags_in) next_is_include = False - for f in self.flags['c_flags'] + self.flags['cxx_flags']: + for f in flags_temp[str_key]: f = f.strip() if next_is_include: - forced_includes.append(f) + includes.append(f) + flags_in[str_key].remove(f) next_is_include = False continue - if f.startswith('-D'): - defines.append(('D', f[2:].split('=', 1))) - elif f.startswith('-U'): - defines.append(('U', [f[2:]])) - elif f == "-include": + if f == "-include": + flags_in[str_key].remove(f) next_is_include = True + return includes + + @staticmethod + def get_c_std_and_remove_from_flag(flags_in, str_key): + comp_std = '' + c_std = { + 'c90': 'c90', 'c89': 'c90', 'gnu90': 'gnu90', 'gnu89': 'gnu90', + 'c99': 'c99', 'c9x': 'c99', 'gnu99': 'gnu99', 'gnu9x': 'gnu98', + 'c11': 'c11', 'c1x': 'c11', 'gnu11': 'gnu11', 'gnu1x': 'gnu11' + } + cpp_std = { + 'c++98': 'cpp98', 'c++03': 'cpp98', + 'gnu++98': 'gnucpp98', 'gnu++03': 'gnucpp98', + 'c++0x': 'cpp0x', 'gnu++0x': 'gnucpp0x', + 'c++11': 'cpp11', 'gnu++11': 'gnucpp11', + 'c++1y': 'cpp1y', 'gnu++1y': 'gnucpp1y', + 'c++14': 'cpp14', 'gnu++14': 'gnucpp14', + 'c++1z': 'cpp1z', 'gnu++1z': 'gnucpp1z', + } + + flags_temp = copy.deepcopy(flags_in) + for f in flags_temp[str_key]: + f = f.strip() + if f.startswith('-std='): + comp_std = f[len('-std='):] + flags_in[str_key].remove(f) + elif f.startswith('-'): + std = f[len('-'):] + if std in c_std or std in cpp_std: + comp_std = std + flags_in[str_key].remove(f) + return comp_std + + def validate_resources(self): + if not self.resources.linker_script: + raise NotSupportedException("No linker script found.") + + def create_jinja_ctx(self): + + self.validate_resources() # Convert all Backslashes to Forward Slashes self.resources.win_to_unix() + print 'Include folders: {0}'.format(len(self.resources.inc_dirs)) + + print 'Symbols: {0}'.format(len(self.toolchain.get_symbols())) + + self.ld_script = self.filter_dot( + self.resources.linker_script) + print 'Linker script: {0}'.format(self.ld_script) + + # Read in all profiles, we'll extract compiler options. + profiles = self.get_all_profiles() + + profile_ids = [s.lower() for s in profiles] + profile_ids.sort() + + self.options = {} + for prof_id in profile_ids: + # There are 4 categories of options, a category common too + # all tools and a specific category for each of the tools. + opts = {} + opts['defines'] = {} + opts['common'] = {} + opts['as'] = {} + opts['c'] = {} + opts['cpp'] = {} + opts['ld'] = {} + + opts['id'] = prof_id + opts['name'] = opts['id'].capitalize() + + print + print 'Build configuration: {0}'.format(opts['name']) + + profile = profiles[prof_id] + + # A small hack, do not bother with src_path again, + # pass an empty string to avoid crashing. + src_paths = [''] + target_name = self.toolchain.target.name + + toolchain = prepare_toolchain( + src_paths, "", target_name, self.TOOLCHAIN, build_profile=[profile]) + + flags = self.toolchain_flags(toolchain) + + print 'Common flags:', ' '.join(flags['common_flags']) + print 'C++ flags:', ' '.join(flags['cxx_flags']) + print 'C flags:', ' '.join(flags['c_flags']) + print 'ASM flags:', ' '.join(flags['asm_flags']) + print 'Linker flags:', ' '.join(flags['ld_flags']) + + opts['defines'] = self.get_defines_and_remove_from_flags(flags, 'common_flags') + opts['forced_includes'] = self.get_includes_and_remove_from_flags(flags, 'common_flags') + opts['common'] = flags['common_flags'] + opts['as'] = flags['asm_flags'] + opts['c'] = flags['c_flags'] + opts['cpp'] = flags['cxx_flags'] + opts['ld'] = flags['ld_flags'] + + self.options[prof_id] = opts + + sources = [] # list of strings + + forced_includes = self.get_includes_and_remove_from_flags(flags, 'c_flags') + forced_includes += self.get_includes_and_remove_from_flags(flags, 'cxx_flags') + + # Remove Duplicates + forced_includes = list(set(forced_includes)) + + c_std = self.get_c_std_and_remove_from_flag(flags, 'c_flags') + cpp_std = self.get_c_std_and_remove_from_flag(flags, 'cxx_flags') + + # Make one list of all resources for r_type in ['c_sources', 's_sources', 'cpp_sources']: sources.extend(getattr(self.resources, r_type)) - for r_type in ['headers']: - headers.extend(getattr(self.resources, r_type)) + # Remove all leading './' + c_sources = [self.filter_dot(field) for field in getattr(self.resources, 'c_sources')] + cpp_sources = [self.filter_dot(field) for field in getattr(self.resources, 'cpp_sources')] + s_sources = [self.filter_dot(field) for field in getattr(self.resources, 's_sources')] + headers = [self.filter_dot(field) for field in getattr(self.resources, 'headers')] + sources = [self.filter_dot(field) for field in sources] + include_paths = [self.filter_dot(field) for field in self.resources.inc_dirs] - starting_dot = re.compile(r'(^[.]/|^[.]$)') - sources = [starting_dot.sub('', field) for field in sources] - headers = [starting_dot.sub('', field) for field in headers] - include_paths = [starting_dot.sub('', field) for field in self.resources.inc_dirs] + if 'nbproject' in include_paths: + include_paths.remove('nbproject') - headers.sort() - sources.sort() - - headers_output = create_netbeans_file_list(headers) - sources_output = create_netbeans_file_list(sources) - ctx = { + jinja_ctx = { 'name': self.project_name, 'elf_location': join('BUILD', self.project_name) + '.elf', 'c_symbols': self.toolchain.get_symbols(), 'asm_symbols': self.toolchain.get_symbols(True), - 'c_flags': self.flags['c_flags'], - 'cxx_flags': self.flags['cxx_flags'], + 'c_flags': flags['c_flags'], + 'cxx_flags': flags['cxx_flags'], 'ld_flags': self.flags['ld_flags'], 'asm_flags': self.flags['asm_flags'], 'common_flags': self.flags['common_flags'], 'target': self.target, 'include_paths': include_paths, - 'sources': sources, + 'forced_includes': forced_includes, + 'c_sources': c_sources, + 'cpp_sources': cpp_sources, + 's_sources': s_sources, 'headers': headers, - 'headers_folder': headers_output, - 'sources_folder': sources_output, - 'load_exe': str(self.LOAD_EXE).lower() + 'headers_folder': self.get_netbeans_file_list(sorted(headers)), + 'sources_folder': self.get_netbeans_file_list(sorted(sources)), + 'options': self.options, + 'c_std': self.get_netbeans_c_std(c_std), + 'cpp_std': self.get_netbeans_cpp_std(cpp_std), + 'linker_script': self.ld_script, } + return jinja_ctx + + def generate(self): + """Generate Makefile, configurations.xml & project.xml Netbeans project file + """ + # super(Netbeans, self).generate() + + jinja_ctx = self.create_jinja_ctx() + + print + print 'Create a GNU ARM Netbeans C++ managed project' + print 'Project name: {0}'.format(self.project_name) + print 'Target: {0}'.format(self.toolchain.target.name) + print 'Toolchain: {0}'.format(self.TOOLCHAIN) if not exists(join(self.export_dir, 'nbproject')): makedirs(join(self.export_dir, 'nbproject')) - self.gen_file('nb/configurations.tmpl', ctx, 'nbproject/configurations.xml') - self.gen_file('nb/project.tmpl', ctx, 'nbproject/project.xml') - self.gen_file('nb/mbedignore.tmpl', ctx, '.mbedignore') + self.gen_file('nb/configurations.tmpl', jinja_ctx, 'nbproject/configurations.xml') + self.gen_file('nb/project.tmpl', jinja_ctx, 'nbproject/project.xml') + self.gen_file('nb/mbedignore.tmpl', jinja_ctx, '.mbedignore') + self.gen_file('nb/Makefile.tmpl', jinja_ctx, 'Makefile') + print + print 'Done. Import the \'{0}\' project in Netbeans.'.format(self.project_name) -def create_netbeans_file_list(file_list): - output = [] - prev_dir = '' - folder_count = 1 - for idx, item in enumerate(file_list): - cur_dir = os.path.dirname(item) - dir_temp = os.path.normpath(cur_dir) - prev_dir_temp = os.path.normpath(prev_dir) - dir_list = dir_temp.split(os.sep) - prev_dir_list = prev_dir_temp.split(os.sep) - dir_depth = len(dir_list) + # ------------------------------------------------------------------------- - # print 'PREV_DIR: ' + str(prev_dir_list) + @staticmethod + def filter_dot(str_in): + """ + Remove the './' prefix, if present. + This function assumes that resources.win_to_unix() + replaced all windows backslashes with slashes. + """ + if str_in is None: + return None + if str_in[:2] == './': + return str_in[2:] + return str_in - # print 'CURR_DIR: ' + str(dir_list) + # ------------------------------------------------------------------------- - # Current File is in Directory: Compare the given dir with previous Dir - if cur_dir and prev_dir != cur_dir: - # evaluate all matched items (from current and previous list) - matched = [] - for element in dir_list: - if element in prev_dir_list: - matched.append(element) + @staticmethod + def get_all_profiles(): + tools_path = dirname(dirname(dirname(__file__))) + file_names = [join(tools_path, "profiles", fn) for fn in os.listdir( + join(tools_path, "profiles")) if fn.endswith(".json")] - # calculate difference between matched and length - diff = dir_depth - len(matched) + # print file_names - # print 'MATCHED: ' + str(matched) + # profile_names = [basename(fn).replace(".json", "") + # for fn in file_names] + # print profile_names - # if previous dir was not root - if prev_dir != '': - # if the elements count is not equal we calculate the difference - if len(dir_list) != len(prev_dir_list): - dir_depth_prev = len(prev_dir_list) - delta = dir_depth_prev - len(matched) + profiles = {} - for i in range(dir_depth_prev - delta, dir_depth_prev): + for fn in file_names: + content = load(open(fn)) + profile_name = basename(fn).replace(".json", "") + profiles[profile_name] = content + + return profiles + + @staticmethod + def get_netbeans_file_list(file_list): + output = [] + prev_dir = '' + folder_count = 1 + for idx, item in enumerate(file_list): + cur_dir = os.path.dirname(item) + dir_temp = os.path.normpath(cur_dir) + prev_dir_temp = os.path.normpath(prev_dir) + dir_list = dir_temp.split(os.sep) + prev_dir_list = prev_dir_temp.split(os.sep) + dir_depth = len(dir_list) + + # print 'PREV_DIR: ' + str(prev_dir_list) + + # print 'CURR_DIR: ' + str(dir_list) + + # Current File is in Directory: Compare the given dir with previous Dir + if cur_dir and prev_dir != cur_dir: + # evaluate all matched items (from current and previous list) + matched = [] + for element in dir_list: + if element in prev_dir_list: + matched.append(element) + + # calculate difference between matched and length + diff = dir_depth - len(matched) + + # print 'MATCHED: ' + str(matched) + + # if previous dir was not root + if prev_dir != '': + # if the elements count is not equal we calculate the difference + if len(dir_list) != len(prev_dir_list): + dir_depth_prev = len(prev_dir_list) + delta = dir_depth_prev - len(matched) + + for i in range(dir_depth_prev - delta, dir_depth_prev): + output.append('') + + # if the elements count is equal, we subtract the matched length from the total length + else: + for i in range(len(matched), len(dir_list)): + output.append('') + + for i in range(dir_depth - diff, dir_depth): + output.append('') + folder_count += 1 + + # Current File is in root + else: + # Close Tag if we are in root and the previous dir wasn't + if cur_dir == '' and prev_dir != '': + for i in range(0, len(prev_dir_list)): output.append('') - # if the elements count is equal, we subtract the matched length from the total length - else: - for i in range(len(matched), len(dir_list)): - output.append('') - - for i in range(dir_depth - diff, dir_depth): - output.append('') - folder_count += 1 - - # Current File is in root - else: - # Close Tag if we are in root and the previous dir wasn't - if cur_dir == '' and prev_dir != '': - for i in range(0, len(prev_dir_list)): + # Save the Current Dir + prev_dir = cur_dir + output.append('' + str(item) + '') + # if last iteration close all open tags + if idx == len(file_list) - 1 and cur_dir != '': + for i in range(0, len(dir_list)): output.append('') - # Save the Current Dir - prev_dir = cur_dir - output.append('' + str(item) + '') - # if last iteration close all open tags - if idx == len(file_list) - 1 and cur_dir != '': - for i in range(0, len(dir_list)): - output.append('') + return output - return output + @staticmethod + def get_netbeans_c_std(c_std): + c_std_netbeans = 0 + if '89' in c_std: + c_std_netbeans = 2 + elif '99' in c_std: + c_std_netbeans = 3 + elif '11' in c_std: + c_std_netbeans = 10 + return c_std_netbeans - -class NetbeansGcc(Netbeans, GccArm): - LOAD_EXE = True - NAME = "Netbeans-GCC-ARM" - - -class NetbeansArmc5(Netbeans, Armc5): - LOAD_EXE = False - NAME = "Netbeans-Armc5" - - -class NetbeansIAR(Netbeans, IAR): - LOAD_EXE = True - NAME = "Netbeans-IAR" + @staticmethod + def get_netbeans_cpp_std(cpp_std): + cpp_std_netbeans = 0 + if '98' in cpp_std: + cpp_std_netbeans = 4 + elif '11' in cpp_std: + cpp_std_netbeans = 8 + elif '14' in cpp_std: + cpp_std_netbeans = 11 + return cpp_std_netbeans diff --git a/tools/export/nb/configurations.tmpl b/tools/export/nb/configurations.tmpl index 93241d6934..6f0c69992c 100644 --- a/tools/export/nb/configurations.tmpl +++ b/tools/export/nb/configurations.tmpl @@ -1,8 +1,6 @@ - - @@ -10,6 +8,11 @@ {{ header }} {% endfor %} + + {{ linker_script }} + @@ -21,6 +24,10 @@ {{ source }} {% endfor %} + + Makefile + ^(nbproject)$ + + . + Makefile - + {% for id in options -%} + {% set opts = options[id] %} + default true @@ -43,37 +56,53 @@ + {{ c_std }} - {% for include in include_paths -%} - {{ include }} - {% endfor %} + {% for inc_dir in include_paths -%}{% if inc_dir -%} + {{ inc_dir }} + {% endif -%} + {% endfor -%} - - {% for flag in c_flags -%} - {{ flag }} - {% endfor %} + + {% for inc_file in forced_includes -%} + {{ inc_file }} + {% endfor -%} + + {%- for flag in c_flags -%}{{ flag+" "}}{%- endfor -%} + {%- for item in opts['common'] -%}{{ item+" "}}{%- endfor -%} + {% for item in opts['defines'] -%} + {{ item }} + {% endfor -%} {% for symbol in c_symbols -%} {{ symbol }} - {% endfor %} + {% endfor -%} + {{ cpp_std }} - {% for include in include_paths -%} - {{ include }} - {% endfor %} + {% for inc_dir in include_paths -%}{% if inc_dir -%} + {{ inc_dir }} + {% endif -%} + {% endfor -%} - - {% for flag in cxx_flags -%} - {{ flag }} - {% endfor %} + + {% for inc_file in forced_includes -%} + {{ inc_file }} + {% endfor -%} + + {%- for flag in cxx_flags -%}{{ flag+" "}}{%- endfor -%} + {%- for item in opts['common'] -%}{{ item+" "}}{%- endfor -%} + {% for item in opts['defines'] -%} + {{ item }} + {% endfor -%} {% for symbol in c_symbols -%} {{ symbol }} - {% endfor %} + {% endfor -%} @@ -82,124 +111,57 @@ 5 - {% for include in include_paths -%} - {{ include }} - {% endfor %} + {% for inc_dir in include_paths -%}{% if inc_dir -%} + {{ inc_dir }} + {% endif -%} + {% endfor -%} - - {% for flag in asm_flags -%} - {{ flag }} - {% endfor %} + + {% for inc_file in forced_includes -%} + {{ inc_file }} + {% endfor -%} + + {%- for flag in asm_flags -%}{{ flag+" "}}{%- endfor -%} + {%- for item in opts['common'] -%}{{ item+" "}}{%- endfor -%} {% for symbol in asm_symbols -%} {{ symbol }} - {% endfor %} + {% endfor -%} - - {% for flag in ld_flags -%} - {{ flag }} - {% endfor %} - + arm-none-eabi-gcc + {%- for symbol in opts['ld'] -%}{{ symbol+" "}}{%- endfor -%} - {% for h in headers -%} - {% endfor %} - {% for s in sources -%} - - - {% endfor %} - - - - - - - default - true - false - - - {% for h in headers -%} - - - {% endfor %} - {% for s in sources -%} - - - {% endfor %} - - 5 - - {% for include in include_paths -%} - {{ include }} - {% endfor %} - - - {% for flag in c_flags -%} - {{ flag }} - {% endfor %} - - - {% for symbol in c_symbols -%} - {{ symbol }} - {% endfor %} - + {% endfor -%} + {% for s in c_sources -%} + + - - 5 - - {% for include in include_paths -%} - {{ include }} - {% endfor %} - - - {% for flag in cxx_flags -%} - {{ flag }} - {% endfor %} - - - {% for symbol in c_symbols -%} - {{ symbol }} - {% endfor %} - + + {% endfor -%} + {% for s in cpp_sources -%} + + - - 5 - - - 5 - - {% for include in include_paths -%} - {{ include }} - {% endfor %} - - - {% for flag in asm_flags -%} - {{ flag }} - {% endfor %} - - - {% for symbol in asm_symbols -%} - {{ symbol }} - {% endfor %} - - - - - {% for flag in ld_flags -%} - {{ flag }} - {% endfor %} - - - - + + {% endfor -%} + {% for s in s_sources -%} + + + {% endfor -%} + + + + + + {% endfor -%} diff --git a/tools/export/nb/project.tmpl b/tools/export/nb/project.tmpl index c73b0eebbd..3d4ea0d1bf 100644 --- a/tools/export/nb/project.tmpl +++ b/tools/export/nb/project.tmpl @@ -4,9 +4,9 @@ {{name}} - + c cpp - + h UTF-8