1# 2# File : iar.py 3# This file is part of RT-Thread RTOS 4# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License along 17# with this program; if not, write to the Free Software Foundation, Inc., 18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19# 20# Change Logs: 21# Date Author Notes 22# 2015-01-20 Bernard Add copyright information 23# 24 25import os 26import sys 27import string 28import utils 29 30import xml.etree.ElementTree as etree 31from xml.etree.ElementTree import SubElement 32from utils import _make_path_relative 33from utils import xml_indent 34 35fs_encoding = sys.getfilesystemencoding() 36 37iar_workspace = '''<?xml version="1.0" encoding="iso-8859-1"?> 38 39<workspace> 40 <project> 41 <path>$WS_DIR$\%s</path> 42 </project> 43 <batchBuild/> 44</workspace> 45 46 47''' 48 49def IARAddGroup(parent, name, files, project_path): 50 group = SubElement(parent, 'group') 51 group_name = SubElement(group, 'name') 52 group_name.text = name 53 54 for f in files: 55 fn = f.rfile() 56 name = fn.name 57 path = os.path.dirname(fn.abspath) 58 basename = os.path.basename(path) 59 path = _make_path_relative(project_path, path) 60 path = os.path.join(path, name) 61 62 file = SubElement(group, 'file') 63 file_name = SubElement(file, 'name') 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 70def IARWorkspace(target): 71 # make an workspace 72 workspace = target.replace('.ewp', '.eww') 73 out = open(workspace, 'w') 74 xml = iar_workspace % target 75 out.write(xml) 76 out.close() 77 78def IARProject(target, script): 79 project_path = os.path.dirname(os.path.abspath(target)) 80 81 tree = etree.parse('template.ewp') 82 root = tree.getroot() 83 84 out = open(target, 'w') 85 86 CPPPATH = [] 87 CPPDEFINES = [] 88 LINKFLAGS = '' 89 CCFLAGS = '' 90 Libs = [] 91 lib_prefix = ['lib', ''] 92 lib_suffix = ['.a', '.o', ''] 93 94 def searchLib(group): 95 for path_item in group['LIBPATH']: 96 for prefix_item in lib_prefix: 97 for suffix_item in lib_suffix: 98 lib_full_path = os.path.join(path_item, prefix_item + item + suffix_item) 99 if os.path.isfile(lib_full_path): 100 return lib_full_path 101 else: 102 return '' 103 104 # add group 105 for group in script: 106 IARAddGroup(root, group['name'], group['src'], project_path) 107 108 # get each include path 109 if 'CPPPATH' in group and group['CPPPATH']: 110 CPPPATH += group['CPPPATH'] 111 112 # get each group's definitions 113 if 'CPPDEFINES' in group and group['CPPDEFINES']: 114 CPPDEFINES += group['CPPDEFINES'] 115 116 # get each group's link flags 117 if 'LINKFLAGS' in group and group['LINKFLAGS']: 118 LINKFLAGS += group['LINKFLAGS'] 119 120 if 'LIBS' in group and group['LIBS']: 121 for item in group['LIBS']: 122 lib_path = searchLib(group) 123 if lib_path != '': 124 lib_path = _make_path_relative(project_path, lib_path) 125 Libs += [lib_path] 126 # print('found lib isfile: ' + lib_path) 127 else: 128 print('not found LIB: ' + item) 129 130 # make relative path 131 paths = set() 132 for path in CPPPATH: 133 inc = _make_path_relative(project_path, os.path.normpath(path)) 134 paths.add(inc) #.replace('\\', '/') 135 136 # setting options 137 options = tree.findall('configuration/settings/data/option') 138 for option in options: 139 # print option.text 140 name = option.find('name') 141 142 if name.text == 'CCIncludePath2' or name.text == 'newCCIncludePaths': 143 for path in paths: 144 state = SubElement(option, 'state') 145 if os.path.isabs(path) or path.startswith('$'): 146 state.text = path 147 else: 148 state.text = '$PROJ_DIR$\\' + path 149 150 if name.text == 'CCDefines': 151 for define in CPPDEFINES: 152 state = SubElement(option, 'state') 153 state.text = define 154 155 if name.text == 'IlinkAdditionalLibs': 156 for path in Libs: 157 state = SubElement(option, 'state') 158 if os.path.isabs(path) or path.startswith('$'): 159 path = path.decode(fs_encoding) 160 else: 161 path = ('$PROJ_DIR$\\' + path).decode(fs_encoding) 162 state.text = path 163 164 xml_indent(root) 165 out.write(etree.tostring(root, encoding='utf-8').decode()) 166 out.close() 167 168 IARWorkspace(target) 169 170def IARVersion(): 171 import subprocess 172 import re 173 174 def IARPath(): 175 import rtconfig 176 177 # backup environ 178 old_environ = os.environ 179 os.environ['RTT_CC'] = 'iar' 180 utils.ReloadModule(rtconfig) 181 182 # get iar path 183 path = rtconfig.EXEC_PATH 184 185 # restore environ 186 os.environ = old_environ 187 utils.ReloadModule(rtconfig) 188 189 return path 190 191 path = IARPath(); 192 193 if os.path.exists(path): 194 cmd = os.path.join(path, 'iccarm.exe') 195 else: 196 print('Error: get IAR version failed. Please update the IAR installation path in rtconfig.py!') 197 return "0.0" 198 199 child = subprocess.Popen([cmd, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 200 stdout, stderr = child.communicate() 201 202 # example stdout: IAR ANSI C/C++ Compiler V8.20.1.14183/W32 for ARM 203 return re.search('[\d\.]+', stdout).group(0) 204