]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/Python/MkFar.py
3 """This is a python script that takes user input from the command line and
4 creates a far (Framework Archive Manifest) file for distribution."""
6 import os
, sys
, getopt
, string
, xml
.dom
.minidom
, zipfile
, md5
7 from XmlRoutines
import *
8 from WorkspaceRoutines
import *
11 """This class is used to collect arbitrarty data from the template file."""
13 """Assign the default values for the far fields."""
14 far
.FileName
= "output.far"
26 """The far object is constructed from the template file the user passed in."""
28 def parseMsa(msaFile
, spdDir
):
30 """ XXX Parse an msa file and return a list of all the files that this msa
35 msaDir
= os
.path
.dirname(msaFile
)
37 msa
= xml
.dom
.minidom
.parse(inWorkspace(os
.path
.join(spdDir
, msaFile
)))
40 "/ModuleSurfaceArea/SourceFiles/Filename",
41 "/ModuleSurfaceArea/NonProcessedFiles/Filename" ]
43 for xmlPath
in xmlPaths
:
44 for f
in XmlList(msa
, xmlPath
):
45 filelist
.append(str(os
.path
.join(msaDir
, XmlElementData(f
))))
49 def parseSpd(spdFile
):
51 """Parse an spd file and return a list of all the files that this spd
56 spdDir
= os
.path
.dirname(spdFile
)
58 spd
= xml
.dom
.minidom
.parse(inWorkspace(spdFile
))
61 "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass/IncludeHeader",
62 "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader/IncludeHeader",
63 "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader" ]
65 for xmlPath
in xmlPaths
:
66 for f
in XmlList(spd
, xmlPath
):
67 files
.append(str(XmlElementData(f
)))
69 for f
in XmlList(spd
, "/PackageSurfaceArea/MsaFiles/Filename"):
70 msaFile
= str(XmlElementData(f
))
71 files
+= parseMsa(msaFile
, spdDir
)
74 os
.chdir(inWorkspace(spdDir
))
75 for root
, dirs
, entries
in os
.walk("Include"):
76 # Some files need to be skipped.
77 for r
in ["CVS", ".svn"]:
81 files
.append(os
.path
.join(os
.path
.normpath(root
), entry
))
86 def makeFarHeader(doc
):
88 """Create a dom tree for the Far Header. It will use information from the
89 template file passed on the command line, if present."""
91 header
= doc
.createElement("FarHeader")
92 name
= doc
.createElement("FarName")
93 name
.appendChild(doc
.createTextNode(far
.FarName
))
94 header
.appendChild(name
)
95 guidVal
= doc
.createElement("GuidValue")
96 guidVal
.appendChild(doc
.createTextNode(genguid()))
97 header
.appendChild(guidVal
)
98 ver
= doc
.createElement("Version")
99 ver
.appendChild(doc
.createTextNode(far
.Version
))
100 header
.appendChild(ver
)
101 abstract
= doc
.createElement("Abstract")
102 abstract
.appendChild(doc
.createTextNode(far
.Abstract
))
103 header
.appendChild(abstract
)
104 desc
= doc
.createElement("Description")
105 desc
.appendChild(doc
.createTextNode(far
.Description
))
106 header
.appendChild(desc
)
107 copy
= doc
.createElement("Copyright")
108 copy
.appendChild(doc
.createTextNode(far
.Copyright
))
109 header
.appendChild(copy
)
110 lic
= doc
.createElement("License")
111 lic
.appendChild(doc
.createTextNode(far
.License
))
112 header
.appendChild(lic
)
113 spec
= doc
.createElement("Specification")
114 spec
.appendChild(doc
.createTextNode("FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052"))
115 header
.appendChild(spec
)
119 def getSpdGuidVersion(spdFile
):
121 """Returns a tuple (guid, version) which is read from the given spdFile."""
123 spd
= xml
.dom
.minidom
.parse(inWorkspace(spdFile
))
125 return (XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/GuidValue"),
126 XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/Version"))
128 def makeFar(files
, farname
):
130 """Make a far out of the given filelist and writes it to the file farname."""
132 domImpl
= xml
.dom
.minidom
.getDOMImplementation()
133 man
= domImpl
.createDocument(None, "FrameworkArchiveManifest", None)
134 top_element
= man
.documentElement
136 top_element
.appendChild(makeFarHeader(man
))
138 packList
= man
.createElement("FarPackageList")
139 top_element
.appendChild(packList
)
141 platList
= man
.createElement("FarPlatformList")
142 top_element
.appendChild(platList
)
144 contents
= man
.createElement("Contents")
145 top_element
.appendChild(contents
)
147 exts
= man
.createElement("UserExtensions")
148 top_element
.appendChild(exts
)
150 zip = zipfile
.ZipFile(farname
, "w")
151 for infile
in set(files
):
152 if not os
.path
.exists(inWorkspace(infile
)):
153 print "Skipping non-existent file '%s'." % infile
154 (_
, extension
) = os
.path
.splitext(infile
)
155 if extension
== ".spd":
156 filelist
= parseSpd(infile
)
157 spdDir
= os
.path
.dirname(infile
)
159 (spdGuid
, spdVersion
) = getSpdGuidVersion(infile
)
161 package
= man
.createElement("FarPackage")
162 packList
.appendChild(package
)
164 spdfilename
= farFileNode(man
, inWorkspace(infile
))
165 zip.write(inWorkspace(infile
), infile
)
166 spdfilename
.appendChild(man
.createTextNode(lean(infile
)))
167 package
.appendChild(spdfilename
)
169 guidValue
= man
.createElement("GuidValue")
170 guidValue
.appendChild(man
.createTextNode(spdGuid
))
171 package
.appendChild(guidValue
)
173 version
= man
.createElement("Version")
174 version
.appendChild(man
.createTextNode(spdVersion
))
175 package
.appendChild(version
)
177 defaultPath
= man
.createElement("DefaultPath")
178 defaultPath
.appendChild(man
.createTextNode(spdDir
))
179 package
.appendChild(defaultPath
)
181 farPlatformList
= man
.createElement("FarPlatformList")
182 package
.appendChild(farPlatformList
)
184 packContents
= man
.createElement("Contents")
185 package
.appendChild(packContents
)
187 ue
= man
.createElement("UserExtensions")
188 package
.appendChild(ue
)
190 for spdfile
in filelist
:
191 content
= farFileNode(man
, inWorkspace(os
.path
.join(spdDir
, spdfile
)))
192 zip.write(inWorkspace(os
.path
.join(spdDir
, spdfile
)), spdfile
)
193 content
.appendChild(man
.createTextNode(lean(spdfile
)))
194 packContents
.appendChild(content
)
196 elif extension
== ".fpd":
198 platform
= man
.createElement("FarPlatform")
199 platList
.appendChild(platform
)
201 fpdfilename
= farFileNode(man
, inWorkspace(infile
))
202 zip.write(inWorkspace(infile
), infile
)
203 platform
.appendChild(fpdfilename
)
204 fpdfilename
.appendChild(man
.createTextNode(lean(infile
)))
207 content
= farFileNode(man
, inWorkspace(infile
))
208 zip.write(inWorkspace(infile
), infile
)
209 content
.appendChild(man
.createTextNode(lean(infile
)))
210 contents
.appendChild(content
)
212 zip.writestr("FrameworkArchiveManifest.xml", man
.toprettyxml(2*" "))
216 def farFileNode(doc
, filename
):
218 """This is a function that returns a dom tree for a given file that is
219 included in the far. An md5sum is calculated for that file."""
221 content
= doc
.createElement("FarFilename")
222 f
=open(filename
, "rb")
223 content
.setAttribute("Md5sum", md5
.md5(f
.read()).hexdigest())
227 # This acts like the main() function for the script, unless it is 'import'ed
228 # into another script.
229 if __name__
== '__main__':
231 # Create a pretty printer for dumping data structures in a readable form.
232 # pp = pprint.PrettyPrinter(indent=2)
234 # Process the command line args.
235 optlist
, args
= getopt
.getopt(sys
.argv
[1:], 'hf:t:', [ 'template=', 'far=', 'help'])
237 # First pass through the options list.
239 if o
in ["-h", "--help"]:
241 Pass a list of .spd and .fpd files to be placed into a far for distribution.
242 You may give the name of the far with a -f or --far option. For example:
244 %s --far library.far MdePkg/MdePkg.spd
246 The file paths of .spd and .fpd are treated as relative to the WORKSPACE
247 environment variable which must be set to a valid workspace root directory.
248 """ % os
.path
.basename(sys
.argv
[0])
251 optlist
.remove((o
,a
))
252 if o
in ["-t", "--template"]:
253 # The template file is processed first, so that command line options can
256 execfile(templateName
)
257 optlist
.remove((o
,a
))
259 # Second pass through the options list. These can override the first pass.
262 if o
in ["-f", "--far"]:
265 # Let's err on the side of caution and not let people blow away data
267 if os
.path
.exists(far
.FileName
):
268 print "Error: File %s exists. Not overwriting." % far
.FileName
271 makeFar(far
.SpdFiles
+ far
.FpdFiles
+ far
.ExtraFiles
+ args
, far
.FileName
)