summaryrefslogtreecommitdiff
path: root/Tools
diff options
context:
space:
mode:
authorjwang36 <jwang36@6f19259b-4bc3-4df7-8a09-765794883524>2007-01-22 09:59:07 +0000
committerjwang36 <jwang36@6f19259b-4bc3-4df7-8a09-765794883524>2007-01-22 09:59:07 +0000
commit2897231803d9d506f7cb7c68eeb59dcc4805084d (patch)
treeb0037ca2ff28fcb45f143987bb1168e937f0b237 /Tools
parent41ac48e930170db72a0c764b7b81c7a81c1f4ba7 (diff)
downloadedk2-platforms-2897231803d9d506f7cb7c68eeb59dcc4805084d.tar.xz
Python script for generating build files for platform and modules, which uses the enhanced XmlRoutines.py written by Bruce.
The functionalities include: - parse all packages(.spd) and modules(.msa) - parse active platform(.fpd). You must set active platform in target.txt otherwise nothing will be parsed. - parse tools_def.txt and target.txt - generate Ant build files for active platform and its modules. The generated build file is re-designed and can be called separately once generated. - multi-thread build The functionalities which haven't been implemented include: - AutoGen. No AutoGen.h and AutoGen.c will be generated. If you want run the build file, you have to run the "build" command in advance to generate the AutoGen.h/.c files and remove the any other intermediate files. - generate FFS and FV files. Only compiling will be done by the generated build file. Usage: - type "python ${WORKSPACE}/Tools/Python/buildgen/BuildFile.py" in shell to generate build file - goto "${WORKSPACE}/Build/${platform}/${target}_${toolchaintag}/", type "ant" to run the build file git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2278 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Tools')
-rw-r--r--Tools/Python/buildgen/AntTasks.py84
-rw-r--r--Tools/Python/buildgen/BuildConfig.py185
-rw-r--r--Tools/Python/buildgen/BuildFile.py574
-rw-r--r--Tools/Python/buildgen/FrameworkElement.py523
-rw-r--r--Tools/Python/buildgen/SurfaceAreaElement.py1549
-rw-r--r--Tools/Python/buildgen/XmlRoutines.py104
-rw-r--r--Tools/Python/buildgen/module_build_path.txt5
-rw-r--r--Tools/Python/buildgen/platform_build_path.txt5
8 files changed, 3029 insertions, 0 deletions
diff --git a/Tools/Python/buildgen/AntTasks.py b/Tools/Python/buildgen/AntTasks.py
new file mode 100644
index 0000000000..ce694f9b80
--- /dev/null
+++ b/Tools/Python/buildgen/AntTasks.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+"""Ant Tasks Dom Element"""
+
+import xml.dom.minidom, os
+
+class AntTask:
+ def __init__(self, document, _name, _body=None, **_attributes):
+ """Instantiate an Ant task element
+ document, _name=task name, _body=task body, **_attributes=task attributes
+ """
+ self.Document = document
+ self.Root = ""
+
+ if _name == None or _name == "":
+ raise Exception("No Ant task name")
+
+ taskElement = self.Document.createElement(_name)
+ for name in _attributes:
+ taskElement.setAttribute(name, _attributes[name])
+
+ if _body != None:
+ if isinstance(_body, str):
+ text = self.Document.createTextNode(_body)
+ taskElement.appendChild(text)
+ elif isinstance(_body, list):
+ for subtask in _body:
+ taskElement.appendChild(subtask)
+
+ self.Root = taskElement
+
+ def SubTask(self, _name, _body=None, **_attributes):
+ """Insert a sub-task into this task"""
+ newTask = AntTask(self.Document, _name , _body, **_attributes)
+ self.Root.appendChild(newTask.Root)
+ return newTask
+
+ def AddSubTask(self, subTask):
+ """Insert a existing sub-task into this task"""
+ self.Root.appendChild(subTask.Root.cloneNode(True))
+ return subTask
+
+ def Comment(self, string):
+ """Generate a XML comment"""
+ self.Root.appendChild(self.Document.createComment(string))
+
+ def Blankline(self):
+ """Generate a blank line"""
+ self.Root.appendChild(self.Document.createTextNode(""))
+
+
+class AntBuildFile(AntTask):
+ _FileComment = "DO NOT EDIT\nThis file is auto-generated by the build utility\n\nAbstract:\nAuto-generated ANT build file for building Framework modules and platforms\n"
+
+ def __init__(self, name, basedir=".", default="all"):
+ """Instantiate an Ant build.xml
+ name=project name, basedir=project default directory, default=default target of this project
+ """
+ self.Document = xml.dom.minidom.getDOMImplementation().createDocument(None, "project", None)
+ self.Root = self.Document.documentElement
+
+ self.Document.insertBefore(self.Document.createComment(self._FileComment), self.Root)
+ self.Root.setAttribute("name", name)
+ self.Root.setAttribute("basedir", basedir)
+ self.Root.setAttribute("default", default)
+
+ def Create(self, file):
+ """Generate the build.xml using given file path"""
+ buildFileDir = os.path.dirname(file)
+ if not os.path.exists(buildFileDir):
+ os.makedirs(buildFileDir)
+
+ f = open(file, "w")
+ f.write(self.Document.toprettyxml(2*" ", encoding="UTF-8"))
+ f.close()
diff --git a/Tools/Python/buildgen/BuildConfig.py b/Tools/Python/buildgen/BuildConfig.py
new file mode 100644
index 0000000000..e91bd294a5
--- /dev/null
+++ b/Tools/Python/buildgen/BuildConfig.py
@@ -0,0 +1,185 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+"""Tools and build configuration"""
+
+from sets import Set
+
+class Config(dict):
+ def __init__(self, file):
+ """file (target configuration file)"""
+ configFile = open(file)
+ while True:
+ line = configFile.readline()
+ if line == "": break ## no more line
+
+ line = line.strip()
+ # skip blank line
+ if line == "": continue
+ # skip comment line
+ if line[0] == '#': continue
+ # skip invalid line
+ if line[0] == '=':
+ print "! invalid configuration:", line
+ continue
+
+ defStrings = line.split('=', 1)
+ name = defStrings[0].strip()
+ value = defStrings[1].strip()
+ self[name] = value
+
+ configFile.close()
+
+ def __getitem__(self, attr):
+ if attr not in self:
+ return ""
+
+ value = dict.__getitem__(self, attr)
+ if value == None:
+ value = ""
+ return value
+
+class ToolConfig(dict):
+ def __init__(self, file):
+ """file (tools configuration file path)"""
+ self.Targets = Set()
+ self.Toolchains = Set()
+ self.Archs = Set()
+ self.ToolCodes = Set()
+ self.Families = Set()
+ self.Attributes = Set(["FAMILY", "NAME", "PATH", "FLAGS", "EXT", "DPATH", "SPATH", "LIBPATH", "INCLUDEPATH"])
+
+ configFile = open(file)
+ while True:
+ line = configFile.readline()
+ if line == "": break
+
+ line = line.strip()
+ # skip blank line
+ if line == "": continue
+ # skip comment line
+ if line[0] == '#': continue
+ # skip invalid line
+ if line[0] == '=':
+ print "! invalid definition:", line
+ continue
+
+ # split the definition at the first "="
+ tool_def = line.split('=', 1)
+ name = tool_def[0].strip()
+ value = tool_def[1].strip()
+
+ # the name of a tool definition must have five parts concatenated by "_"
+ keys = name.split('_')
+ # skip non-definition line
+ if len(keys) < 5: continue
+
+ keys = (keys[1], keys[0], keys[2], keys[3], keys[4])
+ self[keys] = value
+
+ ###############################################
+ ## statistics
+ ###############################################
+ if keys[0] != '*': self.Toolchains.add(keys[0])
+ if keys[1] != '*': self.Targets.add(keys[1])
+ if keys[2] != '*': self.Archs.add(keys[2])
+ if keys[3] != '*': self.ToolCodes.add(keys[3])
+ if keys[4] == "FAMILY": self.Families.add(value)
+ elif keys[4] == '*': raise Exception("No * allowed in ATTRIBUTE field")
+
+ configFile.close()
+ # expand the "*" in each field
+ self.expand()
+
+ def __getitem__(self, attrs):
+ if len(attrs) != 5:
+ return ""
+
+ if attrs not in self:
+ return ""
+
+ value = dict.__getitem__(self, attrs)
+ if value == None:
+ value = ""
+ return value
+
+ def expand(self):
+ summary = {}
+ toolchains = []
+ targets = []
+ archs = []
+ toolcodes = []
+ for key in self:
+ value = self[key]
+ if key[0] == '*':
+ toolchains = self.Toolchains
+ else:
+ toolchains = [key[0]]
+
+ for toolchain in toolchains:
+ if key[1] == '*':
+ targets = self.Targets
+ else:
+ targets = [key[1]]
+
+ for target in targets:
+ if key[2] == '*':
+ archs = self.Archs
+ else:
+ archs = [key[2]]
+
+ for arch in archs:
+ if key[3] == '*':
+ toolcodes = self.ToolCodes
+ else:
+ toolcodes = [key[3]]
+
+ for toolcode in toolcodes:
+ attribute = key[4]
+ summary[(toolchain, target, arch, toolcode, attribute)] = value
+ self.clear()
+ for toolchain in self.Toolchains:
+ for target in self.Targets:
+ for arch in self.Archs:
+ for toolcode in self.ToolCodes:
+ key = (toolchain, target, arch, toolcode, "NAME")
+ if key not in summary: continue
+ for attr in self.Attributes:
+ key = (toolchain, target, arch, toolcode, attr)
+ if key not in summary: continue
+ self[key] = summary[key]
+
+
+ def __str__(self):
+ s = ""
+ for entry in self:
+ s += entry[0] + "_" + entry[1] + "_" + entry[2] + "_" + entry[3] + "_" + entry[4]
+ s += " = " + self[entry] + "\n"
+ return s
+
+class TargetConfig(Config):
+ pass
+
+## for test
+if __name__ == "__main__":
+ import os
+ if "WORKSPACE" not in os.environ:
+ raise "No WORKSPACE given"
+ cfg = ToolConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "tools_def.txt"))
+ tgt = TargetConfig(os.path.join(os.environ["WORKSPACE"], "Tools", "Conf", "target.txt"))
+
+ for key in cfg:
+ print key,"=",cfg[key]
+
+ print
+ for name in tgt:
+ print name,"=",tgt[name]
+ \ No newline at end of file
diff --git a/Tools/Python/buildgen/BuildFile.py b/Tools/Python/buildgen/BuildFile.py
new file mode 100644
index 0000000000..8514e4c8a4
--- /dev/null
+++ b/Tools/Python/buildgen/BuildFile.py
@@ -0,0 +1,574 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+"""Generate build file for given platform"""
+
+import os, sys, copy
+import xml.dom.minidom, pprint
+import FrameworkElement
+
+from SurfaceAreaElement import *
+from XmlRoutines import *
+from AntTasks import *
+from sets import Set
+
+class BuildFile:
+ def __init__(self, workspace, platform, toolchain, target):
+ if workspace == None or workspace == "":
+ raise Exception("No workspace, no build")
+ if platform == None or platform == "":
+ raise Exception("No platform, no build")
+ if toolchain == None or toolchain == "":
+ raise Exception("No toolchain, no build")
+ if target == None or target == "":
+ raise Exception("No target, no build")
+
+ self.Workspace = workspace
+ self.Platform = platform
+ self.Toolchain = toolchain
+ self.Target = target
+ self.Path = ""
+
+ def Generate(self):
+ """Generate the build file"""
+ pass
+
+# generating build.xml for platform
+class AntPlatformBuildFile(BuildFile):
+ def __init__(self, workspace, platform, toolchain, target):
+ BuildFile.__init__(self, workspace, platform, toolchain, target)
+ # Form the build file path, hard-coded at present. It should be specified by a configuration file
+ self.Path = os.path.join(self.Workspace.Path, self.Platform.OutputPath, target + "_" + toolchain, "build.xml")
+ print ""
+ # Generate a common build option property file in the format of Java's property file
+ self.DefaultBuildOptions()
+
+ # new a build file object
+ self.BuildXml = AntBuildFile(name="platform", basedir=".", default="all")
+
+ # generate the top level properties, tasks, etc.
+ self.Header()
+
+ # generate "prebuild" target
+ self.PreBuild()
+
+ # generate "libraries" target for building library modules
+ self.Libraries()
+
+ # generate "modules" target for building non-library modules
+ self.Modules()
+
+ # generate "fvs" target for building firmware volume. (not supported yet)
+
+ # generate "fds" target for building FlashDevice. (not supported yet)
+
+ # generate "postbuild" target
+ self.PostBuild()
+
+ def Generate(self):
+ print "Generating platform build file ...", self.Path
+ self.BuildXml.Create(self.Path)
+
+ def Header(self):
+ _topLevel = self.BuildXml
+ # import external tasks
+ _topLevel.SubTask("taskdef", resource="GenBuild.tasks")
+ _topLevel.SubTask("taskdef", resource="frameworktasks.tasks")
+ _topLevel.SubTask("taskdef", resource="net/sf/antcontrib/antlib.xml")
+
+ # platform wide properties
+ _topLevel.Blankline()
+ _topLevel.Comment("WORKSPACE wide attributes")
+ _topLevel.SubTask("property", environment="env")
+ _topLevel.SubTask("property", name="WORKSPACE_DIR", value="${env.WORKSPACE}")
+ _topLevel.SubTask("property", name="CONFIG_DIR", value="${WORKSPACE_DIR}/Tools/Conf")
+
+ _topLevel.Blankline()
+ _topLevel.Comment("Common build attributes")
+ _topLevel.SubTask("property", name="THREAD_COUNT", value=self.Workspace.ThreadCount)
+ _topLevel.SubTask("property", name="SINGLE_MODULE_BUILD", value="no")
+ _topLevel.SubTask("property", name="MODULE_BUILD_TARGET", value="platform_module_build")
+
+ _topLevel.Blankline()
+ _topLevel.SubTask("property", name="TOOLCHAIN", value=self.Toolchain)
+ _topLevel.SubTask("property", name="TARGET", value=self.Target)
+
+ _topLevel.Blankline()
+ _topLevel.Comment("Platform attributes")
+ _topLevel.SubTask("property", name="PLATFORM", value=self.Platform.Name)
+ _topLevel.SubTask("property", name="PLATFORM_GUID", value=self.Platform.GuidValue)
+ _topLevel.SubTask("property", name="PLATFORM_VERSION", value=self.Platform.Version)
+ _topLevel.SubTask("property", name="PLATFORM_RELATIVE_DIR", value=self.Platform.Dir)
+ _topLevel.SubTask("property", name="PLATFORM_DIR", value="${WORKSPACE_DIR}/${PLATFORM_RELATIVE_DIR}")
+ _topLevel.SubTask("property", name="PLATFORM_OUTPUT_DIR", value=self.Platform.OutputPath)
+
+ # user configurable build path for platform
+ _topLevel.Blankline()
+ _topLevel.Comment("Common path definition for platform build")
+ _topLevel.SubTask("property", file="${WORKSPACE_DIR}/Tools/Python/buildgen/platform_build_path.txt")
+
+ # common build tasks in the form of Ant macro
+ _topLevel.Blankline()
+ _topLevel.Comment("Task Macros for Compiling, Assembling, Linking, etc.")
+ _topLevel.SubTask("import", file="${CONFIG_DIR}/BuildMacro.xml")
+ _topLevel.Blankline()
+ _topLevel.SubTask("echo", message="${PLATFORM}-${PLATFORM_VERSION} (${PLATFORM_RELATIVE_DIR})", level="info")
+
+ # define the targets execution sequence
+ _topLevel.Blankline()
+ _topLevel.Comment("Default target")
+ _topLevel.SubTask("target", name="all", depends="prebuild, libraries, modules, postbuild")
+
+ def PreBuild(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: prebuild ")
+
+ # prebuild is defined by user in the fpd file through <UserExtionsion> element,
+ # which has attribute "identifier=0" or "identifier=prebuild"
+ prebuildTasks = []
+ if self.Platform.UserExtensions.has_key("0"):
+ prebuildTasks = self.Platform.UserExtensions["0"]
+ elif self.Platform.UserExtensions.has_key("postbuild"):
+ prebuildTasks = self.Platform.UserExtensions["prebuild"]
+
+ _topLevel.SubTask("target", prebuildTasks, name="prebuild")
+
+ def Libraries(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: libraries ")
+
+ librariesTarget = _topLevel.SubTask("target", name="libraries")
+ parallelBuild = librariesTarget.SubTask("parallel", threadCount="${THREAD_COUNT}")
+
+ libraryNumber = 0
+ for arch in self.Platform.Libraries:
+ libraryNumber += len(self.Platform.Libraries[arch])
+ libraryIndex = 0
+ for arch in self.Platform.Libraries:
+ for lib in self.Platform.Libraries[arch]:
+ libraryIndex += 1
+ print "Generating library build files ... %d%%\r" % int((float(libraryIndex) / float(libraryNumber)) * 100),
+ buildFile = AntModuleBuildFile(self.Workspace, self.Platform, lib, self.Toolchain, self.Target, arch)
+ buildFile.Generate()
+ buildDir = os.path.join("${TARGET_DIR}", arch, lib.Module.Package.SubPath(lib.Module.Dir),
+ lib.Module.FileBaseName)
+ parallelBuild.SubTask("ant", dir=buildDir,
+ #antfile="build.xml",
+ inheritAll="true",
+ target="${MODULE_BUILD_TARGET}")
+ print ""
+
+ def Modules(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: modules ")
+
+ modulesTarget = _topLevel.SubTask("target", name="modules")
+ parallelBuild = modulesTarget.SubTask("parallel", threadCount="${THREAD_COUNT}")
+
+ moduleNumber = 0
+ for arch in self.Platform.Modules:
+ moduleNumber += len(self.Platform.Modules[arch])
+
+ moduleIndex = 0
+ for arch in self.Platform.Modules:
+ for module in self.Platform.Modules[arch]:
+ moduleIndex += 1
+ print "Generating module build files ... %d%%\r" % int((float(moduleIndex) / float(moduleNumber)) * 100),
+
+ buildDir = os.path.join("${TARGET_DIR}", arch, module.Module.Package.SubPath(module.Module.Dir),
+ module.Module.FileBaseName)
+ parallelBuild.SubTask("ant", dir=buildDir,
+ #antfile="build.xml",
+ inheritAll="true",
+ target="${MODULE_BUILD_TARGET}")
+ buildFile = AntModuleBuildFile(self.Workspace, self.Platform, module, self.Toolchain, self.Target, arch)
+ buildFile.Generate()
+ print ""
+
+ def Fvs(self):
+ pass
+
+ def Fds(self):
+ pass
+
+ def PostBuild(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: postbuild ")
+
+ # postbuild is defined by user in the fpd file through <UserExtionsion> element,
+ # which has attribute "identifier=1" or "identifier=postbuild"
+ postbuildTasks = []
+ if self.Platform.UserExtensions.has_key("1"):
+ postbuildTasks = self.Platform.UserExtensions["1"]
+ elif self.Platform.UserExtensions.has_key("postbuild"):
+ postbuildTasks = self.Platform.UserExtensions["postbuild"]
+
+ _topLevel.SubTask("target", postbuildTasks, name="postbuild")
+
+ def Clean(self):
+ pass
+
+ def CleanAll(self):
+ pass
+
+ def UserExtensions(self):
+ pass
+
+ def DefaultBuildOptions(self):
+ """Generate ${ARCH}_build.opt which contains the default build&tool definitions"""
+ tools = self.Workspace.ToolConfig.ToolCodes
+ for arch in self.Workspace.ActiveArchs:
+ optFileDir = os.path.join(self.Workspace.Path, self.Platform.OutputPath,
+ self.Target + "_" + self.Toolchain)
+ optFileName = arch + "_build.opt"
+ if not os.path.exists(optFileDir): os.makedirs(optFileDir)
+ f = open(os.path.join(optFileDir, optFileName), "w")
+ for tool in tools:
+ key = (self.Toolchain, self.Target, arch, tool, "FLAGS")
+ flag = self.Workspace.ToolConfig[key]
+ f.write("DEFAULT_%s_FLAGS=%s\n" % (tool, flag))
+
+ f.write("\n")
+ for tool in tools:
+ key = (self.Toolchain, self.Target, arch, tool, "FLAGS")
+ if key in self.Platform.BuildOptions:
+ flag = self.Platform.BuildOptions[key]
+ else:
+ key = (self.Toolchain, self.Target, arch, tool, "FAMILY")
+ family = self.Workspace.ToolConfig[key]
+ key = (family, self.Target, arch, tool, "FLAGS")
+ if key in self.Platform.BuildOptions:
+ flag = self.Platform.BuildOptions[key]
+ else:
+ flag = ""
+ f.write("PLATFORM_%s_FLAGS=%s\n" % (tool, flag))
+
+ f.write("\n")
+ for tool in tools:
+ for attr in self.Workspace.ToolConfig.Attributes:
+ if attr == "FLAGS": continue
+ key = (self.Toolchain, self.Target, arch, tool, attr)
+ value = self.Workspace.ToolConfig[key]
+ if attr == "NAME":
+ f.write("%s=%s\n" % (tool, value))
+ else:
+ f.write("%s_%s=%s\n" % (tool, attr, value))
+ f.write("%s_FLAGS=${DEFAULT_%s_FLAGS} ${DEFAULT_MODULE_%s_FLAGS} ${PLATFORM_%s_FLAGS} ${MODULE_%s_FLAGS}\n" %
+ (tool, tool, tool, tool, tool))
+ f.write("\n")
+
+ f.close()
+
+class AntModuleBuildFile(BuildFile):
+ def __init__(self, workspace, platform, module, toolchain, target, arch):
+ BuildFile.__init__(self, workspace, platform, toolchain, target)
+ self.Module = module
+ self.Arch = arch
+ self.Path = os.path.join(self.Workspace.Path, self.Platform.OutputPath,
+ target + "_" + toolchain, arch, self.Module.Module.Package.Dir,
+ self.Module.Module.Dir, self.Module.Module.FileBaseName, "build.xml")
+ self.BuildXml = AntBuildFile(self.Module.Module.Name)
+
+ self.SourceFiles = self.GetSourceFiles()
+
+ self.Header()
+ self.PreBuild()
+ self.Libraries()
+ self.Sourcefiles()
+ self.Sections()
+ self.Ffs()
+ self.PostBuild()
+
+ def Generate(self):
+ # print self.Path,"\r",
+ self.BuildXml.Create(self.Path)
+
+ def Header(self):
+ _topLevel = self.BuildXml
+ _topLevel.SubTask("taskdef", resource="frameworktasks.tasks")
+ _topLevel.SubTask("taskdef", resource="cpptasks.tasks")
+ _topLevel.SubTask("taskdef", resource="cpptasks.types")
+ _topLevel.SubTask("taskdef", resource="net/sf/antcontrib/antlib.xml")
+
+ _topLevel.Blankline()
+ _topLevel.Comment(" TODO ")
+ _topLevel.SubTask("property", environment="env")
+ _topLevel.SubTask("property", name="WORKSPACE_DIR", value="${env.WORKSPACE}")
+
+ _topLevel.Blankline()
+ _topLevel.Comment("Common build attributes")
+ _topLevel.SubTask("property", name="SINGLE_MODULE_BUILD", value="yes")
+ _topLevel.SubTask("property", name="MODULE_BUILD_TARGET", value="single_module_build")
+ _topLevel.SubTask("property", name="PLATFORM_PREBUILD", value="yes")
+ _topLevel.SubTask("property", name="PLATFORM_POSTBUILD", value="no")
+
+ _topLevel.Blankline()
+ _topLevel.Comment(" TODO ")
+ ifTask = _topLevel.SubTask("if")
+ ifTask.SubTask("istrue", value="${SINGLE_MODULE_BUILD}")
+ thenTask = ifTask.SubTask("then")
+ platformBuildFile = os.path.join("${WORKSPACE_DIR}", self.Platform.OutputPath,
+ self.Target + "_" + self.Toolchain, "build.xml")
+ thenTask.SubTask("import", file=platformBuildFile)
+
+ _topLevel.Blankline()
+ _topLevel.SubTask("property", name="ARCH", value=self.Arch)
+
+ module = self.Module.Module
+ package = module.Package
+ _topLevel.Blankline()
+ _topLevel.SubTask("property", name="PACKAGE", value=package.Name)
+ _topLevel.SubTask("property", name="PACKAGE_GUID", value=package.GuidValue)
+ _topLevel.SubTask("property", name="PACKAGE_VERSION", value=package.Version)
+ _topLevel.SubTask("property", name="PACKAGE_RELATIVE_DIR", value=package.Dir)
+ _topLevel.SubTask("property", name="PACKAGE_DIR", value=os.path.join("${WORKSPACE_DIR}","${PACKAGE_RELATIVE_DIR}"))
+
+ _topLevel.Blankline()
+ _topLevel.SubTask("property", name="MODULE", value=module.Name)
+ _topLevel.SubTask("property", name="MODULE_GUID", value=module.GuidValue)
+ _topLevel.SubTask("property", name="MODULE_VERSION", value=module.Version)
+ _topLevel.SubTask("property", name="MODULE_TYPE", value=module.Type)
+ _topLevel.SubTask("property", name="MODULE_FILE_BASE_NAME", value=module.FileBaseName)
+ _topLevel.SubTask("property", name="MODULE_RELATIVE_DIR", value=module.Dir)
+ _topLevel.SubTask("property", name="MODULE_DIR", value=os.path.join("${PACKAGE_DIR}", "${MODULE_RELATIVE_DIR}"))
+ _topLevel.SubTask("property", name="BASE_NAME", value=module.BaseName)
+
+ _topLevel.Blankline()
+ _topLevel.SubTask("property", file="${WORKSPACE_DIR}/Tools/Python/buildgen/module_build_path.txt")
+
+ self._BuildOption()
+
+ _topLevel.Blankline()
+ _topLevel.SubTask("property", name="ENTRYPOINT", value="_ModuleEntryPoint")
+
+ _topLevel.SubTask("property", name="SOURCE_FILES", value="\n ".join(self._GetSourceFileList()))
+ _topLevel.SubTask("property", name="LIBS", value="\n ".join(self._GetLibList()))
+
+ _topLevel.Blankline()
+ _topLevel.SubTask("property", file="${PLATFORM_BUILD_DIR}/%s_build.opt" % self.Arch)
+ _topLevel.Blankline()
+ _topLevel.SubTask("echo", message="${MODULE}-${MODULE_VERSION} [${ARCH}] from package ${PACKAGE}-${PACKAGE_VERSION} (${MODULE_RELATIVE_DIR})", level="info")
+
+ _topLevel.Blankline()
+ _topLevel.Comment("Default target")
+ _topLevel.SubTask("target", name="all", depends="single_module_build")
+ _topLevel.SubTask("target", name="platform_module_build", depends="prebuild, sourcefiles, sections, output, postbuild")
+ _topLevel.SubTask("target", name="single_module_build", depends="prebuild, libraries, sourcefiles, sections, output, postbuild")
+
+ def _BuildOption(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ baseModule = self.Module.Module
+ tools = self.Workspace.ToolConfig.ToolCodes
+
+ for tool in tools:
+ key = (self.Toolchain, self.Target, self.Arch, tool, "FLAGS")
+ flag = ""
+ if key in baseModule.BuildOptions:
+ flag = baseModule.BuildOptions[key]
+ _topLevel.SubTask("property", name="DEFAULT_MODULE_%s_FLAGS" % tool, value=flag)
+
+ _topLevel.Blankline()
+ for tool in tools:
+ key = (self.Toolchain, self.Target, self.Arch, tool, "FLAGS")
+ flag = ""
+ if key in self.Module.BuildOptions:
+ flag = self.Module.BuildOptions[key]
+ _topLevel.SubTask("property", name="MODULE_%s_FLAGS" % tool, value=flag)
+
+ def PreBuild(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: prebuild ")
+
+ prebuildTasks = []
+ module = self.Module.Module
+ if module.UserExtensions.has_key("0"):
+ prebuildTasks = module.UserExtensions["0"]
+ elif module.UserExtensions.has_key("postbuild"):
+ prebuildTasks = module.UserExtensions["prebuild"]
+
+ _topLevel.SubTask("target", prebuildTasks, name="prebuild")
+
+
+ def Libraries(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: libraries ")
+
+ librariesTarget = _topLevel.SubTask("target", name="libraries")
+ parallelBuild = librariesTarget.SubTask("parallel", threadCount="${THREAD_COUNT}")
+ for lib in self.Module.Libraries:
+ module = lib.Module
+ buildDir = os.path.join("${BIN_DIR}", module.Package.SubPath(module.Dir), module.FileBaseName)
+ libTask = parallelBuild.SubTask("ant", dir=buildDir,
+ inheritAll="false",
+ target="${MODULE_BUILD_TARGET}")
+ libTask.SubTask("property", name="PLATFORM_PREBUILD", value="false")
+ libTask.SubTask("property", name="PLATFORM_POSTBUILD", value="false")
+
+ def Sourcefiles(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: sourcefiles ")
+ _sourcefilesTarget = _topLevel.SubTask("target", name="sourcefiles")
+
+ _incTask = AntTask(self.BuildXml.Document, "EXTRA.INC")
+ _incTask.SubTask("includepath", path="${WORKSPACE_DIR}")
+ _incTask.SubTask("includepath", path="${MODULE_DIR}")
+ _incTask.SubTask("includepath", path=os.path.join("${MODULE_DIR}", self.Arch.capitalize()))
+ _incTask.SubTask("includepath", path="${DEST_DIR_DEBUG}")
+ if self.Arch in self.Module.Module.IncludePaths:
+ for inc in self.Module.Module.IncludePaths[self.Arch]:
+ _incTask.SubTask("includepath", path=os.path.join("${WORKSPACE_DIR}", inc))
+
+ # init
+ if not self.Module.Module.IsBinary:
+ _buildTask = _sourcefilesTarget.SubTask("Build_Init")
+ _buildTask.AddSubTask(_incTask)
+
+ # AutoGen firt
+ _buildTask = _sourcefilesTarget.SubTask("Build_AUTOGEN", FILEEXT="c", FILENAME="AutoGen", FILEPATH=".")
+ _buildTask.AddSubTask(_incTask)
+
+ # uni file follows
+ type = "UNI"
+ if type in self.SourceFiles:
+ for srcpath in self.SourceFiles[type]:
+ taskName = "Build_" + type
+ fileDir = os.path.dirname(srcpath)
+ if fileDir == "": fileDir = "."
+ fileBaseName,fileExt = os.path.basename(srcpath).rsplit(".", 1)
+ _buildTask = _sourcefilesTarget.SubTask(taskName, FILENAME=fileBaseName, FILEEXT=fileExt, FILEPATH=fileDir)
+ _buildTask.AddSubTask(_incTask)
+
+ # others: c, vfr, ...
+ for type in self.SourceFiles:
+ if type == "Unicode": continue
+ for srcpath in self.SourceFiles[type]:
+ taskName = "Build_" + type
+ fileDir = os.path.dirname(srcpath)
+ if fileDir == "": fileDir = "."
+ fileBaseName,fileExt = os.path.basename(srcpath).rsplit(".", 1)
+ _buildTask = _sourcefilesTarget.SubTask(taskName, FILENAME=fileBaseName, FILEEXT=fileExt, FILEPATH=fileDir)
+ _buildTask.AddSubTask(_incTask)
+
+ def Sections(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: sections ")
+ _sectionsTarget = _topLevel.SubTask("target", name="sections")
+
+ def Ffs(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: output ")
+ _sectionsTarget = _topLevel.SubTask("target", name="output")
+
+ def PostBuild(self):
+ _topLevel = self.BuildXml
+ _topLevel.Blankline()
+ _topLevel.Comment(" TARGET: postbuild ")
+
+ postbuildTasks = []
+ module = self.Module.Module
+ if module.UserExtensions.has_key("1"):
+ postbuildTasks = module.UserExtensions["1"]
+ elif module.UserExtensions.has_key("postbuild"):
+ postbuildTasks = module.UserExtensions["postbuild"]
+
+ _topLevel.SubTask("target", postbuildTasks, name="postbuild")
+
+ def Clean(self):
+ pass
+
+ def CleanAll(self):
+ pass
+
+ def UserExtensions(self):
+ pass
+
+ def GetSourceFiles(self):
+ ## check arch, toolchain, family, toolcode, ext
+ ## if the arch of source file supports active arch
+ ## if the toolchain of source file supports active toolchain
+ ## if the toolchain family of source file supports active toolchain family
+ ## if the ext of the source file is supported by the toolcode
+ module = self.Module.Module
+ files = {} # file type -> src
+ for type in module.SourceFiles[self.Arch]:
+ if not module.IsBuildable(type):
+ # print type,"is not buildable"
+ continue
+
+ if type not in files:
+ files[type] = []
+ for src in module.SourceFiles[self.Arch][type]:
+ if self.Toolchain not in src.Toolchains:
+ # print self.Toolchain,"not in ",src.Toolchains
+ continue
+ if not self.IsCompatible(src.Families, self.Workspace.ActiveFamilies):
+ # print src.Families,"not compatible with",self.Workspace.ActiveFamilies
+ continue
+ toolcode = src.GetToolCode(src.Type)
+ if toolcode != "":
+ ext = self.Workspace.GetToolDef(self.Toolchain, self.Target, self.Arch, toolcode, "EXT")
+ if ext != "" and ext != src.Ext:
+ # print ext,"in tools_def.txt is not the same as",src.Ext
+ continue
+ ## fileFullPath = os.path.join("${MODULE_DIR}", )
+ ## print fileFullPath
+ files[type].append(src.Path)
+
+ return files
+
+ def Intersection(self, list1, list2):
+ return list(Set(list1) & Set(list2))
+
+ def IsCompatible(self, list1, list2):
+ return len(self.Intersection(list1, list2)) > 0
+
+ def _GetLibList(self):
+ libList = []
+ for lib in self.Module.Libraries:
+ module = lib.Module
+ libList.append(os.path.join("${BIN_DIR}", module.Name + ".lib"))
+ return libList
+
+ def _GetSourceFileList(self):
+ srcList = []
+ for type in self.SourceFiles:
+ srcList.extend(self.SourceFiles[type])
+ return srcList
+
+class NmakeFile(BuildFile):
+ pass
+
+class GmakeFile(BuildFile):
+ pass
+
+# for test
+if __name__ == "__main__":
+ workspacePath = os.getenv("WORKSPACE", os.getcwd())
+ startTime = time.clock()
+ ws = Workspace(workspacePath, [], [])
+
+ # generate build.xml
+ ap = ws.ActivePlatform
+ for target in ws.ActiveTargets:
+ ant = AntPlatformBuildFile(ws, ap, ws.ActiveToolchain, target)
+ ant.Generate()
+
+ print "\n[Finished in %fs]" % (time.clock() - startTime)
diff --git a/Tools/Python/buildgen/FrameworkElement.py b/Tools/Python/buildgen/FrameworkElement.py
new file mode 100644
index 0000000000..6fd8740789
--- /dev/null
+++ b/Tools/Python/buildgen/FrameworkElement.py
@@ -0,0 +1,523 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+"""Framework Element Classes
+
+TODO
+"""
+
+################################################################################
+##
+## Element class: base class for representing framework elements
+##
+################################################################################
+class Element:
+ def __init__(self, **kwargs):
+ """(Name, GuidValue, Version, Path, Dir, Archs, Usage, Features, Signature)"""
+ ## The path and directory where the information of the element comes from
+ self.Path = "."
+ self.Dir = "."
+
+ ## Element name, guid and version
+ self.Name = ""
+ self.GuidValue = ""
+ self.Version = ""
+
+ ## The element supported architecture
+ self.Archs = []
+
+ ## Indiciate how the element is used
+ self.Usage = "ALWAYS_CONSUMED"
+
+ ## Indicate what kind of features this element is bound
+ self.Features = []
+
+ ## Element signature, used to check the its integerity
+ self.Signature = 0
+
+ def __str__(self):
+ return self.Name + "-" + self.Version + " " + " [" + self.GuidValue + "]"
+
+ def __eq__(self, other):
+ if not isinstance(other, Element):
+ return False
+
+ if self.GuidValue != other.GuidValue:
+ return False
+
+ if self.Version != other.Version:
+ return False
+
+ return True
+
+ def __hash__(self):
+ return hash(self.GuidValue + self.Version)
+
+################################################################################
+##
+## ToolOption: build tool option
+##
+################################################################################
+class ToolOption(Element):
+
+ def __init__(self, **kwargs):
+ """Prefix, Value, Tool, Toolchains, Families, Targets"""
+ Element.__init__(self)
+
+ self.Prefix = "/"
+ self.Value = ""
+ self.Tool = ""
+ self.Toolchains = ""
+ self.Families = "MSFT"
+ self.Targets = "DEBUG"
+
+################################################################################
+##
+## BuildTool: build tool
+##
+################################################################################
+class BuildTool(Element):
+ def __init__(self, **kwargs):
+ """Options, Toolchains, Families, Targets"""
+ Element.__init__(self)
+
+ self.Options = []
+ self.Toolchains = []
+ self.Families = []
+ self.Targets = []
+
+################################################################################
+##
+## SourceFile: files in a module for build
+##
+################################################################################
+class SourceFile(Element):
+ def __init__(self, **kwargs):
+ """BaseName, Ext, Type, Toolchains, Families, Targets"""
+ Element.__init__(self)
+
+ self.BaseName = ""
+ self.Ext = ""
+ self.Type = ""
+ self.Toolchains = []
+ self.Families = []
+ self.Targets = []
+
+################################################################################
+##
+## IncludeFile: header file
+##
+################################################################################
+class IncludeFile(SourceFile):
+ def __init__(self, **kwargs):
+ """Type, Package, ModuleType"""
+ SourceFile.__init__(self)
+
+ self.Type = "HeaderFile"
+ self.Package = ""
+ self.ModuleType = ""
+
+################################################################################
+##
+## IncludePath:
+##
+################################################################################
+class IncludePath(IncludeFile):
+ pass
+
+################################################################################
+##
+## LibraryInterface: library class interface
+##
+################################################################################
+class LibraryInterface(Element):
+ def __init__(self, **kwargs):
+ """Package, FavoriteInstance, Instances, ModuleTypes, Consumers"""
+ Element.__init__(self)
+
+ self.Package = ""
+ self.FavoriteInstance = ""
+ self.Instances = []
+ self.ModuleTypes = []
+ self.Consumers = []
+
+ def __eq__(self, other):
+ if not isinstance(other, LibraryInterface):
+ return False
+ return self.Name == other.Name
+
+ def __hash__(self):
+ return hash(self.Name)
+
+################################################################################
+##
+## LibraryClass: library class
+##
+################################################################################
+class LibraryClass(Element):
+ def __init__(self, **kwargs):
+ """
+ ()
+ """
+ Element.__init__(self)
+
+ self.Interface = ""
+ self.FavoriteInstance = ""
+
+ def __eq__(self, other):
+ if not isinstance(other, LibraryClass):
+ return False
+ return self.Name == other.Name
+
+ def __hash__(self):
+ return hash(self.Name)
+
+################################################################################
+##
+## Guid:
+##
+################################################################################
+class Guid(Element):
+ def __init__(self, **kwargs):
+ """CName, Types, ModuleTypes"""
+ Element.__init__(self)
+
+ self.CName = ""
+ self.Types = []
+ self.ModuleTypes= []
+
+################################################################################
+##
+## Protocol:
+##
+################################################################################
+class Protocol(Guid):
+ pass
+
+################################################################################
+##
+## ProtocolNotify:
+##
+################################################################################
+class ProtocolNotify(Protocol):
+ pass
+
+################################################################################
+##
+## Ppi:
+##
+################################################################################
+class Ppi(Guid):
+ pass
+
+################################################################################
+##
+## PpiNotify:
+##
+################################################################################
+class PpiNotify(Ppi):
+ pass
+
+################################################################################
+##
+## Extern:
+##
+################################################################################
+class Extern(Element):
+ def __init__(self, **kwargs):
+ """Specifications, ModuleEntryPoints, ModuleUnloadImages, Constructors, Destructors, DriverBindings, ComponentNames, DriverConfigs, DriverDiags, SetVirtualAddressMapCallBacks, ExitBootServicesCallBacks"""
+ Element.__init__(self)
+
+ self.Specifications = []
+ self.ModuleEntryPoints = []
+ self.ModuleUnloadImages = []
+ self.Constructors = []
+ self.Destructors = []
+ self.DriverBindings = []
+ self.ComponentNames = []
+ self.DriverConfigs = []
+ self.DriverDiags = []
+ self.SetVirtualAddressMapCallBacks = []
+ self.ExitBootServicesCallBacks = []
+
+################################################################################
+##
+## Sku:
+##
+################################################################################
+class Sku(Element):
+ def __init__(self, **kwargs):
+ """Id, Value"""
+ Element.__init__(self)
+
+ self.Id = 0
+ self.Value = ""
+
+################################################################################
+##
+## Pcd:
+##
+################################################################################
+class Pcd(Element):
+ def __init__(self, **kwargs):
+ """Types, CName, Value, Token, TokenSpace, DatumType, Sku, ModuleTypes"""
+ Element.__init__(self)
+
+ self.Types = []
+ self.CName = ""
+ self.Value = ""
+ self.Token = ""
+ self.TokenSpace = ""
+ self.DatumType = ""
+ self.Default = ""
+ self.Sku = ""
+ self.ModuleTypes= []
+
+################################################################################
+##
+## Module: framework module
+##
+################################################################################
+class Module(Element):
+ def __init__(self, **kwargs):
+ """Workspace, Package, Type, BaseName, FileBaseName, IsLibrary, PcdIsDriver,
+ NeedsFlashMap_h, SourceFiles, IncludePaths, IncludeFiles, NonProcessedFiles,
+ LibraryClasses, Guids, Protocols, Ppis, Externs, Pcds,
+ UserExtensions, BuildOptions, Environment
+ """
+ Element.__init__(self)
+
+ self.Workspace = ""
+ self.Package = ""
+ self.Type = ""
+ self.BaseName = ""
+ self.FileBaseName = ""
+ self.IsLibrary = False
+ self.IsBinary = False
+ self.PcdIsDriver = False
+ self.NeedsFlashMap_h = False
+ self.SourceFiles = {} # arch -> {file type -> [source file list]}
+ self.IncludePaths = {} # arch -> [path list]
+ self.IncludeFiles = {}
+
+ self.NonProcessedFiles = []
+ self.LibraryClasses = {} # arch -> [library class list]
+
+ self.Guids = {} # arch -> [guid object list]
+ self.Protocols = {} # arch -> []
+ self.Ppis = {} # arch -> []
+
+ self.Externs = {} # arch -> []
+ self.Pcds = {} # arch -> []
+
+ self.UserExtensions = {} # identifier -> ...
+ self.BuildOptions = {} # (toolchain, target, arch, toolcode, "FLAGS") -> flag
+ self.Environment = {}
+
+ def __eq__(self, other):
+ if not isinstance(other, Module):
+ return False
+
+ if self.GuidValue != other.GuidValue:
+ return False
+
+ if self.Version != other.Version:
+ return False
+
+ if self.Package != other.Package:
+ return False
+
+ return True
+
+ def __hash__(self):
+ return hash(self.GuidValue + self.Version + hash(self.Package))
+
+################################################################################
+##
+## PlatformModule: module for build
+##
+################################################################################
+class PlatformModule(Element):
+ def __init__(self, **kwargs):
+ """Workspace, Platform, Module, Libraries, Pcds, FfsLayouts, FvBindings
+ BuildOptions, BuildType, BuildFile, BuildPath, Sections, FfsFile, Environment
+ """
+ Element.__init__(self)
+ self.Workspace = ""
+ self.Platform = ""
+ self.Module = ""
+ self.Libraries = []
+ self.Pcds = []
+ self.FfsLayouts = []
+ self.FvBindings = []
+ self.BuildOptions = {}
+
+ self.BuildType = "efi" ## efi or lib
+ self.BuildFile = "build.xml"
+ self.BuildPath = "${MODULE_BUILD_DIR}"
+ self.Sections = []
+ self.FfsFile = ""
+
+ self.Environment = {} # name/value pairs
+
+ def __eq__(self, other):
+ if not isinstance(other, PlatformModule):
+ if not isinstance(other, Module):
+ return False
+ elif self.Module != other:
+ return False
+ elif self.Module != other.Module:
+ return False
+
+ return True
+
+ def __hash__(self):
+ return hash(self.Module)
+
+################################################################################
+##
+## Package: framework package
+##
+################################################################################
+class Package(Element):
+ def __init__(self, **kwargs):
+ """Workspace, ReadOnly, Repackage, Modules, PackageIncludes, StandardIncludes,
+ LibraryInterfaces, Guids, Protocols, Ppis, Pcds, Environment
+ """
+ Element.__init__(self)
+
+ self.Workspace = ""
+ self.ReadOnly = True
+ self.Repackage = True
+ self.Modules = []
+ self.PackageIncludes = {} # module type -> [include file list]
+ self.StandardIncludes = []
+ self.LibraryInterfaces = {} # class name -> include file
+ self.Guids = {} # cname -> guid object
+ self.Protocols = {} # cname -> protocol object
+ self.Ppis = {} # cname -> ppi object
+ self.Pcds = {} # token -> pcd object
+
+ self.Environment = {}
+
+################################################################################
+##
+## PackageDependency:
+##
+################################################################################
+class PackageDependency(Element):
+ def __init__(self, **kwargs):
+ """Package"""
+ Element.__init__(self)
+
+ self.Package = ""
+
+################################################################################
+##
+## Platform:
+##
+################################################################################
+class Platform(Element):
+ def __init__(self, **kwargs):
+ """Targets, OutputPath, Images, Modules, DynamicPcds, Fvs, Libraries
+ BuildFile, BuildPath, BuildOptions, UserExtensions
+ """
+ Element.__init__(self)
+
+ self.Targets = []
+ self.OutputPath = ""
+ self.Images = []
+ self.Modules = {} # arch -> [module list]
+ self.DynamicPcds = []
+ self.FfsLayouts = {}
+ self.Fvs = {}
+
+ self.Libraries = {} # arch -> [library instance]
+ self.BuildFile = "build.xml"
+ self.BuildPath = "${PLATFORM_BUILD_DIR}"
+ self.BuildOptions = {}
+ self.UserExtensions = {}
+
+ self.Environment = {} # name/value pairs
+
+################################################################################
+##
+## Workspace:
+##
+################################################################################
+class Workspace(Element):
+ def __init__(self, **kwargs):
+ """Packages, Platforms, Fars, Modules, PlatformIndex, PackageIndex"""
+ Element.__init__(self)
+
+ self.Packages = []
+ self.Platforms = []
+ self.Fars = []
+ self.Modules = []
+
+ ## "GUID" : {guid : {version : platform}}
+ ## "PATH" : {path : platform}
+ ## "NAME" : {name : [platform]}
+ self.PlatformXref = {
+ "GUID" : {},
+ "PATH" : {},
+ "NAME" : {},
+ }
+ ## "GUID" : {guid : {version : package}}
+ ## "PATH" : {path : package}
+ ## "NAME" : {name : package}
+ self.PackageXref = {
+ "GUID" : {},
+ "PATH" : {},
+ "NAME" : {},
+ }
+ ## "GUID" : {guid : {version : [module]}}
+ ## "PATH" : {path : module}
+ ## "NAME" : {name : module}
+ self.ModuleXref = {
+ "GUID" : {},
+ "PATH" : {},
+ "NAME" : {},
+ }
+ ## "NAME" : {name : library interface}
+ ## "PATH" : {path : library interface}
+ self.LibraryInterfaceXref = {
+ "PATH" : {},
+ "NAME" : {},
+ }
+ ## TODO
+ self.FarIndex = {}
+
+ # from target.txt
+ self.TargetConfig = {}
+ # from tools_def.txt
+ self.ToolConfig = {}
+
+ self.ActivePlatform = ""
+ self.ActiveToolchain = ""
+ self.ActiveFamilies = []
+ self.ActiveModules = []
+ self.ActiveTargets = []
+ self.ActiveArchs = []
+
+ self.IndividualModuleBuild = False
+ self.MultiThreadBuild = False
+ self.ThreadCount = "2"
+
+ self.Environment = {}
+
+################################################################################
+##
+## For test:
+##
+################################################################################
+if __name__ == "__main__":
+ pass
diff --git a/Tools/Python/buildgen/SurfaceAreaElement.py b/Tools/Python/buildgen/SurfaceAreaElement.py
new file mode 100644
index 0000000000..29aaa8398e
--- /dev/null
+++ b/Tools/Python/buildgen/SurfaceAreaElement.py
@@ -0,0 +1,1549 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+"""Framework SurfaceArea Elemments"""
+#
+# TODO: FFS layout, Flash, FV, PCD
+#
+import os, sys, re, getopt, string, glob, xml.dom.minidom, pprint, time, copy, shelve
+from XmlRoutines import *
+import FrameworkElement
+import BuildConfig
+
+################################################################################
+##
+## Convert given list to a string in the format like: [a, b, c]
+##
+################################################################################
+def ListString(lst):
+ return "[%s]" % ",".join(lst)
+
+class SurfaceAreaElement:
+ """Base class for Surface Area XML element"""
+ _ModuleTypes = ('BASE', 'SEC', 'PEI_CORE', 'PEIM', 'DXE_CORE', 'DXE_DRIVER',
+ 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'DXE_SMM_DRIVER',
+ 'TOOL', 'UEFI_DRIVER', 'UEFI_APPLICATION', 'USER_DEFINED')
+ _GuidTypes = ('DATA_HUB_RECORD', 'EFI_EVENT', 'EFI_SYSTEM_CONFIGURATION_TABLE',
+ 'EFI_VARIABLE', 'GUID', 'HII_PACKAGE_LIST', 'HOB', 'TOKEN_SPACE_GUID')
+ _Archs = ('EBC', 'IA32', 'X64', 'IPF', 'ARM', 'PPC')
+ _Usages = ('ALWAYS_CONSUMED', 'SOMETIMES_CONSUMED', 'ALWAYS_PRODUCED',
+ 'SOMETIMES_PRODUCED', 'TO_START', 'BY_START', 'PRIVATE')
+ _FileTypes = {
+ ".c" : "CCode",
+ ".C" : "CCode",
+ ".cpp" : "CCode",
+ ".Cpp" : "CCode",
+ ".CPP" : "CCode",
+ ".h" : "CHeader",
+ ".H" : "CHeader",
+ ".asm" : "ASM",
+ ".Asm" : "Assembly",
+ ".ASM" : "Assembly",
+ ".s" : "IpfAssembly",
+ ".S" : "GccAssembly",
+ ".uni" : "UNI",
+ ".Uni" : "Unicode",
+ ".UNI" : "Unicode",
+ ".vfr" : "VFR",
+ ".Vfr" : "VFR",
+ ".VFR" : "VFR",
+ ".dxs" : "DPX",
+ ".Dxs" : "DPX",
+ ".DXS" : "DPX",
+ ".fv" : "FirmwareVolume",
+ ".Fv" : "FirmwareVolume",
+ ".FV" : "FirmwareVolume",
+ ".efi" : "EFI",
+ ".Efi" : "EFI",
+ ".EFI" : "EFI",
+ ".SEC" : "FFS",
+ ".PEI" : "FFS",
+ ".DXE" : "FFS",
+ ".APP" : "FFS",
+ ".FYI" : "FFS",
+ ".FFS" : "FFS",
+ ".bmp" : "BMP",
+ ".i" : "PPCode",
+ ".asl" : "ASL",
+ ".Asl" : "ASL",
+ ".ASL" : "ASL",
+ }
+ _ToolMapping = {
+ "CCode" : "CC",
+ "CHeader" : "",
+ "ASM" : "ASM",
+ "Assembly" : "ASM",
+ "IpfAssembly" : "ASM",
+ "GccAssembly" : "ASM",
+ "UNI" : "",
+ "Unicode" : "",
+ "VFR" : "",
+ "DPX" : "",
+ "FirmwareVolume" : "",
+ "EFI" : "",
+ "FFS" : "",
+ "PPCode" : "PP",
+ "BMP" : "",
+ }
+
+ _BuildableFileTypes = ("CCode", "ASM", "Assembly", "IpfAssembly", "GccAssembly", "UNI", "Unicode", "VFR", "DPX", "EFI")
+
+ def __init__(self, workspace, owner=None, dom=None, parse=True, postprocess=True):
+ self._Workspace = workspace
+
+ if owner == None: self._Owner = ""
+ else: self._Owner = owner
+
+ if dom == None: self._Root = ""
+ else: self._Root = dom
+
+ self._Elements = {}
+
+ if parse: self.Parse()
+ if postprocess: self.Postprocess()
+
+ def Parse(self):
+ """Parse the XML element in DOM form"""
+ pass
+
+ def Postprocess(self):
+ """Re-organize the original information form XML DOM into a format which can be used directly"""
+ pass
+
+ def GetArchList(self, dom):
+ """Parse the SupArchList attribute. If not spcified, return all ARCH supported"""
+ archs = XmlAttribute(dom, "SupArchList").split()
+ if archs == []:
+ if self._Owner.Archs != []:
+ archs = self._Owner.Archs
+ elif self._Workspace.ActiveArchs != []:
+ archs = self._Workspace.ActiveArchs
+ elif self._Workspace.ActivePlatform != "" and self._Workspace.ActivePlatform.Archs != []:
+ archs = self._Workspace.ActivePlatform.Archs
+ else:
+ archs = self._Archs
+ return archs
+
+ def GetModuleTypeList(self, dom):
+ """Parse the SupModuleList attribute. If not specified, return all supported module types"""
+ moduleTypes = XmlAttribute(dom, "SupModuleList").split()
+ if moduleTypes == []:
+ moduleTypes = self._ModuleTypes
+ return moduleTypes
+
+ def GetGuidTypeList(self, dom):
+ """Parse GuidTypeList attribute. Default to GUID if not specified"""
+ guidTypes = XmlAttribute(dom, "GuidTypeList")
+ if guidTypes == []:
+ guidTypes = ["GUID"]
+ return guidTypes
+
+ def GetFeatureList(self, dom):
+ """Parse FeatureFlag attribute"""
+ return XmlAttribute(dom, "FeatureFlag").split()
+
+ def GetToolchainTagList(self, dom):
+ """Parse TagName attribute. Return all defined toolchains defined in tools_def.txt if not given"""
+ toolchainTagString = XmlAttribute(dom, "TagName")
+ if toolchainTagString == "":
+ return self._Workspace.ToolConfig.Toolchains
+ return toolchainTagString.split()
+
+ def GetToolchainFamilyList(self, dom):
+ """Parse ToolChainFamily attribute. Return all defined toolchain families in tools_def.txt if not given"""
+ familyString = XmlAttribute(dom, "ToolChainFamily")
+ if familyString != "":
+ return familyString.split()
+ return self._Workspace.ToolConfig.Families
+
+ def GetTargetList(self, dom):
+ """Parse BuildTargets attribute. Return all build targets defined in tools_def.txt if not given"""
+ targetList = XmlAttribute(dom, "BuildTargets").split()
+ if targetList == []:
+ targetList = self._Workspace.ToolConfig.Targets
+ return targetList
+
+ def GetUsage(self, dom):
+ """Parse Usage attribute. Default to ALWAYS_CONSUMED if not given"""
+ usageString = XmlAttribute(dom, "Usage")
+ if usageString == "":
+ return "ALWAYS_CONSUMED"
+ return usageString
+
+ def GetBuildOptionList(self, dom):
+ """Parse Options/Option element. Return a options dictionay with keys as (toolchain, target, arch, toolcode, attr)"""
+ optionList = XmlList(dom, "/Options/Option")
+ buildOptions = {}
+ for option in optionList:
+ targets = self.GetTargetList(option)
+ toolchainFamilies = self.GetToolchainFamilyList(option)
+ toolchainTags = self.GetToolchainTagList(option)
+ toolcode = XmlAttribute(option, "ToolCode")
+ archs = self.GetArchList(option)
+ flag = XmlElementData(option)
+ # print flag
+
+ toolchains = []
+ if toolchainTags != []:
+ toolchains = toolchainTags
+ elif toolchainFamilies != []:
+ toolchains = toolchainFamilies
+ else:
+ raise Exception("No toolchain specified for a build option: " + self._Owner.Name)
+
+ if targets == []: targets = self._Workspace.ActiveTargets
+ if archs == []: archs = self._Workspace.ActiveArchs
+
+ for toolchain in toolchains:
+ for target in targets:
+ for arch in archs:
+ buildOptions[(toolchain, target, arch, toolcode, "FLAGS")] = flag
+ return buildOptions
+
+ def GetFvBindingList(self, dom):
+ """Parse FvBinding element. If not specified, return NULL FV"""
+ fvBindingList = XmlElementData(dom).split()
+ if fvBindingList == []:
+ fvBindingList = ["NULL"]
+ return fvBindingList
+
+ def IsBuildable(self, type):
+ """Test if a file with the type can be built by a tool"""
+ return type in self._BuildableFileTypes
+
+ def GetToolCode(self, type):
+ """Get the toolcode which must be used to build files with the type"""
+ toolcode = ""
+ if type in self._ToolMapping:
+ toolcode = self._ToolMapping[type]
+ return toolcode
+
+ def GetBoolean(self, dom):
+ """Transate true/false in string form to python's True/False value"""
+ boolString = XmlElementData(dom).upper()
+ if boolString == "" or boolString == "FALSE" or boolString == "NO":
+ return False
+ else:
+ return True
+
+class LibraryDeclaration(FrameworkElement.LibraryInterface, SurfaceAreaElement):
+ def __init__(self, workspace, package, dom):
+ FrameworkElement.LibraryInterface.__init__(self)
+ self.Package = package
+ SurfaceAreaElement.__init__(self, workspace, package, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.Name = XmlAttribute(dom, "Name")
+ self.Path = os.path.normpath(XmlElementData(XmlElement(dom, "/LibraryClass/IncludeHeader")))
+ self.Dir = os.path.dirname(self.Path)
+
+ attribute = XmlAttribute(dom, "RecommendedInstanceGuid")
+ if attribute is not '':
+ self.FavoriteIntance = FrameworkElement.Module()
+ self.FavoriteIntance.Guid = attribute
+
+ attribute = XmlAttribute(dom, "RecommendedInstanceVersion")
+ if attribute is not '':
+ if self.FavoriteIntance == "":
+ raise "No GUID for the recommened library instance"
+ self.FavoriteIntance.Version = attribute
+
+ self.Archs = self.GetArchList(dom)
+ self.ModuleTypes = self.GetModuleTypeList(dom)
+
+class LibraryClass(FrameworkElement.LibraryClass, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.LibraryClass.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+
+ self.Name = XmlElementData(XmlElement(dom, "/LibraryClass/Keyword"))
+ self.Usage = self.GetUsage(dom)
+ self.Features = self.GetFeatureList(dom)
+ self.Archs = self.GetArchList(dom)
+
+ attribute = XmlAttribute(dom, "RecommendedInstanceGuid")
+ if attribute is not '':
+ self.FavoriteIntance = FrameworkElement.Module()
+ self.FavoriteIntance.Guid = attribute
+
+ attribute = XmlAttribute(dom, "RecommendedInstanceVersion")
+ if attribute is not '':
+ if self.FavoriteIntance == "":
+ self.FavoriteIntance = FrameworkElement.Module()
+ self.FavoriteIntance.Version = attribute
+
+ def Postprocess(self):
+ self.Interface = self._Workspace.GetLibraryInterface(self.Name)
+
+class SourceFile(FrameworkElement.SourceFile, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.SourceFile.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.Path = os.path.normpath(XmlElementData(dom))
+ self.Dir = os.path.dirname(self.Path)
+ self.Type = self.GetFileType()
+ self.Toolchains = self.GetToolchainTagList(dom)
+ self.Families = self.GetToolchainFamilyList(dom)
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ def GetFileType(self):
+ type = XmlAttribute(self._Root, "ToolCode")
+ if type == "":
+ fileName = os.path.basename(self.Path)
+ self.BaseName,self.Ext = os.path.splitext(fileName)
+ if self.Ext in self._FileTypes:
+ type = self._FileTypes[self.Ext]
+ else:
+ type = ""
+ return type
+
+class PackageDependency(FrameworkElement.PackageDependency, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.PackageDependency.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.GuidValue = XmlAttribute(dom, "PackageGuid").upper()
+ self.Version = XmlAttribute(dom, "PackageVersion")
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ def Postprocess(self):
+ self.Package = self._Workspace.GetPackage(self.GuidValue, self.Version)
+ if self.Package == "": raise "No package with GUID=" + self.GuidValue + "VERSION=" + self.Version
+
+class Protocol(FrameworkElement.Protocol, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.Protocol.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.CName = XmlElementData(XmlElement(dom, "/Protocol/ProtocolCName"))
+ self.Usage = self.GetUsage(dom)
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ def Postprocess(self):
+ for pd in self._Owner._Elements["PackageDependencies"]:
+ if self.CName not in pd.Package.Protocols: continue
+ self.GuidValue = pd.Package.Protocols[self.CName]
+
+class ProtocolNotify(FrameworkElement.ProtocolNotify, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.ProtocolNotify.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+
+ self.CName = XmlElementData(XmlElement(dom, "/ProtocolNotify/ProtocolCName"))
+ self.Usage = self.GetUsage(dom)
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ def Postprocess(self):
+ for pd in self._Owner._Elements["PackageDependencies"]:
+ if self.CName not in pd.Package.Protocols: continue
+ self.GuidValue = pd.Package.Protocols[self.CName]
+
+class Ppi(FrameworkElement.Ppi, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.Ppi.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.CName = XmlElementData(XmlElement(dom, "/Ppi/PpiCName"))
+ self.Usage = self.GetUsage(dom)
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ def Postprocess(self):
+ for pd in self._Owner._Elements["PackageDependencies"]:
+ if self.CName not in pd.Package.Ppis: continue
+ self.GuidValue = pd.Package.Ppis[self.CName]
+
+class PpiNotify(FrameworkElement.PpiNotify, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.PpiNotify.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.CName = XmlElementData(XmlElement(dom, "/PpiNotify/PpiCName"))
+ self.Usage = self.GetUsage(dom)
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ def Postprocess(self):
+ for pd in self._Owner._Elements["PackageDependencies"]:
+ if self.CName not in pd.Package.Ppis: continue
+ self.GuidValue = pd.Package.Ppis[self.CName]
+
+class Guid(FrameworkElement.Guid, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.Guid.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.CName = XmlElementData(XmlElement(dom, "/GuidCNames/GuidCName"))
+ self.Usage = self.GetUsage(dom)
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ def Postprocess(self):
+ for pd in self._Owner._Elements["PackageDependencies"]:
+ if self.CName not in pd.Package.Guids: continue
+ self.GuidValue = pd.Package.Guids[self.CName]
+
+class Extern(FrameworkElement.Extern, SurfaceAreaElement):
+ def __init__(self, workspace, module, dom):
+ FrameworkElement.Extern.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, module, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.Archs = self.GetArchList(dom)
+ self.Features = self.GetFeatureList(dom)
+
+ extern = XmlElement(dom, "/Extern/ModuleEntryPoint")
+ if extern is not None and extern is not '':
+ self.ModuleEntryPoints.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/ModuleUnloadImage")
+ if extern is not None and extern is not '':
+ self.ModuleUnloadImages.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/Constructor")
+ if extern is not None and extern is not '':
+ self.Constructors.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/Destructor")
+ if extern is not None and extern is not '':
+ self.Destructors.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/DriverBinding")
+ if extern is not None and extern is not '':
+ self.DriverBindings.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/ComponentName")
+ if extern is not None and extern is not '':
+ self.ComponentNames.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/DriverConfig")
+ if extern is not None and extern is not '':
+ self.DriverConfigs.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/DriverDiag")
+ if extern is not None and extern is not '':
+ self.DriverDiags.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/SetVirtualAddressMapCallBacks")
+ if extern is not None and extern is not '':
+ self.SetVirtualAddressMapCallBacks.append(XmlElementData(extern))
+
+ extern = XmlElement(dom, "/Extern/ExitBootServicesCallBack")
+ if extern is not None and extern is not '':
+ self.ExitBootServicesCallBacks.append(XmlElementData(extern))
+
+class IndustryStdHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
+ def __init__(self, workspace, package, dom):
+ FrameworkElement.IncludeFile.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, package, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.Path = os.path.normpath(XmlElementData(XmlElement(dom, "/IndustryStdHeader/IncludeHeader")))
+ self.Dir = os.path.dirname(self.Path)
+ self.Archs = self.GetArchList(dom)
+ self.ModuleTypes = self.GetModuleTypeList(dom)
+
+class PackageHeader(FrameworkElement.IncludeFile, SurfaceAreaElement):
+ def __init__(self, workspace, package, dom):
+ FrameworkElement.IncludeFile.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, package, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.Path = os.path.normpath(XmlElementData(dom))
+ self.Dir = os.path.dirname(self.Path)
+ self.ModuleType = XmlAttribute(dom, "ModuleType")
+
+class GuidDeclaration(FrameworkElement.Guid, SurfaceAreaElement):
+ def __init__(self, workspace, package, dom):
+ FrameworkElement.Guid.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, package, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.CName = XmlElementData(XmlElement(dom, "/Entry/C_Name"))
+ self.GuidValue = XmlElementData(XmlElement(dom, "/Entry/GuidValue")).upper()
+ self.Name = XmlAttribute(dom, "Name")
+ self.Types = self.GetGuidTypeList(dom)
+ self.Archs = self.GetArchList(dom)
+ self.ModuleTypes = self.GetModuleTypeList(dom)
+
+ def Postprocess(self):
+ pass
+
+class ProtocolDeclaration(GuidDeclaration, SurfaceAreaElement):
+ pass
+
+class PpiDeclaration(GuidDeclaration, SurfaceAreaElement):
+ pass
+
+class PcdDeclaration(FrameworkElement.Pcd, SurfaceAreaElement):
+ def __init__(self, workspace, package, dom):
+ FrameworkElement.Pcd.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, package, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.Types = XmlElementData(XmlElement(dom, "/PcdEntry/ValidUsage")).split()
+ self.CName = XmlElementData(XmlElement(dom, "/PcdEntry/C_Name"))
+ self.Token = XmlElementData(XmlElement(dom, "/PcdEntry/Token"))
+ self.TokenSpace = XmlElementData(XmlElement(dom, "/PcdEntry/TokenSpaceGuidCName"))
+ self.DatumType = XmlElementData(XmlElement(dom, "/PcdEntry/DatumType"))
+ self.Default = XmlElementData(XmlElement(dom, "/PcdEntry/DefaultValue"))
+ self.Archs = self.GetArchList(dom)
+ self.ModuleTypes= self.GetModuleTypeList(dom)
+
+class LibraryInstance(FrameworkElement.PlatformModule, SurfaceAreaElement):
+ def __init__(self, workspace, platformModule, dom):
+ FrameworkElement.PlatformModule.__init__(self)
+ SurfaceAreaElement.__init__(self, workspace, platformModule, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
+ self.Version = XmlAttribute(dom, "ModuleVersion")
+ self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
+ self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
+
+ def Postprocess(self):
+ self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
+ self._Elements["PackageGuid"], self._Elements["PackageVersion"])
+ self.Platform = self._Owner.Platform
+ self.Archs = self._Owner.Archs
+ self.Pcds = self._Owner.Pcds
+ self.BuildType = "lib"
+
+class PlatformModule(FrameworkElement.PlatformModule, SurfaceAreaElement):
+ def __init__(self, workspace, platform, dom):
+ FrameworkElement.PlatformModule.__init__(self)
+ self.Platform = platform
+ SurfaceAreaElement.__init__(self, workspace, platform, dom)
+
+ def Parse(self):
+ dom = self._Root
+ self.GuidValue = XmlAttribute(dom, "ModuleGuid").upper()
+ self.Version = XmlAttribute(dom, "ModuleVersion")
+ self.Archs = self.GetArchList(dom)
+
+ self._Elements["PackageGuid"] = XmlAttribute(dom, "PackageGuid").upper()
+ self._Elements["PackageVersion"] = XmlAttribute(dom, "PackageVersion")
+
+ libraryList = XmlList(dom, "/ModuleSA/Libraries/Instance")
+ for lib in libraryList:
+ self.Libraries.append(LibraryInstance(self._Workspace, self, lib))
+
+ dom = XmlElement(dom, "/ModuleSA/ModuleSaBuildOptions")
+ self.FvBindings = self.GetFvBindingList(XmlElement(dom, "/ModuleSaBuildOptions/FvBinding"))
+ self.FfsLayouts = XmlElementData(XmlElement(dom, "/ModuleSaBuildOptions/FfsFormatKey")).split()
+ self.BuildOptions = self.GetBuildOptionList(XmlElement(dom, "/ModuleSaBuildOptions/Options"))
+
+ def Postprocess(self):
+ self.Module = self._Workspace.GetModule(self.GuidValue, self.Version,
+ self._Elements["PackageGuid"], self._Elements["PackageVersion"])
+ if self.Module == "":
+ raise Exception("No module found: \n\t\tGUID=%s \n\t\tVERSION=%s \n\t\tPACKAGE_GUID=%s \n\t\tPACKAGE_VERSION=%s" % (
+ self.GuidValue, self.Version, self._Elements["PackageGuid"], self._Elements["PackageVersion"]))
+
+## def SetupEnvironment(self):
+## self.Environment = {
+## "ARCH" : "",
+## "MODULE_BUILD_TARGET" : "",
+## "SINGLE_MODULE_BUILD" : "",
+## "PLATFORM_PREBUILD" : "",
+## "PLATFORM_POSTBUILD" : "",
+## "LIBS" : "",
+## "SOURCE_FILES" : "",
+## "ENTRYPOINT" : "_ModuleEntryPoint",
+## } # name/value pairs
+## self.Environment["MODULE_BUILD_TARGET"] = "platform_module_build"
+
+class ModuleSurfaceArea(FrameworkElement.Module, SurfaceAreaElement):
+ def __init__(self, workspace, package, path):
+ FrameworkElement.Module.__init__(self)
+
+ self.Path = os.path.normpath(path)
+ self.Dir = os.path.dirname(self.Path)
+ self.FileBaseName,_ext = os.path.splitext(os.path.basename(self.Path))
+ self.Package = package
+ SurfaceAreaElement.__init__(self, workspace, package)
+
+ def _MsaHeader(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.Name = XmlElementData(XmlElement(dom, "/MsaHeader/ModuleName"))
+ self.Type = XmlElementData(XmlElement(dom, "/MsaHeader/ModuleType"))
+ self.GuidValue = XmlElementData(XmlElement(dom, "/MsaHeader/GuidValue")).upper()
+ self.Version = XmlElementData(XmlElement(dom, "/MsaHeader/Version"))
+
+ def _ModuleDefinitions(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.Archs = XmlElementData(XmlElement(dom, "/ModuleDefinitions/SupportedArchitectures")).split()
+ self.IsBinary = self.GetBoolean(XmlElement(dom, "/ModuleDefinitions/BinaryModule"))
+ self.BaseName = XmlElementData(XmlElement(dom, "/ModuleDefinitions/OutputFileBasename"))
+
+ def _LibraryClassDefinitions(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ lcList = []
+ for lc in XmlList(dom, "/LibraryClassDefinitions/LibraryClass"):
+ lcList.append(LibraryClass(self._Workspace, self, lc))
+ self._Elements["LibraryClassDefinitions"] = lcList
+
+ def _SourceFiles(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ srcList = []
+ for f in XmlList(dom, "/SourceFiles/Filename"):
+ srcList.append(SourceFile(self._Workspace, self, f))
+ self._Elements["SourceFiles"] = srcList
+
+ def _NonProcessedFiles(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ for f in XmlList(dom, "/NonProcessedFiles/Filename"):
+ self.NonProcessedFiles.append(SourceFile(self._Workspace, self, f))
+
+ def _PackageDependencies(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ pdList = []
+ for pkg in XmlList(dom, "/PackageDependencies/Package"):
+ pdList.append(PackageDependency(self._Workspace, self, pkg))
+ self._Elements["PackageDependencies"] = pdList
+
+ def _Protocols(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+
+ protocolList = []
+ for p in XmlList(dom, "/Protocols/Protocol"):
+ protocolList.append(Protocol(self._Workspace, self, p))
+ for p in XmlList(dom, "/Protocols/ProtocolNotify"):
+ protocolList.append(ProtocolNotify(self._Workspace, self, p))
+
+ self._Elements["Protocols"] = protocolList
+
+ def _Ppis(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+
+ ppiList = []
+ for p in XmlList(dom, "/PPIs/Ppi"):
+ ppiList.append(Ppi(self._Workspace, self, p))
+ for p in XmlList(dom, "/PPIs/PpiNotify"):
+ ppiList.append(PpiNotify(self._Workspace, self, p))
+
+ self._Elements["PPIs"] = ppiList
+
+ def _Guids(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ guidList = []
+ for g in XmlList(dom, "/Guids/GuidCNames"):
+ guidList.append(Guid(self._Workspace, self, g))
+ self._Elements["Guids"] = guidList
+
+ def _Externs(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.PcdIsDriver = self.GetBoolean(XmlElement(dom, "/Externs/PcdIsDriver"))
+ self.NeedsFlashMap_h = self.GetBoolean(XmlElement(dom, "/Externs/TianoR8FlashMap_h"))
+
+ externList = []
+ specs = FrameworkElement.Extern()
+ specs.Archs = self._Archs
+ externList.append(specs)
+ for spec in XmlList(dom, "/Externs/Specification"):
+ specs.Specifications.append(XmlElementData(spec))
+ for ext in XmlList(dom, "/Externs/Extern"):
+ externList.append(Extern(self._Workspace, self, ext))
+ self._Elements["Externs"] = externList
+
+ def _ModuleBuildOptions(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.BuildOptions = self.GetBuildOptionList(XmlElement(dom, "/ModuleBuildOptions/Options"))
+
+ def _UserExtensions(self, xpath):
+ domList = XmlList(self._Root, xpath)
+ if domList == []: return
+ for extension in domList:
+ userId = XmlAttribute(extension, "UserID")
+ identifier = XmlAttribute(extension, "Identifier")
+ if userId == '' or identifier == '':
+ raise Exception("No UserId or Identifier specified")
+ if userId != "TianoCore": continue
+ if identifier not in self.UserExtensions:
+ self.UserExtensions[identifier] = []
+
+ contentList = self.UserExtensions[identifier]
+ for node in extension.childNodes:
+ #print node.nodeType
+ contentList.append(node.cloneNode(True))
+
+ def Parse(self):
+ fileFullPath = self._Workspace.SubPath(os.path.dirname(self.Package.Path), self.Path)
+ self._Root = xml.dom.minidom.parse(fileFullPath)
+ assert self._Root.documentElement.tagName == "ModuleSurfaceArea"
+
+ # print " Parsing...",self.Path
+ self._MsaHeader("/ModuleSurfaceArea/MsaHeader")
+ self._ModuleDefinitions("/ModuleSurfaceArea/ModuleDefinitions")
+ self._PackageDependencies("/ModuleSurfaceArea/PackageDependencies")
+ self._LibraryClassDefinitions("/ModuleSurfaceArea/LibraryClassDefinitions")
+ self._SourceFiles("/ModuleSurfaceArea/SourceFiles")
+ self._NonProcessedFiles("/ModuleSurfaceArea/NonProcessedFiles")
+ self._Protocols("/ModuleSurfaceArea/Protocols")
+ self._Ppis("/ModuleSurfaceArea/Ppis")
+ self._Guids("/ModuleSurfaceArea/Guids")
+ self._Externs("/ModuleSurfaceArea/Externs")
+ self._ModuleBuildOptions("/ModuleSurfaceArea/ModuleBuildOptions")
+ self._UserExtensions("/ModuleSurfaceArea/UserExtensions")
+
+ def Postprocess(self):
+ # resolve package dependency
+ if self._Elements.has_key("PackageDependencies"):
+ for pd in self._Elements["PackageDependencies"]:
+ package = pd.Package
+ if self.Type not in package.PackageIncludes:
+ print "! Module type %s is not supported in the package %s" % (self.Type, package.Name)
+
+ for arch in pd.Archs:
+ if arch not in self.IncludePaths:
+ self.IncludePaths[arch] = []
+ self.IncludePaths[arch].append(package.SubPath("Include"))
+ self.IncludePaths[arch].append(package.SubPath("Include", arch.capitalize()))
+
+ if arch not in self.IncludeFiles:
+ self.IncludeFiles[arch] = []
+ if self.Type in package.PackageIncludes:
+ for path in package.PackageIncludes[self.Type]:
+ self.IncludeFiles[arch].append(package.SubPath(path))
+
+ # resolve library class
+ if self._Elements.has_key("LibraryClassDefinitions"):
+ for lc in self._Elements["LibraryClassDefinitions"]:
+ lc.Interface = self._Workspace.GetLibraryInterface(lc.Name)
+ if "ALWAYS_PRODUCED" in lc.Usage:
+ self.IsLibrary = True
+ lc.Interface.Instances.append(self)
+ else:
+ lc.Interface.Consumers.append(self)
+
+ for arch in lc.Archs:
+ if arch not in self.LibraryClasses:
+ self.LibraryClasses[arch] = []
+ self.LibraryClasses[arch].append(lc)
+
+ # expand source files
+ if self._Elements.has_key("SourceFiles"):
+ for src in self._Elements["SourceFiles"]:
+ for arch in src.Archs:
+ if arch not in self.SourceFiles:
+ self.SourceFiles[arch] = {}
+ if src.Type not in self.SourceFiles[arch]:
+ self.SourceFiles[arch][src.Type] = []
+ self.SourceFiles[arch][src.Type].append(src)
+
+ # expand guids
+ if self._Elements.has_key("Guids"):
+ for guid in self._Elements["Guids"]:
+ for arch in guid.Archs:
+ if arch not in self.Guids:
+ self.Guids[arch] = []
+ self.Guids[arch].append(guid)
+
+ # expand protocol
+ if self._Elements.has_key("Protocols"):
+ for protocol in self._Elements["Protocols"]:
+ for arch in protocol.Archs:
+ if arch not in self.Protocols:
+ self.Protocols[arch] = []
+ self.Protocols[arch].append(protocol)
+
+ # expand ppi
+ if self._Elements.has_key("PPIs"):
+ for ppi in self._Elements["PPIs"]:
+ for arch in ppi.Archs:
+ if arch not in self.Ppis:
+ self.Ppis[arch] = []
+ self.Ppis[arch].append(ppi)
+
+ # expand extern
+ if self._Elements.has_key("Externs"):
+ for extern in self._Elements["Externs"]:
+ for arch in extern.Archs:
+ if arch not in self.Externs:
+ self.Externs[arch] = []
+ self.Externs[arch].append(extern)
+## def SetupEnvironment(self):
+## self.Environment["MODULE"] = self.Name
+## self.Environment["MODULE_GUID"] = self.GuidValue
+## self.Environment["MODULE_VERSION"] = self.Version
+## self.Environment["MODULE_TYPE"] = self.Type
+## self.Environment["MODULE_FILE_BASE_NAME"] = os.path.basename(self.Path).split(".")[0]
+## self.Environment["MODULE_RELATIVE_DIR"] = os.path.dirname(self.Path)
+## self.Environment["BASE_NAME"] = self.OutputName
+
+class Workspace(FrameworkElement.Workspace, SurfaceAreaElement):
+ _Db = "Tools/Conf/FrameworkDatabase.db"
+ _Target = "Tools/Conf/Target.txt"
+ _PlatformBuildPath = "Tools/Conf/platform_build_path.txt"
+ _ModuleBuildPath = "Tools/Conf/module_build_path.txt"
+
+ def __init__(self, path, fpdList=None, msaList=None):
+ FrameworkElement.Workspace.__init__(self)
+ SurfaceAreaElement.__init__(self, self, None, None, False, False)
+ self.Path = os.path.normpath(path)
+ self.Dir = os.path.dirname(self.Path)
+ self._Elements["PlatformList"] = fpdList
+ self._Elements["ModuleList"] = msaList
+ self.Parse()
+ self.Postprocess()
+
+ def _FdbHeader(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.Name = XmlElementData(XmlElement(dom, "/FdbHeader/DatabaseName"))
+ self.GuidValue = XmlElementData(XmlElement(dom, "/FdbHeader/GuidValue")).upper()
+ self.Version = XmlElementData(XmlElement(dom, "/FdbHeader/Version"))
+
+ def _PackageList(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+
+ fileList = XmlList(dom, "/PackageList/Filename")
+ packages = []
+ for f in fileList:
+ packages.append(os.path.normpath(XmlElementData(f)))
+ self._Elements["PackageList"] = packages
+
+ def _PlatformList(self, xpath):
+ if len(self._Elements["PlatformList"]) > 0:
+ return
+
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+
+ fileList = XmlList(dom, "/PlatformList/Filename")
+ platforms = []
+ for f in fileList:
+ platforms.append(os.path.normpath(XmlElementData(f)))
+ self._Elements["PlatformList"] = platforms
+
+ def _FarList(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+
+ fileList = XmlList(dom, "/FarList/Filename")
+ fars = []
+ for f in fileList:
+ fars.append(os.path.normpath(XmlElementData(f)))
+ self._Elements["FarList"] = fars
+
+ def ParseWorkspaceDatabase(self):
+ # parse frameworkdatabase.db
+ self._Root = xml.dom.minidom.parse(self.SubPath(self._Db))
+ assert self._Root.documentElement.tagName == "FrameworkDatabase"
+
+ self._FdbHeader("/FrameworkDatabase/FdbHeader")
+ self._PackageList("/FrameworkDatabase/PackageList")
+ self._PlatformList("/FrameworkDatabase/PlatformList")
+ self._FarList("/FrameworkDatabase/FarList")
+
+ def ParseConfig(self):
+ # parse target.txt
+ self.ParseTargetConfig()
+ # parse tools_def.txt
+ self.ParseToolConfig()
+ # parse platform/module_build_path.txt
+
+ # active toolchain
+ # print self.TargetConfig
+ self.ActiveToolchain = self.TargetConfig["TOOL_CHAIN_TAG"]
+ if self.ActiveToolchain not in self.ToolConfig.Toolchains:
+ raise "Not supported tool chain tag %s" % self.ActiveToolchain
+
+ # active toolchain family
+ self.ActiveFamilies = []
+ for key in self.ToolConfig:
+ if self.ActiveToolchain in key and "FAMILY" in key:
+ family = self.ToolConfig[key]
+ if family not in self.ActiveFamilies:
+ self.ActiveFamilies.append(family)
+
+
+ def ParsePackage(self, packagePaths=None):
+ if packagePaths == None:
+ return
+
+ for packagePath in packagePaths:
+ self.Packages.append(PackageSurfaceArea(self, packagePath))
+
+ def ParsePlatform(self, platformPaths=None):
+ # Only one active platform is allowed
+ activePlatformPath = ""
+ if self.TargetConfig["ACTIVE_PLATFORM"] == "":
+ if platformPaths != None and len(platformPaths) == 1:
+ activePlatformPath = platformPaths[0]
+ else:
+ raise Exception("No active platform specified or implied!")
+ else:
+ activePlatformPath = os.path.normpath(self.TargetConfig["ACTIVE_PLATFORM"])
+
+ self.ActivePlatform = PlatformSurfaceArea(self, activePlatformPath)
+ self.Platforms.append(self.ActivePlatform)
+
+ def ParseTargetConfig(self):
+ self.TargetConfig = BuildConfig.TargetConfig(self.SubPath(self._Target))
+ # print self.TargetConfig
+
+ def ParseToolConfig(self):
+ self.ToolConfig = BuildConfig.ToolConfig(self.SubPath(self.TargetConfig["TOOL_CHAIN_CONF"]))
+
+ def GetModule(self, guid, version, packageGuid, packageVersion):
+ moduleGuidIndex = self.ModuleXref["GUID"]
+ if guid not in moduleGuidIndex:
+ print "! No module has GUID=" + guid
+ return ""
+
+ moduleVersionList = moduleGuidIndex[guid]
+ # print moduleVersionList
+ moduleList = []
+ module = ""
+ if version != "":
+ if version in moduleVersionList:
+ moduleList = moduleVersionList[version]
+ else:
+ return ""
+ else:
+ ## no version given, return the first one
+ version = "0.0"
+ for ver in moduleVersionList:
+ if ver > version: version = ver
+ moduleList = moduleVersionList[version]
+
+ if packageGuid == "":
+ ## if no package GUID given, just return the latest one
+ version = "0.0"
+ for m in moduleList:
+ if m.Package.Version > version:
+ version = m.Package.Version
+ module = m
+ else:
+ version = "0.0"
+ for m in moduleList:
+ if m.Package.GuidValue != packageGuid: continue
+ if packageVersion == "":
+ ## if no version given, just return the latest
+ if m.Package.Version > version:
+ version = m.Package.Version
+ module = m
+ elif packageVersion == m.Package.Version:
+ module = m
+ break;
+
+ return module
+
+ def GetModuleByPath(self, path):
+ ownerPackage = ""
+ ownerPackageFullPath = ""
+ for package in self.Packages:
+ ownerPackageFullPath = self.SubPath(package.Path)
+ if path.startswith(packageFullPath): break
+
+ if ownerPackage == "":
+ return ""
+
+ for module in ownerPackage.Modules:
+ moduleFullPath = os.path.join(ownerPackageFullPath, module.Path)
+ if moduleFullPath == path:
+ return module
+
+ return ""
+
+ def GetPackage(self, guid, version):
+ packageGuidIndex = self.PackageXref["GUID"]
+ if guid not in packageGuidIndex:
+ # raise Exception("No package has GUID=" + guid)
+ return ""
+
+ packageList = packageGuidIndex[guid]
+ package = ""
+ if version != "":
+ if version in packageList:
+ package = packageList[version]
+ else:
+ ## no version given, return the latest one
+ version = "0.0"
+ for ver in packageList:
+ if ver > version: version = ver
+ package = packageList[version]
+
+ return package
+
+ def GetPlatform(self, guid, version):
+ pass
+
+ def GetPlatformByPath(self, path):
+ for platform in self.Platforms:
+ platformFullPath = self.SubPath(platform.Path)
+ if platformFullPath == path:
+ return platform
+ return ""
+
+ def GetLibraryInterface(self, name):
+ if name not in self.LibraryInterfaceXref["NAME"]:
+ return ""
+ return self.LibraryInterfaceXref["NAME"][name]
+
+ def SubPath(self, *relativePathList):
+ return os.path.normpath(os.path.join(self.Path, *relativePathList))
+
+ def SetupCrossRef(self):
+ ##
+ ## setup platform cross reference as nest-dict
+ ## guid -> {version -> platform}
+ ##
+ ## platformList = self.Platforms
+ ## for p in platformList:
+ ## guid = p.GuidValue
+ ## version = p.Version
+ ## if guid not in self.PlatformIndex:
+ ## self.PlatformIndex[guid] = {}
+ ## if version in self.PlatformIndex[guid]:
+ ## raise Exception("Duplicate platform")
+ ## self.PlatformIndex[guid][version] = p
+
+ ##
+ ## setup package cross reference as nest-dict
+ ## guid -> {version -> package}
+ ## name -> [package list]
+ ## path -> package
+ ##
+ packageList = self.Packages
+ for p in packageList:
+ guid = p.GuidValue
+ version = p.Version
+ packageGuidIndex = self.PackageXref["GUID"]
+ if guid not in packageGuidIndex:
+ packageGuidIndex[guid] = {}
+ if version in packageGuidIndex[guid]:
+ raise Exception("Duplicate package: %s-%s [%s]" % p.Name, version, guid)
+ packageGuidIndex[guid][version] = p
+
+ packageNameIndex = self.PackageXref["NAME"]
+ name = p.Name
+ if name not in packageNameIndex:
+ packageNameIndex[name] = []
+ packageNameIndex[name].append(p)
+
+ packagePathIndex = self.PackageXref["PATH"]
+ path = p.Path
+ if path in packagePathIndex:
+ raise Exception("Duplicate package: %s %s" % p.Name, p.Path)
+ packagePathIndex[path] = p.Path
+
+ ##
+ ## setup library class cross reference as
+ ## library class name -> library class object
+ ##
+ for lcname in p.LibraryInterfaces:
+ if lcname in self.LibraryInterfaceXref["NAME"]:
+ raise Exception("Duplicate library class: %s in package %s" % (lcname, name))
+ lcInterface = p.LibraryInterfaces[lcname]
+ self.LibraryInterfaceXref["NAME"][lcname] = lcInterface
+
+ if lcInterface not in self.LibraryInterfaceXref["PATH"]:
+ self.LibraryInterfaceXref["PATH"][lcInterface] = []
+ self.LibraryInterfaceXref["PATH"][lcInterface].append(lcname)
+
+ ##
+ ## setup package cross reference as nest-dict
+ ## guid -> {version -> [module list]}
+ ## name -> [module list]
+ ## path -> module
+ for p in packageList:
+ p.ParseMsaFile()
+
+ moduleList = p.Modules
+ for m in moduleList:
+ name = m.Name
+ path = m.Path
+ guid = m.GuidValue
+ version = m.Version
+ moduleGuidIndex = self.ModuleXref["GUID"]
+ if guid not in moduleGuidIndex:
+ moduleGuidIndex[guid] = {}
+ else:
+ print "! Duplicate module GUID found:", guid, path
+
+ if version not in moduleGuidIndex[guid]:
+ moduleGuidIndex[guid][version] = []
+ if m in moduleGuidIndex[guid][version]:
+ raise Exception("Duplicate modules in the same package: %s-%s [%s]" % (name, version, guid))
+ moduleGuidIndex[guid][version].append(m)
+
+ modulePathIndex = self.ModuleXref["PATH"]
+ path = p.SubPath(m.Path)
+ if path in modulePathIndex:
+ raise Exception("Duplicate modules in the same package: %s %s" % (name, path))
+ modulePathIndex[path] = m
+
+ moduleNameIndex = self.ModuleXref["NAME"]
+ if name not in moduleNameIndex:
+ moduleNameIndex[name] = []
+ moduleNameIndex[name].append(m)
+
+ def GetToolDef(self, toolchain, target, arch, toolcode, attr):
+ return self.ToolConfig[(toolchain, target, arch, toolcode, attr)]
+
+ def Parse(self):
+ self.ParseConfig()
+ self.ParseWorkspaceDatabase()
+
+ def SetupBuild(self):
+ # active archs
+ self.ActiveArchs = self.TargetConfig["TARGET_ARCH"].split()
+ if self.ActiveArchs == []:
+ self.ActiveArchs = self.ActivePlatform.Archs
+
+ # active targets
+ self.ActiveTargets = self.TargetConfig["TARGET"].split()
+ if self.ActiveTargets == []:
+ self.ActiveTargets = self.ActivePlatform.Targets
+
+
+ # active modules
+ for msa in self._Elements["ModuleList"]:
+ module = self.GetModuleByPath(msa)
+ if module == "":
+ raise Exception(msa + " is not in any package!")
+ self.ActiveModules.append(module)
+ self.IndividualModuleBuild = True
+ if self.TargetConfig["MULTIPLE_THREAD"].upper() == "ENABLE":
+ self.MultiThreadBuild = True
+ if "MAX_CONCURRENT_THREAD_NUMBER" in self.TargetConfig:
+ self.ThreadCount = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
+ else:
+ self.ThreadCount = "1"
+
+ def Postprocess(self):
+ self.ParsePackage(self._Elements["PackageList"])
+ self.SetupCrossRef()
+ self.ParsePlatform(self._Elements["PlatformList"])
+ self.SetupBuild()
+
+## def SetupEnvironment(self):
+## config = BuildConfig.Config(self.SubPath(self._PlatformBuildPath))
+## for name in config:
+## self.Environment[name] = config[name]
+##
+## config = BuildConfig.Config(self.SubPath(self._ModuleBuildPath))
+## for name in config:
+## self.Environment[name] = config[name]
+##
+## multiThread = self.TargetConfig["MULTIPLE_THREAD"].upper()
+## threadNumber = self.TargetConfig["MAX_CONCURRENT_THREAD_NUMBER"]
+## if multiThread == "" or multiThread == "FALSE":
+## self.Environment["MULTIPLE_THREAD"] = False
+## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 1
+## else:
+## self.Environment["MULTIPLE_THREAD"] = True
+## if threadNumber != "":
+## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = threadNumber
+## else:
+## self.Environment["MAX_CONCURRENT_THREAD_NUMBER"] = 2
+
+class PackageSurfaceArea(FrameworkElement.Package, SurfaceAreaElement):
+ def __init__(self, workspace, path):
+ FrameworkElement.Package.__init__(self)
+
+ self.Path = os.path.normpath(path)
+ self.Dir = os.path.dirname(self.Path)
+ SurfaceAreaElement.__init__(self, workspace, workspace, None, True, True)
+
+ def _SpdHeader(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ self.Name = XmlElementData(XmlElement(dom, "/SpdHeader/PackageName"))
+ self.GuidValue = XmlElementData(XmlElement(dom, "/SpdHeader/GuidValue")).upper()
+ self.Version = XmlElementData(XmlElement(dom, "/SpdHeader/Version"))
+
+ def _PackageDefinitions(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ self.ReadOnly = XmlElementData(XmlElement(dom, "/PackageDefinitions/ReadOnly"))
+ self.Repackage = XmlElementData(XmlElement(dom, "/PackageDefinitions/RePackage"))
+
+ def _LibraryClassDeclarations(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ lcdList = XmlList(dom, "/LibraryClassDeclarations/LibraryClass")
+ lcds = []
+ for lc in lcdList:
+ lcds.append(LibraryDeclaration(self._Workspace, self, lc))
+ self._Elements["LibraryClassDeclarations"] = lcds
+
+ def _IndustryStdIncludes(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ headerList = XmlList(dom, "/IndustryStdIncludes/IndustryStdHeader")
+ headers = []
+ for h in headerList:
+ headers.append(IndustryStdHeader(self._Workspace, self, h))
+ self._Elements["IndustryStdIncludes"] = headers
+
+ def _MsaFiles(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ msaFileList = XmlList(dom, "/MsaFiles/Filename")
+ msaFiles = []
+ for msa in msaFileList:
+ filePath = os.path.normpath(XmlElementData(msa))
+ msaFiles.append(filePath)
+ self._Elements["MsaFiles"] = msaFiles
+
+ def _PackageHeaders(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ headerList = XmlList(dom, "/PackageHeaders/IncludePkgHeader")
+ headers = []
+ for h in headerList:
+ headers.append(PackageHeader(self._Workspace, self, h))
+ self._Elements["PackageHeaders"] = headers
+
+ def _GuidDeclarations(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ guidList = XmlList(dom, "/GuidDeclarations/Entry")
+ guids = []
+ for guid in guidList:
+ guids.append(GuidDeclaration(self._Workspace, self, guid))
+ self._Elements["GuidDeclarations"] = guids
+
+ def _ProtocolDeclarations(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ protocolList = XmlList(dom, "/ProtocolDeclarations/Entry")
+ protocols = []
+ for p in protocolList:
+ protocols.append(ProtocolDeclaration(self._Workspace, self, p))
+ self._Elements["ProtocolDeclarations"] = protocols
+
+ def _PpiDeclarations(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ ppiList = XmlList(dom, "/PpiDeclarations/Entry")
+ ppis = []
+ for p in ppiList:
+ ppis.append(PpiDeclaration(self._Workspace, self, p))
+ self._Elements["PpiDeclarations"] = ppis
+
+ def _PcdDeclarations(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ pcdList = XmlList(dom, "/PcdDeclarations/PcdEntry")
+ pcds = []
+ for p in pcdList:
+ pcds.append(PcdDeclaration(self._Workspace, self, p))
+ self._Elements["PcdDeclarations"] = pcds
+
+ def SubPath(self, *relativePathList):
+ return os.path.normpath(os.path.join(self.Dir, *relativePathList))
+
+ def Parse(self):
+ self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
+ assert self._Root.documentElement.tagName == "PackageSurfaceArea"
+
+ # print "Parsing...",self.Path
+ self._SpdHeader("/PackageSurfaceArea/SpdHeader")
+ self._PackageDefinitions("/PackageSurfaceArea/PackageDefinitions")
+ self._LibraryClassDeclarations("/PackageSurfaceArea/LibraryClassDeclarations")
+ self._IndustryStdIncludes("/PackageSurfaceArea/IndustryStdIncludes")
+ self._MsaFiles("/PackageSurfaceArea/MsaFiles")
+ self._PackageHeaders("/PackageSurfaceArea/PackageHeaders")
+ self._GuidDeclarations("/PackageSurfaceArea/GuidDeclarations")
+ self._ProtocolDeclarations("/PackageSurfaceArea/ProtocolDeclarations")
+ self._PpiDeclarations("/PackageSurfaceArea/PpiDeclarations")
+ self._PcdDeclarations("/PackageSurfaceArea/PcdDeclarations")
+
+ def Postprocess(self):
+ # setup guid, protocol, ppi
+ for guid in self._Elements["GuidDeclarations"]:
+ if guid.CName in self.Guids:
+ print "! Duplicate GUID CName (%s) in package %s" % (guid.CName, self.Path)
+ self.Guids[guid.CName] = guid
+
+ for protocol in self._Elements["ProtocolDeclarations"]:
+ if protocol.CName in self.Protocols:
+ print "! Duplicate Protocol CName (%s) in package %s" % (protocol.CName, self.Path)
+ self.Protocols[protocol.CName] = protocol
+
+ for ppi in self._Elements["PpiDeclarations"]:
+ if ppi.CName in self.Ppis:
+ print "! Duplicate PPI CName (%s) in package (%s)" % (ppi.CName, self.Path)
+ self.Ppis[ppi.CName] = ppi
+
+ # package header
+ for inc in self._Elements["PackageHeaders"]:
+ if inc.ModuleType not in self.PackageIncludes:
+ self.PackageIncludes[inc.ModuleType] = []
+ self.PackageIncludes[inc.ModuleType].append(inc.Path)
+
+ # library class
+ for lcd in self._Elements["LibraryClassDeclarations"]:
+ if lcd.Name in self.LibraryInterfaces:
+ raise "Duplicate library class: " + lcd.Name
+ self.LibraryInterfaces[lcd.Name] = lcd
+
+ # parse mas files
+ # self.ParseMsaFile()
+ # resolve RecommendedInstance
+
+ def ParseMsaFile(self):
+ for msaFilePath in self._Elements["MsaFiles"]:
+ self.Modules.append(ModuleSurfaceArea(self._Workspace, self, msaFilePath))
+
+class PlatformSurfaceArea(FrameworkElement.Platform, SurfaceAreaElement):
+ def __init__(self, workspace, path):
+ FrameworkElement.Platform.__init__(self)
+
+ self.Path = os.path.normpath(path)
+ self.Dir = os.path.dirname(self.Path)
+ SurfaceAreaElement.__init__(self, workspace)
+
+ def _PlatformHeader(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.Name = XmlElementData(XmlElement(dom, "/PlatformHeader/PlatformName"))
+ self.GuidValue = XmlElementData(XmlElement(dom, "/PlatformHeader/GuidValue")).upper()
+ self.Version = XmlElementData(XmlElement(dom, "/PlatformHeader/Version"))
+
+ def _PlatformDefinitions(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.Archs = XmlElementData(XmlElement(dom, "/PlatformDefinitions/SupportedArchitectures")).split()
+ if self.Archs == []:
+ raise Exception("No ARCH specified in platform " + self.Path)
+ self.Targets = XmlElementData(XmlElement(dom, "/PlatformDefinitions/BuildTargets")).split()
+ self.OutputPath = os.path.normpath(XmlElementData(XmlElement(dom, "/PlatformDefinitions/OutputDirectory")))
+
+ def _Flash(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+
+ def _FrameworkModules(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ moduleList = XmlList(dom, "/FrameworkModules/ModuleSA")
+ modules = []
+ for m in moduleList:
+ modules.append(PlatformModule(self._Workspace, self, m))
+ self._Elements["FrameworkModules"] = modules
+
+ def _DynamicPcdBuildDefinitions(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+
+ def _BuildOptions(self, xpath):
+ dom = XmlElement(self._Root, xpath)
+ if dom == '': return
+ self.BuildOptions = self.GetBuildOptionList(XmlElement(dom, "/BuildOptions/Options"))
+ # print self.BuildOptions
+
+ def _UserExtensions(self, xpath):
+ domList = XmlList(self._Root, xpath)
+ if domList == []: return
+ for extension in domList:
+ userId = XmlAttribute(extension, "UserID")
+ identifier = XmlAttribute(extension, "Identifier")
+
+ if userId == '' or identifier == '':
+ raise Exception("No UserId or Identifier specified")
+ if userId != "TianoCore": continue
+ if identifier not in self.UserExtensions:
+ self.UserExtensions[identifier] = []
+
+ contentList = self.UserExtensions[identifier]
+ for node in extension.childNodes:
+ # print node.nodeType
+ contentList.append(node.cloneNode(True))
+
+ def Parse(self):
+ self._Root = xml.dom.minidom.parse(self._Workspace.SubPath(self.Path))
+ assert self._Root.documentElement.tagName == "PlatformSurfaceArea"
+
+ self._PlatformHeader("/PlatformSurfaceArea/PlatformHeader")
+ self._PlatformDefinitions("/PlatformSurfaceArea/PlatformDefinitions")
+ self._Flash("/PlatformSurfaceArea/Flash")
+ self._FrameworkModules("/PlatformSurfaceArea/FrameworkModules")
+ self._DynamicPcdBuildDefinitions("/PlatformSurfaceArea/DynamicPcdBuildDefinitions")
+ self._BuildOptions("/PlatformSurfaceArea/BuildOptions")
+ self._UserExtensions("/PlatformSurfaceArea/UserExtensions")
+
+ def Postprocess(self):
+ # summarize all library modules for build
+ for module in self._Elements["FrameworkModules"]:
+ for arch in module.Archs:
+ if arch not in self.Modules:
+ self.Modules[arch] = []
+ self.Modules[arch].append(module)
+
+ if arch not in self.Libraries:
+ self.Libraries[arch] = []
+ for li in module.Libraries:
+ if li in self.Libraries[arch]: continue
+ self.Libraries[arch].append(li)
+
+ # FV
+ for fvName in module.FvBindings:
+ if fvName not in self.Fvs:
+ self.Fvs[fvName] = []
+ self.Fvs[fvName].append(module)
+ # build options
+ # user extension
+
+## def SetupEnvironment(self):
+## self.Environment["PLATFORM"] = self.Name
+## self.Environment["PLATFORM_GUID"] = self.GuidValue
+## self.Environment["PLATFORM_VERSION"] = self.Version
+## self.Environment["PLATFORM_RELATIVE_DIR"] = self.Path
+## self.Environment["PLATFORM_OUTPUT_DIR"] = self.OutputPath
+
+def PrintWorkspace(ws):
+ print "\nPlatforms:\n"
+ for guid in ws.PlatformXref["GUID"]:
+ for ver in ws.PlatformXref["GUID"][guid]:
+ platform = ws.PlatformXref["GUID"][guid][ver]
+ print " %s %s-%s" % (guid, platform.Name, ver)
+ for pm in platform.Modules:
+ print " %-40s %-10s <%s-%s>" % (pm.Module.Name+"-"+pm.Module.Version,
+ ListString(pm.Archs), pm.Module.Package.Name,
+ pm.Module.Package.Version)
+ for li in pm.Libraries:
+ print " %-47s <%s-%s>" % (li.Module.Name+"-"+li.Module.Version,
+ li.Module.Package.Name, li.Module.Package.Version)
+ print ""
+
+ print "\nPackages:\n"
+ for guid in ws.PackageXref["GUID"]:
+ for ver in ws.PackageXref["GUID"][guid]:
+ print " %s %s-%s" % (guid, ws.PackageXref["GUID"][guid][ver].Name, ver)
+
+ print "\nModules:\n"
+ for guid in ws.ModuleXref["GUID"]:
+ for ver in ws.ModuleXref["GUID"][guid]:
+ for module in ws.ModuleXref["GUID"][guid][ver]:
+ print " %s %-40s [%s-%s]" % (guid, module.Name+"-"+ver, module.Package.Name, module.Package.Version)
+ print " Depending on packages:"
+ for arch in module.IncludePaths:
+ print " ", arch, ":"
+ for path in module.IncludePaths[arch]:
+ print " ", path
+ print "\n"
+
+ for arch in module.IncludeFiles:
+ print " ", arch, ":"
+ for path in module.IncludeFiles[arch]:
+ print " ", path
+ print "\n"
+
+ print " Source files:"
+ for arch in module.SourceFiles:
+ print " ", arch, ":"
+ for type in module.SourceFiles[arch]:
+ for src in module.SourceFiles[arch][type]:
+ print " %-40s (%s)" % (src.Path, src.Type)
+ print "\n"
+ print "\nLibrary Classes:"
+ for name in ws.LibraryInterfaceXref["NAME"]:
+ lc = ws.LibraryInterfaceXref["NAME"][name]
+ pkgPath = os.path.dirname(lc.Package.Path)
+ print "\n [%s] <%s>" % (lc.Name, pkgPath + os.path.sep + lc.Path)
+
+ print " Produced By:"
+ for li in lc.Instances:
+ print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
+
+ print " Consumed By:"
+ for li in lc.Consumers:
+ print " %-40s <%s>" % (li.Name+"-"+li.Version, li.Package.SubPath(li.Path))
+
+ print "\nActive Platform:"
+ for arch in ws.ActivePlatform.Libraries:
+ print " Library Instances (%s) (%d libraries)" % (arch , len(ws.ActivePlatform.Libraries[arch]))
+ for li in ws.ActivePlatform.Libraries[arch]:
+ print " %s-%s (%s-%s)" % (li.Module.Name, li.Module.Version,
+ li.Module.Package.Name, li.Module.Package.Version)
+
+ for arch in ws.ActivePlatform.Modules:
+ print " Driver Modules (%s) (%d modules)" % (arch, len(ws.ActivePlatform.Modules[arch]))
+ for m in ws.ActivePlatform.Modules[arch]:
+ print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
+ m.Module.Package.Name, m.Module.Package.Version)
+
+ for fv in ws.ActivePlatform.Fvs:
+ print
+ print " Firmware Volume (%s) (%d modules)" % (fv, len(ws.ActivePlatform.Fvs[fv]))
+ for m in ws.ActivePlatform.Fvs[fv]:
+ print " %s-%s (%s-%s)" % (m.Module.Name, m.Module.Version,
+ m.Module.Package.Name, m.Module.Package.Version)
+
+# for test
+if __name__ == "__main__":
+ # os.environ["WORKSPACE"]
+ workspacePath = os.getenv("WORKSPACE", os.getcwd())
+ saFile = ""
+ if len(sys.argv) <= 1:
+ saFile = os.path.join(workspacePath, "Tools/Conf/FrameworkDatabase.db")
+ else:
+ saFile = sys.argv[1]
+
+ print "Parsing ... %s\n" % saFile
+
+ startTime = time.clock()
+ sa = Workspace(workspacePath, [], [])
+## dbak = None
+## if os.path.exists("workspace.bak"):
+## dbak = shelve.open("workspace.bak", protocol=2)
+## sa = dbak.db
+## dbak.close()
+## else:
+## sa = FrameworkDatabase(saFile)
+## dbak = shelve.open("workspace.bak", protocol=2)
+## dbak.db = sa
+## dbak.close()
+ # sa = PackageSurfaceArea(saFile)
+ # sa = PlatformSurfaceArea(saFile)
+ # sa = ModuleSurfaceArea(saFile)
+ # print sa
+
+ PrintWorkspace(sa)
+ print "\n[Finished in %fs]" % (time.clock() - startTime)
+
diff --git a/Tools/Python/buildgen/XmlRoutines.py b/Tools/Python/buildgen/XmlRoutines.py
new file mode 100644
index 0000000000..8d659c4372
--- /dev/null
+++ b/Tools/Python/buildgen/XmlRoutines.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+"""This is an XML API that uses a syntax similar to XPath, but it is written in
+ standard python so that no extra python packages are required to use it."""
+
+import xml.dom.minidom
+
+def XmlList(Dom, String):
+ """Get a list of XML Elements using XPath style syntax."""
+ if String == "" or Dom == None or not isinstance(Dom, xml.dom.Node):
+ return []
+
+ if String[0] == "/":
+ String = String[1:]
+
+ if Dom.nodeType==Dom.DOCUMENT_NODE:
+ Dom = Dom.documentElement
+
+ tagList = String.split('/')
+ nodes = [Dom]
+ childNodes = []
+ index = 0
+ end = len(tagList) - 1
+ while index <= end:
+ for node in nodes:
+ if node.nodeType == node.ELEMENT_NODE and node.tagName == tagList[index]:
+ if index < end:
+ childNodes.extend(node.childNodes)
+ else:
+ childNodes.append(node)
+
+ nodes = childNodes
+ childNodes = []
+ index += 1
+
+ return nodes
+
+def XmlElement (Dom, String):
+ """Return a single element that matches the String which is XPath style syntax."""
+ if String == "" or Dom == None or not isinstance(Dom, xml.dom.Node):
+ return ""
+
+ if String[0] == "/":
+ String = String[1:]
+
+ if Dom.nodeType==Dom.DOCUMENT_NODE:
+ Dom = Dom.documentElement
+
+ tagList = String.split('/')
+ childNodes = [Dom]
+ index = 0
+ end = len(tagList) - 1
+ while index <= end:
+ for node in childNodes:
+ if node.nodeType == node.ELEMENT_NODE and node.tagName == tagList[index]:
+ if index < end:
+ childNodes = node.childNodes
+ else:
+ return node
+ break
+
+ index += 1
+
+ return ""
+
+def XmlElementData (Dom):
+ """Get the text for this element."""
+ if Dom == None or Dom == '' or Dom.firstChild == None:
+ return ''
+
+ return Dom.firstChild.data.strip(' ')
+
+def XmlAttribute (Dom, String):
+ """Return a single attribute that named by String."""
+ if Dom == None or Dom == '':
+ return ''
+
+ try:
+ return Dom.getAttribute(String).strip(' ')
+ except:
+ return ''
+
+def XmlTopTag(Dom):
+ """Return the name of the Root or top tag in the XML tree."""
+ if Dom == None or Dom == '' or Dom.firstChild == None:
+ return ''
+ return Dom.firstChild.nodeName
+
+
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+if __name__ == '__main__':
+
+ # Nothing to do here. Could do some unit tests.
+ pass
diff --git a/Tools/Python/buildgen/module_build_path.txt b/Tools/Python/buildgen/module_build_path.txt
new file mode 100644
index 0000000000..e5c8ed103d
--- /dev/null
+++ b/Tools/Python/buildgen/module_build_path.txt
@@ -0,0 +1,5 @@
+BIN_DIR=${PLATFORM_BUILD_DIR}/${ARCH}
+MODULE_BUILD_DIR=${BIN_DIR}/${PACKAGE_RELATIVE_DIR}/${MODULE_RELATIVE_DIR}/${MODULE_FILE_BASE_NAME}
+DEST_DIR_OUTPUT=${MODULE_BUILD_DIR}/OUTPUT
+DEST_DIR_DEBUG=${MODULE_BUILD_DIR}/DEBUG
+
diff --git a/Tools/Python/buildgen/platform_build_path.txt b/Tools/Python/buildgen/platform_build_path.txt
new file mode 100644
index 0000000000..1218ac0ff8
--- /dev/null
+++ b/Tools/Python/buildgen/platform_build_path.txt
@@ -0,0 +1,5 @@
+BUILD_DIR=${WORKSPACE_DIR}/${PLATFORM_OUTPUT_DIR}
+PLATFORM_BUILD_DIR=${BUILD_DIR}/${TARGET}_${TOOLCHAIN}
+TARGET_DIR=${PLATFORM_BUILD_DIR}
+FV_DIR=${TARGET_DIR}/FV
+