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