]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/PackagingTool/MkPkg.py
f6d693d2da2ccb3ad8ce69182368105c1160019e
[mirror_edk2.git] / BaseTools / Source / Python / PackagingTool / MkPkg.py
1 ## @file
2 # Install distribution package.
3 #
4 # Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 ##
15 # Import Modules
16 #
17 import os
18 import os.path
19 import sys
20 import glob
21 import shutil
22 import traceback
23 import platform
24 from optparse import OptionParser
25 import md5
26 import time
27 import uuid
28
29 from PackageFile import *
30 import Common.EdkLogger as EdkLogger
31 from Common.BuildToolError import *
32 from Common.Misc import *
33 from Common.XmlParser import *
34 from CommonDataClass.DistributionPackageClass import *
35 from Common.DecClassObjectLight import Dec
36 from Common.InfClassObjectLight import Inf
37
38 from PackageFile import *
39
40 # Version and Copyright
41 VersionNumber = "0.1"
42 __version__ = "%prog Version " + VersionNumber
43 __copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
44
45 ## Check environment variables
46 #
47 # Check environment variables that must be set for build. Currently they are
48 #
49 # WORKSPACE The directory all packages/platforms start from
50 # EDK_TOOLS_PATH The directory contains all tools needed by the build
51 # PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
52 #
53 # If any of above environment variable is not set or has error, the build
54 # will be broken.
55 #
56 def CheckEnvVariable():
57 # check WORKSPACE
58 if "WORKSPACE" not in os.environ:
59 EdkLogger.error("MkPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
60 ExtraData="WORKSPACE")
61
62 WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
63 if not os.path.exists(WorkspaceDir):
64 EdkLogger.error("MkPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
65 elif ' ' in WorkspaceDir:
66 EdkLogger.error("MkPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
67 ExtraData=WorkspaceDir)
68 os.environ["WORKSPACE"] = WorkspaceDir
69
70 ## Parse command line options
71 #
72 # Using standard Python module optparse to parse command line option of this tool.
73 #
74 # @retval Opt A optparse.Values object containing the parsed options
75 # @retval Args Target of build command
76 #
77 def MyOptionParser():
78 UsageString = "%prog -m <module_file> -p <package_file> [-o distribution_file] " + \
79 "[-x xml-file-header] [-t tools-directory] [-f misc-files] [-q | -v] [-h]"
80
81 Parser = OptionParser(description=__copyright__,version=__version__,prog="MkPkg",usage=UsageString)
82
83 Parser.add_option("-?", action="help", help="show this help message and exit")
84
85 Parser.add_option("-o", "--output-file", action="store", type="string", dest="DistributionFile",
86 help="Specify the distribution file to be created.")
87
88 Parser.add_option("-f", "--misc-files", action="append", type="string", dest="MiscFiles",
89 help="Specify any misc files.")
90
91 Parser.add_option("-x", "--xml-file-header", action="store", type=None, dest="TemplateFile",
92 help="Specify the xml file which includes header information for creating the distribution file.")
93
94 Parser.add_option("-t", "--tools-directory", action="store", type=None, dest="ToolsDir",
95 help="Specify the directory name of tools.")
96
97 Parser.add_option("-m", "--module", action="append", type="string", dest="ModuleFileList",
98 help="The inf file of module to be distributed standalone.")
99
100 Parser.add_option("-p", "--package", action="append", type="string", dest="PackageFileList",
101 help="The dec file of package to be distributed.")
102
103 Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
104 help="Disable all messages except FATAL ERRORS.")
105
106 Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
107 help="Turn on verbose output")
108
109 Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
110 help="Enable debug messages at specified level.")
111
112 Parser.set_defaults(LogLevel=EdkLogger.INFO)
113
114 (Opt, Args)=Parser.parse_args()
115 # error check
116 if not Opt.ModuleFileList and not Opt.PackageFileList:
117 EdkLogger.error("MkPkg", OPTION_NOT_SUPPORTED, ExtraData="At least one package file or module file must be specified")
118 if Opt.TemplateFile:
119 if not os.path.exists(Opt.TemplateFile):
120 EdkLogger.error(
121 "\nMkPkg",
122 FILE_NOT_FOUND,
123 "Template file [%s] not found" % Opt.TemplateFile
124 )
125 return Opt
126
127 ## Tool entrance method
128 #
129 # This method mainly dispatch specific methods per the command line options.
130 # If no error found, return zero value so the caller of this tool can know
131 # if it's executed successfully or not.
132 #
133 # @retval 0 Tool was successful
134 # @retval 1 Tool failed
135 #
136 def Main():
137 EdkLogger.Initialize()
138 Options = MyOptionParser()
139 try:
140 if Options.LogLevel < EdkLogger.DEBUG_9:
141 EdkLogger.SetLevel(Options.LogLevel + 1)
142 else:
143 EdkLogger.SetLevel(Options.LogLevel)
144
145 CheckEnvVariable()
146 WorkspaceDir = os.environ["WORKSPACE"]
147
148 # Init DistributionFile
149 if not Options.DistributionFile:
150 Options.DistributionFile = "DistributionPackage.zip"
151
152 # Check Tools Dir
153 if Options.ToolsDir:
154 if not os.path.isdir(os.path.normpath(os.path.join(WorkspaceDir, Options.ToolsDir))):
155 EdkLogger.error(
156 "\nMkPkg",
157 FILE_NOT_FOUND,
158 "Tools directory [%s] not found" % Options.ToolsDir
159 )
160
161 # Check misc files
162 if Options.MiscFiles:
163 for Item in Options.MiscFiles:
164 FullPath = os.path.normpath(os.path.join(WorkspaceDir, Item))
165 if not os.path.isfile(FullPath):
166 EdkLogger.error(
167 "\nMkPkg",
168 FILE_NOT_FOUND,
169 "Misc file [%s] not found" % Item
170 )
171
172 #Check package file existing and valid
173 if Options.PackageFileList:
174 for Item in Options.PackageFileList:
175 (Name, Ext) = os.path.splitext(Item)
176 if Ext.upper() != '.DEC':
177 EdkLogger.error(
178 "\nMkPkg",
179 OPTION_VALUE_INVALID,
180 "[%s] is not a valid package name" % Item
181 )
182 Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
183 if not os.path.exists(Path):
184 EdkLogger.error(
185 "\nMkPkg",
186 FILE_NOT_FOUND,
187 "[%s] not found" % Item
188 )
189 #Check module file existing and valid
190 if Options.ModuleFileList:
191 for Item in Options.ModuleFileList:
192 (Name, Ext) = os.path.splitext(Item)
193 if Ext.upper() != '.INF':
194 EdkLogger.error(
195 "\nMkPkg",
196 OPTION_VALUE_INVALID,
197 "[%s] is not a valid module name" % Item
198 )
199 Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
200 if not os.path.exists(Path):
201 EdkLogger.error(
202 "\nMkPkg",
203 FILE_NOT_FOUND,
204 "[%s] not found" % Item
205 )
206
207 ContentFile = PackageFile("content.zip", "w")
208 DistPkg = DistributionPackageClass()
209 DistPkg.GetDistributionPackage(WorkspaceDir, Options.PackageFileList, Options.ModuleFileList)
210 DistPkgXml = DistributionPackageXml()
211 for Item in DistPkg.PackageSurfaceArea:
212 ContentFile.Pack(os.path.dirname(os.path.normpath(os.path.join(WorkspaceDir,Item[2]))))
213 for Item in DistPkg.ModuleSurfaceArea:
214 ContentFile.Pack(os.path.dirname(os.path.normpath(os.path.join(WorkspaceDir,Item[2]))))
215
216 # Add tools files and information
217 if Options.ToolsDir:
218 ToolsFiles = MiscFileClass()
219 ToolsRoot = os.path.normpath(os.path.join(WorkspaceDir, Options.ToolsDir))
220 ContentFile.Pack(ToolsRoot)
221 ToolsFileList = GetFiles(ToolsRoot, ['CVS', '.svn'])
222 for Item in ToolsFileList:
223 OriPath = Item[len(WorkspaceDir)+1:]
224 FileObj = FileClass()
225 FileObj.Filename = OriPath
226 (Name, Ext) = os.path.splitext(OriPath)
227 if Ext.upper() in ['EXE', 'COM', 'EFI']:
228 FileObj.Executable = 'True'
229 ToolsFiles.Files.append(FileObj)
230 DistPkg.Tools = ToolsFiles
231
232 # Add misc files and information
233 if Options.MiscFiles:
234 MiscFiles = MiscFileClass()
235 for Item in Options.MiscFiles:
236 ContentFile.PackFile(Item)
237 FileObj = FileClass()
238 FileObj.Filename = Item
239 (Name, Ext) = os.path.splitext(Item)
240 if Ext.upper() in ['EXE', 'COM', 'EFI']:
241 FileObj.Executable = 'True'
242 MiscFiles.Files.append(FileObj)
243 DistPkg.MiscellaneousFiles = MiscFiles
244
245 print "Compressing Distribution Package File ..."
246 ContentFile.Close()
247
248 # Add temp distribution header
249 if Options.TemplateFile:
250 TempXML = DistributionPackageXml()
251 DistPkg.Header = TempXML.FromXml(Options.TemplateFile).Header
252 # Add init dp information
253 else:
254 DistPkg.Header.Name = 'Distribution Package'
255 DistPkg.Header.Guid = str(uuid.uuid4())
256 DistPkg.Header.Version = '1.0'
257
258 # Add Md5Sigature
259 Md5Sigature = md5.new(open(str(ContentFile)).read())
260 DistPkg.Header.Signature = Md5Sigature.hexdigest()
261 # Add current Date
262 DistPkg.Header.Date = str(time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()))
263
264 # Finish final dp file
265 DistPkgFile = PackageFile(Options.DistributionFile, "w")
266 DistPkgFile.PackFile(str(ContentFile))
267 DistPkgFile.PackData(DistPkgXml.ToXml(DistPkg), "dist.pkg")
268 DistPkgFile.Close()
269 print "DONE"
270
271 except FatalError, X:
272 if Options and Options.LogLevel < EdkLogger.DEBUG_9:
273 EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
274 ReturnCode = X.args[0]
275 except KeyboardInterrupt:
276 ReturnCode = ABORT_ERROR
277 if Options and Options.LogLevel < EdkLogger.DEBUG_9:
278 EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
279 except:
280 EdkLogger.error(
281 "\nMkPkg",
282 CODE_ERROR,
283 "Unknown fatal error when creating [%s]" % Options.DistributionFile,
284 ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
285 RaiseError=False
286 )
287 EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
288 ReturnCode = CODE_ERROR
289 finally:
290 Progressor.Abort()
291
292 if __name__ == '__main__':
293 sys.exit(Main())
294