]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Python/MkFar.py
7531527f582bfc522110fee95b5dd77f88f73abe
[mirror_edk2.git] / Tools / Python / MkFar.py
1 #!/usr/bin/env python
2
3 import os, sys, getopt, string, xml.dom.minidom, zipfile, md5
4 from XmlRoutines import *
5 from WorkspaceRoutines import *
6
7 class Far:
8 """This class is used to collect arbitrarty data from the template file."""
9 def __init__(far):
10 """Assign the default values for the far fields."""
11 far.FileName = "output.far"
12 far.FarName=""
13 far.Version=""
14 far.License=""
15 far.Description=""
16 far.Copyright=""
17 far.SpdFiles=""
18 far.FpdFile=""
19 far.ExtraFile=""
20
21 far = Far()
22
23 def parseMsa(msaFile, spdDir):
24
25 filelist = [msaFile]
26
27 msaDir = os.path.dirname(msaFile)
28
29 msa = xml.dom.minidom.parse(inWorkspace(os.path.join(spdDir, msaFile)))
30
31 xmlPaths = [
32 "/ModuleSurfaceArea/SourceFiles/Filename",
33 "/ModuleSurfaceArea/NonProcessedFiles/Filename" ]
34
35 for xmlPath in xmlPaths:
36 for f in XmlList(msa, xmlPath):
37 filelist.append(str(os.path.join(msaDir, XmlElementData(f))))
38
39 return filelist
40
41 def parseSpd(spdFile):
42
43 files = []
44
45 spdDir = os.path.dirname(spdFile)
46
47 spd = xml.dom.minidom.parse(inWorkspace(spdFile))
48
49 xmlPaths = [
50 "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass/IncludeHeader",
51 "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader/IncludeHeader",
52 "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader" ]
53
54 for xmlPath in xmlPaths:
55 for f in XmlList(spd, xmlPath):
56 files.append(str(XmlElementData(f)))
57
58 for f in XmlList(spd, "/PackageSurfaceArea/MsaFiles/Filename"):
59 msaFile = str(XmlElementData(f))
60 files += parseMsa(msaFile, spdDir)
61
62 cwd = os.getcwd()
63 os.chdir(inWorkspace(spdDir))
64 for root, dirs, entries in os.walk("Include"):
65 for r in ["CVS", ".svn"]:
66 if r in dirs:
67 dirs.remove(r)
68 for entry in entries:
69 files.append(os.path.join(os.path.normpath(root), entry))
70 os.chdir(cwd)
71
72 return files
73
74 def makeFarHeader(doc):
75
76 header = doc.createElement("FarHeader")
77 name = doc.createElement("FarName")
78 name.appendChild(doc.createTextNode(far.FarName))
79 header.appendChild(name)
80 guidVal = doc.createElement("GuidValue")
81 guidVal.appendChild(doc.createTextNode(genguid()))
82 header.appendChild(guidVal)
83 ver = doc.createElement("Version")
84 ver.appendChild(doc.createTextNode(far.Version))
85 header.appendChild(ver)
86 abstract = doc.createElement("Abstract")
87 abstract.appendChild(doc.createTextNode(far.Abstract))
88 header.appendChild(abstract)
89 desc = doc.createElement("Description")
90 desc.appendChild(doc.createTextNode(far.Description))
91 header.appendChild(desc)
92 copy = doc.createElement("Copyright")
93 copy.appendChild(doc.createTextNode(far.Copyright))
94 header.appendChild(copy)
95 lic = doc.createElement("License")
96 lic.appendChild(doc.createTextNode(far.License))
97 header.appendChild(lic)
98 spec = doc.createElement("Specification")
99 spec.appendChild(doc.createTextNode("FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052"))
100 header.appendChild(spec)
101
102 return header
103
104 def getSpdGuidVersion(spdFile):
105
106 spd = xml.dom.minidom.parse(inWorkspace(spdFile))
107
108 return (XmlElement(spd, "/PackageSurfaceArea/SpdHeader/GuidValue"),
109 XmlElement(spd, "/PackageSurfaceArea/SpdHeader/Version"))
110
111 def makeFar(filelist, farname):
112
113 domImpl = xml.dom.minidom.getDOMImplementation()
114 man = domImpl.createDocument(None, "FrameworkArchiveManifest", None)
115 top_element = man.documentElement
116
117 top_element.appendChild(makeFarHeader(man))
118
119 packList = man.createElement("FarPackageList")
120 top_element.appendChild(packList)
121
122 platList = man.createElement("FarPlatformList")
123 top_element.appendChild(platList)
124
125 contents = man.createElement("Contents")
126 top_element.appendChild(contents)
127
128 exts = man.createElement("UserExtensions")
129 top_element.appendChild(exts)
130
131 zip = zipfile.ZipFile(farname, "w")
132 for infile in filelist:
133 if not os.path.exists(inWorkspace(infile)):
134 print "Skipping non-existent file '%s'." % infile
135 (_, extension) = os.path.splitext(infile)
136 if extension == ".spd":
137 filelist = parseSpd(infile)
138 spdDir = os.path.dirname(infile)
139
140 (spdGuid, spdVersion) = getSpdGuidVersion(infile)
141
142 package = man.createElement("FarPackage")
143 packList.appendChild(package)
144
145 spdfilename = farFileNode(man, inWorkspace(infile))
146 zip.write(inWorkspace(infile), infile)
147 spdfilename.appendChild(man.createTextNode(infile))
148 package.appendChild(spdfilename)
149
150 guidValue = man.createElement("GuidValue")
151 guidValue.appendChild(man.createTextNode(spdGuid))
152 package.appendChild(guidValue)
153
154 version = man.createElement("Version")
155 version.appendChild(man.createTextNode(spdVersion))
156 package.appendChild(version)
157
158 defaultPath = man.createElement("DefaultPath")
159 defaultPath.appendChild(man.createTextNode(spdDir))
160 package.appendChild(defaultPath)
161
162 farPlatformList = man.createElement("FarPlatformList")
163 package.appendChild(farPlatformList)
164
165 packContents = man.createElement("Contents")
166 package.appendChild(packContents)
167
168 ue = man.createElement("UserExtensions")
169 package.appendChild(ue)
170
171 for spdfile in filelist:
172 content = farFileNode(man, inWorkspace(os.path.join(spdDir, spdfile)))
173 zip.write(inWorkspace(os.path.join(spdDir, spdfile)), spdfile)
174 content.appendChild(man.createTextNode(spdfile))
175 packContents.appendChild(content)
176
177 elif extension == ".fpd":
178
179 platform = man.createElement("FarPlatform")
180 platList.appendChild(platform)
181
182 fpdfilename = farFileNode(man, inWorkspace(infile))
183 zip.write(inWorkspace(infile), infile)
184 platform.appendChild(fpdfilename)
185 fpdfilename.appendChild( man.createTextNode(infile) )
186
187 else:
188 content = farFileNode(man, inWorkspace(infile))
189 zip.write(inWorkspace(infile), infile)
190 content.appendChild(man.createTextNode(infile))
191 contents.appendChild(content)
192
193 zip.writestr("FrameworkArchiveManifest.xml", man.toprettyxml(2*" "))
194 zip.close()
195 return
196
197 def farFileNode(doc, filename):
198 content = doc.createElement("FarFilename")
199 f=open(filename, "rb")
200 content.setAttribute("Md5sum", md5.md5(f.read()).hexdigest())
201 f.close()
202 return content
203
204 # This acts like the main() function for the script, unless it is 'import'ed
205 # into another script.
206 if __name__ == '__main__':
207
208 # Create a pretty printer for dumping data structures in a readable form.
209 # pp = pprint.PrettyPrinter(indent=2)
210
211 # Process the command line args.
212 optlist, args = getopt.getopt(sys.argv[1:], 'hf:t:', [ 'template=', 'far=', 'help'])
213
214 for o, a in optlist:
215 if o in ["-h", "--help"]:
216 print """
217 Pass a list of .spd and .fpd files to be placed into a far for distribution.
218 You may give the name of the far with a -f or --far option. For example:
219
220 %s --far library.far MdePkg/MdePkg.spd
221
222 The file paths of .spd and .fpd are treated as relative to the WORKSPACE
223 envirnonment variable which must be set to a valid workspace root directory.
224 """ % os.path.basename(sys.argv[0])
225
226 sys.exit()
227 if o in ["-t", "--template"]:
228 # The template file is processed first, so that command line options can
229 # override it.
230 templateName = a
231 execfile(templateName)
232 if o in ["-f", "--far"]:
233 far.FileName = a
234 if os.path.exists(far.FileName):
235 print "Error: File %s exists. Not overwriting." % far.FileName
236 sys.exit()
237
238 makeFar(args, far.FileName)