]>
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 AddToZip(zip, infile
):
30 """Add a file to a zip file, provided it is not already there."""
32 if not infile
in zip.namelist():
33 zip.write(inWorkspace(infile
), infile
)
35 def parseMsa(msaFile
, spdDir
):
37 """Parse an msa file and return a list of all the files that this msa
42 msaDir
= os
.path
.dirname(msaFile
)
44 msa
= xml
.dom
.minidom
.parse(inWorkspace(os
.path
.join(spdDir
, msaFile
)))
47 "/ModuleSurfaceArea/SourceFiles/Filename",
48 "/ModuleSurfaceArea/NonProcessedFiles/Filename" ]
50 for xmlPath
in xmlPaths
:
51 for f
in XmlList(msa
, xmlPath
):
52 filelist
.append(str(os
.path
.join(msaDir
, XmlElementData(f
))))
56 def parseSpd(spdFile
):
58 """Parse an spd file and return a list of all the files that this spd
63 spdDir
= os
.path
.dirname(spdFile
)
65 spd
= xml
.dom
.minidom
.parse(inWorkspace(spdFile
))
67 # We are currently ignoring these hints.
68 readonly
= XmlElement(spd
, "/PackageSurfaceArea/PackageDefinitions/ReadOnly") != "false"
69 repackage
= XmlElement(spd
, "/PackageSurfaceArea/PackageDefinitions/RePackage") != "false"
72 "/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass/IncludeHeader",
73 "/PackageSurfaceArea/IndustryStdIncludes/IndustryStdHeader/IncludeHeader" ]
75 # These are covered by the Industry Standard Includes.
76 # "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader"
78 for xmlPath
in xmlPaths
:
79 for f
in XmlList(spd
, xmlPath
):
80 files
.append(str(XmlElementData(f
)))
82 for f
in XmlList(spd
, "/PackageSurfaceArea/MsaFiles/Filename"):
83 msaFile
= str(XmlElementData(f
))
84 files
+= parseMsa(msaFile
, spdDir
)
87 os
.chdir(inWorkspace(spdDir
))
88 for root
, dirs
, entries
in os
.walk("Include"):
89 # Some files need to be skipped.
90 for r
in ["CVS", ".svn"]:
94 files
.append(os
.path
.join(os
.path
.normpath(root
), entry
))
99 def makeFarHeader(doc
):
101 """Create a dom tree for the Far Header. It will use information from the
102 template file passed on the command line, if present."""
104 header
= XmlAppendChildElement(doc
.documentElement
, "FarHeader")
106 XmlAppendChildElement(header
, "FarName", far
.FarName
)
107 XmlAppendChildElement(header
, "GuidValue", genguid())
108 XmlAppendChildElement(header
, "Version", far
.Version
)
109 XmlAppendChildElement(header
, "Abstract", far
.Abstract
)
110 XmlAppendChildElement(header
, "Description", far
.Description
)
111 XmlAppendChildElement(header
, "Copyright", far
.Copyright
)
112 XmlAppendChildElement(header
, "License", far
.License
)
113 XmlAppendChildElement(header
, "Specification", "FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052")
117 def getSpdGuidVersion(spdFile
):
119 """Returns a tuple (guid, version) which is read from the given spdFile."""
121 spd
= xml
.dom
.minidom
.parse(inWorkspace(spdFile
))
123 return (XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/GuidValue"),
124 XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/Version"))
126 def makeFar(files
, farname
):
128 """Make a far out of the given filelist and writes it to the file farname."""
130 domImpl
= xml
.dom
.minidom
.getDOMImplementation()
131 man
= domImpl
.createDocument(None, "FrameworkArchiveManifest", None)
132 top_element
= man
.documentElement
134 top_element
.appendChild(makeFarHeader(man
))
136 packList
= XmlAppendChildElement(top_element
, "FarPackageList")
137 platList
= XmlAppendChildElement(top_element
, "FarPlatformList")
138 contents
= XmlAppendChildElement(top_element
, "Contents")
139 XmlAppendChildElement(top_element
, "UserExtensions")
142 zip = zipfile
.ZipFile(farname
, "w", zipfile
.ZIP_DEFLATED
)
144 zip = zipfile
.ZipFile(farname
, "w", zipfile
.ZIP_STORED
)
145 for infile
in set(files
):
146 if not os
.path
.exists(inWorkspace(infile
)):
147 print "Error: Non-existent file '%s'." % infile
149 (_
, extension
) = os
.path
.splitext(infile
)
150 if extension
== ".spd":
151 filelist
= parseSpd(infile
)
152 spdDir
= os
.path
.dirname(infile
)
154 (spdGuid
, spdVersion
) = getSpdGuidVersion(infile
)
156 package
= XmlAppendChildElement(packList
, "FarPackage")
157 XmlAppendChildElement(package
, "FarFilename", lean(infile
), {"Md5Sum": Md5(inWorkspace(infile
))})
158 AddToZip(zip, infile
)
159 XmlAppendChildElement(package
, "GuidValue", spdGuid
)
160 XmlAppendChildElement(package
, "Version", spdVersion
)
161 XmlAppendChildElement(package
, "DefaultPath", spdDir
)
162 XmlAppendChildElement(package
, "FarPlatformList")
163 packContents
= XmlAppendChildElement(package
, "Contents")
164 XmlAppendChildElement(package
, "UserExtensions")
166 for spdfile
in filelist
:
167 XmlAppendChildElement(packContents
, "FarFilename", lean(spdfile
), {"Md5Sum": Md5(inWorkspace(os
.path
.join(spdDir
, spdfile
)))})
168 AddToZip(zip, os
.path
.join(spdDir
,spdfile
))
170 elif extension
== ".fpd":
172 platform
= XmlAppendChildElement(platList
, "FarPlatform")
173 XmlAppendChildElement(platform
, "FarFilename", lean(infile
), {"Md5Sum": Md5(inWorkspace(infile
))})
174 AddToZip(zip, infile
)
177 XmlAppendChildElement(contents
, "FarFilename", lean(infile
), {"Md5Sum": Md5(inWorkspace(infile
))})
178 AddToZip(zip, infile
)
180 zip.writestr("FrameworkArchiveManifest.xml", man
.toxml('UTF-8'))
184 # This acts like the main() function for the script, unless it is 'import'ed
185 # into another script.
186 if __name__
== '__main__':
188 # Create a pretty printer for dumping data structures in a readable form.
189 # pp = pprint.PrettyPrinter(indent=2)
191 # Process the command line args.
192 optlist
, args
= getopt
.getopt(sys
.argv
[1:], 'ho:t:v', [ 'template=', 'output=', 'far=', 'help', 'debug', 'verbose', 'version'])
194 # First pass through the options list.
196 if o
in ["-h", "--help"]:
198 Pass a list of .spd and .fpd files to be placed into a far for distribution.
199 You may give the name of the far with a -f or --far option. For example:
201 %s --template far-template --far library.far MdePkg/MdePkg.spd
203 The file paths of .spd and .fpd are treated as relative to the WORKSPACE
204 environment variable which must be set to a valid workspace root directory.
206 A template file may be passed in with the --template option. This template file
207 is a text file that allows more contol over the contents of the far.
208 """ % os
.path
.basename(sys
.argv
[0])
211 optlist
.remove((o
,a
))
212 if o
in ["-t", "--template"]:
213 # The template file is processed first, so that command line options can
216 execfile(templateName
)
217 optlist
.remove((o
,a
))
219 # Second pass through the options list. These can override the first pass.
221 if o
in ["-o", "--far", "--output"]:
224 # Let's err on the side of caution and not let people blow away data
226 if os
.path
.exists(far
.FileName
):
227 print "Error: File %s exists. Not overwriting." % far
.FileName
230 makeFar(far
.SpdFiles
+ far
.FpdFiles
+ far
.ExtraFiles
+ args
, far
.FileName
)