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