iar.py 6.1 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
import os
import sys
import string
28
import utils
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

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
X
xieyangrun 已提交
53

54 55 56 57 58 59 60
    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)
X
xieyangrun 已提交
61

62 63
        file = SubElement(group, 'file')
        file_name = SubElement(file, 'name')
X
xieyangrun 已提交
64

65
        if os.path.isabs(path):
66
            file_name.text = path # path.decode(fs_encoding)
67
        else:
68
            file_name.text = '$PROJ_DIR$\\' + path # ('$PROJ_DIR$\\' + path).decode(fs_encoding)
69 70

def IARWorkspace(target):
X
xieyangrun 已提交
71
    # make an workspace
72
    workspace = target.replace('.ewp', '.eww')
73
    out = open(workspace, 'w')
74 75 76
    xml = iar_workspace % target
    out.write(xml)
    out.close()
X
xieyangrun 已提交
77

78 79 80 81 82 83
def IARProject(target, script):
    project_path = os.path.dirname(os.path.abspath(target))

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

84
    out = open(target, 'w')
85 86 87 88 89

    CPPPATH = []
    CPPDEFINES = []
    LINKFLAGS = ''
    CCFLAGS = ''
90
    Libs = []
X
xieyangrun 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103
    lib_prefix = ['lib', '']
    lib_suffix = ['.a', '.o', '']

    def searchLib(group):
        for path_item in group['LIBPATH']:
            for prefix_item in lib_prefix:
                for suffix_item in lib_suffix:
                    lib_full_path = os.path.join(path_item, prefix_item + item + suffix_item)
                    if os.path.isfile(lib_full_path):
                        return lib_full_path
        else:
            return ''

104 105 106 107 108
    # add group
    for group in script:
        IARAddGroup(root, group['name'], group['src'], project_path)

        # get each include path
109
        if 'CPPPATH' in group and group['CPPPATH']:
110
            CPPPATH += group['CPPPATH']
X
xieyangrun 已提交
111

112
        # get each group's definitions
113
        if 'CPPDEFINES' in group and group['CPPDEFINES']:
114
            CPPDEFINES += group['CPPDEFINES']
X
xieyangrun 已提交
115

116
        # get each group's link flags
117
        if 'LINKFLAGS' in group and group['LINKFLAGS']:
118
            LINKFLAGS += group['LINKFLAGS']
X
xieyangrun 已提交
119

120
        if 'LIBS' in group and group['LIBS']:
121
            for item in group['LIBS']:
X
xieyangrun 已提交
122
                lib_path = searchLib(group)
123 124 125
                if lib_path != '':
                    lib_path = _make_path_relative(project_path, lib_path)
                    Libs += [lib_path]
X
xieyangrun 已提交
126 127 128
                    # print('found lib isfile: ' + lib_path)
                else:
                    print('not found LIB: ' + item)
129

X
xieyangrun 已提交
130
    # make relative path
131 132 133 134
    paths = set()
    for path in CPPPATH:
        inc = _make_path_relative(project_path, os.path.normpath(path))
        paths.add(inc) #.replace('\\', '/')
135

136 137 138 139 140
    # setting options
    options = tree.findall('configuration/settings/data/option')
    for option in options:
        # print option.text
        name = option.find('name')
141

142
        if name.text == 'CCIncludePath2' or name.text == 'newCCIncludePaths':
143 144
            for path in paths:
                state = SubElement(option, 'state')
145
                if os.path.isabs(path) or path.startswith('$'):
146 147 148 149
                    state.text = path
                else:
                    state.text = '$PROJ_DIR$\\' + path

150 151 152 153
        if name.text == 'CCDefines':
            for define in CPPDEFINES:
                state = SubElement(option, 'state')
                state.text = define
154 155 156 157 158 159 160 161 162 163

        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

164
    xml_indent(root)
165
    out.write(etree.tostring(root, encoding='utf-8').decode())
166
    out.close()
167

168
    IARWorkspace(target)
X
xieyangrun 已提交
169

170 171 172 173 174 175 176
def IARVersion():
    import subprocess
    import re

    def IARPath():
        import rtconfig

177
        # backup environ
178 179
        old_environ = os.environ
        os.environ['RTT_CC'] = 'iar'
180
        utils.ReloadModule(rtconfig)
181 182 183 184 185 186

        # get iar path
        path = rtconfig.EXEC_PATH

        # restore environ
        os.environ = old_environ
187
        utils.ReloadModule(rtconfig)
188 189 190 191 192 193 194 195

        return path

    path = IARPath();

    if os.path.exists(path):
        cmd = os.path.join(path, 'iccarm.exe')
    else:
196
        print('Error: get IAR version failed. Please update the IAR installation path in rtconfig.py!')
197 198 199 200 201 202
        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
203
    return re.search('[\d\.]+', stdout).group(0)