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