1# 2# File : vs2012.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 uuid 29import utils 30from xml.etree.ElementTree import SubElement 31from utils import _make_path_relative 32from utils import xml_indent 33 34# Add parent directory to path to import building 35sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 36import building 37 38import xml.etree.ElementTree as etree 39 40fs_encoding = sys.getfilesystemencoding() 41 42#reference 43# http://woodpecker.org.cn/diveintopython3/xml.html 44# https://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/processing-xml-in-python-with-element-tree.html 45# http://www.cnblogs.com/ifantastic/archive/2013/04/12/3017110.html 46 47filter_project = etree.Element('Project', attrib={'ToolsVersion':'4.0'}) 48def get_uuid(): 49 id = uuid.uuid1() # UUID('3e5526c0-2841-11e3-a376-20cf3048bcb3') 50 if sys.version > '3': 51 idstr = id.urn[9:] #'urn:uuid:3e5526c0-2841-11e3-a376-20cf3048bcb3'[9:] 52 else: 53 # python3 is no decode function 54 idstr = id.get_urn()[9:] #'urn:uuid:3e5526c0-2841-11e3-a376-20cf3048bcb3'[9:] 55 56 return '{'+idstr+'}' 57 58def VS2012_AddGroup(parent, group_name, files, project_path): 59 for f in files: 60 fn = f.rfile() 61 name = fn.name 62 path = os.path.dirname(fn.abspath) 63 64 path = _make_path_relative(project_path, path) 65 path = os.path.join(path, name) 66 67 ClCompile = SubElement(parent, 'ClCompile') 68 69 if sys.version > '3': 70 ClCompile.set('Include', path) 71 else: 72 # python3 is no decode function 73 ClCompile.set('Include', path.decode(fs_encoding)) 74 75 Filter = SubElement(ClCompile, 'Filter') 76 Filter.text='Source Files\\'+group_name 77 78def VS2012_CreateFilter(script, project_path): 79 c_ItemGroup = SubElement(filter_project, 'ItemGroup') 80 filter_ItemGroup = SubElement(filter_project, 'ItemGroup') 81 82 Filter = SubElement(filter_ItemGroup, 'Filter') 83 Filter.set('Include', 'Source Files') 84 UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier') 85 UniqueIdentifier.text = get_uuid() 86 Extensions = SubElement(Filter, 'Extensions') 87 Extensions.text = 'cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx' 88 89 Filter = SubElement(filter_ItemGroup, 'Filter') 90 Filter.set('Include', 'Header Files') 91 UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier') 92 UniqueIdentifier.text = get_uuid() 93 Extensions = SubElement(Filter, 'Extensions') 94 Extensions.text = 'h;hpp;hxx;hm;inl;inc;xsd' 95 for group in script: 96 VS2012_AddGroup(c_ItemGroup, group['name'], group['src'], project_path) 97 Filter = SubElement(filter_ItemGroup, 'Filter') 98 Filter.set('Include', 'Source Files\\'+group['name']) 99 UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier') 100 UniqueIdentifier.text = get_uuid() 101 102#program: object from scons 103# parent: xml node 104# file_type: C or H 105# files: c/h list 106# project_path 107def VS_add_ItemGroup(parent, file_type, files, project_path): 108 from building import Rtt_Root 109 RTT_ROOT = os.path.normpath(Rtt_Root) 110 111 file_dict = {'C':"ClCompile", 'H':'ClInclude'} 112 item_tag = file_dict[file_type] 113 114 ItemGroup = SubElement(parent, 'ItemGroup') 115 for f in files: 116 fn = f.rfile() 117 name = fn.name 118 path = os.path.dirname(fn.abspath) 119 120 objpath = path.lower() 121 if len(project_path) >= len(RTT_ROOT) : 122 if objpath.startswith(project_path.lower()) : 123 objpath = ''.join('bsp'+objpath[len(project_path):]) 124 else : 125 objpath = ''.join('kernel'+objpath[len(RTT_ROOT):]) 126 else : 127 if objpath.startswith(RTT_ROOT.lower()) : 128 objpath = ''.join('kernel'+objpath[len(RTT_ROOT):]) 129 else : 130 objpath = ''.join('bsp'+objpath[len(project_path):]) 131 path = _make_path_relative(project_path, path) 132 path = os.path.join(path, name) 133 134 File = SubElement(ItemGroup, item_tag) 135 136 if sys.version > '3': 137 File.set('Include', path) 138 else: 139 # python3 is no decode function 140 File.set('Include', path.decode(fs_encoding)) 141 142 if file_type == 'C' : 143 ObjName = SubElement(File, 'ObjectFileName') 144 ObjName.text = ''.join('$(IntDir)'+objpath+'\\') 145 146def VS_add_HeadFiles(program, elem, project_path): 147 utils.source_ext = [] 148 utils.source_ext = ["h"] 149 for item in program: 150 utils.walk_children(item) 151 utils.source_list.sort() 152 # print utils.source_list 153 ItemGroup = SubElement(elem, 'ItemGroup') 154 155 filter_h_ItemGroup = SubElement(filter_project, 'ItemGroup') 156 for f in utils.source_list: 157 path = _make_path_relative(project_path, f) 158 File = SubElement(ItemGroup, 'ClInclude') 159 160 if sys.version > '3': 161 File.set('Include', path) 162 else: 163 # python3 is no decode function 164 File.set('Include', path.decode(fs_encoding)) 165 166 # add project.vcxproj.filter 167 ClInclude = SubElement(filter_h_ItemGroup, 'ClInclude') 168 169 if sys.version > '3': 170 ClInclude.set('Include', path) 171 else: 172 # python3 is no decode function 173 ClInclude.set('Include', path.decode(fs_encoding)) 174 175 Filter = SubElement(ClInclude, 'Filter') 176 Filter.text='Header Files' 177 178def VS2012Project(target, script, program): 179 project_path = os.path.dirname(os.path.abspath(target)) 180 181 tree = etree.parse('template_vs2012.vcxproj') 182 root = tree.getroot() 183 elem = root 184 185 out = open(target, 'w') 186 out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n') 187 188 ProjectFiles = [] 189 190 # add "*.c or *.h" files 191 192 VS2012_CreateFilter(script, project_path) 193 # add "*.c" files 194 for group in script: 195 VS_add_ItemGroup(elem, 'C', group['src'], project_path) 196 197 # add "*.h" files 198 VS_add_HeadFiles(program, elem, project_path) 199 200 # write head include path 201 if 'CPPPATH' in building.Env: 202 cpp_path = building.Env['CPPPATH'] 203 paths = set() 204 for path in cpp_path: 205 inc = _make_path_relative(project_path, os.path.normpath(path)) 206 paths.add(inc) #.replace('\\', '/') 207 208 paths = [i for i in paths] 209 paths.sort() 210 cpp_path = ';'.join(paths) + ';%(AdditionalIncludeDirectories)' 211 212 # write include path 213 for elem in tree.iter(tag='AdditionalIncludeDirectories'): 214 elem.text = cpp_path 215 break 216 217 # write cppdefinitons flags 218 if 'CPPDEFINES' in building.Env: 219 for elem in tree.iter(tag='PreprocessorDefinitions'): 220 CPPDEFINES = building.Env['CPPDEFINES'] 221 definitions = [] 222 if type(CPPDEFINES[0]) == type(()): 223 for item in CPPDEFINES: 224 definitions += [i for i in item] 225 definitions = ';'.join(definitions) 226 else: 227 definitions = ';'.join(building.Env['CPPDEFINES']) 228 229 definitions = definitions + ';%(PreprocessorDefinitions)' 230 elem.text = definitions 231 break 232 # write link flags 233 234 # write lib dependence (Link) 235 if 'LIBS' in building.Env: 236 for elem in tree.iter(tag='AdditionalDependencies'): 237 libs_with_extention = [i+'.lib' for i in building.Env['LIBS']] 238 libs = ';'.join(libs_with_extention) + ';%(AdditionalDependencies)' 239 elem.text = libs 240 break 241 242 # write lib include path 243 if 'LIBPATH' in building.Env: 244 lib_path = building.Env['LIBPATH'] 245 paths = set() 246 for path in lib_path: 247 inc = _make_path_relative(project_path, os.path.normpath(path)) 248 paths.add(inc) 249 250 paths = [i for i in paths] 251 paths.sort() 252 lib_paths = ';'.join(paths) + ';%(AdditionalLibraryDirectories)' 253 for elem in tree.iter(tag='AdditionalLibraryDirectories'): 254 elem.text = lib_paths 255 break 256 257 xml_indent(root) 258 259 if sys.version > '3': 260 vcxproj_string = etree.tostring(root, encoding='unicode') 261 else: 262 # python3 is no decode function 263 vcxproj_string = etree.tostring(root, encoding='utf-8') 264 265 root_node=r'<Project DefaultTargets="Build" ToolsVersion="4.0">' 266 out.write(r'<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">') 267 out.write(vcxproj_string[len(root_node):]) 268 out.close() 269 270 xml_indent(filter_project) 271 272 if sys.version > '3': 273 filter_string = etree.tostring(filter_project, encoding='unicode') 274 else: 275 # python3 is no decode function 276 filter_string = etree.tostring(filter_project, encoding='utf-8') 277 278 out = open('project.vcxproj.filters', 'w') 279 out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n') 280 root_node=r'<Project ToolsVersion="4.0">' 281 out.write(r'<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">') 282 out.write(filter_string[len(root_node):]) 283 out.close() 284 285