3
import xml.etree.ElementTree as ET
5
from os.path import basename
6
from xml.dom import minidom
10
def create_project_target(env, currentSource, buildElement, projectFileDir, buildTarget, compiler, project):
12
if isinstance(buildTarget, dict):
13
target = buildTarget[currentSource]
15
targetElement = ET.SubElement(buildElement, "Target", {"title":target})
16
sources, includes = extensions.get_sources_and_includes(env, currentSource)
18
outPutRelative = projectFileDir.rel_path(currentSource)
19
objectPath = os.path.dirname(outPutRelative)
23
ET.SubElement(targetElement, "Option", {"output":outPutRelative})
24
ET.SubElement(targetElement, "Option", {"object_output": objectPath})
25
ET.SubElement(targetElement, "Option", {"type":"0" })
26
ET.SubElement(targetElement, "Option", {"create_hex":"1"})
27
ET.SubElement(targetElement, "Option", {"compiler":compiler })
28
ET.SubElement(targetElement, "Option", {"projectDeviceOptionsRelation":"0"})
30
compilerElem = ET.SubElement(targetElement, "Compiler")
31
for flag in env["CCFLAGS"]:
32
ET.SubElement(compilerElem, "Add", option=flag)
33
for define in env["CPPDEFINES"]:
34
if isinstance(define, dict):
36
ET.SubElement(compilerElem, "Add", symbol="%s=%s" %(key, define[key]))
38
ET.SubElement(compilerElem, "Add", symbol=define)
40
for includePath in env["CPPPATH"]:
41
includeDir = env.Dir(includePath).srcnode()
42
includeDirRel = projectFileDir.rel_path(includeDir)
43
ET.SubElement(compilerElem, "Add", directory=includeDirRel)
45
cppElem = ET.SubElement(targetElement, "Cpp")
46
for flag in env["CXXFLAGS"] + env["CCFLAGS"]:
47
ET.SubElement(cppElem, "Add", option=flag)
49
asmElem = ET.SubElement(targetElement, "Assembler")
50
for flag in env["ASFLAGS"]:
51
ET.SubElement(asmElem, "Add", option=flag)
54
linkElem = ET.SubElement(targetElement, "Linker")
55
for flag in env["LINKFLAGS"]:
56
flag = flag.rstrip('"').strip('"')
57
if flag.startswith("-T"):
59
ET.SubElement(linkElem, "Add", option=flag)
61
deviceElem = ET.SubElement(targetElement, "Device")
63
device = env["DEVICE"]
65
ET.SubElement(deviceElem, "Add", option="$device=" + device["cpu"])
67
for src in sources | includes:
68
item = projectFileDir.rel_path(src.srcnode())
69
filename, file_extension = os.path.splitext(item)
70
if file_extension.lower() in env["CPPSUFFIXES"]:
72
unit = ET.SubElement(project, "Unit", { "filename":item})
73
if file_extension.lower() in [".c", ".cpp", ".s", ".cxx", ".cc"]:
74
ET.SubElement(unit, "Option", { "compilerVar":"CC"})
76
add_build_commands(targetElement)
79
def add_build_commands(targetElement):
80
makeCommands = ET.SubElement(targetElement, "MakeCommands")
81
ET.SubElement(makeCommands, "Build", command="scons.bat -f $makefile $target")
82
ET.SubElement(makeCommands, "CompileFile", command="scons.bat -f $makefile $file")
83
ET.SubElement(makeCommands, "Clean", command="scons.bat -f $makefile $target -c")
84
ET.SubElement(makeCommands, "DistClean", command="scons.bat -f $makefile $target -c")
85
ET.SubElement(makeCommands, "SilentBuild", command="scons.bat -f $makefile $target")
86
ET.SubElement(makeCommands, "AskRebuildNeeded", command="echo 1")
88
def generate_common_project(target, source, env, projectFile, compiler):
89
buildTarget = "Default"
90
if "CURRENT_BUILD_TARGET" in env:
91
buildTarget = env["CURRENT_BUILD_TARGET"]
93
rootDir = env.Dir("#/").srcnode().abspath
94
projectFileDir = env.Dir(os.path.dirname(target[0].abspath))
95
targetFilename = basename(source[0].abspath)
96
rootConstruct = env.File(os.path.join(rootDir, "SConstruct")).srcnode()
97
rootConstructRelative = projectFileDir.rel_path(rootConstruct)
99
project = ET.SubElement(projectFile, "Project")
100
ET.SubElement(project, "Option", { "title":targetFilename})
101
ET.SubElement(project, "Option", { "compiler":compiler})
103
ET.SubElement(project, "Option", makefile=rootConstructRelative)
104
ET.SubElement(project, "Option", makefile_is_custom="1")
105
ET.SubElement(project, "Option", make_tool="scons.bat")
107
buildElement = ET.SubElement(project, "Build")
108
for currentSource in source:
109
create_project_target(env, currentSource, buildElement, projectFileDir, buildTarget, compiler, project)
111
add_build_commands(project)
114
def get_cb_compiler_name(env):
115
if "CB_COMPILER" in env:
116
return env["CB_COMPILER"]
121
def save_project(projectFileNode, targetFilePath):
122
xmlstr = minidom.parseString(ET.tostring(projectFileNode, encoding="utf8", method="xml")).toprettyxml(indent=" ")
123
with open(targetFilePath, "w") as f:
126
def add_common_debugger_section(xmlExtensionsNode, debuggerPort):
127
debuggerNode = ET.SubElement(xmlExtensionsNode, "debugger")
128
remoteDebuggingNode = ET.SubElement(debuggerNode, "remote_debugging")
129
optionsNode = ET.SubElement(remoteDebuggingNode, "options", conn_type="0", ip_address="localhost", ip_port=debuggerPort)
130
return remoteDebuggingNode
132
def add_st_link_debugging_settings(xmlExtensionsNode, debuggerPort, target):
133
debuggerNode = ET.SubElement(xmlExtensionsNode, "debugger")
134
targetDebuggingSettingsNode = ET.SubElement(debuggerNode, "target_debugging_settings", target=target, active_interface="ST-link")
135
debugInterfaceNode = ET.SubElement(targetDebuggingSettingsNode, "debug_interface",
136
interface_id="ST-link",
137
ip_address="localhost",
138
ip_port=debuggerPort,
139
path="${EMBITZ}\share\contrib",
140
executable="STLinkGDB.exe",
141
description="..\..\Mcucpp\svd\STM32F1_svd_V1.0.0\STM32F100.svd",
142
dont_start_server="false",
146
active_family="STMicroelectronics",
149
familyOptionsNode = ET.SubElement(debugInterfaceNode, "family_options", family_id="STMicroelectronics")
150
ET.SubElement(familyOptionsNode, "option", opt_id="ID_JTAG_SWD", opt_value="swd")
151
ET.SubElement(familyOptionsNode, "option", opt_id="ID_VECTOR_START", opt_value="0x08000000")
152
ET.SubElement(familyOptionsNode, "option", opt_id="ID_RESET_TYPE", opt_value="System")
153
ET.SubElement(familyOptionsNode, "option", opt_id="ID_LOAD_PROGRAM", opt_value="1")
154
ET.SubElement(familyOptionsNode, "option", opt_id="ID_SEMIHOST_CHECK", opt_value="1")
155
ET.SubElement(familyOptionsNode, "option", opt_id="ID_RAM_EXEC", opt_value="0")
156
ET.SubElement(familyOptionsNode, "option", opt_id="ID_VEC_TABLE", opt_value="1")
157
ET.SubElement(familyOptionsNode, "option", opt_id="ID_DONT_CONN_RESET", opt_value="0")
158
ET.SubElement(familyOptionsNode, "option", opt_id="ID_ALL_MODE_DEBUG", opt_value="0")
159
ET.SubElement(familyOptionsNode, "option", opt_id="ID_DEV_ADDR", opt_value="")
160
ET.SubElement(familyOptionsNode, "option", opt_id="ID_VERBOSE_LEVEL", opt_value="3")
164
def generate_embitz_project(target, source, env):
165
buildTarget = "Default"
166
if "CURRENT_BUILD_TARGET" in env:
167
buildTarget = env["CURRENT_BUILD_TARGET"]
168
projectFile = ET.Element("EmBitz_project_file")
169
ET.SubElement(projectFile, "EmBitzVersion", attrib={"release" : "1.11", "revision" : "0"})
170
ET.SubElement(projectFile, "FileVersion", attrib={"major":"1", "minor":"0"})
171
projectNode = generate_common_project(target, source, env, projectFile, "armgcc_eb")
172
extensionsNode = ET.SubElement(projectNode, "Extensions")
173
add_st_link_debugging_settings(extensionsNode, "4242", buildTarget)
174
save_project(projectFile, target[0].abspath)
177
def generate_cb_project(target, source, env):
178
projectFile = ET.Element("CodeBlocks_project_file")
179
ET.SubElement(projectFile, "FileVersion", attrib={"major":"1", "minor":"6"})
180
projectNode = generate_common_project(target, source, env, projectFile, get_cb_compiler_name(env))
181
extensionsNode = ET.SubElement(projectNode, "Extensions")
182
add_common_debugger_section(extensionsNode, "4242")
183
save_project(projectFile, target[0].abspath)
189
def generate(env, **kw):
190
bld = env.Builder(action = generate_embitz_project, suffix = '.ebp')
191
env.Append(BUILDERS = {'EmbitzProject' : bld})
192
bld = env.Builder(action = generate_cb_project, suffix = '.cbp')
193
env.Append(BUILDERS = {'CodeBlocksProject' : bld})