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 Title: MCUXpresso exporter.
00018 
00019 Description: Creates a managed build project that can be imported by
00020 the MCUXpresso IDE from NXP
00021 
00022 Based on GNU ARM Eclipse Exporter from Liviu Ionescu <ilg@livius.net>
00023 modified for MCUXpresso by Johannes Stratmann <jojos62@online.de>
00024 """
00025 from __future__ import print_function, absolute_import
00026 from builtins import str
00027 
00028 import copy
00029 import tempfile
00030 import shutil
00031 
00032 from subprocess import Popen, PIPE
00033 from os import getcwd, remove
00034 from os.path import splitext, basename, exists
00035 from random import randint
00036 
00037 from tools.export.gnuarmeclipse import GNUARMEclipse, UID
00038 from tools.export.exporters import apply_supported_whitelist
00039 from tools.targets import TARGET_MAP
00040 from tools.utils import NotSupportedException
00041 from tools.build_api import prepare_toolchain
00042 
00043 
00044 POST_BINARY_WHITELIST = set([
00045     "TEENSY3_1Code.binary_hook",
00046     "MCU_NRF51Code.binary_hook",
00047     "LPCTargetCode.lpc_patch",
00048     "LPC4088Code.binary_hook"
00049 ])
00050 
00051 class MCUXpresso(GNUARMEclipse):
00052     NAME = 'MCUXpresso'
00053     TOOLCHAIN = 'GCC_ARM'
00054 
00055     MBED_CONFIG_HEADER_SUPPORTED = True
00056 
00057     @classmethod
00058     def is_target_supported(cls, target_name):
00059         # targes suppoerted when .cproject templatefile exists
00060         if exists(cls.TEMPLATE_DIR + '/mcuxpresso/' + target_name + '_cproject.tmpl'):
00061             target = TARGET_MAP[target_name]
00062             return apply_supported_whitelist(
00063                 cls.TOOLCHAIN, POST_BINARY_WHITELIST, target)
00064         else:
00065             return False
00066 
00067     # override
00068     def generate(self):
00069         """
00070         Generate the .project and .cproject files.
00071         """
00072         if not self.resources.linker_script:
00073             raise NotSupportedException("No linker script found.")
00074 
00075         self.resources.win_to_unix()
00076 
00077         # TODO: use some logger to display additional info if verbose
00078 
00079         self.libraries = []
00080         # print 'libraries'
00081         # print self.resources.libraries
00082         for lib in self.resources.libraries:
00083             l, _ = splitext(basename(lib))
00084             self.libraries.append(l[3:])
00085 
00086         self.system_libraries = [
00087             'stdc++', 'supc++', 'm', 'c', 'gcc', 'nosys'
00088         ]
00089 
00090         # Read in all profiles, we'll extract compiler options.
00091         profiles = self.get_all_profiles()
00092 
00093         profile_ids = [s.lower() for s in profiles]
00094         profile_ids.sort()
00095 
00096         # TODO: get the list from existing .cproject
00097         build_folders = [s.capitalize() for s in profile_ids]
00098         build_folders.append('BUILD')
00099         # print build_folders
00100 
00101         objects = [self.filter_dot(s) for s in self.resources.objects]
00102         for bf in build_folders:
00103             objects = [o for o in objects if not o.startswith(bf + '/')]
00104         # print 'objects'
00105         # print objects
00106 
00107         self.compute_exclusions()
00108 
00109         self.include_path = [
00110             self.filter_dot(s) for s in self.resources.inc_dirs]
00111 
00112         self.as_defines = self.toolchain.get_symbols(True)
00113         self.c_defines = self.toolchain.get_symbols()
00114         self.cpp_defines = self.c_defines
00115 
00116         self.ld_script = self.filter_dot(
00117             self.resources.linker_script)
00118 
00119         self.options = {}
00120         profile_ids.remove('develop')
00121         for id in profile_ids:
00122 
00123             # There are 4 categories of options, a category common too
00124             # all tools and a specific category for each of the tools.
00125             opts = {}
00126             opts['common'] = {}
00127             opts['as'] = {}
00128             opts['c'] = {}
00129             opts['cpp'] = {}
00130             opts['ld'] = {}
00131 
00132             opts['id'] = id
00133             opts['name'] = opts['id'].capitalize()
00134 
00135             print
00136 
00137             profile = profiles[id]
00138 
00139             # A small hack, do not bother with src_path again,
00140             # pass an empty string to avoid crashing.
00141             src_paths = ['']
00142             target_name = self.toolchain.target.name
00143             toolchain = prepare_toolchain(
00144                 src_paths, "", target_name, self.TOOLCHAIN, build_profile=[profile])
00145 
00146             # Hack to fill in build_dir
00147             toolchain.build_dir = self.toolchain.build_dir
00148 
00149             flags = self.toolchain_flags(toolchain)
00150 
00151             # Most GNU ARM Eclipse options have a parent,
00152             # either debug or release.
00153             if '-O0' in flags['common_flags'] or '-Og' in flags['common_flags']:
00154                 opts['parent_id'] = 'debug'
00155             else:
00156                 opts['parent_id'] = 'release'
00157 
00158             self.process_options(opts, flags)
00159 
00160             opts['as']['defines'] = self.as_defines
00161             opts['c']['defines'] = self.c_defines
00162             opts['cpp']['defines'] = self.cpp_defines
00163 
00164             opts['common']['include_paths'] = self.include_path
00165             opts['common']['excluded_folders'] = '|'.join(
00166                 self.excluded_folders)
00167             self.excluded_folders = [item.replace("\\", "/") for item in self.excluded_folders]
00168 
00169             opts['ld']['library_paths'] = [
00170                 self.filter_dot(s) for s in self.resources.lib_dirs]
00171 
00172             opts['ld']['object_files'] = objects
00173             opts['ld']['user_libraries'] = self.libraries
00174             opts['ld']['system_libraries'] = self.system_libraries
00175             opts['ld']['script'] = "linker-script-%s.ld" % id
00176             opts['cpp_cmd'] = " ".join(toolchain.preproc)
00177 
00178             # Unique IDs used in multiple places.
00179             # Those used only once are implemented with {{u.id}}.
00180             u = UID()
00181             uid = {}
00182             uid['config'] = u.id
00183             uid['tool_c_compiler'] = u.id
00184             uid['tool_c_compiler_input'] = u.id
00185             uid['tool_cpp_compiler'] = u.id
00186             uid['tool_cpp_compiler_input'] = u.id
00187 
00188             opts['uid'] = uid
00189 
00190             self.options[id] = opts
00191 
00192         jinja_ctx = {
00193             'name': self.project_name,
00194             'ld_script': self.ld_script,
00195 
00196             # Compiler & linker command line options
00197             'options': self.options,
00198 
00199             # Must be an object with an `id` property, which
00200             # will be called repeatedly, to generate multiple UIDs.
00201             'u': u,
00202         }
00203 
00204         self.gen_file('mcuxpresso/.project.tmpl', jinja_ctx,
00205                       '.project', trim_blocks=True, lstrip_blocks=True)
00206         self.gen_file('mcuxpresso/{0}_cproject.tmpl'.format(target_name), jinja_ctx,
00207                       '.cproject', trim_blocks=True, lstrip_blocks=True)
00208         self.gen_file('mcuxpresso/makefile.targets.tmpl', jinja_ctx,
00209                       'makefile.targets', trim_blocks=True, lstrip_blocks=True)
00210         self.gen_file_nonoverwrite('mcuxpresso/mbedignore.tmpl', jinja_ctx,
00211                                    '.mbedignore')
00212 
00213         print('Done. Import the \'{0}\' project in MCUXpresso.'.format(
00214             self.project_name))
00215 
00216     @staticmethod
00217     def clean(_):
00218         remove('.project')
00219         remove('.cproject')
00220         if exists('Debug'):
00221             shutil.rmtree('Debug')
00222         if exists('Release'):
00223             shutil.rmtree('Release')
00224         if exists('makefile.targets'):
00225             remove('makefile.targets')
00226 
00227     # override
00228     @staticmethod
00229     def build(project_name, log_name="build_log.txt", cleanup=True):
00230         """
00231         Headless build an Eclipse project.
00232 
00233         The following steps are performed:
00234         - a temporary workspace is created,
00235         - the project is imported,
00236         - a clean build of all configurations is performed and
00237         - the temporary workspace is removed.
00238 
00239         The build results are in the Debug & Release folders.
00240 
00241         All executables (eclipse & toolchain) must be in the PATH.
00242 
00243         The general method to start a headless Eclipse build is:
00244 
00245         $ eclipse \
00246         --launcher.suppressErrors \
00247         -nosplash \
00248         -application org.eclipse.cdt.managedbuilder.core.headlessbuild \
00249         -data /path/to/workspace \
00250         -import /path/to/project \
00251         -cleanBuild "project[/configuration] | all"
00252         """
00253 
00254         # TODO: possibly use the log file.
00255 
00256         # Create a temporary folder for the workspace.
00257         tmp_folder = tempfile.mkdtemp()
00258 
00259         cmd = [
00260             'mcuxpressoide',
00261             '--launcher.suppressErrors',
00262             '-nosplash',
00263             '-application org.eclipse.cdt.managedbuilder.core.headlessbuild',
00264             '-data', tmp_folder,
00265             '-import', getcwd(),
00266             '-cleanBuild', project_name
00267         ]
00268 
00269         p = Popen(' '.join(cmd), shell=True, stdout=PIPE, stderr=PIPE)
00270         out, err = p.communicate()
00271         ret_code = p.returncode
00272         stdout_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
00273         err_string = "=" * 10 + "STDERR" + "=" * 10 + "\n"
00274         err_string += err
00275         success = any(l.startswith("Finished building target:") for l in out.split("\n"))
00276 
00277         if success:
00278             ret_string = "SUCCESS\n"
00279         else:
00280             ret_string = "FAILURE: build returned %s \n" % ret_code
00281 
00282         print("%s\n%s\n%s\n%s" % (stdout_string, out, err_string, ret_string))
00283 
00284         if log_name:
00285             # Write the output to the log file
00286             with open(log_name, 'w+') as f:
00287                 f.write(stdout_string)
00288                 f.write(out)
00289                 f.write(err_string)
00290                 f.write(ret_string)
00291 
00292         # Cleanup the exported and built files
00293         if cleanup:
00294             if exists(log_name):
00295                 remove(log_name)
00296             MCUXpresso.clean(project_name)
00297 
00298         # Always remove the temporary folder.
00299         if exists(tmp_folder):
00300             shutil.rmtree(tmp_folder)
00301 
00302         return not(success)
00303 
00304 
00305     # -------------------------------------------------------------------------
00306 
00307     def process_options(self, opts, flags_in):
00308         """
00309         CDT managed projects store lots of build options in separate
00310         variables, with separate IDs in the .cproject file.
00311         When the CDT build is started, all these options are brought
00312         together to compose the compiler and linker command lines.
00313 
00314         Here the process is reversed, from the compiler and linker
00315         command lines, the options are identified and various flags are
00316         set to control the template generation process.
00317 
00318         Once identified, the options are removed from the command lines.
00319 
00320         The options that were not identified are options that do not
00321         have CDT equivalents and will be passed in the 'Other options'
00322         categories.
00323 
00324         Although this process does not have a very complicated logic,
00325         given the large number of explicit configuration options
00326         used by the GNU ARM Eclipse managed build plug-in, it is tedious...
00327         """
00328 
00329         # Make a copy of the flags, to be one by one removed after processing.
00330         flags = copy.deepcopy(flags_in)
00331 
00332         # Initialise the 'last resort' options where all unrecognised
00333         # options will be collected.
00334         opts['as']['other'] = ''
00335         opts['c']['other'] = ''
00336         opts['cpp']['other'] = ''
00337         opts['ld']['other'] = ''
00338 
00339         MCPUS = {
00340             'Cortex-M0': {'mcpu': 'cortex-m0', 'fpu_unit': None},
00341             'Cortex-M0+': {'mcpu': 'cortex-m0plus', 'fpu_unit': None},
00342             'Cortex-M1': {'mcpu': 'cortex-m1', 'fpu_unit': None},
00343             'Cortex-M3': {'mcpu': 'cortex-m3', 'fpu_unit': None},
00344             'Cortex-M4': {'mcpu': 'cortex-m4', 'fpu_unit': None},
00345             'Cortex-M4F': {'mcpu': 'cortex-m4', 'fpu_unit': 'fpv4spd16'},
00346             'Cortex-M7': {'mcpu': 'cortex-m7', 'fpu_unit': None},
00347             'Cortex-M7F': {'mcpu': 'cortex-m7', 'fpu_unit': 'fpv4spd16'},
00348             'Cortex-M7FD': {'mcpu': 'cortex-m7', 'fpu_unit': 'fpv5d16'},
00349             'Cortex-A9': {'mcpu': 'cortex-a9', 'fpu_unit': 'vfpv3'}
00350         }
00351 
00352         MCPU_NXP = {
00353             'cortex-m7' : 'cm7',
00354             'cortex-m4' : 'cm4',
00355             'cortex-m3' : 'cm3',
00356             'cortex-m1' : 'cm1',
00357             'cortex-m0' : 'cm0',
00358             'cortex-m0.small-multiply' : 'cm0.smallmul',
00359             'cortex-m0plus' : 'cm0plus',
00360             'cortex-m0plus.small-multiply' : 'cm0plus.smallmul'
00361         }
00362 
00363         # Remove options that are supplied by CDT
00364         self.remove_option(flags['common_flags'], '-c')
00365         self.remove_option(flags['common_flags'], '-MMD')
00366 
00367         # As 'plan B', get the CPU from the target definition.
00368         core = self.toolchain.target.core
00369 
00370         opts['common']['arm.target.family'] = None
00371 
00372         # cortex-m0, cortex-m0-small-multiply, cortex-m0plus,
00373         # cortex-m0plus-small-multiply, cortex-m1, cortex-m1-small-multiply,
00374         # cortex-m3, cortex-m4, cortex-m7.
00375         str = self.find_options(flags['common_flags'], '-mcpu=')
00376         if str != None:
00377             opts['common']['arm.target.family'] = str[len('-mcpu='):]
00378             opts['common']['arm.target.family_nxp'] = MCPU_NXP[str[len('-mcpu='):]]
00379             self.remove_option(flags['common_flags'], str)
00380             self.remove_option(flags['ld_flags'], str)
00381         else:
00382             if core not in MCPUS:
00383                 raise NotSupportedException(
00384                     'Target core {0} not supported.'.format(core))
00385             opts['common']['arm.target.family'] = MCPUS[core]['mcpu']
00386 
00387         opts['common']['arm.target.arch'] = 'none'
00388         str = self.find_options(flags['common_flags'], '-march=')
00389         arch = str[len('-march='):]
00390         archs = {'armv6-m': 'armv6-m', 'armv7-m': 'armv7-m', 'armv7-a': 'armv7-a'}
00391         if arch in archs:
00392             opts['common']['arm.target.arch'] = archs[arch]
00393             self.remove_option(flags['common_flags'], str)
00394 
00395         opts['common']['arm.target.instructionset'] = 'thumb'
00396         if '-mthumb' in flags['common_flags']:
00397             self.remove_option(flags['common_flags'], '-mthumb')
00398             self.remove_option(flags['ld_flags'], '-mthumb')
00399         elif '-marm' in flags['common_flags']:
00400             opts['common']['arm.target.instructionset'] = 'arm'
00401             self.remove_option(flags['common_flags'], '-marm')
00402             self.remove_option(flags['ld_flags'], '-marm')
00403 
00404         opts['common']['arm.target.thumbinterwork'] = False
00405         if '-mthumb-interwork' in flags['common_flags']:
00406             opts['common']['arm.target.thumbinterwork'] = True
00407             self.remove_option(flags['common_flags'], '-mthumb-interwork')
00408 
00409         opts['common']['arm.target.endianness'] = None
00410         if '-mlittle-endian' in flags['common_flags']:
00411             opts['common']['arm.target.endianness'] = 'little'
00412             self.remove_option(flags['common_flags'], '-mlittle-endian')
00413         elif '-mbig-endian' in flags['common_flags']:
00414             opts['common']['arm.target.endianness'] = 'big'
00415             self.remove_option(flags['common_flags'], '-mbig-endian')
00416 
00417         opts['common']['arm.target.fpu.unit'] = None
00418         opts['common']['arm.target.fpu.unit_nxp'] = None
00419         # default, fpv4spd16, fpv5d16, fpv5spd16
00420         str = self.find_options(flags['common_flags'], '-mfpu=')
00421         if str != None:
00422             fpu = str[len('-mfpu='):]
00423             fpus = {
00424                 'fpv4-sp-d16': 'fpv4spd16',
00425                 'fpv5-d16': 'fpv5d16',
00426                 'fpv5-sp-d16': 'fpv5spd16'
00427             }
00428             fpus_nxp = {
00429                 'fpv4-sp-d16': 'fpv4',
00430                 'fpv5-d16': 'fpv5dp',
00431                 'fpv5-sp-d16': 'fpv5sp'
00432             }
00433             if fpu in fpus:
00434                 opts['common']['arm.target.fpu.unit'] = fpus[fpu]
00435                 opts['common']['arm.target.fpu.unit_nxp'] = fpus_nxp[fpu]
00436 
00437                 self.remove_option(flags['common_flags'], str)
00438                 self.remove_option(flags['ld_flags'], str)
00439         if opts['common']['arm.target.fpu.unit'] == None:
00440             if core not in MCPUS:
00441                 raise NotSupportedException(
00442                     'Target core {0} not supported.'.format(core))
00443             if MCPUS[core]['fpu_unit']:
00444                 opts['common'][
00445                     'arm.target.fpu.unit'] = MCPUS[core]['fpu_unit']
00446 
00447         # soft, softfp, hard.
00448         str = self.find_options(flags['common_flags'], '-mfloat-abi=')
00449         if str != None:
00450             opts['common']['arm.target.fpu.abi'] = str[
00451                 len('-mfloat-abi='):]
00452             self.remove_option(flags['common_flags'], str)
00453             self.remove_option(flags['ld_flags'], str)
00454             if opts['common']['arm.target.fpu.abi'] == 'hard':
00455                 opts['common']['arm.target.fpu.unit_nxp'] += '.hard'
00456 
00457         # Default optimisation level for Release.
00458         opts['common']['optimization.level'] = '-Os'
00459 
00460         # If the project defines an optimisation level, it is used
00461         # only for the Release configuration, the Debug one used '-Og'.
00462         str = self.find_options(flags['common_flags'], '-O')
00463         if str != None:
00464             levels = {
00465                 '-O0': 'none', '-O1': 'optimize', '-O2': 'more',
00466                 '-O3': 'most', '-Os': 'size', '-Og': 'debug'
00467             }
00468             if str in levels:
00469                 opts['common']['optimization.level'] = levels[str]
00470                 self.remove_option(flags['common_flags'], str)
00471 
00472         include_files = []
00473         for all_flags in [flags['common_flags'], flags['c_flags'], flags['cxx_flags']]:
00474             while '-include' in all_flags:
00475                 ix = all_flags.index('-include')
00476                 str = all_flags[ix + 1]
00477                 if str not in include_files:
00478                     include_files.append(str)
00479                 self.remove_option(all_flags, '-include')
00480                 self.remove_option(all_flags, str)
00481 
00482         opts['common']['include_files'] = include_files
00483 
00484         if '-ansi' in flags['c_flags']:
00485             opts['c']['compiler.std'] = '-ansi'
00486             self.remove_option(flags['c_flags'], str)
00487         else:
00488             str = self.find_options(flags['c_flags'], '-std')
00489             std = str[len('-std='):]
00490             c_std = {
00491                 'c90': 'c90', 'c89': 'c90', 'gnu90': 'gnu90', 'gnu89': 'gnu90',
00492                 'c99': 'c99', 'c9x': 'c99', 'gnu99': 'gnu99', 'gnu9x': 'gnu98',
00493                 'c11': 'c11', 'c1x': 'c11', 'gnu11': 'gnu11', 'gnu1x': 'gnu11'
00494             }
00495             if std in c_std:
00496                 opts['c']['compiler.std'] = c_std[std]
00497                 self.remove_option(flags['c_flags'], str)
00498 
00499         if '-ansi' in flags['cxx_flags']:
00500             opts['cpp']['compiler.std'] = '-ansi'
00501             self.remove_option(flags['cxx_flags'], str)
00502         else:
00503             str = self.find_options(flags['cxx_flags'], '-std')
00504             std = str[len('-std='):]
00505             cpp_std = {
00506                 'c++98': 'cpp98', 'c++03': 'cpp03',
00507                 'gnu++98': 'gnupp98', 'gnu++03': 'gnupp03',
00508                 'c++0x': 'cpp03', 'gnu++0x': 'gnupp03',
00509                 'c++11': 'cpp11', 'gnu++11': 'gnupp11',
00510                 'c++1y': 'cpp11', 'gnu++1y': 'gnupp11',
00511                 'c++14': 'cpp14', 'gnu++14': 'gnupp14',
00512                 'c++1z': 'cpp1z', 'gnu++1z': 'gnupp1z',
00513             }
00514             if std in cpp_std:
00515                 opts['cpp']['compiler.std'] = cpp_std[std]
00516                 self.remove_option(flags['cxx_flags'], str)
00517 
00518         # Common optimisation options.
00519         optimization_options = {
00520             '-flto': 'optimization.lto',
00521             '--ffat-lto-objects': 'optimization.lto_objects'
00522         }
00523         for option in optimization_options:
00524             opts['common'][optimization_options[option]] = False
00525             if option in flags['common_flags']:
00526                 opts['common'][optimization_options[option]] = True
00527                 self.remove_option(flags['common_flags'], option)
00528 
00529         # Common warning options.
00530         warning_options = {
00531             '-fsyntax-only': 'warnings.syntaxonly',
00532             '-pedantic': 'warnings.pedantic',
00533             '-pedantic-errors': 'warnings.pedanticerrors',
00534             '-w': 'warnings.nowarn',
00535             '-Wall': 'warnings.allwarn',
00536             '-Wextra': 'warnings.extrawarn',
00537             '-Wconversion': 'warnings.conversion',
00538             '-Werror': 'warnings.toerrors',
00539         }
00540 
00541         for option in warning_options:
00542             opts['common'][warning_options[option]] = False
00543             if option in flags['common_flags']:
00544                 opts['common'][warning_options[option]] = True
00545                 self.remove_option(flags['common_flags'], option)
00546 
00547         # Common debug options.
00548         debug_levels = {
00549             '-g': 'default',
00550             '-g1': 'minimal',
00551             '-g3': 'max',
00552         }
00553         opts['common']['debugging.level'] = 'none'
00554         for option in debug_levels:
00555             if option in flags['common_flags']:
00556                 opts['common'][
00557                     'debugging.level'] = debug_levels[option]
00558                 self.remove_option(flags['common_flags'], option)
00559 
00560 
00561         opts['common']['debugging.prof'] = False
00562         if '-p' in flags['common_flags']:
00563             opts['common']['debugging.prof'] = True
00564             self.remove_option(flags['common_flags'], '-p')
00565 
00566         opts['common']['debugging.gprof'] = False
00567         if '-pg' in flags['common_flags']:
00568             opts['common']['debugging.gprof'] = True
00569             self.remove_option(flags['common_flags'], '-gp')
00570 
00571         # Assembler options.
00572         opts['as']['usepreprocessor'] = False
00573         while '-x' in flags['asm_flags']:
00574             ix = flags['asm_flags'].index('-x')
00575             str = flags['asm_flags'][ix + 1]
00576 
00577             if str == 'assembler-with-cpp':
00578                 opts['as']['usepreprocessor'] = True
00579             else:
00580                 # Collect all other assembler options.
00581                 opts['as']['other'] += ' -x ' + str
00582 
00583             self.remove_option(flags['asm_flags'], '-x')
00584             self.remove_option(flags['asm_flags'], 'assembler-with-cpp')
00585 
00586         opts['as']['nostdinc'] = False
00587         if '-nostdinc' in flags['asm_flags']:
00588             opts['as']['nostdinc'] = True
00589             self.remove_option(flags['asm_flags'], '-nostdinc')
00590 
00591         opts['as']['verbose'] = False
00592         if '-v' in flags['asm_flags']:
00593             opts['as']['verbose'] = True
00594             self.remove_option(flags['asm_flags'], '-v')
00595 
00596         # C options.
00597         opts['c']['nostdinc'] = False
00598         if '-nostdinc' in flags['c_flags']:
00599             opts['c']['nostdinc'] = True
00600             self.remove_option(flags['c_flags'], '-nostdinc')
00601 
00602         opts['c']['verbose'] = False
00603         if '-v' in flags['c_flags']:
00604             opts['c']['verbose'] = True
00605             self.remove_option(flags['c_flags'], '-v')
00606 
00607 
00608         # C++ options.
00609         opts['cpp']['nostdinc'] = False
00610         if '-nostdinc' in flags['cxx_flags']:
00611             opts['cpp']['nostdinc'] = True
00612             self.remove_option(flags['cxx_flags'], '-nostdinc')
00613 
00614         opts['cpp']['nostdincpp'] = False
00615         if '-nostdinc++' in flags['cxx_flags']:
00616             opts['cpp']['nostdincpp'] = True
00617             self.remove_option(flags['cxx_flags'], '-nostdinc++')
00618 
00619         optimization_options = {
00620             '-fno-exceptions': 'optimization.noexceptions',
00621             '-fno-rtti': 'optimization.nortti',
00622             '-fno-use-cxa-atexit': 'optimization.nousecxaatexit',
00623             '-fno-threadsafe-statics': 'optimization.nothreadsafestatics',
00624         }
00625 
00626         for option in optimization_options:
00627             opts['cpp'][optimization_options[option]] = False
00628             if option in flags['cxx_flags']:
00629                 opts['cpp'][optimization_options[option]] = True
00630             if option in flags['common_flags']:
00631                 opts['cpp'][optimization_options[option]] = True
00632 
00633         opts['cpp']['verbose'] = False
00634         if '-v' in flags['cxx_flags']:
00635             opts['cpp']['verbose'] = True
00636             self.remove_option(flags['cxx_flags'], '-v')
00637 
00638         # Linker options.
00639         linker_options = {
00640             '-nostartfiles': 'nostart',
00641             '-nodefaultlibs': 'nodeflibs',
00642             '-nostdlib': 'nostdlibs',
00643         }
00644 
00645         for option in linker_options:
00646             opts['ld'][linker_options[option]] = False
00647             if option in flags['ld_flags']:
00648                 opts['ld'][linker_options[option]] = True
00649                 self.remove_option(flags['ld_flags'], option)
00650 
00651         opts['ld']['gcsections'] = False
00652         if '-Wl,--gc-sections' in flags['ld_flags']:
00653             opts['ld']['gcsections'] = True
00654             self.remove_option(flags['ld_flags'], '-Wl,--gc-sections')
00655 
00656         opts['ld']['flags'] = []
00657         to_remove = []
00658         for opt in flags['ld_flags']:
00659             if opt.startswith('-Wl,--wrap,'):
00660                 opts['ld']['flags'].append(
00661                     '--wrap=' + opt[len('-Wl,--wrap,'):])
00662                 to_remove.append(opt)
00663         for opt in to_remove:
00664             self.remove_option(flags['ld_flags'], opt)
00665 
00666         # Other tool remaining options are separated by category.
00667         opts['as']['otherwarnings'] = self.find_options(
00668             flags['asm_flags'], '-W')
00669 
00670         opts['c']['otherwarnings'] = self.find_options(
00671             flags['c_flags'], '-W')
00672         opts['c']['otheroptimizations'] = self.find_options(flags[
00673             'c_flags'], '-f')
00674 
00675         opts['cpp']['otherwarnings'] = self.find_options(
00676             flags['cxx_flags'], '-W')
00677         opts['cpp']['otheroptimizations'] = self.find_options(
00678             flags['cxx_flags'], '-f')
00679 
00680         # Other common remaining options are separated by category.
00681         opts['common']['optimization.other'] = self.find_options(
00682             flags['common_flags'], '-f')
00683         opts['common']['warnings.other'] = self.find_options(
00684             flags['common_flags'], '-W')
00685 
00686         # Remaining common flags are added to each tool.
00687         opts['as']['other'] += ' ' + \
00688             ' '.join(flags['common_flags']) + ' ' + \
00689             ' '.join(flags['asm_flags'])
00690         opts['c']['other'] += ' ' + \
00691             ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['c_flags'])
00692         opts['cpp']['other'] += ' ' + \
00693             ' '.join(flags['common_flags']) + ' ' + \
00694             ' '.join(flags['cxx_flags'])
00695         opts['ld']['other'] += ' ' + \
00696             ' '.join(flags['common_flags']) + ' ' + ' '.join(flags['ld_flags'])
00697 
00698         if len(self.system_libraries) > 0:
00699             opts['ld']['other'] += ' -Wl,--start-group '
00700             opts['ld'][
00701                 'other'] += ' '.join('-l' + s for s in self.system_libraries) + ' '
00702             opts['ld'][
00703                 'other'] += ' '.join('-l' + s for s in self.libraries)
00704             opts['ld']['other'] += ' -Wl,--end-group '
00705 
00706         # Strip all 'other' flags, since they might have leading spaces.
00707         opts['as']['other'] = opts['as']['other'].strip()
00708         opts['c']['other'] = opts['c']['other'].strip()
00709         opts['cpp']['other'] = opts['cpp']['other'].strip()
00710         opts['ld']['other'] = opts['ld']['other'].strip()