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.
Diff: export/mcuxpresso/__init__.py
- Revision:
- 40:7d3fa6b99b2b
- Child:
- 43:2a7da56ebd24
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/export/mcuxpresso/__init__.py Tue Oct 10 16:56:30 2017 -0500
@@ -0,0 +1,742 @@
+"""
+mbed SDK
+Copyright (c) 2011-2016 ARM Limited
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Title: MCUXpresso exporter.
+
+Description: Creates a managed build project that can be imported by
+the MCUXpresso IDE from NXP
+
+Based on GNU ARM Eclipse Exporter from Liviu Ionescu <ilg@livius.net>
+modified for MCUXpresso by Johannes Stratmann <jojos62@online.de>
+"""
+
+import copy
+import tempfile
+import shutil
+
+from subprocess import Popen, PIPE
+from os import getcwd, remove
+from os.path import splitext, basename, exists
+from random import randint
+
+from tools.export.gnuarmeclipse import GNUARMEclipse, UID
+from tools.export.exporters import 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 MCUXpresso(GNUARMEclipse):
+ NAME = 'MCUXpresso'
+ TOOLCHAIN = 'GCC_ARM'
+
+ MBED_CONFIG_HEADER_SUPPORTED = True
+
+ @classmethod
+ def is_target_supported(cls, target_name):
+ # targes suppoerted when .cproject templatefile exists
+ if exists(cls.TEMPLATE_DIR + '/mcuxpresso/' + target_name + '_cproject.tmpl'):
+ target = TARGET_MAP[target_name]
+ return apply_supported_whitelist(
+ cls.TOOLCHAIN, POST_BINARY_WHITELIST, target)
+ else:
+ return False
+
+ # override
+ def generate(self):
+ """
+ Generate the .project and .cproject files.
+ """
+ if not self.resources.linker_script:
+ raise NotSupportedException("No linker script found.")
+
+ print
+ print 'Create a GNU ARM Eclipse 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)
+
+ self.resources.win_to_unix()
+
+ # TODO: use some logger to display additional info if verbose
+
+ self.libraries = []
+ # print 'libraries'
+ # print self.resources.libraries
+ for lib in self.resources.libraries:
+ l, _ = splitext(basename(lib))
+ self.libraries.append(l[3:])
+
+ self.system_libraries = [
+ 'stdc++', 'supc++', 'm', 'c', 'gcc', 'nosys'
+ ]
+
+ # 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()
+
+ # TODO: get the list from existing .cproject
+ build_folders = [s.capitalize() for s in profile_ids]
+ build_folders.append('BUILD')
+ # print build_folders
+
+ objects = [self.filter_dot(s) for s in self.resources.objects]
+ for bf in build_folders:
+ objects = [o for o in objects if not o.startswith(bf + '/')]
+ # print 'objects'
+ # print objects
+
+ self.compute_exclusions()
+
+ self.include_path = [
+ self.filter_dot(s) for s in self.resources.inc_dirs]
+ print 'Include folders: {0}'.format(len(self.include_path))
+
+ self.as_defines = self.toolchain.get_symbols(True)
+ self.c_defines = self.toolchain.get_symbols()
+ self.cpp_defines = self.c_defines
+ print 'Symbols: {0}'.format(len(self.c_defines))
+
+ self.ld_script = self.filter_dot(
+ self.resources.linker_script)
+ print 'Linker script: {0}'.format(self.ld_script)
+
+ self.options = {}
+ profile_ids.remove('develop')
+ for 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['common'] = {}
+ opts['as'] = {}
+ opts['c'] = {}
+ opts['cpp'] = {}
+ opts['ld'] = {}
+
+ opts['id'] = id
+ opts['name'] = opts['id'].capitalize()
+
+ print
+ print 'Build configuration: {0}'.format(opts['name'])
+
+ profile = profiles[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])
+
+ # Hack to fill in build_dir
+ toolchain.build_dir = self.toolchain.build_dir
+
+ 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'])
+
+ # Most GNU ARM Eclipse options have a parent,
+ # either debug or release.
+ if '-O0' in flags['common_flags'] or '-Og' in flags['common_flags']:
+ opts['parent_id'] = 'debug'
+ else:
+ opts['parent_id'] = 'release'
+
+ self.process_options(opts, flags)
+
+ opts['as']['defines'] = self.as_defines
+ opts['c']['defines'] = self.c_defines
+ opts['cpp']['defines'] = self.cpp_defines
+
+ opts['common']['include_paths'] = self.include_path
+ opts['common']['excluded_folders'] = '|'.join(
+ self.excluded_folders)
+ self.excluded_folders = [item.replace("\\", "/") for item in self.excluded_folders]
+
+ opts['ld']['library_paths'] = [
+ self.filter_dot(s) for s in self.resources.lib_dirs]
+
+ opts['ld']['object_files'] = objects
+ opts['ld']['user_libraries'] = self.libraries
+ opts['ld']['system_libraries'] = self.system_libraries
+ opts['ld']['script'] = "linker-script-%s.ld" % id
+ opts['cpp_cmd'] = " ".join(toolchain.preproc)
+
+ # Unique IDs used in multiple places.
+ # Those used only once are implemented with {{u.id}}.
+ u = UID()
+ uid = {}
+ uid['config'] = u.id
+ uid['tool_c_compiler'] = u.id
+ uid['tool_c_compiler_input'] = u.id
+ uid['tool_cpp_compiler'] = u.id
+ uid['tool_cpp_compiler_input'] = u.id
+
+ opts['uid'] = uid
+
+ self.options[id] = opts
+
+ jinja_ctx = {
+ 'name': self.project_name,
+ 'ld_script': self.ld_script,
+
+ # Compiler & linker command line options
+ 'options': self.options,
+
+ # Must be an object with an `id` property, which
+ # will be called repeatedly, to generate multiple UIDs.
+ 'u': u,
+ }
+
+ self.gen_file('mcuxpresso/.project.tmpl', jinja_ctx,
+ '.project', trim_blocks=True, lstrip_blocks=True)
+ self.gen_file('mcuxpresso/{0}_cproject.tmpl'.format(target_name), jinja_ctx,
+ '.cproject', trim_blocks=True, lstrip_blocks=True)
+ self.gen_file('mcuxpresso/makefile.targets.tmpl', jinja_ctx,
+ 'makefile.targets', trim_blocks=True, lstrip_blocks=True)
+ self.gen_file('mcuxpresso/mbedignore.tmpl', jinja_ctx, '.mbedignore')
+
+ print
+ print 'Done. Import the \'{0}\' project in Eclipse.'.format(self.project_name)
+
+ # override
+ @staticmethod
+ def build(project_name, log_name="build_log.txt", cleanup=True):
+ """
+ Headless build an Eclipse project.
+
+ The following steps are performed:
+ - a temporary workspace is created,
+ - the project is imported,
+ - a clean build of all configurations is performed and
+ - the temporary workspace is removed.
+
+ The build results are in the Debug & Release folders.
+
+ All executables (eclipse & toolchain) must be in the PATH.
+
+ The general method to start a headless Eclipse build is:
+
+ $ eclipse \
+ --launcher.suppressErrors \
+ -nosplash \
+ -application org.eclipse.cdt.managedbuilder.core.headlessbuild \
+ -data /path/to/workspace \
+ -import /path/to/project \
+ -cleanBuild "project[/configuration] | all"
+ """
+
+ # TODO: possibly use the log file.
+
+ # Create a temporary folder for the workspace.
+ tmp_folder = tempfile.mkdtemp()
+
+ cmd = [
+ 'mcuxpressoide',
+ '--launcher.suppressErrors',
+ '-nosplash',
+ '-application org.eclipse.cdt.managedbuilder.core.headlessbuild',
+ '-data', tmp_folder,
+ '-import', getcwd(),
+ '-cleanBuild', project_name
+ ]
+
+ p = Popen(' '.join(cmd), shell=True, stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ ret_code = p.returncode
+ stdout_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
+ err_string = "=" * 10 + "STDERR" + "=" * 10 + "\n"
+ err_string += err
+ success = any(l.startswith("Finished building target:") for l in out.split("\n"))
+
+ if success:
+ ret_string = "SUCCESS\n"
+ else:
+ ret_string = "FAILURE: build returned %s \n" % ret_code
+
+ print "%s\n%s\n%s\n%s" % (stdout_string, out, err_string, ret_string)
+
+ if log_name:
+ # Write the output to the log file
+ with open(log_name, 'w+') as f:
+ f.write(stdout_string)
+ f.write(out)
+ f.write(err_string)
+ f.write(ret_string)
+
+ # Cleanup the exported and built files
+ if cleanup:
+ if exists(log_name):
+ remove(log_name)
+ remove('.project')
+ remove('.cproject')
+ if exists('Debug'):
+ shutil.rmtree('Debug')
+ if exists('Release'):
+ shutil.rmtree('Release')
+ if exists('makefile.targets'):
+ remove('makefile.targets')
+
+ # Always remove the temporary folder.
+ if exists(tmp_folder):
+ shutil.rmtree(tmp_folder)
+
+ return not(success)
+
+
+ # -------------------------------------------------------------------------
+
+ def process_options(self, opts, flags_in):
+ """
+ CDT managed projects store lots of build options in separate
+ variables, with separate IDs in the .cproject file.
+ When the CDT build is started, all these options are brought
+ together to compose the compiler and linker command lines.
+
+ Here the process is reversed, from the compiler and linker
+ command lines, the options are identified and various flags are
+ set to control the template generation process.
+
+ Once identified, the options are removed from the command lines.
+
+ The options that were not identified are options that do not
+ have CDT equivalents and will be passed in the 'Other options'
+ categories.
+
+ Although this process does not have a very complicated logic,
+ given the large number of explicit configuration options
+ used by the GNU ARM Eclipse managed build plug-in, it is tedious...
+ """
+
+ # Make a copy of the flags, to be one by one removed after processing.
+ flags = copy.deepcopy(flags_in)
+
+ if False:
+ print
+ print 'common_flags', flags['common_flags']
+ print 'asm_flags', flags['asm_flags']
+ print 'c_flags', flags['c_flags']
+ print 'cxx_flags', flags['cxx_flags']
+ print 'ld_flags', flags['ld_flags']
+
+ # Initialise the 'last resort' options where all unrecognised
+ # options will be collected.
+ opts['as']['other'] = ''
+ opts['c']['other'] = ''
+ opts['cpp']['other'] = ''
+ opts['ld']['other'] = ''
+
+ MCPUS = {
+ 'Cortex-M0': {'mcpu': 'cortex-m0', 'fpu_unit': None},
+ 'Cortex-M0+': {'mcpu': 'cortex-m0plus', 'fpu_unit': None},
+ 'Cortex-M1': {'mcpu': 'cortex-m1', 'fpu_unit': None},
+ 'Cortex-M3': {'mcpu': 'cortex-m3', 'fpu_unit': None},
+ 'Cortex-M4': {'mcpu': 'cortex-m4', 'fpu_unit': None},
+ 'Cortex-M4F': {'mcpu': 'cortex-m4', 'fpu_unit': 'fpv4spd16'},
+ 'Cortex-M7': {'mcpu': 'cortex-m7', 'fpu_unit': None},
+ 'Cortex-M7F': {'mcpu': 'cortex-m7', 'fpu_unit': 'fpv4spd16'},
+ 'Cortex-M7FD': {'mcpu': 'cortex-m7', 'fpu_unit': 'fpv5d16'},
+ 'Cortex-A9': {'mcpu': 'cortex-a9', 'fpu_unit': 'vfpv3'}
+ }
+
+ MCPU_NXP = {
+ 'cortex-m7' : 'cm7',
+ 'cortex-m4' : 'cm4',
+ 'cortex-m3' : 'cm3',
+ 'cortex-m1' : 'cm1',
+ 'cortex-m0' : 'cm0',
+ 'cortex-m0.small-multiply' : 'cm0.smallmul',
+ 'cortex-m0plus' : 'cm0plus',
+ 'cortex-m0plus.small-multiply' : 'cm0plus.smallmul'
+ }
+
+ # Remove options that are supplied by CDT
+ self.remove_option(flags['common_flags'], '-c')
+ self.remove_option(flags['common_flags'], '-MMD')
+
+ # As 'plan B', get the CPU from the target definition.
+ core = self.toolchain.target.core
+
+ opts['common']['arm.target.family'] = None
+
+ # cortex-m0, cortex-m0-small-multiply, cortex-m0plus,
+ # cortex-m0plus-small-multiply, cortex-m1, cortex-m1-small-multiply,
+ # cortex-m3, cortex-m4, cortex-m7.
+ str = self.find_options(flags['common_flags'], '-mcpu=')
+ if str != None:
+ opts['common']['arm.target.family'] = str[len('-mcpu='):]
+ opts['common']['arm.target.family_nxp'] = MCPU_NXP[str[len('-mcpu='):]]
+ self.remove_option(flags['common_flags'], str)
+ self.remove_option(flags['ld_flags'], str)
+ else:
+ if core not in MCPUS:
+ raise NotSupportedException(
+ 'Target core {0} not supported.'.format(core))
+ opts['common']['arm.target.family'] = MCPUS[core]['mcpu']
+
+ opts['common']['arm.target.arch'] = 'none'
+ str = self.find_options(flags['common_flags'], '-march=')
+ arch = str[len('-march='):]
+ archs = {'armv6-m': 'armv6-m', 'armv7-m': 'armv7-m', 'armv7-a': 'armv7-a'}
+ if arch in archs:
+ opts['common']['arm.target.arch'] = archs[arch]
+ self.remove_option(flags['common_flags'], str)
+
+ opts['common']['arm.target.instructionset'] = 'thumb'
+ if '-mthumb' in flags['common_flags']:
+ self.remove_option(flags['common_flags'], '-mthumb')
+ self.remove_option(flags['ld_flags'], '-mthumb')
+ elif '-marm' in flags['common_flags']:
+ opts['common']['arm.target.instructionset'] = 'arm'
+ self.remove_option(flags['common_flags'], '-marm')
+ self.remove_option(flags['ld_flags'], '-marm')
+
+ opts['common']['arm.target.thumbinterwork'] = False
+ if '-mthumb-interwork' in flags['common_flags']:
+ opts['common']['arm.target.thumbinterwork'] = True
+ self.remove_option(flags['common_flags'], '-mthumb-interwork')
+
+ opts['common']['arm.target.endianness'] = None
+ if '-mlittle-endian' in flags['common_flags']:
+ opts['common']['arm.target.endianness'] = 'little'
+ self.remove_option(flags['common_flags'], '-mlittle-endian')
+ elif '-mbig-endian' in flags['common_flags']:
+ opts['common']['arm.target.endianness'] = 'big'
+ self.remove_option(flags['common_flags'], '-mbig-endian')
+
+ opts['common']['arm.target.fpu.unit'] = None
+ opts['common']['arm.target.fpu.unit_nxp'] = None
+ # default, fpv4spd16, fpv5d16, fpv5spd16
+ str = self.find_options(flags['common_flags'], '-mfpu=')
+ if str != None:
+ fpu = str[len('-mfpu='):]
+ fpus = {
+ 'fpv4-sp-d16': 'fpv4spd16',
+ 'fpv5-d16': 'fpv5d16',
+ 'fpv5-sp-d16': 'fpv5spd16'
+ }
+ fpus_nxp = {
+ 'fpv4-sp-d16': 'fpv4',
+ 'fpv5-d16': 'fpv5dp',
+ 'fpv5-sp-d16': 'fpv5sp'
+ }
+ if fpu in fpus:
+ opts['common']['arm.target.fpu.unit'] = fpus[fpu]
+ opts['common']['arm.target.fpu.unit_nxp'] = fpus_nxp[fpu]
+
+ self.remove_option(flags['common_flags'], str)
+ self.remove_option(flags['ld_flags'], str)
+ if opts['common']['arm.target.fpu.unit'] == None:
+ if core not in MCPUS:
+ raise NotSupportedException(
+ 'Target core {0} not supported.'.format(core))
+ if MCPUS[core]['fpu_unit']:
+ opts['common'][
+ 'arm.target.fpu.unit'] = MCPUS[core]['fpu_unit']
+
+ # soft, softfp, hard.
+ str = self.find_options(flags['common_flags'], '-mfloat-abi=')
+ if str != None:
+ opts['common']['arm.target.fpu.abi'] = str[
+ len('-mfloat-abi='):]
+ self.remove_option(flags['common_flags'], str)
+ self.remove_option(flags['ld_flags'], str)
+ if opts['common']['arm.target.fpu.abi'] == 'hard':
+ opts['common']['arm.target.fpu.unit_nxp'] += '.hard'
+
+ # Default optimisation level for Release.
+ opts['common']['optimization.level'] = '-Os'
+
+ # If the project defines an optimisation level, it is used
+ # only for the Release configuration, the Debug one used '-Og'.
+ str = self.find_options(flags['common_flags'], '-O')
+ if str != None:
+ levels = {
+ '-O0': 'none', '-O1': 'optimize', '-O2': 'more',
+ '-O3': 'most', '-Os': 'size', '-Og': 'debug'
+ }
+ if str in levels:
+ opts['common']['optimization.level'] = levels[str]
+ self.remove_option(flags['common_flags'], str)
+
+ include_files = []
+ for all_flags in [flags['common_flags'], flags['c_flags'], flags['cxx_flags']]:
+ while '-include' in all_flags:
+ ix = all_flags.index('-include')
+ str = all_flags[ix + 1]
+ if str not in include_files:
+ include_files.append(str)
+ self.remove_option(all_flags, '-include')
+ self.remove_option(all_flags, str)
+
+ opts['common']['include_files'] = include_files
+
+ if '-ansi' in flags['c_flags']:
+ opts['c']['compiler.std'] = '-ansi'
+ self.remove_option(flags['c_flags'], str)
+ else:
+ str = self.find_options(flags['c_flags'], '-std')
+ std = str[len('-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'
+ }
+ if std in c_std:
+ opts['c']['compiler.std'] = c_std[std]
+ self.remove_option(flags['c_flags'], str)
+
+ if '-ansi' in flags['cxx_flags']:
+ opts['cpp']['compiler.std'] = '-ansi'
+ self.remove_option(flags['cxx_flags'], str)
+ else:
+ str = self.find_options(flags['cxx_flags'], '-std')
+ std = str[len('-std='):]
+ cpp_std = {
+ 'c++98': 'cpp98', 'c++03': 'cpp03',
+ 'gnu++98': 'gnupp98', 'gnu++03': 'gnupp03',
+ 'c++0x': 'cpp03', 'gnu++0x': 'gnupp03',
+ 'c++11': 'cpp11', 'gnu++11': 'gnupp11',
+ 'c++1y': 'cpp11', 'gnu++1y': 'gnupp11',
+ 'c++14': 'cpp14', 'gnu++14': 'gnupp14',
+ 'c++1z': 'cpp1z', 'gnu++1z': 'gnupp1z',
+ }
+ if std in cpp_std:
+ opts['cpp']['compiler.std'] = cpp_std[std]
+ self.remove_option(flags['cxx_flags'], str)
+
+ # Common optimisation options.
+ optimization_options = {
+ '-flto': 'optimization.lto',
+ '--ffat-lto-objects': 'optimization.lto_objects'
+ }
+ for option in optimization_options:
+ opts['common'][optimization_options[option]] = False
+ if option in flags['common_flags']:
+ opts['common'][optimization_options[option]] = True
+ self.remove_option(flags['common_flags'], option)
+
+ # Common warning options.
+ warning_options = {
+ '-fsyntax-only': 'warnings.syntaxonly',
+ '-pedantic': 'warnings.pedantic',
+ '-pedantic-errors': 'warnings.pedanticerrors',
+ '-w': 'warnings.nowarn',
+ '-Wall': 'warnings.allwarn',
+ '-Wextra': 'warnings.extrawarn',
+ '-Wconversion': 'warnings.conversion',
+ '-Werror': 'warnings.toerrors',
+ }
+
+ for option in warning_options:
+ opts['common'][warning_options[option]] = False
+ if option in flags['common_flags']:
+ opts['common'][warning_options[option]] = True
+ self.remove_option(flags['common_flags'], option)
+
+ # Common debug options.
+ debug_levels = {
+ '-g': 'default',
+ '-g1': 'minimal',
+ '-g3': 'max',
+ }
+ opts['common']['debugging.level'] = 'none'
+ for option in debug_levels:
+ if option in flags['common_flags']:
+ opts['common'][
+ 'debugging.level'] = debug_levels[option]
+ self.remove_option(flags['common_flags'], option)
+
+
+ opts['common']['debugging.prof'] = False
+ if '-p' in flags['common_flags']:
+ opts['common']['debugging.prof'] = True
+ self.remove_option(flags['common_flags'], '-p')
+
+ opts['common']['debugging.gprof'] = False
+ if '-pg' in flags['common_flags']:
+ opts['common']['debugging.gprof'] = True
+ self.remove_option(flags['common_flags'], '-gp')
+
+ # Assembler options.
+ opts['as']['usepreprocessor'] = False
+ while '-x' in flags['asm_flags']:
+ ix = flags['asm_flags'].index('-x')
+ str = flags['asm_flags'][ix + 1]
+
+ if str == 'assembler-with-cpp':
+ opts['as']['usepreprocessor'] = True
+ else:
+ # Collect all other assembler options.
+ opts['as']['other'] += ' -x ' + str
+
+ self.remove_option(flags['asm_flags'], '-x')
+ self.remove_option(flags['asm_flags'], 'assembler-with-cpp')
+
+ opts['as']['nostdinc'] = False
+ if '-nostdinc' in flags['asm_flags']:
+ opts['as']['nostdinc'] = True
+ self.remove_option(flags['asm_flags'], '-nostdinc')
+
+ opts['as']['verbose'] = False
+ if '-v' in flags['asm_flags']:
+ opts['as']['verbose'] = True
+ self.remove_option(flags['asm_flags'], '-v')
+
+ # C options.
+ opts['c']['nostdinc'] = False
+ if '-nostdinc' in flags['c_flags']:
+ opts['c']['nostdinc'] = True
+ self.remove_option(flags['c_flags'], '-nostdinc')
+
+ opts['c']['verbose'] = False
+ if '-v' in flags['c_flags']:
+ opts['c']['verbose'] = True
+ self.remove_option(flags['c_flags'], '-v')
+
+
+ # C++ options.
+ opts['cpp']['nostdinc'] = False
+ if '-nostdinc' in flags['cxx_flags']:
+ opts['cpp']['nostdinc'] = True
+ self.remove_option(flags['cxx_flags'], '-nostdinc')
+
+ opts['cpp']['nostdincpp'] = False
+ if '-nostdinc++' in flags['cxx_flags']:
+ opts['cpp']['nostdincpp'] = True
+ self.remove_option(flags['cxx_flags'], '-nostdinc++')
+
+ optimization_options = {
+ '-fno-exceptions': 'optimization.noexceptions',
+ '-fno-rtti': 'optimization.nortti',
+ '-fno-use-cxa-atexit': 'optimization.nousecxaatexit',
+ '-fno-threadsafe-statics': 'optimization.nothreadsafestatics',
+ }
+
+ for option in optimization_options:
+ opts['cpp'][optimization_options[option]] = False
+ if option in flags['cxx_flags']:
+ opts['cpp'][optimization_options[option]] = True
+ if option in flags['common_flags']:
+ opts['cpp'][optimization_options[option]] = True
+
+ opts['cpp']['verbose'] = False
+ if '-v' in flags['cxx_flags']:
+ opts['cpp']['verbose'] = True
+ self.remove_option(flags['cxx_flags'], '-v')
+
+ # Linker options.
+ linker_options = {
+ '-nostartfiles': 'nostart',
+ '-nodefaultlibs': 'nodeflibs',
+ '-nostdlib': 'nostdlibs',
+ }
+
+ for option in linker_options:
+ opts['ld'][linker_options[option]] = False
+ if option in flags['ld_flags']:
+ opts['ld'][linker_options[option]] = True
+ self.remove_option(flags['ld_flags'], option)
+
+ opts['ld']['gcsections'] = False
+ if '-Wl,--gc-sections' in flags['ld_flags']:
+ opts['ld']['gcsections'] = True
+ self.remove_option(flags['ld_flags'], '-Wl,--gc-sections')
+
+ opts['ld']['flags'] = []
+ to_remove = []
+ for opt in flags['ld_flags']:
+ if opt.startswith('-Wl,--wrap,'):
+ opts['ld']['flags'].append(
+ '--wrap=' + opt[len('-Wl,--wrap,'):])
+ to_remove.append(opt)
+ for opt in to_remove:
+ self.remove_option(flags['ld_flags'], opt)
+
+ # Other tool remaining options are separated by category.
+ opts['as']['otherwarnings'] = self.find_options(
+ flags['asm_flags'], '-W')
+
+ opts['c']['otherwarnings'] = self.find_options(
+ flags['c_flags'], '-W')
+ opts['c']['otheroptimizations'] = self.find_options(flags[
+ 'c_flags'], '-f')
+
+ opts['cpp']['otherwarnings'] = self.find_options(
+ flags['cxx_flags'], '-W')
+ opts['cpp']['otheroptimizations'] = self.find_options(
+ flags['cxx_flags'], '-f')
+
+ # Other common remaining options are separated by category.
+ opts['common']['optimization.other'] = self.find_options(
+ flags['common_flags'], '-f')
+ opts['common']['warnings.other'] = self.find_options(
+ flags['common_flags'], '-W')
+
+ # Remaining common flags are added to each tool.
+ opts['as']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + \
+ ' '.join(flags['asm_flags'])
+ opts['c']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['c_flags'])
+ opts['cpp']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + \
+ ' '.join(flags['cxx_flags'])
+ opts['ld']['other'] += ' ' + \
+ ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['ld_flags'])
+
+ if len(self.system_libraries) > 0:
+ opts['ld']['other'] += ' -Wl,--start-group '
+ opts['ld'][
+ 'other'] += ' '.join('-l' + s for s in self.system_libraries) + ' '
+ opts['ld'][
+ 'other'] += ' '.join('-l' + s for s in self.libraries)
+ opts['ld']['other'] += ' -Wl,--end-group '
+
+ # Strip all 'other' flags, since they might have leading spaces.
+ opts['as']['other'] = opts['as']['other'].strip()
+ opts['c']['other'] = opts['c']['other'].strip()
+ opts['cpp']['other'] = opts['cpp']['other'].strip()
+ opts['ld']['other'] = opts['ld']['other'].strip()
+
+ if False:
+ print
+ print opts
+
+ print
+ print 'common_flags', flags['common_flags']
+ print 'asm_flags', flags['asm_flags']
+ print 'c_flags', flags['c_flags']
+ print 'cxx_flags', flags['cxx_flags']
+ print 'ld_flags', flags['ld_flags']
+
