1#
2# File      : codeblocks.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
42def CB_AddHeadFiles(program, elem, project_path):
43    utils.source_ext = []
44    utils.source_ext = ["h"]
45    for item in program:
46        utils.walk_children(item)
47    utils.source_list.sort()
48    # print utils.source_list
49
50    for f in utils.source_list:
51        path = _make_path_relative(project_path, f)
52        Unit = SubElement(elem, 'Unit')
53        Unit.set('filename', path.decode(fs_encoding))
54
55def CB_AddCFiles(ProjectFiles, parent, gname, files, project_path):
56    for f in files:
57        fn = f.rfile()
58        name = fn.name
59        path = os.path.dirname(fn.abspath)
60
61        path = _make_path_relative(project_path, path)
62        path = os.path.join(path, name)
63
64        Unit = SubElement(parent, 'Unit')
65        Unit.set('filename', path.decode(fs_encoding))
66        Option = SubElement(Unit, 'Option')
67        Option.set('compilerVar', "CC")
68
69def CBProject(target, script, program):
70    project_path = os.path.dirname(os.path.abspath(target))
71
72    if os.path.isfile('template.cbp'):
73        tree = etree.parse('template.cbp')
74    else:
75        tree = etree.parse(os.path.join(os.path.dirname(__file__), 'template.cbp'))
76
77    root = tree.getroot()
78
79    out = open(target, 'w')
80    out.write('<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n')
81
82    ProjectFiles = []
83
84    # SECTION 1. add "*.c|*.h" files group
85    for elem in tree.iter(tag='Project'):
86        # print elem.tag, elem.attrib
87        break
88    # add c files
89    for group in script:
90        group_xml = CB_AddCFiles(ProjectFiles, elem, group['name'], group['src'], project_path)
91    # add h files
92    CB_AddHeadFiles(program, elem, project_path)
93
94    # SECTION 2.
95    # write head include path
96    if 'CPPPATH' in building.Env:
97        cpp_path = building.Env['CPPPATH']
98        paths  = set()
99        for path in cpp_path:
100            inc = _make_path_relative(project_path, os.path.normpath(path))
101            paths.add(inc) #.replace('\\', '/')
102
103        paths = [i for i in paths]
104        paths.sort()
105        # write include path, definitions
106        for elem in tree.iter(tag='Compiler'):
107            break
108        for path in paths:
109            Add = SubElement(elem, 'Add')
110            Add.set('directory', path)
111
112        for macro in building.Env.get('CPPDEFINES', []):
113            Add = SubElement(elem, 'Add')
114            for d in macro:
115                Add.set('option', "-D"+d)
116
117        # write link flags
118    '''
119        # write lib dependence
120        if 'LIBS' in building.Env:
121            for elem in tree.iter(tag='Tool'):
122                if elem.attrib['Name'] == 'VCLinkerTool':
123                    break
124            libs_with_extention = [i+'.lib' for i in building.Env['LIBS']]
125            libs = ' '.join(libs_with_extention)
126            elem.set('AdditionalDependencies', libs)
127
128        # write lib include path
129        if 'LIBPATH' in building.Env:
130            lib_path = building.Env['LIBPATH']
131            paths  = set()
132            for path in lib_path:
133                inc = _make_path_relative(project_path, os.path.normpath(path))
134                paths.add(inc) #.replace('\\', '/')
135
136            paths = [i for i in paths]
137            paths.sort()
138            lib_paths = ';'.join(paths)
139            elem.set('AdditionalLibraryDirectories', lib_paths)
140    '''
141    xml_indent(root)
142    out.write(etree.tostring(root, encoding='utf-8'))
143    out.close()
144