Python script for generating build files for platform and modules, which uses the...
authorjwang36 <jwang36@de2fecce-e211-0410-80a6-f3fac2684e05>
Mon, 22 Jan 2007 09:59:07 +0000 (09:59 +0000)
committerjwang36 <jwang36@de2fecce-e211-0410-80a6-f3fac2684e05>
Mon, 22 Jan 2007 09:59:07 +0000 (09:59 +0000)
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.tianocore.org/svn/edk2/trunk@2278 de2fecce-e211-0410-80a6-f3fac2684e05

edk2/Tools/Python/buildgen/AntTasks.py [new file with mode: 0644]
edk2/Tools/Python/buildgen/BuildConfig.py [new file with mode: 0644]
edk2/Tools/Python/buildgen/BuildFile.py [new file with mode: 0644]
edk2/Tools/Python/buildgen/FrameworkElement.py [new file with mode: 0644]
edk2/Tools/Python/buildgen/SurfaceAreaElement.py [new file with mode: 0644]
edk2/Tools/Python/buildgen/XmlRoutines.py [new file with mode: 0644]
edk2/Tools/Python/buildgen/module_build_path.txt [new file with mode: 0644]
edk2/Tools/Python/buildgen/platform_build_path.txt [new file with mode: 0644]

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