iar.py 5.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#
# File      : iar.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License along
#  with this program; if not, write to the Free Software Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date           Author       Notes
# 2015-01-20     Bernard      Add copyright information
#

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
import os
import sys
import string

import xml.etree.ElementTree as etree
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent

fs_encoding = sys.getfilesystemencoding()

iar_workspace = '''<?xml version="1.0" encoding="iso-8859-1"?>

<workspace>
  <project>
    <path>$WS_DIR$\%s</path>
  </project>
  <batchBuild/>
</workspace>


'''

def IARAddGroup(parent, name, files, project_path):
    group = SubElement(parent, 'group')
    group_name = SubElement(group, 'name')
    group_name.text = name
    
    for f in files:
        fn = f.rfile()
        name = fn.name
        path = os.path.dirname(fn.abspath)
    
        basename = os.path.basename(path)
        path = _make_path_relative(project_path, path)
        path = os.path.join(path, name)
        
        file = SubElement(group, 'file')
        file_name = SubElement(file, 'name')
64 65 66 67
        if os.path.isabs(path):
            file_name.text = path.decode(fs_encoding)
        else:
            file_name.text = ('$PROJ_DIR$\\' + path).decode(fs_encoding)
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

def IARWorkspace(target):
    # make an workspace 
    workspace = target.replace('.ewp', '.eww')
    out = file(workspace, 'wb')
    xml = iar_workspace % target
    out.write(xml)
    out.close()
    
def IARProject(target, script):
    project_path = os.path.dirname(os.path.abspath(target))

    tree = etree.parse('template.ewp')
    root = tree.getroot()

    out = file(target, 'wb')

    CPPPATH = []
    CPPDEFINES = []
    LINKFLAGS = ''
    CCFLAGS = ''
89
    Libs = []
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
    
    # add group
    for group in script:
        IARAddGroup(root, group['name'], group['src'], project_path)

        # get each include path
        if group.has_key('CPPPATH') and group['CPPPATH']:
            CPPPATH += group['CPPPATH']
        
        # get each group's definitions
        if group.has_key('CPPDEFINES') and group['CPPDEFINES']:
            CPPDEFINES += group['CPPDEFINES']
        
        # get each group's link flags
        if group.has_key('LINKFLAGS') and group['LINKFLAGS']:
            LINKFLAGS += group['LINKFLAGS']
106 107 108 109 110 111 112 113 114 115 116 117 118 119
            
        if group.has_key('LIBS') and group['LIBS']:
            for item in group['LIBS']:
                lib_path = ''

                for path_item in group['LIBPATH']:
                    full_path = os.path.join(path_item, item + '.a')
                    if os.path.isfile(full_path): # has this library
                        lib_path = full_path

                if lib_path != '':
                    lib_path = _make_path_relative(project_path, lib_path)
                    Libs += [lib_path]

120 121 122 123 124
    # make relative path 
    paths = set()
    for path in CPPPATH:
        inc = _make_path_relative(project_path, os.path.normpath(path))
        paths.add(inc) #.replace('\\', '/')
125

126 127 128 129 130
    # setting options
    options = tree.findall('configuration/settings/data/option')
    for option in options:
        # print option.text
        name = option.find('name')
131

132
        if name.text == 'CCIncludePath2' or name.text == 'newCCIncludePaths':
133 134
            for path in paths:
                state = SubElement(option, 'state')
135
                if os.path.isabs(path) or path.startswith('$'):
136 137 138 139
                    state.text = path
                else:
                    state.text = '$PROJ_DIR$\\' + path

140 141 142 143
        if name.text == 'CCDefines':
            for define in CPPDEFINES:
                state = SubElement(option, 'state')
                state.text = define
144 145 146 147 148 149 150 151 152 153

        if name.text == 'IlinkAdditionalLibs':
            for path in Libs:
                state = SubElement(option, 'state')
                if os.path.isabs(path) or path.startswith('$'):
                    path = path.decode(fs_encoding)
                else:
                    path = ('$PROJ_DIR$\\' + path).decode(fs_encoding)
                state.text = path

154 155 156
    xml_indent(root)
    out.write(etree.tostring(root, encoding='utf-8'))
    out.close()
157

158
    IARWorkspace(target)
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
    
def IARVersion():
    import subprocess
    import re

    def IARPath():
        import rtconfig

        # set environ
        old_environ = os.environ
        os.environ['RTT_CC'] = 'iar'
        reload(rtconfig)

        # get iar path
        path = rtconfig.EXEC_PATH

        # restore environ
        os.environ = old_environ
        reload(rtconfig)

        return path

    path = IARPath();

    if os.path.exists(path):
        cmd = os.path.join(path, 'iccarm.exe')
    else:
        print('Get IAR version error. Please update IAR installation path in rtconfig.h!')
        return "0.0"

    child = subprocess.Popen([cmd, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    stdout, stderr = child.communicate()

    # example stdout: IAR ANSI C/C++ Compiler V8.20.1.14183/W32 for ARM
    return re.search('[\d\.]+', stdout).group(0)