234 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #
 | |
| # File      : vs2012.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
 | |
| #
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| import string
 | |
| import building
 | |
| import uuid
 | |
| 
 | |
| import xml.etree.ElementTree as etree
 | |
| from xml.etree.ElementTree import SubElement
 | |
| from utils import _make_path_relative
 | |
| from utils import xml_indent
 | |
| import utils
 | |
| 
 | |
| fs_encoding = sys.getfilesystemencoding()
 | |
| 
 | |
| #reference
 | |
| # http://woodpecker.org.cn/diveintopython3/xml.html
 | |
| # https://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/processing-xml-in-python-with-element-tree.html
 | |
| # http://www.cnblogs.com/ifantastic/archive/2013/04/12/3017110.html
 | |
| 
 | |
| filter_project = etree.Element('Project', attrib={'ToolsVersion':'4.0'})
 | |
| def get_uuid():
 | |
|     id = uuid.uuid1()  # UUID('3e5526c0-2841-11e3-a376-20cf3048bcb3')
 | |
|     idstr = id.get_urn()[9:] #'urn:uuid:3e5526c0-2841-11e3-a376-20cf3048bcb3'[9:]
 | |
|     return '{'+idstr+'}'
 | |
| 
 | |
| def VS2012_AddGroup(parent, group_name, files, project_path):
 | |
|     for f in files:
 | |
|         fn = f.rfile()
 | |
|         name = fn.name
 | |
|         path = os.path.dirname(fn.abspath)
 | |
| 
 | |
|         path = _make_path_relative(project_path, path)
 | |
|         path = os.path.join(path, name)
 | |
| 
 | |
|         ClCompile = SubElement(parent, 'ClCompile')
 | |
|         ClCompile.set('Include', path.decode(fs_encoding))
 | |
| 
 | |
|         Filter = SubElement(ClCompile, 'Filter')
 | |
|         Filter.text='Source Files\\'+group_name
 | |
| 
 | |
| def VS2012_CreateFilter(script, project_path):
 | |
|     c_ItemGroup = SubElement(filter_project, 'ItemGroup')
 | |
|     filter_ItemGroup = SubElement(filter_project, 'ItemGroup')
 | |
| 
 | |
|     Filter = SubElement(filter_ItemGroup, 'Filter')
 | |
|     Filter.set('Include', 'Source Files')
 | |
|     UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier')
 | |
|     UniqueIdentifier.text = get_uuid()
 | |
|     Extensions = SubElement(Filter, 'Extensions')
 | |
|     Extensions.text = 'cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx'
 | |
| 
 | |
|     Filter = SubElement(filter_ItemGroup, 'Filter')
 | |
|     Filter.set('Include', 'Header Files')
 | |
|     UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier')
 | |
|     UniqueIdentifier.text = get_uuid()
 | |
|     Extensions = SubElement(Filter, 'Extensions')
 | |
|     Extensions.text = 'h;hpp;hxx;hm;inl;inc;xsd'
 | |
|     for group in script:
 | |
|         VS2012_AddGroup(c_ItemGroup, group['name'], group['src'], project_path)
 | |
|         Filter = SubElement(filter_ItemGroup, 'Filter')
 | |
|         Filter.set('Include', 'Source Files\\'+group['name'])
 | |
|         UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier')
 | |
|         UniqueIdentifier.text = get_uuid()
 | |
| 
 | |
| #program: object from scons
 | |
| # parent: xml node
 | |
| # file_type: C or H
 | |
| # files: c/h list
 | |
| # project_path
 | |
| def VS_add_ItemGroup(parent, file_type, files, project_path):
 | |
|     from building import Rtt_Root
 | |
|     RTT_ROOT = os.path.normpath(Rtt_Root)
 | |
| 
 | |
|     file_dict = {'C':"ClCompile", 'H':'ClInclude'}
 | |
|     item_tag = file_dict[file_type]
 | |
| 
 | |
|     ItemGroup = SubElement(parent, 'ItemGroup')
 | |
|     for f in files:
 | |
|         fn = f.rfile()
 | |
|         name = fn.name
 | |
|         path = os.path.dirname(fn.abspath)
 | |
| 
 | |
|         objpath = path.lower()
 | |
|         if len(project_path) >= len(RTT_ROOT) :
 | |
|             if objpath.startswith(project_path.lower()) :
 | |
|                 objpath = ''.join('bsp'+objpath[len(project_path):])
 | |
|             else :
 | |
|                 objpath = ''.join('kernel'+objpath[len(RTT_ROOT):])
 | |
|         else :
 | |
|             if objpath.startswith(RTT_ROOT.lower()) :
 | |
|                 objpath = ''.join('kernel'+objpath[len(RTT_ROOT):])
 | |
|             else :
 | |
|                 objpath = ''.join('bsp'+objpath[len(project_path):])
 | |
|         path = _make_path_relative(project_path, path)
 | |
|         path = os.path.join(path, name)
 | |
| 
 | |
|         File = SubElement(ItemGroup, item_tag)
 | |
|         File.set('Include', path.decode(fs_encoding))
 | |
|         if file_type == 'C' :
 | |
|             ObjName = SubElement(File, 'ObjectFileName')
 | |
|             ObjName.text = ''.join('$(IntDir)'+objpath+'\\')
 | |
| 
 | |
| def VS_add_HeadFiles(program, elem, project_path):
 | |
|     utils.source_ext = []
 | |
|     utils.source_ext = ["h"]
 | |
|     for item in program:
 | |
|         utils.walk_children(item)    
 | |
|     utils.source_list.sort()
 | |
|     # print utils.source_list
 | |
|     ItemGroup = SubElement(elem, 'ItemGroup')
 | |
| 
 | |
|     filter_h_ItemGroup = SubElement(filter_project, 'ItemGroup')
 | |
|     for f in utils.source_list:
 | |
|         path = _make_path_relative(project_path, f)
 | |
|         File = SubElement(ItemGroup, 'ClInclude')
 | |
|         File.set('Include', path.decode(fs_encoding))
 | |
| 
 | |
|         # add project.vcxproj.filter
 | |
|         ClInclude = SubElement(filter_h_ItemGroup, 'ClInclude')
 | |
|         ClInclude.set('Include', path.decode(fs_encoding))
 | |
|         Filter = SubElement(ClInclude, 'Filter')
 | |
|         Filter.text='Header Files'
 | |
| 
 | |
| def VS2012Project(target, script, program):
 | |
|     project_path = os.path.dirname(os.path.abspath(target))
 | |
|     
 | |
|     tree = etree.parse('template_vs2012.vcxproj')
 | |
|     root = tree.getroot()
 | |
|     elem = root
 | |
|     
 | |
|     out = file(target, 'wb')
 | |
|     out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n')
 | |
|     
 | |
|     ProjectFiles = []
 | |
|     
 | |
|     # add "*.c or *.h" files
 | |
| 
 | |
|     VS2012_CreateFilter(script, project_path)
 | |
|     # add "*.c" files
 | |
|     for group in script:
 | |
|         VS_add_ItemGroup(elem, 'C', group['src'], project_path)
 | |
| 
 | |
|     # add "*.h" files
 | |
|     VS_add_HeadFiles(program, elem, project_path)
 | |
| 
 | |
|     # write head include path
 | |
|     if 'CPPPATH' in building.Env:
 | |
|         cpp_path = building.Env['CPPPATH']
 | |
|         paths = set()
 | |
|         for path in cpp_path:
 | |
|             inc = _make_path_relative(project_path, os.path.normpath(path))
 | |
|             paths.add(inc) #.replace('\\', '/')
 | |
|     
 | |
|         paths = [i for i in paths]
 | |
|         paths.sort()
 | |
|         cpp_path = ';'.join(paths) + ';%(AdditionalIncludeDirectories)'
 | |
| 
 | |
|         # write include path
 | |
|         for elem in tree.iter(tag='AdditionalIncludeDirectories'):
 | |
|             elem.text = cpp_path
 | |
|             break
 | |
| 
 | |
|     # write cppdefinitons flags
 | |
|     if 'CPPDEFINES' in building.Env:
 | |
|         for elem in tree.iter(tag='PreprocessorDefinitions'):
 | |
|             definitions = ';'.join(building.Env['CPPDEFINES']) + ';%(PreprocessorDefinitions)'
 | |
|             elem.text = definitions
 | |
|             break
 | |
|     # write link flags
 | |
| 
 | |
|     # write lib dependence (Link)
 | |
|     if 'LIBS' in building.Env:
 | |
|         for elem in tree.iter(tag='AdditionalDependencies'):
 | |
|             libs_with_extention = [i+'.lib' for i in building.Env['LIBS']]
 | |
|             libs = ';'.join(libs_with_extention) + ';%(AdditionalDependencies)'
 | |
|             elem.text = libs
 | |
|             break
 | |
| 
 | |
|     # write lib include path
 | |
|     if 'LIBPATH' in building.Env:
 | |
|         lib_path = building.Env['LIBPATH']
 | |
|         paths  = set()
 | |
|         for path in lib_path:
 | |
|             inc = _make_path_relative(project_path, os.path.normpath(path))
 | |
|             paths.add(inc)
 | |
|     
 | |
|         paths = [i for i in paths]
 | |
|         paths.sort()
 | |
|         lib_paths = ';'.join(paths) + ';%(AdditionalLibraryDirectories)'
 | |
|         for elem in tree.iter(tag='AdditionalLibraryDirectories'):
 | |
|             elem.text = lib_paths
 | |
|             break
 | |
| 
 | |
|     xml_indent(root)
 | |
|     vcxproj_string = etree.tostring(root, encoding='utf-8')
 | |
|     root_node=r'<Project DefaultTargets="Build" ToolsVersion="4.0">'
 | |
|     out.write(r'<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">')
 | |
|     out.write(vcxproj_string[len(root_node):])
 | |
|     out.close()
 | |
| 
 | |
|     xml_indent(filter_project)
 | |
|     filter_string = etree.tostring(filter_project, encoding='utf-8')
 | |
|     out = file('project.vcxproj.filters', 'wb')
 | |
|     out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n')
 | |
|     root_node=r'<Project ToolsVersion="4.0">'
 | |
|     out.write(r'<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">')
 | |
|     out.write(filter_string[len(root_node):])
 | |
|     out.close()
 | |
| 
 |