2 # Update msvc project...
4 # This basically reads in the existing project file and replaces the list of
5 # files in there while keeping the project settings and compiler flags
7 from lxml import etree as ElementTree
12 # Namespace handling in ElementTree really sucks...
13 ms_ns = "http://schemas.microsoft.com/developer/msbuild/2003"
16 vcxproj = ElementTree.parse("firm.vcxproj")
17 project = vcxproj.getroot()
19 # Find the correct "ItemGroup" element. (somehow there are multiple of them
20 # in the file). The first one without a "Label" attribute seems to be the
23 for igroup in project.findall(ns+"ItemGroup"):
24 if "Label" in igroup.attrib:
26 mainItemGroup = igroup
28 # Remove all existing compile statement, we will recreate them
29 for comp in (mainItemGroup.findall(ns+"ClCompile") +
30 mainItemGroup.findall(ns+"ClInclude") +
31 mainItemGroup.findall(ns+"None") +
32 mainItemGroup.findall(ns+"CustomBuild")):
33 mainItemGroup.remove(comp)
35 filters = ElementTree.parse("firm.vcxproj.filters")
36 fproject = filters.getroot()
37 # The first "ItemGroup" appears to contain directories, the second one
38 # most of the files. (and the 3rd/4th is unclear to me...)
41 for igroup in fproject.findall(ns+"ItemGroup"):
42 if dirfilters == None:
48 # Simply remove everything
49 for f in dirfilters.findall(ns+"Filter"):
51 for f in filefilters.findall(ns+"Filter"):
54 # simply remove everything
56 # Directory where we find sourcefiles and at the same time the list of
57 # directories that will appear in the project.
58 # Note that you have to specify all parent dirs, so if you have "ir/foo"
59 # then make sure "ir" is in the list too before "ir/foo"
83 backends = [ "ia32", "arm", "amd64", "sparc", "TEMPLATE" ]
84 dirs += map(lambda x: "ir/be/%s" % x, backends)
86 # Adds a file to the project. With build type @p type.
87 # This also adds a filter with the same name as the files directory
90 inc = "$(FirmRoot)\\%s" % f.replace("/", "\\")
91 element = ElementTree.SubElement(mainItemGroup, ns+type, Include=inc)
92 fc = ElementTree.SubElement(filefilters, ns+type, Include=inc)
93 filt = ElementTree.SubElement(fc, ns+"Filter")
94 filt.text = os.path.dirname(f).replace("/", "\\")
98 # "Normal" .c/.h files
100 # Create the filtergroup for the directory
101 wind = d.replace("/", "\\")
102 f = ElementTree.SubElement(dirfilters, ns+"Filter", Include=wind)
103 ui = ElementTree.SubElement(f, ns+"UniqueIdentifier")
104 ui.text = "{%s}" % uuid.uuid4()
106 # Compile normal C files
107 for cfile in glob.glob("%s/*.c" % d):
108 addFile("ClCompile", cfile)
109 # "Include" header files
110 for hfile in glob.glob("%s/*.h" % d):
111 addFile("ClInclude", hfile)
113 # CustomBuild stuff for the backends
116 spec = "ir/be/%s/%s_spec.pl" % (be,be)
117 custombuild.append(spec)
118 cb = addFile("CustomBuild", spec)
119 message = ElementTree.SubElement(cb, ns+"Message")
120 message.text = "Translate Spec: %(FullPath)"
121 command = ElementTree.SubElement(cb, ns+"Command")
123 """$(FirmRoot)\\ir\\be\\scripts\\generate_emitter.pl %%(FullPath) $(FirmRoot)\\ir\\be\\%(arch)s
124 $(FirmRoot)\\ir\\be\\scripts\\generate_new_opcodes.pl %%(FullPath) $(FirmRoot)\\ir\\be\\%(arch)s
125 $(FirmRoot)\\ir\\be\\scripts\\generate_regalloc_if.pl %%(FullPath) $(FirmRoot)\\ir\\be\\%(arch)s
126 $(FirmRoot)\\ir\\be\\scripts\\generate_machine.pl %%(FullPath) $(FirmRoot)\\ir\\be\\%(arch)s
130 "ir/be/scripts/generate_emitter.pl",
131 "ir/be/scripts/generate_new_opcodes.pl",
132 "ir/be/scripts/generate_regalloc_if.pl",
133 "ir/be/scripts/generate_machine.pl",
135 inputfiles = map(lambda x: "$(FirmRoot)\\%s" % x.replace("/", "\\"), inputfiles)
136 inputfiles.append("$(AdditonalInputs)")
137 inputs = ElementTree.SubElement(cb, ns+"AdditionalInputs")
138 inputs.text = ";".join(inputfiles)
141 "ir/be/%s/gen_%s_emitter.c" % (be,be),
142 "ir/be/%s/gen_%s_emitter.h" % (be,be),
143 "ir/be/%s/gen_%s_new_nodes.c" % (be,be),
144 "ir/be/%s/gen_%s_new_nodes.h" % (be,be),
145 "ir/be/%s/gen_%s_regalloc_if.c" % (be,be),
146 "ir/be/%s/gen_%s_regalloc_if.h" % (be,be),
147 "ir/be/%s/gen_%s_machine.c" % (be,be),
148 "ir/be/%s/gen_%s_machine.h" % (be,be)
150 outputfiles = map(lambda x: "$(FirmRoot)\\%s" % x.replace("/", "\\"), outputfiles)
151 outputfiles.append("$(Outputs)")
152 outputs = ElementTree.SubElement(cb, ns+"Outputs")
153 outputs.text = ";".join(outputfiles)
155 # CustomBuild for ir_io:
156 custombuild.append("scripts/gen_ir_io.py")
157 cb = addFile("CustomBuild", "scripts/gen_ir_io.py")
158 message = ElementTree.SubElement(cb, ns+"Message")
159 message.text = "Generating I/O code: %(FullPath)"
160 command = ElementTree.SubElement(cb, ns+"Command")
161 command.text = "python %(FullPath) $(FirmRoot)\\scripts\\ir_spec.py $(FirmRoot)\\ir\\ir"
162 additionalinputs = ElementTree.SubElement(cb, ns+"AdditionalInputs")
163 additionalinputs.text = "$(FirmRoot)\\scripts\\ir_spec.py;%(AdditionalInputs)"
164 outputs = ElementTree.SubElement(cb, ns+"Outputs")
165 outputs.text = "$(FirmRoot)\\ir\\ir\\gen_irio_import.inl;$(FirmRoot)\\ir\\ir\\gen_irio_export.inl;$(FirmRoot)\\ir\\ir\\gen_irio_lex.inl;%(Outputs)"
167 # CustomBuild for ir_spec:
168 custombuild.append("scripts/gen_ir.py")
169 cb = addFile("CustomBuild", "scripts/gen_ir.py")
170 message = ElementTree.SubElement(cb, ns+"Message")
171 message.text = "Translate IR-Spec: %(FullPath)"
172 command = ElementTree.SubElement(cb, ns+"Command")
173 command.text = "python %(FullPath) $(FirmRoot) $(FirmRoot)\\ir\\ir"
174 additionalinputs = ElementTree.SubElement(cb, ns+"AdditionalInputs")
175 additionalinputs.text = "$(FirmRoot)\\scripts\\gen_ir.py;%(AdditionalInputs)"
176 outputs = ElementTree.SubElement(cb, ns+"Outputs")
177 outputs.text = "$(FirmRoot)\ir\ir\gen_ir_cons.c.inl;$(FirmRoot)\ir\ir\gen_irnode.h;$(FirmRoot)\ir\ir\gen_irnode.c.inl;$(FirmRoot)\ir\ir\gen_irop.c.inl;%(Outputs)"
179 # Stuff we simply include... but which is neither a .c nor a .h file
181 "ir/ir/irflag_t.def",
182 "ir/libcore/lc_printf_arg_types.def",
184 stuff += glob.glob("scripts/*.py")
185 stuff += glob.glob("ir/be/scripts/*.pl")
191 vcxproj.write("/tmp/out.xml")
192 filters.write("/tmp/outf.xml")
194 # Use xmllint to reformat the output to something more readable
195 vcxo = "/tmp/firm.vcxproj"
196 vcxfo = "/tmp/firm.vcxproj.filters"
197 os.system("xmllint --format /tmp/out.xml > %s" % vcxo)
198 os.system("xmllint --format /tmp/outf.xml > %s" % vcxfo)
200 print "Generated: %s %s" % (vcxo, vcxfo)