コード例 #1
0
ファイル: target.py プロジェクト: SALLYPEMDAS/ravenscar_stm32
class Target(TargetConfiguration, ArchSupport):
    """Handles the creation of runtimes for a particular target"""
    @property
    def rel_path(self):
        if self._parent is not None:
            return self._parent.rel_path + self.name + '/'
        else:
            return self.name + '/'

    def __init__(self):
        """Initialize the target

        The build_flags dictionnary is used to set attributes of
        runtime_build.gpr"""
        TargetConfiguration.__init__(self)
        ArchSupport.__init__(self)
        self.config_files = {}
        self.runtimes = {}

        self.rts_options = RTSProfiles(self)

        self.build_flags = {
            'source_dirs':
            None,
            'common_flags': [
                '-fcallgraph-info=su,da', '-ffunction-sections',
                '-fdata-sections'
            ],
            'asm_flags': [],
            'c_flags': ['-DIN_RTS', '-Dinhibit_libc']
        }

        readme = self.readme_file
        if readme:
            self.config_files.update({'README': readfile(readme)})

        for profile in self.system_ads:
            # Set the scenario variable values for the base profile
            rts = FilesHolder()
            self.runtimes[profile] = rts
            if 'ravenscar' not in profile:
                rts.rts_vars = self.rts_options.zfp_scenarios(math_lib=False)
            elif 'full' in profile:
                rts.rts_vars = self.rts_options.full_scenarios(math_lib=True)
            else:
                rts.rts_vars = self.rts_options.sfp_scenarios(math_lib=False)
            # By default, system.ads files are searched for in
            # bb-runtimes/src/system.
            # This works fine in general, however, for custom runtimes, we may
            # need to change the location of this file for various reasons
            # so if we detect a slash in the base name, this means that we
            # lookup the file as any other regular source file.
            system_ads = self.system_ads[profile]
            if '/' in system_ads:
                rts.add_sources('arch', {'system.ads': system_ads})
            else:
                rts.add_sources('arch',
                                {'system.ads': 'src/system/%s' % system_ads})
            rts.build_flags = copy.deepcopy(self.build_flags)
            rts.config_files = {}

            # Update the runtimes objects according to target specifications
            self.amend_rts(profile, rts)
            # Check that dependencies are met
            self.rts_options.check_deps(rts.rts_vars)

        assert len(self.runtimes) > 0, "No runtime defined"

    def amend_rts(self, rts_profile, rts):
        """to be overriden by the actual target to refine the runtime"""
        pass

    ###############
    # runtime.xml #
    ###############

    def dump_runtime_xml(self, rts_name, rts):
        " Dumps the runtime.xml file that gives the configuration to gprbuild"
        ret = '<?xml version="1.0" ?>\n\n'
        ret += '<gprconfig>\n'
        ret += '  <configuration>\n'
        ret += '    <config><![CDATA[\n'
        if self.loaders is not None:
            # Add USER loader so users can always specify their own linker
            # script. To ensure the USER loader is always used for this
            # purpose it cannot be defined by a target
            assert 'USER' not in self.loaders, \
                "target cannot define USER loader"

            loaders = self.loaders + ("USER", )

            ret += '   type Loaders is ("%s");\n' % '", "'.join(loaders)
            ret += '   Loader : Loaders := external("LOADER", "%s");\n\n' % (
                loaders[0])
        elif len(self.ld_scripts) == 1:
            # No loader defined, and a single ld script
            # Let's make it user-configurable
            ret += '   LDSCRIPT := external("LDSCRIPT",\n'
            ret += '                        "${RUNTIME_DIR(ada)}/ld/%s");' % (
                self.ld_scripts[0]['name'], )
            ret += '\n\n'

        ret += '   package Compiler is\n'
        if len(self.compiler_switches) > 0:
            ret += '      Common_Required_Switches := ("%s");\n' % \
                   '", "'.join(self.compiler_switches)
        else:
            ret += '      Common_Required_Switches := ();\n'

        if len(self.c_switches) > 0:
            ret += '      C_Required_Switches := ("%s");\n' % \
                   '", "'.join(self.c_switches)

        ret += '\n'

        for lang in ('Ada', 'C', 'Asm', 'Asm2', 'Asm_Cpp'):
            w = '      '
            ret += w + 'for Leading_Required_Switches ("%s") use\n' % lang
            w = '         '
            ret += w + 'Compiler\'Leading_Required_Switches ("%s") &\n' % \
                       lang
            ret += w + 'Common_Required_Switches'
            if lang != 'Ada' and len(self.c_switches) > 0:
                ret += ' &\n' + w
                ret += 'C_Required_Switches'
            ret += ';\n'
        ret += '   end Compiler;\n\n'

        switches = []
        if len(self.ld_scripts) == 1 and self.loaders is None:
            switches.append('"-T", LDSCRIPT')
        else:
            for val in self.ld_scripts:
                if val['loader'] is None:
                    # use for all loaders
                    switches.append('"-T", "%s"' % val['name'])
        for sw in self.ld_switches:
            if sw['loader'] is None or sw['loader'] == '':
                switches.append('"%s"' % sw['switch'])

        ret += '   package Linker is\n'
        indent = 6
        blank = indent * ' '
        ret += blank + \
            'for Required_Switches use Linker\'Required_Switches &\n'
        ret += blank + '  ("-Wl,-L${RUNTIME_DIR(ada)}/adalib",\n'
        indent = 9
        blank = indent * ' '

        ret += blank + '"-nostartfiles"'
        if rts.rts_vars['RTS_Profile'] != "ravenscar-full":
            ret += ', "-nolibc"'
        else:
            # libgnat depends on libc for malloc stuff
            # libc and libgcc depends on libgnat for syscalls and abort
            ret += (', "-lgnat", "-lc", "-lgcc", "-lgnat"')

        if len(self.ld_scripts) > 0:
            ret += ',\n' + blank + '"-L${RUNTIME_DIR(ada)}/ld"'

        if len(switches) > 0:
            ret += ',\n' + blank
            ret += (',\n' + blank).join(switches)
            blank = indent * ' '
        ret += ') &\n' + blank + 'Compiler.Common_Required_Switches;\n'
        indent = 6
        blank = indent * ' '

        if self.loaders is not None:
            ret += '\n' + blank
            ret += 'case Loader is\n'
            indent += 3
            blank = indent * ' '

            for l in loaders:
                ret += blank
                ret += 'when "%s" =>\n' % l
                indent += 3
                blank = indent * ' '

                switches = []
                for val in self.ld_scripts:
                    if val['loader'] is None:
                        continue
                    if isinstance(val['loader'], basestring):
                        if val['loader'] == l:
                            switches.append('"-T", "%s"' % val['name'])
                    else:
                        if l in val['loader']:
                            switches.append('"-T", "%s"' % val['name'])
                for sw in self.ld_switches:
                    if isinstance(sw['loader'], basestring) \
                            and sw['loader'] == l:
                        switches.append('"%s"' % sw['switch'])
                    if isinstance(sw['loader'], list) \
                            and l in sw['loader']:
                        switches.append('"%s"' % sw['switch'])
                if len(switches) > 0:
                    ret += blank
                    ret += \
                        'for Required_Switches use Linker\'Required_Switches'
                    ret += ' &\n' + blank + '  '
                    ret += '(%s);\n' % (',\n   ' + blank).join(switches)
                indent -= 3
                blank = indent * ' '

            indent -= 3
            blank = indent * ' '
            ret += '%send case;\n' % blank

        ret += ('   end Linker;\n'
                ']]>\n'
                '   </config>\n'
                '  </configuration>\n'
                '</gprconfig>\n')
        return ret
コード例 #2
0
ファイル: target.py プロジェクト: NicoPy/bb-runtimes
class Target(TargetConfiguration, ArchSupport):
    """Handles the creation of runtimes for a particular target"""
    def __init__(self):
        """Initialize the target

        The build_flags dictionnary is used to set attributes of
        runtime_build.gpr"""
        TargetConfiguration.__init__(self)
        ArchSupport.__init__(self)
        self.config_files = {}
        self.runtimes = {}

        self.rts_options = RTSProfiles(self)

        self.build_flags = {
            'source_dirs':
            None,
            'common_flags': [
                '-fcallgraph-info=su,da', '-ffunction-sections',
                '-fdata-sections'
            ],
            'asm_flags': [],
            'c_flags': ['-DIN_RTS', '-Dinhibit_libc']
        }

        readme = self.readme_file
        if readme:
            self.config_files.update({'README': readfile(readme)})

        for profile in self.system_ads:
            # Set the scenario variable values for the base profile
            rts = FilesHolder()
            self.runtimes[profile] = rts
            if 'ravenscar' not in profile:
                rts.rts_vars = self.rts_options.zfp_scenarios(math_lib=False)
            elif 'full' in profile:
                rts.rts_vars = self.rts_options.full_scenarios(math_lib=True)
            else:
                rts.rts_vars = self.rts_options.sfp_scenarios(math_lib=False)
            # By default, system.ads files are searched for in
            # bb-runtimes/src/system.
            # This works fine in general, however, for custom runtimes, we may
            # need to change the location of this file for various reasons
            # so if we detect a slash in the base name, this means that we
            # lookup the file as any other regular source file.
            system_ads = self.system_ads[profile]
            if '/' in system_ads:
                rts.add_source_alias('gnat', 'system.ads', system_ads)
            else:
                rts.add_source_alias('gnat', 'system.ads',
                                     'src/system/%s' % system_ads)
            rts.build_flags = copy.deepcopy(self.build_flags)
            rts.config_files = {}

            # Update the runtimes objects according to target specifications
            self.amend_rts(profile, rts)
            # Check that dependencies are met
            self.rts_options.check_deps(rts.rts_vars)

        assert len(self.runtimes) > 0, "No runtime defined"

    @property
    def compiler_switches(self):
        return []

    def amend_rts(self, rts_profile, rts):
        """to be overriden by the actual target to refine the runtime"""
        pass

    def other_sources(self, profile):
        """Used to return a list of source dirs to install.

         The expected returned format is:
         { 'rts_subdir': [ <dir1>, <dir2> ] }

         the sources in <dir1>, <dir2> will then be installed in the runtime's
         subdirectory rts_subdir.
         """
        return None

    def other_projects(self, profile):
        """List of projects to build in the runtime"""
        return None

    ###############
    # runtime.xml #
    ###############

    def dump_runtime_xml(self, rts_name, rts):
        """Dumps the runtime.xml file that gives the configuration to gprbuild
        """
        ret = '<?xml version="1.0" ?>\n\n'
        ret += '<gprconfig>\n'
        ret += '  <configuration>\n'
        ret += '    <config><![CDATA[\n'
        if self.loaders is not None:
            # Add USER loader so users can always specify their own linker
            # script. To ensure the USER loader is always used for this
            # purpose it cannot be defined by a target
            assert 'USER' not in self.loaders, \
                "target cannot define USER loader"

            loaders = list(self.loaders) + ['USER']
        else:
            assert len(self.ld_scripts) <= 1, (
                "target configuration error: no loader specified and several"
                " ld scripts are defined")
            if len(self.ld_scripts) == 1:
                loaders = ['DEFAULT', 'USER']
                self.ld_scripts[0].add_loader('DEFAULT')
            else:
                loaders = ['USER']

        ret += '   type Loaders is ("%s");\n' % '", "'.join(loaders)
        ret += '   Loader : Loaders := external("LOADER", "%s");\n\n' % \
            loaders[0]

        ret += '   package Compiler is\n'
        if len(self.compiler_switches) > 0:
            ret += '      Common_Required_Switches := ("%s");\n' % \
                   '", "'.join(self.compiler_switches)
        else:
            ret += '      Common_Required_Switches := ();\n'

        if len(self.c_switches) > 0:
            ret += '      C_Required_Switches := ("%s");\n' % \
                   '", "'.join(self.c_switches)

        ret += '\n'

        for lang in ('Ada', 'C', 'Asm', 'Asm2', 'Asm_Cpp'):
            w = '      '
            ret += w + 'for Leading_Required_Switches ("%s") use\n' % lang
            w = '         '
            ret += w + 'Compiler\'Leading_Required_Switches ("%s") &\n' % \
                       lang
            ret += w + 'Common_Required_Switches'
            if lang != 'Ada' and len(self.c_switches) > 0:
                ret += ' &\n' + w
                ret += 'C_Required_Switches'
            ret += ';\n'
        ret += '   end Compiler;\n\n'

        switches = []
        for sw in self.ld_switches:
            if sw['loader'] is None or sw['loader'] == '':
                switches.append('"%s"' % sw['switch'])

        ret += '   package Linker is\n'
        indent = 6
        blank = indent * ' '
        ret += blank + \
            'for Required_Switches use Linker\'Required_Switches &\n'
        ret += blank + '  ("-Wl,-L${RUNTIME_DIR(Ada)}/adalib",\n'
        indent = 9
        blank = indent * ' '

        ret += blank + '"-nostartfiles"'
        if rts.rts_vars['RTS_Profile'] != "ravenscar-full":
            ret += ', "-nolibc"'
        else:
            # in the ravenscar-full case, the runtime depends on
            # functionalities from newlib, such as memory allocation.
            ret += ', "-lc", "-lgnat"'

        # Add the user script path first, so that they have precedence
        ret += ',\n' + blank + '"-L${RUNTIME_DIR(ada)}/ld_user"'
        # And then our own script(s), if any
        if len(self.ld_scripts) > 0:
            ret += ',\n' + blank + '"-L${RUNTIME_DIR(ada)}/ld"'

        if len(switches) > 0:
            ret += ',\n' + blank
            ret += (',\n' + blank).join(switches)
            blank = indent * ' '
        ret += ') &\n' + blank + 'Compiler.Common_Required_Switches;\n'
        indent = 6
        blank = indent * ' '

        if loaders is not None:
            ret += '\n' + blank
            ret += 'case Loader is\n'
            indent += 3
            blank = indent * ' '

            for loader in loaders:
                ret += blank
                ret += 'when "%s" =>\n' % loader
                if loader == 'USER':
                    continue
                indent += 3
                blank = indent * ' '

                switches = []
                for val in self.ld_scripts:
                    if val.loaders is None or loader in val.loaders:
                        switches.append('"-T", "%s"' % val.name)
                for sw in self.ld_switches:
                    if is_string(sw['loader']) \
                            and sw['loader'] == loader:
                        switches.append('"%s"' % sw['switch'])
                    if isinstance(sw['loader'], list) \
                            and loader in sw['loader']:
                        switches.append('"%s"' % sw['switch'])
                if len(switches) > 0:
                    ret += blank
                    ret += \
                        'for Required_Switches use Linker\'Required_Switches'
                    ret += ' &\n' + blank + '  '
                    ret += '(%s);\n' % (',\n   ' + blank).join(switches)
                indent -= 3
                blank = indent * ' '

            indent -= 3
            blank = indent * ' '
            ret += '%send case;\n' % blank

        ret += ('   end Linker;\n'
                ']]>\n'
                '   </config>\n'
                '  </configuration>\n'
                '</gprconfig>\n')
        return ret