xref: /nrf52832-nimble/rt-thread/tools/vs.py (revision 104654410c56c573564690304ae786df310c91fc)
1#
2# File      : vs.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 utils
30
31import xml.etree.ElementTree as etree
32from xml.etree.ElementTree import SubElement
33from utils import _make_path_relative
34from utils import xml_indent
35fs_encoding = sys.getfilesystemencoding()
36
37def VS_AddGroup(ProjectFiles, parent, name, files, libs, project_path):
38    Filter = SubElement(parent, 'Filter')
39    Filter.set('Name', name) #set group name to group
40
41    for f in files:
42        fn = f.rfile()
43        name = fn.name
44        path = os.path.dirname(fn.abspath)
45
46        path = _make_path_relative(project_path, path)
47        path = os.path.join(path, name)
48
49        File = SubElement(Filter, 'File')
50        File.set('RelativePath', path.decode(fs_encoding))
51
52    for lib in libs:
53        name = os.path.basename(lib)
54        path = os.path.dirname(lib)
55
56        path = _make_path_relative(project_path, path)
57        path = os.path.join(path, name)
58
59        File = SubElement(Filter, 'File')
60        File.set('RelativePath', path.decode(fs_encoding))
61
62def VS_AddHeadFilesGroup(program, elem, project_path):
63    utils.source_ext = []
64    utils.source_ext = ["h"]
65    for item in program:
66        utils.walk_children(item)
67    utils.source_list.sort()
68    # print utils.source_list
69
70    for f in utils.source_list:
71        path = _make_path_relative(project_path, f)
72        File = SubElement(elem, 'File')
73        File.set('RelativePath', path.decode(fs_encoding))
74
75def VSProject(target, script, program):
76    project_path = os.path.dirname(os.path.abspath(target))
77
78    tree = etree.parse('template_vs2005.vcproj')
79    root = tree.getroot()
80
81    out = open(target, 'w')
82    out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n')
83
84    ProjectFiles = []
85
86    # add "*.c" files group
87    for elem in tree.iter(tag='Filter'):
88        if elem.attrib['Name'] == 'Source Files':
89            #print elem.tag, elem.attrib
90            break
91
92    for group in script:
93        libs = []
94        if 'LIBS' in group and group['LIBS']:
95            for item in group['LIBS']:
96                lib_path = ''
97                for path_item in group['LIBPATH']:
98                    full_path = os.path.join(path_item, item + '.lib')
99                    if os.path.isfile(full_path): # has this library
100                        lib_path = full_path
101
102                if lib_path != '':
103                    libs.append(lib_path)
104
105        group_xml = VS_AddGroup(ProjectFiles, elem, group['name'], group['src'], libs, project_path)
106
107    # add "*.h" files group
108    for elem in tree.iter(tag='Filter'):
109        if elem.attrib['Name'] == 'Header Files':
110            break
111    VS_AddHeadFilesGroup(program, elem, project_path)
112
113    # write head include path
114    if 'CPPPATH' in building.Env:
115        cpp_path = building.Env['CPPPATH']
116        paths  = set()
117        for path in cpp_path:
118            inc = _make_path_relative(project_path, os.path.normpath(path))
119            paths.add(inc) #.replace('\\', '/')
120
121        paths = [i for i in paths]
122        paths.sort()
123        cpp_path = ';'.join(paths)
124
125        # write include path, definitions
126        for elem in tree.iter(tag='Tool'):
127            if elem.attrib['Name'] == 'VCCLCompilerTool':
128                #print elem.tag, elem.attrib
129                break
130        elem.set('AdditionalIncludeDirectories', cpp_path)
131
132    # write cppdefinitons flags
133    if 'CPPDEFINES' in building.Env:
134        CPPDEFINES = building.Env['CPPDEFINES']
135        definitions = []
136        if type(CPPDEFINES[0]) == type(()):
137            for item in CPPDEFINES:
138                definitions += [i for i in item]
139            definitions = ';'.join(definitions)
140        else:
141            definitions = ';'.join(building.Env['CPPDEFINES'])
142        elem.set('PreprocessorDefinitions', definitions)
143    # write link flags
144
145    # write lib dependence
146    if 'LIBS' in building.Env:
147        for elem in tree.iter(tag='Tool'):
148            if elem.attrib['Name'] == 'VCLinkerTool':
149                break
150        libs_with_extention = [i+'.lib' for i in building.Env['LIBS']]
151        libs = ' '.join(libs_with_extention)
152        elem.set('AdditionalDependencies', libs)
153
154    # write lib include path
155    if 'LIBPATH' in building.Env:
156        lib_path = building.Env['LIBPATH']
157        paths  = set()
158        for path in lib_path:
159            inc = _make_path_relative(project_path, os.path.normpath(path))
160            paths.add(inc) #.replace('\\', '/')
161
162        paths = [i for i in paths]
163        paths.sort()
164        lib_paths = ';'.join(paths)
165        elem.set('AdditionalLibraryDirectories', lib_paths)
166
167    xml_indent(root)
168    out.write(etree.tostring(root, encoding='utf-8'))
169    out.close()
170