public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 1/6] .azurepipelines: Add Platform CI template
       [not found] <20200420191216.24572-1-michael.kubacki@outlook.com>
@ 2020-04-20 19:12 ` Michael Kubacki
  2020-04-24 20:22   ` [EXTERNAL] [edk2-devel] " Bret Barkelew
  2020-04-20 19:12 ` [PATCH v2 2/6] ArmVirtPkg: Add Platform CI and configuration for Core CI Michael Kubacki
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Michael Kubacki @ 2020-04-20 19:12 UTC (permalink / raw)
  To: devel; +Cc: Sean Brogan, Bret Barkelew, Michael D Kinney, Liming Gao

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570

Add template for Platform CI steps for a Pytools based build.
Add README to describe the template and how to use it.
Add helpful information for working with azurepipelines, templates, and
lessons learned.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 .azurepipelines/ReadMe.md                              |  50 ++++++++
 .azurepipelines/templates/ReadMe.md                    |  59 +++++++++
 .azurepipelines/templates/platform-build-run-steps.yml | 134 ++++++++++++++++++++
 3 files changed, 243 insertions(+)

diff --git a/.azurepipelines/ReadMe.md b/.azurepipelines/ReadMe.md
new file mode 100644
index 000000000000..cf57d282c197
--- /dev/null
+++ b/.azurepipelines/ReadMe.md
@@ -0,0 +1,50 @@
+# Azure DevOps Pipelines
+
+These yml files are used to provide CI builds using the Azure DevOps Pipeline Service.
+Most of the CI leverages edk2-pytools to support cross platform building and execution.
+
+## Core CI
+
+Focused on building and testing all packages in Edk2 without an actual target platform.
+
+See `.pytools/ReadMe.py` for more details
+
+## Platform CI
+
+Focused on building a single target platform and confirming functionality on that platform.
+
+## Conventions
+
+* Files extension should be *.yml.  *.yaml is also supported but in Edk2 we use those for our package configuration.
+* Platform CI files should be in the `<PlatformPkg>/.azurepipelines` folder.
+* Core CI files are in the root folder.
+* Shared templates are in the `templates` folder.
+* Top level CI files should be named `<host os>-<tool_chain_tag>.yml`
+
+## Links
+
+* Basic Azure Landing Site - https://docs.microsoft.com/en-us/azure/devops/pipelines/?view=azure-devops
+* Pipeline jobs - https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml
+* Pipeline yml scheme - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema
+* Pipeline expression - https://docs.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops
+* PyTools - https://github.com/tianocore/edk2-pytool-extensions and https://github.com/tianocore/edk2-pytool-library
+
+## Lessons Learned
+
+### Templates and parameters
+
+They are great but evil.  If they are used as part of determining the steps of a build they must resolve before the build starts.  They can not use variables set in a yml or determined as part of a matrix.  If they are used in a step then they can be bound late.
+
+### File matching patterns
+
+On Linux this can hang if there are too many files in the search list.
+
+### Templates and file splitting
+
+Suggestion is to do one big yaml file that does what you want for one of your targets.  Then do the second one and find the deltas.  From that you can start to figure out the right split of files, steps, jobs.
+
+### Conditional steps
+
+If you want the step to show up in the log but not run, use a step conditional. This is great when a platform doesn't currently support a feature but you want the builders to know that the features exists and maybe someday it will.
+
+If you want the step to not show up use a template step conditional wrapper.  Beware this will be evaluated early (at build start).  This can hide things not needed on a given OS for example.
diff --git a/.azurepipelines/templates/ReadMe.md b/.azurepipelines/templates/ReadMe.md
new file mode 100644
index 000000000000..fa433e3ef597
--- /dev/null
+++ b/.azurepipelines/templates/ReadMe.md
@@ -0,0 +1,59 @@
+# CI Templates
+
+This folder contains azure pipeline yml templates for "Core" and "Platform" Continuous Integration and PR validation.
+
+## Common CI templates
+
+### basetools-build-steps.yml
+
+This template compiles the Edk2 basetools from source.  The steps in this template are
+conditional and will only run if variable `pkg_count` is greater than 0.
+
+It also has two conditional steps only used when the toolchain contains GCC. These two steps
+use `apt` to update the system packages and add those necessary for Edk2 builds.
+
+## Core CI templates
+
+### pr-gate-build-job.yml
+
+This templates contains the jobs and most importantly the matrix of which packages and
+targets to run for Core CI.
+
+### pr-gate-steps.yml
+
+This template is the main Core CI template.  It controls all the steps run and is responsible for most functionality of the Core CI process.  This template sets
+the `pkg_count` variable using the `stuart_pr_eval` tool when the
+build type is "pull request"
+
+### spell-check-prereq-steps.yml
+
+This template installs the node based tools used by the spell checker plugin. The steps
+in this template are conditional and will only run if variable `pkg_count` is greater than 0.
+
+## Platform CI templates
+
+### platform-build-run-steps.yml
+
+This template makes heavy use of pytools to build and run a platform in the Edk2 repo
+
+Also uses basetools-build-steps.yml to compile basetools
+
+#### Special Notes
+
+* For a build type of pull request it will conditionally build if the patches change files that impact the platform.
+  * uses `stuart_pr_eval` to determine impact
+* For manual builds or CI builds it will always build the platform
+* It compiles basetools from source
+* Will use `stuart_build --FlashOnly` to attempt to run the built image if the `Run` parameter is set.
+* See the parameters block for expected configuration options
+* Parameter `extra_install_step` allows the caller to insert extra steps.  This is useful if additional dependencies, tools, or other things need to be installed.  Here is an example of installing qemu on Windows.
+
+    ``` yaml
+    steps:
+    - template: ../../.azurepipelines/templates/build-run-steps.yml
+      parameters:
+        extra_install_step:
+        - powershell: choco install qemu; Write-Host "##vso[task.prependpath]c:\Program Files\qemu"
+          displayName: Install QEMU and Set QEMU on path # friendly name displayed in the UI
+          condition: and(gt(variables.pkg_count, 0), succeeded())
+    ```
diff --git a/.azurepipelines/templates/platform-build-run-steps.yml b/.azurepipelines/templates/platform-build-run-steps.yml
new file mode 100644
index 000000000000..ebf674bfc7d8
--- /dev/null
+++ b/.azurepipelines/templates/platform-build-run-steps.yml
@@ -0,0 +1,134 @@
+
+## @file
+# File steps.yml
+#
+# template file containing the steps to build
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+parameters:
+- name: tool_chain_tag
+  type: string
+  default: ''
+- name: build_pkg
+  type: string
+  default: ''
+- name: build_target
+  type: string
+  default: ''
+- name: build_arch
+  type: string
+  default: ''
+- name: build_file
+  type: string
+  default: ''
+- name: build_flags
+  type: string
+  default: ''
+- name: run_flags
+  type: string
+  default: ''
+
+- name: extra_install_step
+  type: stepList
+  default: []
+
+steps:
+- checkout: self
+  clean: true
+  fetchDepth: 1
+
+- task: UsePythonVersion@0
+  inputs:
+    versionSpec: "3.8.x"
+    architecture: "x64"
+
+- script: pip install -r pip-requirements.txt --upgrade
+  displayName: 'Install/Upgrade pip modules'
+
+# Set default
+- bash: echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
+
+# trim the package list if this is a PR
+- task: CmdLine@1
+  displayName: Check if ${{ parameters.build_pkg }} need testing
+  inputs:
+    filename: stuart_pr_eval
+    arguments: -c ${{ parameters.build_file }} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} --pr-target origin/$(System.PullRequest.targetBranch) --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
+  condition: eq(variables['Build.Reason'], 'PullRequest')
+
+ # Setup repo
+- task: CmdLine@1
+  displayName: Setup
+  inputs:
+    filename: stuart_setup
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
+  condition: and(gt(variables.pkg_count, 0), succeeded())
+
+# Stuart Update
+- task: CmdLine@1
+  displayName: Update
+  inputs:
+    filename: stuart_update
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
+  condition: and(gt(variables.pkg_count, 0), succeeded())
+
+# build basetools
+#   do this after setup and update so that code base dependencies
+#   are all resolved.
+- template: basetools-build-steps.yml
+  parameters:
+    tool_chain_tag: ${{ parameters.tool_chain_tag }}
+
+# Potential Extra steps
+- ${{ parameters.extra_install_step }}
+
+# Build
+- task: CmdLine@1
+  displayName: Build
+  inputs:
+    filename: stuart_build
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
+  condition: and(gt(variables.pkg_count, 0), succeeded())
+
+# Run
+- task: CmdLine@1
+  displayName: Run to shell
+  inputs:
+    filename: stuart_build
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}} ${{ parameters.run_flags }} --FlashOnly
+  condition: and(and(gt(variables.pkg_count, 0), succeeded()), eq(variables['Run'], true))
+  timeoutInMinutes: 1
+
+# Copy the build logs to the artifact staging directory
+- task: CopyFiles@2
+  displayName: "Copy build logs"
+  inputs:
+    targetFolder: "$(Build.ArtifactStagingDirectory)"
+    SourceFolder: "Build"
+    contents: |
+      BUILDLOG_*.txt
+      BUILDLOG_*.md
+      CI_*.txt
+      CI_*.md
+      CISETUP.txt
+      SETUPLOG.txt
+      UPDATE_LOG.txt
+      PREVALLOG.txt
+      TestSuites.xml
+      **/BUILD_TOOLS_REPORT.html
+      **/OVERRIDELOG.TXT
+      BASETOOLS_BUILD*.*
+    flattenFolders: true
+  condition: succeededOrFailed()
+
+# Publish build artifacts to Azure Artifacts/TFS or a file share
+- task: PublishBuildArtifacts@1
+  continueOnError: true
+  displayName: "Publish build logs"
+  inputs:
+    pathtoPublish: "$(Build.ArtifactStagingDirectory)"
+    artifactName: "Build Logs $(System.JobName)"
+  condition: succeededOrFailed()
-- 
2.16.3.windows.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 2/6] ArmVirtPkg: Add Platform CI and configuration for Core CI
       [not found] <20200420191216.24572-1-michael.kubacki@outlook.com>
  2020-04-20 19:12 ` [PATCH v2 1/6] .azurepipelines: Add Platform CI template Michael Kubacki
@ 2020-04-20 19:12 ` Michael Kubacki
  2020-04-24 20:22   ` [EXTERNAL] [edk2-devel] " Bret Barkelew
  2020-04-20 19:12 ` [PATCH v2 3/6] EmulatorPkg: " Michael Kubacki
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Michael Kubacki @ 2020-04-20 19:12 UTC (permalink / raw)
  To: devel; +Cc: Laszlo Ersek, Ard Biesheuvel, Leif Lindholm

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570

Add new Azure Pipeline definitions to build and run ArmVirtPkg with:
  * Ubuntu GCC5
Add PyTool based build of ArmVirtPkg
Add extdep for managing the iasl dependency
Add ArmVirtPkg.ci.yaml for Core CI
Add ReadMe.rst for status, details, and instructions

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 ArmVirtPkg/ArmVirtPkg.ci.yaml                         | 103 ++++++++
 ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml |  89 +++++++
 ArmVirtPkg/PlatformCI/PlatformBuild.py                | 276 ++++++++++++++++++++
 ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml               |  21 ++
 ArmVirtPkg/ReadMe.rst                                 | 139 ++++++++++
 5 files changed, 628 insertions(+)

diff --git a/ArmVirtPkg/ArmVirtPkg.ci.yaml b/ArmVirtPkg/ArmVirtPkg.ci.yaml
new file mode 100644
index 000000000000..4553725ee528
--- /dev/null
+++ b/ArmVirtPkg/ArmVirtPkg.ci.yaml
@@ -0,0 +1,103 @@
+## @file
+# Core CI configuration for ArmVirtPkg
+#
+# ArmVirtPkg is part of Platform Ci for builds so this is only
+# used for code analysis.
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+    ## options defined .pytool/Plugin/CompilerPlugin
+    "CompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+    "HostUnitTestCompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/CharEncodingCheck
+    "CharEncodingCheck": {
+        "IgnoreFiles": []
+    },
+
+    ## options defined .pytool/Plugin/DependencyCheck
+    "DependencyCheck": {
+        "AcceptableDependencies": [
+            "MdePkg/MdePkg.dec",
+            "MdeModulePkg/MdeModulePkg.dec",
+            "ArmVirtPkg/ArmVirtPkg.dec",
+            "NetworkPkg/NetworkPkg.dec",
+            "ArmPkg/ArmPkg.dec",
+            "OvmfPkg/OvmfPkg.dec",
+            "EmbeddedPkg/EmbeddedPkg.dec",
+            "ArmPlatformPkg/ArmPlatformPkg.dec",
+            "SecurityPkg/SecurityPkg.dec",
+            "ShellPkg/ShellPkg.dec"  #Is this ok?
+        ],
+        # For host based unit tests
+        "AcceptableDependencies-HOST_APPLICATION":[
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+        ],
+        # For UEFI shell based apps
+        "AcceptableDependencies-UEFI_APPLICATION":[
+
+        ],
+        "IgnoreInf": []
+    },
+
+    ## options defined .pytool/Plugin/DscCompleteCheck
+    "DscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": ""  # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+    "HostUnitTestDscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/GuidCheck
+    "GuidCheck": {
+        "IgnoreGuidName": [],
+        "IgnoreGuidValue": [],
+        "IgnoreFoldersAndFiles": [],
+        "IgnoreDuplicates": [],
+    },
+
+    ## options defined .pytool/Plugin/LibraryClassCheck
+    "LibraryClassCheck": {
+        "IgnoreHeaderFile": []
+    },
+
+    ## options defined .pytool/Plugin/SpellCheck
+    "SpellCheck": {
+        "AuditOnly": False,           # Fails right now with over 270 errors
+        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
+        "ExtendWords": [
+            "setjump",
+            "plong",
+            "lparam",
+            "lpdword",
+            "lpthread",
+            "lresult",
+            "bootable",
+            "bsymbolic",
+            "endiannness",
+            "fvmain",
+            "multiboot",
+            "qemu's",
+            "ramdisk",
+            "ramfb",
+            "unbootable",
+            "virt's",
+            "werror",
+            "xenio"
+        ],           # words to extend to the dictionary for this package
+        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
+        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+    }
+}
diff --git a/ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
new file mode 100644
index 000000000000..b9452ec5bfaf
--- /dev/null
+++ b/ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -0,0 +1,89 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: ArmVirtQemu
+# OS: Ubuntu
+# Toolchain: GCC5
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'ArmVirtPkg'
+      vm_image: 'ubuntu-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE QEMU_HEADLESS=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          QEMU_AARCH64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "AARCH64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_AARCH64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "AARCH64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_AARCH64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "AARCH64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_ARM_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "ARM"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_ARM_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "ARM"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_ARM_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "ARM"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: GCC5
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        extra_install_step:
+        - bash: sudo apt-get install qemu
+          displayName: Install qemu
+          condition: and(gt(variables.pkg_count, 0), succeeded())
diff --git a/ArmVirtPkg/PlatformCI/PlatformBuild.py b/ArmVirtPkg/PlatformCI/PlatformBuild.py
new file mode 100644
index 000000000000..dff653e919eb
--- /dev/null
+++ b/ArmVirtPkg/PlatformCI/PlatformBuild.py
@@ -0,0 +1,276 @@
+# @file
+# Script to Build ArmVirtPkg UEFI firmware
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+import logging
+import io
+
+from edk2toolext.environment import shell_environment
+from edk2toolext.environment.uefi_build import UefiBuilder
+from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
+from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
+from edk2toolext.invocables.edk2_update import UpdateSettingsManager
+from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
+from edk2toollib.utility_functions import RunCmd
+from edk2toollib.utility_functions import GetHostInfo
+
+# ####################################################################################### #
+#                                Common Configuration                                     #
+# ####################################################################################### #
+
+
+class CommonPlatform():
+    ''' Common settings for this platform.  Define static data here and use
+        for the different parts of stuart
+    '''
+    PackagesSupported = ("ArmVirtPkg",)
+    ArchSupported = ("AARCH64", "ARM")
+    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
+    Scopes = ('armvirt', 'edk2-build')
+    WorkspaceRoot = os.path.realpath(os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
+
+    # ####################################################################################### #
+    #                         Configuration for Update & Setup                                #
+    # ####################################################################################### #
+
+
+class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
+
+    def GetPackagesSupported(self):
+        ''' return iterable of edk2 packages supported by this build.
+        These should be edk2 workspace relative paths '''
+        return CommonPlatform.PackagesSupported
+
+    def GetArchitecturesSupported(self):
+        ''' return iterable of edk2 architectures supported by this build '''
+        return CommonPlatform.ArchSupported
+
+    def GetTargetsSupported(self):
+        ''' return iterable of edk2 target tags supported by this build '''
+        return CommonPlatform.TargetsSupported
+
+    def GetRequiredSubmodules(self):
+        ''' return iterable containing RequiredSubmodule objects.
+        If no RequiredSubmodules return an empty iterable
+        '''
+        rs = []
+
+        # intentionally declare this one with recursive false to avoid overhead
+        rs.append(RequiredSubmodule(
+            "CryptoPkg/Library/OpensslLib/openssl", False))
+
+        # To avoid maintenance of this file for every new submodule
+        # lets just parse the .gitmodules and add each if not already in list.
+        # The GetRequiredSubmodules is designed to allow a build to optimize
+        # the desired submodules but it isn't necessary for this repository.
+        result = io.StringIO()
+        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
+        # Cmd output is expected to look like:
+        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
+        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
+        if ret == 0:
+            for line in result.getvalue().splitlines():
+                _, _, path = line.partition(" ")
+                if path is not None:
+                    if path not in [x.path for x in rs]:
+                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
+        return rs
+
+    def SetArchitectures(self, list_of_requested_architectures):
+        ''' Confirm the requests architecture list is valid and configure SettingsManager
+        to run only the requested architectures.
+
+        Raise Exception if a list_of_requested_architectures is not supported
+        '''
+        unsupported = set(list_of_requested_architectures) - \
+            set(self.GetArchitecturesSupported())
+        if(len(unsupported) > 0):
+            errorString = (
+                "Unsupported Architecture Requested: " + " ".join(unsupported))
+            logging.critical(errorString)
+            raise Exception(errorString)
+        self.ActualArchitectures = list_of_requested_architectures
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+
+        scopes = CommonPlatform.Scopes
+        ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
+
+        if GetHostInfo().os.upper() == "LINUX" and ActualToolChainTag.upper().startswith("GCC"):
+            if "AARCH64" in self.ActualArchitectures:
+                scopes += ("gcc_aarch64_linux",)
+            if "ARM" in self.ActualArchitectures:
+                scopes += ("gcc_arm_linux",)
+        return scopes
+
+    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
+        ''' Filter other cases that this package should be built
+        based on changed files. This should cover things that can't
+        be detected as dependencies. '''
+        build_these_packages = []
+        possible_packages = potentialPackagesList.copy()
+        for f in changedFilesList:
+            # BaseTools files that might change the build
+            if "BaseTools" in f:
+                if os.path.splitext(f) not in [".txt", ".md"]:
+                    build_these_packages = possible_packages
+                    break
+
+            # if the azure pipeline platform template file changed
+            if "platform-build-run-steps.yml" in f:
+                build_these_packages = possible_packages
+                break
+
+
+        return build_these_packages
+
+    def GetPlatformDscAndConfig(self) -> tuple:
+        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
+        any of the changes will be built in the dsc.
+
+        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
+        '''
+        return (os.path.join("ArmVirtPkg", "ArmVirtQemu.dsc"), {})
+
+
+    # ####################################################################################### #
+    #                         Actual Configuration for Platform Build                         #
+    # ####################################################################################### #
+
+
+class PlatformBuilder(UefiBuilder, BuildSettingsManager):
+    def __init__(self):
+        UefiBuilder.__init__(self)
+
+    def AddCommandLineOptions(self, parserObj):
+        ''' Add command line options to the argparser '''
+        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="AARCH64",
+                               help="Optional - Architecture to build.  Default = AARCH64")
+
+    def RetrieveCommandLineOptions(self, args):
+        '''  Retrieve command line options from the argparser '''
+
+        shell_environment.GetBuildVars().SetValue(
+            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
+
+        shell_environment.GetBuildVars().SetValue(
+            "ACTIVE_PLATFORM", "ArmVirtPkg/ArmVirtQemu.dsc", "From CmdLine")
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetPackagesPath(self):
+        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
+        return ()
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        scopes = CommonPlatform.Scopes
+        ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
+        Arch = shell_environment.GetBuildVars().GetValue("TARGET_ARCH", "")
+
+        if GetHostInfo().os.upper() == "LINUX" and ActualToolChainTag.upper().startswith("GCC"):
+            if "AARCH64" == Arch:
+                scopes += ("gcc_aarch64_linux",)
+            elif "ARM" == Arch:
+                scopes += ("gcc_arm_linux",)
+        return scopes
+
+    def GetName(self):
+        ''' Get the name of the repo, platform, or product being build '''
+        ''' Used for naming the log file, among others '''
+        # check the startup nsh flag and if set then rename the log file.
+        # this helps in CI so we don't overwrite the build log since running
+        # uses the stuart_build command.
+        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
+            return "ArmVirtPkg_With_Run"
+        return "ArmVirtPkg"
+
+    def GetLoggingLevel(self, loggerType):
+        ''' Get the logging level for a given type
+        base == lowest logging level supported
+        con  == Screen logging
+        txt  == plain text file logging
+        md   == markdown file logging
+        '''
+        return logging.DEBUG
+
+    def SetPlatformEnv(self):
+        logging.debug("PlatformBuilder SetPlatformEnv")
+        self.env.SetValue("PRODUCT_NAME", "ArmVirtQemu", "Platform Hardcoded")
+        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
+        self.env.SetValue("QEMU_HEADLESS", "FALSE", "Default to false")
+        return 0
+
+    def PlatformPreBuild(self):
+        return 0
+
+    def PlatformPostBuild(self):
+        return 0
+
+    def FlashRomImage(self):
+        VirtualDrive = os.path.join(self.env.GetValue(
+            "BUILD_OUTPUT_BASE"), "VirtualDrive")
+        os.makedirs(VirtualDrive, exist_ok=True)
+        OutputPath_FV = os.path.join(
+            self.env.GetValue("BUILD_OUTPUT_BASE"), "FV")
+        Built_FV = os.path.join(OutputPath_FV, "QEMU_EFI.fd")
+
+        # pad fd to 64mb
+        with open(Built_FV, "ab") as fvfile:
+            fvfile.seek(0, os.SEEK_END)
+            additional = b'\0' * ((64 * 1024 * 1024)-fvfile.tell())
+            fvfile.write(additional)
+
+        # QEMU must be on that path
+
+        # Unique Command and Args parameters per ARCH
+        if (self.env.GetValue("TARGET_ARCH").upper() == "AARCH64"):
+            cmd = "qemu-system-aarch64"
+            args = "-M virt"
+            args += " -cpu cortex-a57"                                          # emulate cpu
+        elif(self.env.GetValue("TARGET_ARCH").upper() == "ARM"):
+            cmd = "qemu-system-arm"
+            args = "-M virt"
+            args += " -cpu cortex-a15"                                          # emulate cpu
+        else:
+            raise NotImplementedError()
+
+        # Common Args
+        args += " -pflash " + Built_FV                                     # path to fw
+        args += " -m 1024"                                                  # 1gb memory
+        # turn off network
+        args += " -net none"
+        # Serial messages out
+        args += " -serial stdio"
+        # Mount disk with startup.nsh
+        args += f" -drive file=fat:rw:{VirtualDrive},format=raw,media=disk"
+
+        # Conditional Args
+        if (self.env.GetValue("QEMU_HEADLESS").upper() == "TRUE"):
+            args += " -display none"  # no graphics
+
+        if (self.env.GetValue("MAKE_STARTUP_NSH").upper() == "TRUE"):
+            f = open(os.path.join(VirtualDrive, "startup.nsh"), "w")
+            f.write("BOOT SUCCESS !!! \n")
+            # add commands here
+            f.write("reset -s\n")
+            f.close()
+
+        ret = RunCmd(cmd, args)
+
+        if ret == 0xc0000005:
+            # for some reason getting a c0000005 on successful return
+            return 0
+
+        return ret
diff --git a/ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml b/ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml
new file mode 100644
index 000000000000..8869ed3ecef1
--- /dev/null
+++ b/ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml
@@ -0,0 +1,21 @@
+## @file
+# Download iasl executable tool from a nuget.org package
+# - package contains different binaries based on host
+# Add the folder with the tool to the path
+#
+# This is only downloaded for scope armvirt thus
+# should have no impact on the asl compiler used by any
+# other platform build
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+  "id": "iasl-armvirt-1",
+  "scope": "armvirt",
+  "type": "nuget",
+  "name": "iasl",
+  "source": "https://api.nuget.org/v3/index.json",
+  "version": "20190215.0.0",
+  "flags": ["set_path", "host_specific"],
+}
diff --git a/ArmVirtPkg/ReadMe.rst b/ArmVirtPkg/ReadMe.rst
new file mode 100644
index 000000000000..6149bff7032d
--- /dev/null
+++ b/ArmVirtPkg/ReadMe.rst
@@ -0,0 +1,139 @@
+==========
+ArmVirtPkg
+==========
+
+This ReadMe.rst summarizes the current state of Azure DevOps based Platform CI
+for ArmVirtPkg. It also describes how to *build* ArmVirtPkg locally using the Pytools build system.
+
+Platform CI Current Status
+--------------------------
+
+AARCH64 Configuration
+`````````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Ubuntu GCC5`_  |apAArch64du| |apAArch64ru| |apAArch64nu|
+=============== ============= ============= =============
+
+ARM Configuration
+`````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Ubuntu GCC5`_  |apArmdu|     |apArmru|     |apArmnu|
+=============== ============= ============= =============
+
+Setup
+-----
+
+The Usual EDK2 Build Setup
+``````````````````````````
+
+- `Python 3.8.x - Download & Install <https://www.python.org/downloads/>`_
+- `GIT - Download & Install <https://git-scm.com/download/>`_
+- `GIT - Configure for EDK II <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#github-help>`_
+- `QEMU - Download, Install, and add to your path <https://www.qemu.org/download/>`_
+- `EDKII Source - Download/Checkout from Github <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#download>`_
+
+**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
+
+Differences from EDK Classic Build Setup
+````````````````````````````````````````
+
+- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
+
+  - This replaces `edksetup Rebuild`" from the classic build system
+
+- **No Action:** edksetup, Submodule initialization and manual installation of NASM and iASL are **not**
+  required, it is handled by the Pytools build system.
+
+Building with Pytools for ArmVirtPkg
+````````````````````````````````````
+
+* Install Pytools
+
+  .. code-block:: bash
+
+    pip install --upgrade -r pip-requirements.txt
+
+* Initialize & Update Submodules
+
+  .. code-block:: bash
+
+    stuart_setup -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+* Initialize & Update Dependencies (e.g. iASL & NASM)
+
+  .. code-block:: bash
+
+    stuart_update -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+* Compile
+
+  .. code-block:: bash
+
+    stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+* Running Emulator
+
+  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
+  - or use the `--FlashOnly` feature to just run the emulator.
+
+  .. code-block:: bash
+
+    stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> --FlashOnly
+
+Notes
+`````
+
+1. Including the expected build architecture and toolchain to the *stuart_update* command is critical. This is because there
+   are extra scopes and tools that will be resolved during the update step that need to match your build step.
+2. Configuring *ACTIVE_PLATFORM* and *TARGET_ARCH* in Conf/target.txt is *not* required. This environment is set by
+   PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
+3. QEMU must be on your path.  On Windows this is a manual process and not part of the QEMU installer.
+
+**NOTE:** Logging the execution output will be in the normal stuart log as well as to your console.
+
+Custom Build Options
+````````````````````
+
+**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in combination
+with the `--FlashOnly` feature to run QEMU to the UEFI shell and then execute the contents of startup.nsh.
+
+**QEMU_HEADLESS=TRUE** Since CI servers run headless QEMU must be told to run with no display otherwise an error occurs.
+Locally you don't need to set this.
+
+Passing Build Defines
+`````````````````````
+To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the commandline. stuart_build currently
+requires values to be assigned, so add a `=1` suffix for bare defines.
+For example, to enable TPM2 support, instead of the traditional "-D TPM2_ENABLE=TRUE", the stuart_build command-line would be:
+
+.. code-block:: bash
+
+  stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py BLD_*_TPM2_ENABLE=TRUE
+
+References
+----------
+- `Installing Pytools <https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md#installing>`_
+- For each workspace, consider creating & using a `Python Virtual Environment <https://docs.python.org/3/library/venv.html>`_
+
+  * `Sample Layout <https://microsoft.github.io/mu/CodeDevelopment/prerequisites/#workspace-virtual-environment-setup-process>`_
+
+- `stuart_build commandline parser <https://github.com/tianocore/edk2-pytool-extensions/blob/56f6a7aee09995c2f22da4765e8b0a29c1cbf5de/edk2toolext/edk2_invocable.py#L109>`_
+
+
+.. ===================================================================
+.. This is a bunch of directives to make the README file more readable
+.. ===================================================================
+
+.. _Ubuntu GCC5: https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=41&branchName=master
+
+.. |apAArch64du| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/ArmVirtPkg/ArmVirtQemu%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20QEMU_AARCH64_DEBUG
+.. |apAArch64ru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/ArmVirtPkg/ArmVirtQemu%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20QEMU_AARCH64_RELEASE
+.. |apAArch64nu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/ArmVirtPkg/ArmVirtQemu%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20QEMU_AARCH64_NOOPT
+
+.. |apArmdu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/ArmVirtPkg/ArmVirtQemu%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20QEMU_ARM_DEBUG
+.. |apArmru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/ArmVirtPkg/ArmVirtQemu%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20QEMU_ARM_RELEASE
+.. |apArmnu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/ArmVirtPkg/ArmVirtQemu%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20QEMU_ARM_NOOPT
-- 
2.16.3.windows.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
       [not found] <20200420191216.24572-1-michael.kubacki@outlook.com>
  2020-04-20 19:12 ` [PATCH v2 1/6] .azurepipelines: Add Platform CI template Michael Kubacki
  2020-04-20 19:12 ` [PATCH v2 2/6] ArmVirtPkg: Add Platform CI and configuration for Core CI Michael Kubacki
@ 2020-04-20 19:12 ` Michael Kubacki
  2020-04-21 14:36   ` [edk2-devel] " Liming Gao
                     ` (2 more replies)
  2020-04-20 19:12 ` [PATCH v2 4/6] OvmfPkg: " Michael Kubacki
                   ` (2 subsequent siblings)
  5 siblings, 3 replies; 16+ messages in thread
From: Michael Kubacki @ 2020-04-20 19:12 UTC (permalink / raw)
  To: devel; +Cc: Jordan Justen, Andrew Fish, Ray Ni

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570

Add new Azure Pipeline definitions to build and run EmulatorPkg with:
  * Ubuntu GCC5
  * Windows VS2019
Add PyTool based build of EmulatorPkg
Add EmulatorPkg.ci.yaml for Core CI
Add ReadMe.rst for status, details and instructions

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 EmulatorPkg/EmulatorPkg.ci.yaml                           |  85 ++++++
 EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    |  95 +++++++
 EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml |  85 ++++++
 EmulatorPkg/PlatformCI/PlatformBuild.py                   | 272 ++++++++++++++++++++
 EmulatorPkg/README.rst                                    | 175 +++++++++++++
 5 files changed, 712 insertions(+)

diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
new file mode 100644
index 000000000000..81f81780ec76
--- /dev/null
+++ b/EmulatorPkg/EmulatorPkg.ci.yaml
@@ -0,0 +1,85 @@
+## @file
+# Core CI configuration for EmulatorPkg
+#
+# EmulatorPkg is part of Platform Ci for builds so this is only
+# used for code analysis.
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+    ## options defined .pytool/Plugin/CompilerPlugin
+    "CompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+    "HostUnitTestCompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/CharEncodingCheck
+    "CharEncodingCheck": {
+        "IgnoreFiles": []
+    },
+
+    ## options defined .pytool/Plugin/DependencyCheck
+    "DependencyCheck": {
+        "AcceptableDependencies": [
+            # For this platform all packages are allowed???
+            "MdePkg/MdePkg.dec",
+            "MdeModulePkg/MdeModulePkg.dec",
+            "EmulatorPkg/EmulatorPkg.dec",
+            "NetworkPkg/NetworkPkg.dec",
+            "EmbeddedPkg/EmbeddedPkg.dec", ## is this one OK??
+        ],
+        # For host based unit tests
+        "AcceptableDependencies-HOST_APPLICATION":[
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+        ],
+        # For UEFI shell based apps
+        "AcceptableDependencies-UEFI_APPLICATION":[],
+        "IgnoreInf": []
+    },
+
+    ## options defined .pytool/Plugin/DscCompleteCheck
+    "DscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": ""  # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+    "HostUnitTestDscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/GuidCheck
+    "GuidCheck": {
+        "IgnoreGuidName": [],
+        "IgnoreGuidValue": [],
+        "IgnoreFoldersAndFiles": [],
+        "IgnoreDuplicates": [],
+    },
+
+    ## options defined .pytool/Plugin/LibraryClassCheck
+    "LibraryClassCheck": {
+        "IgnoreHeaderFile": []
+    },
+
+    ## options defined .pytool/Plugin/SpellCheck
+    "SpellCheck": {
+        "AuditOnly": True,           # Fails right now with over 270 errors
+        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
+        "ExtendWords": [
+            "setjump",
+            "plong",
+            "lparam",
+            "lpdword",
+            "lpthread",
+            "lresult",
+        ],           # words to extend to the dictionary for this package
+        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
+        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+    }
+}
diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
new file mode 100644
index 000000000000..12ef8226ff54
--- /dev/null
+++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -0,0 +1,95 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: EmulatorPkg
+# OS: Ubuntu
+# Toolchain: GCC5
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'EmulatorPkg'
+      vm_image: 'ubuntu-latest'
+      should_run: false
+      run_flags: "MAKE_STARTUP_NSH=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          EmulatorPkg_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: GCC5
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        # Add steps to install some IA32 only dependencies
+        extra_install_step:
+        - bash: sudo dpkg --add-architecture i386
+          displayName: Add i386 to dpkg
+          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
+        - bash: sudo apt-get update
+          displayName: do apt-get update
+          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
+        - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
+          displayName: Add additional i386 packages
+          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
new file mode 100644
index 000000000000..a5baf4b6064b
--- /dev/null
+++ b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
@@ -0,0 +1,85 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: EMULATORPKG
+# OS: Windows
+# Toolchain: VS2019
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'EmulatorPkg'
+      vm_image: 'windows-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          EmulatorPkg_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32 "
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32 "
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32 "
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: VS2019
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
diff --git a/EmulatorPkg/PlatformCI/PlatformBuild.py b/EmulatorPkg/PlatformCI/PlatformBuild.py
new file mode 100644
index 000000000000..6defbf6ef148
--- /dev/null
+++ b/EmulatorPkg/PlatformCI/PlatformBuild.py
@@ -0,0 +1,272 @@
+# @file
+# Script to Build EmulatorPkg UEFI firmware
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+import logging
+import io
+
+from edk2toolext.environment import shell_environment
+from edk2toolext.environment.uefi_build import UefiBuilder
+from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
+from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
+from edk2toolext.invocables.edk2_update import UpdateSettingsManager
+from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
+from edk2toollib.utility_functions import RunCmd
+from edk2toollib.utility_functions import GetHostInfo
+
+# ####################################################################################### #
+#                                Common Configuration                                     #
+# ####################################################################################### #
+
+
+class CommonPlatform():
+    ''' Common settings for this platform.  Define static data here and use
+        for the different parts of stuart
+    '''
+    PackagesSupported = ("EmulatorPkg",)
+    ArchSupported = ("X64", "IA32")
+    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
+    Scopes = ('emulatorpkg', 'edk2-build')
+    WorkspaceRoot = os.path.realpath(os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
+
+    # ####################################################################################### #
+    #                         Configuration for Update & Setup                                #
+    # ####################################################################################### #
+
+
+class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
+
+    def GetPackagesSupported(self):
+        ''' return iterable of edk2 packages supported by this build.
+        These should be edk2 workspace relative paths '''
+        return CommonPlatform.PackagesSupported
+
+    def GetArchitecturesSupported(self):
+        ''' return iterable of edk2 architectures supported by this build '''
+        return CommonPlatform.ArchSupported
+
+    def GetTargetsSupported(self):
+        ''' return iterable of edk2 target tags supported by this build '''
+        return CommonPlatform.TargetsSupported
+
+    def GetRequiredSubmodules(self):
+        ''' return iterable containing RequiredSubmodule objects.
+        If no RequiredSubmodules return an empty iterable
+        '''
+        rs = []
+        # intentionally declare this one with recursive false to avoid overhead
+        rs.append(RequiredSubmodule(
+            "CryptoPkg/Library/OpensslLib/openssl", False))
+
+        # To avoid maintenance of this file for every new submodule
+        # lets just parse the .gitmodules and add each if not already in list.
+        # The GetRequiredSubmodules is designed to allow a build to optimize
+        # the desired submodules but it isn't necessary for this repository.
+        result = io.StringIO()
+        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
+        # Cmd output is expected to look like:
+        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
+        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
+        if ret == 0:
+            for line in result.getvalue().splitlines():
+                _, _, path = line.partition(" ")
+                if path is not None:
+                    if path not in [x.path for x in rs]:
+                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
+        return rs
+
+    def SetArchitectures(self, list_of_requested_architectures):
+        ''' Confirm the requests architecture list is valid and configure SettingsManager
+        to run only the requested architectures.
+
+        Raise Exception if a list_of_requested_architectures is not supported
+        '''
+        unsupported = set(list_of_requested_architectures) - \
+            set(self.GetArchitecturesSupported())
+        if(len(unsupported) > 0):
+            errorString = (
+                "Unsupported Architecture Requested: " + " ".join(unsupported))
+            logging.critical(errorString)
+            raise Exception(errorString)
+        self.ActualArchitectures = list_of_requested_architectures
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
+        ''' Filter other cases that this package should be built
+        based on changed files. This should cover things that can't
+        be detected as dependencies. '''
+        build_these_packages = []
+        possible_packages = potentialPackagesList.copy()
+        for f in changedFilesList:
+            # BaseTools files that might change the build
+            if "BaseTools" in f:
+                if os.path.splitext(f) not in [".txt", ".md"]:
+                    build_these_packages = possible_packages
+                    break
+            # if the azure pipeline platform template file changed
+            if "platform-build-run-steps.yml" in f:
+                build_these_packages = possible_packages
+                break
+        return build_these_packages
+
+    def GetPlatformDscAndConfig(self) -> tuple:
+        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
+        any of the changes will be built in the dsc.
+
+        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
+        '''
+        return (os.path.join("EmulatorPkg", "EmulatorPkg.dsc"), {})
+
+    # ####################################################################################### #
+    #                         Actual Configuration for Platform Build                         #
+    # ####################################################################################### #
+
+
+class PlatformBuilder(UefiBuilder, BuildSettingsManager):
+    def __init__(self):
+        UefiBuilder.__init__(self)
+
+    def AddCommandLineOptions(self, parserObj):
+        ''' Add command line options to the argparser '''
+        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="X64",
+                               help="Optional - architecture to build.  IA32 will use IA32 for Pei & Dxe. "
+                               "X64 will use X64 for both PEI and DXE.")
+
+    def RetrieveCommandLineOptions(self, args):
+        '''  Retrieve command line options from the argparser '''
+
+        shell_environment.GetBuildVars().SetValue(
+            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
+        shell_environment.GetBuildVars().SetValue(
+            "ACTIVE_PLATFORM", "EmulatorPkg/EmulatorPkg.dsc", "From CmdLine")
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetPackagesPath(self):
+        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
+        return ()
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def GetName(self):
+        ''' Get the name of the repo, platform, or product being build '''
+        ''' Used for naming the log file, among others '''
+
+        # check the startup nsh flag and if set then rename the log file.
+        # this helps in CI so we don't overwrite the build log since running
+        # uses the stuart_build command.
+        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
+            return "EmulatorPkg_With_Run"
+        return "EmulatorPkg"
+
+    def GetLoggingLevel(self, loggerType):
+        ''' Get the logging level for a given type
+        base == lowest logging level supported
+        con  == Screen logging
+        txt  == plain text file logging
+        md   == markdown file logging
+        '''
+        return logging.DEBUG
+
+    def SetPlatformEnv(self):
+        logging.debug("PlatformBuilder SetPlatformEnv")
+        self.env.SetValue("PRODUCT_NAME", "EmulatorPkg", "Platform Hardcoded")
+        self.env.SetValue("TOOL_CHAIN_TAG", "VS2019", "Default Toolchain")
+
+        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
+        # requested to be built when building VS2019 or VS2017
+        if self.env.GetValue("TOOL_CHAIN_TAG") == "VS2019" or self.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":
+            key = self.env.GetValue("TOOL_CHAIN_TAG") + "_HOST"
+            if self.env.GetValue("TARGET_ARCH") == "IA32":
+                shell_environment.ShellEnvironment().set_shell_var(key, "x86")
+            elif self.env.GetValue("TARGET_ARCH") == "X64":
+                shell_environment.ShellEnvironment().set_shell_var(key, "x64")
+
+        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
+        # requested to be built when building on linux.
+        if GetHostInfo().os.upper() == "LINUX":
+            self.ConfigureLinuxDLinkPath()
+
+        if GetHostInfo().os.upper() == "WINDOWS":
+            self.env.SetValue("BLD_*_WIN_HOST_BUILD", "TRUE",
+                              "Trigger Windows host build")
+
+        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
+
+        # I don't see what this does but it is in build.sh
+        key = "BLD_*_BUILD_" + self.env.GetValue("TARGET_ARCH")
+        self.env.SetValue(key, "TRUE", "match script in build.sh")
+        return 0
+
+    def PlatformPreBuild(self):
+        return 0
+
+    def PlatformPostBuild(self):
+        return 0
+
+    def FlashRomImage(self):
+        ''' Use the FlashRom Function to run the emulator.  This gives an easy stuart command line to
+        activate the emulator. '''
+
+        OutputPath = os.path.join(self.env.GetValue(
+            "BUILD_OUTPUT_BASE"), self.env.GetValue("TARGET_ARCH"))
+
+        if (self.env.GetValue("MAKE_STARTUP_NSH") == "TRUE"):
+            f = open(os.path.join(OutputPath, "startup.nsh"), "w")
+            f.write("BOOT SUCCESS !!! \n")
+            # add commands here
+            f.write("reset\n")
+            f.close()
+
+        if GetHostInfo().os.upper() == "WINDOWS":
+            cmd = "WinHost.exe"
+        elif GetHostInfo().os.upper() == "LINUX":
+            cmd = "./Host"
+        else:
+            logging.critical("Unsupported Host")
+            return -1
+        return RunCmd(cmd, "", workingdir=OutputPath)
+
+    def ConfigureLinuxDLinkPath(self):
+        '''
+        logic copied from build.sh to setup the correct libraries
+        '''
+        if self.env.GetValue("TARGET_ARCH") == "IA32":
+            LIB_NAMES = ["ld-linux.so.2", "libdl.so.2 crt1.o", "crti.o crtn.o"]
+            LIB_SEARCH_PATHS = ["/usr/lib/i386-linux-gnu",
+                                "/usr/lib32", "/lib32", "/usr/lib", "/lib"]
+        elif self.env.GetValue("TARGET_ARCH") == "X64":
+            LIB_NAMES = ["ld-linux-x86-64.so.2",
+                         "libdl.so.2", "crt1.o", "crti.o", "crtn.o"]
+            LIB_SEARCH_PATHS = ["/usr/lib/x86_64-linux-gnu",
+                                "/usr/lib64", "/lib64", "/usr/lib", "/lib"]
+
+        HOST_DLINK_PATHS = ""
+        for lname in LIB_NAMES:
+            logging.debug(f"Looking for {lname}")
+            for dname in LIB_SEARCH_PATHS:
+                logging.debug(f"In {dname}")
+                if os.path.isfile(os.path.join(dname, lname)):
+                    logging.debug(f"Found {lname} in {dname}")
+                    HOST_DLINK_PATHS += os.path.join(
+                        os.path.join(dname, lname)) + os.pathsep
+                    break
+        HOST_DLINK_PATHS = HOST_DLINK_PATHS.rstrip(os.pathsep)
+        logging.critical(f"Setting HOST_DLINK_PATHS to {HOST_DLINK_PATHS}")
+        shell_environment.ShellEnvironment().set_shell_var(
+            "HOST_DLINK_PATHS", HOST_DLINK_PATHS)
diff --git a/EmulatorPkg/README.rst b/EmulatorPkg/README.rst
new file mode 100644
index 000000000000..d1aa0a367965
--- /dev/null
+++ b/EmulatorPkg/README.rst
@@ -0,0 +1,175 @@
+===========
+EmulatorPkg
+===========
+
+This README.rst summarizes the current state of Azure DevOps Platform CI
+for EmulatorPkg. It also describes how to *build* EmulatorPkg locally using the
+Pytools build system. For general documentation on EmulatorPkg, refer
+to the `ReadMe <./Readme.md>`_.
+
+Platform CI Current Status
+---------------------------
+
+IA32 Configuration
+``````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
+`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
+=============== ============= ============= =============
+
+|TCBZ_2668|_ - Ubuntu GCC5 Segfaults during execution.  The builds
+only compile for Ubuntu GCC5 (not run to shell).
+
+X64 Configuration
+`````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
+`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
+=============== ============= ============= =============
+
+|TCBZ_2639|_ - Ubuntu GCC5 Segfaults during execution.  The builds
+only compile for Ubuntu GCC5 (not run to shell).
+
+Setup
+-----
+
+The Usual EDK2 Build Setup
+``````````````````````````
+
+- `Python 3.8.x - Download & Install <https://www.python.org/downloads/>`_
+- `GIT - Download & Install <https://git-scm.com/download/>`_
+- `GIT - Configure for EDK II <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#github-help>`_
+- `EDKII Source - Download/Checkout from Github <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#download>`_
+
+**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
+
+Install the necessary development packages for your distribution
+````````````````````````````````````````````````````````````````
+
+This varies by distribution, toolchain, and your configuration but here are a few hints.
+
+* For building ARCH IA32 on X64 Ubuntu 18.04 LTS these steps where needed.
+
+  .. code-block:: bash
+
+    sudo dpkg --add-architecture i386
+    sudo apt-get update
+    sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
+
+* For building Basetools and other host applications
+
+  .. code-block:: bash
+
+    sudo apt-get update
+    sudo apt-get install gcc g++ make uuid-dev
+
+Differences from EDK Classic Build Setup
+````````````````````````````````````````
+
+- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
+
+  - This replaces `edksetup Rebuild`" from the classic build system
+  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems-ToolChain-Matrix>`_,
+    defaults to `VS2017` if not specified
+
+- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is
+  handled by the Pytools build system
+
+Install & Configure Pytools for EmulatorPkg
+```````````````````````````````````````````
+
+* Install Pytools
+
+  .. code-block:: bash
+
+    pip install --upgrade -r pip-requirements.txt
+
+* Initialize & Update Submodules
+
+  .. code-block:: bash
+
+    stuart_setup -c EmulatorPkg/PlatformCI/PlatformBuild.py
+
+* Initialize & Update Dependencies (e.g. iASL & NASM)
+
+  .. code-block:: bash
+
+    stuart_update -c EmulatorPkg/PlatformCI/PlatformBuild.py
+
+* Compile (IA32 or X64 supported)
+
+  .. code-block:: bash
+
+    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>] -a <TARGET_ARCH>
+
+* Running Emulator
+
+  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
+  - or use the `--FlashOnly` feature to just run the emulator.
+
+  .. code-block:: bash
+
+    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> --FlashOnly
+
+**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is *not* required.
+This environment is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
+
+Custom Build Options
+````````````````````
+
+**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
+combination with the `--FlashOnly` feature to run the emulator to the UEFI shell and then execute the
+contents of startup.nsh.
+
+Passing Build Defines
+`````````````````````
+
+To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
+stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
+For example, to enable the IP6 Network Stack, the stuart_build command-line would be:
+
+.. code-block:: bash
+
+  stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py BLD_*_NETWORK_IP6_ENABLE=1
+
+References
+----------
+
+- `Installing Pytools <https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md#installing>`_
+- For each workspace, consider creating & using a `Python Virtual Environment <https://docs.python.org/3/library/venv.html>`_
+
+  * `Sample Layout <https://microsoft.github.io/mu/CodeDevelopment/prerequisites/#workspace-virtual-environment-setup-process>`_
+
+- `stuart_build commandline parser <https://github.com/tianocore/edk2-pytool-extensions/blob/56f6a7aee09995c2f22da4765e8b0a29c1cbf5de/edk2toolext/edk2_invocable.py#L109>`_
+
+
+.. ===================================================================
+.. This is a bunch of directives to make the README file more readable
+.. ===================================================================
+
+.. |TCBZ_2668| image:: https://img.shields.io/bugzilla/2668?baseUrl=https%3A%2F%2Fbugzilla.tianocore.org
+.. _TCBZ_2668: https://bugzilla.tianocore.org/show_bug.cgi?id=2668
+
+.. |TCBZ_2639| image:: https://img.shields.io/bugzilla/2639?baseUrl=https%3A%2F%2Fbugzilla.tianocore.org
+.. _TCBZ_2639: https://bugzilla.tianocore.org/show_bug.cgi?id=2639
+
+.. _Win VS2019:  https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=40&branchName=master
+.. _Ubuntu GCC5: https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=39&branchName=master
+
+.. |ap32d| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_IA32_DEBUG
+.. |ap32du| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_IA32_DEBUG
+.. |ap32r| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_IA32_RELEASE
+.. |ap32ru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_IA32_RELEASE
+.. |ap32n| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_IA32_NOOPT
+.. |ap32nu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_IA32_NOOPT
+
+.. |ap64d| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_X64_DEBUG
+.. |ap64du| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_X64_DEBUG
+.. |ap64r| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_X64_RELEASE
+.. |ap64ru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_X64_RELEASE
+.. |ap64n| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_X64_NOOPT
+.. |ap64nu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20EmulatorPkg_X64_NOOPT
-- 
2.16.3.windows.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 4/6] OvmfPkg: Add Platform CI and configuration for Core CI
       [not found] <20200420191216.24572-1-michael.kubacki@outlook.com>
                   ` (2 preceding siblings ...)
  2020-04-20 19:12 ` [PATCH v2 3/6] EmulatorPkg: " Michael Kubacki
@ 2020-04-20 19:12 ` Michael Kubacki
  2020-04-24 20:22   ` [EXTERNAL] [edk2-devel] " Bret Barkelew
  2020-04-20 19:12 ` [PATCH v2 5/6] .pytool: Update CI Settings to support Emulator, ArmVirt, and Ovmf packages Michael Kubacki
  2020-04-20 19:12 ` [PATCH v2 6/6] .azurepipelines: Update Core CI build matrix to include platforms Michael Kubacki
  5 siblings, 1 reply; 16+ messages in thread
From: Michael Kubacki @ 2020-04-20 19:12 UTC (permalink / raw)
  To: devel; +Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570

Add new Azure Pipeline definitions to build and run OvmfPkg with:
  * Ubuntu GCC5
  * Windows VS2019
Add PyTool based build of OvmfPkg
Add extdep for managing the iasl dependency
Add OvmfPkg.ci.yaml for Core CI
Add README.rst for status, details and instructions

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 OvmfPkg/OvmfPkg.ci.yaml                               |  83 +++++++
 OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    | 133 ++++++++++
 OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml | 138 +++++++++++
 OvmfPkg/PlatformCI/PlatformBuild.py                   | 254 ++++++++++++++++++++
 OvmfPkg/PlatformCI/iasl_ext_dep.yaml                  |  21 ++
 OvmfPkg/README.rst                                    | 211 ++++++++++++++++
 6 files changed, 840 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.ci.yaml b/OvmfPkg/OvmfPkg.ci.yaml
new file mode 100644
index 000000000000..98992f0429ff
--- /dev/null
+++ b/OvmfPkg/OvmfPkg.ci.yaml
@@ -0,0 +1,83 @@
+## @file
+# Core CI configuration for OvmfPkg
+#
+# OvmfPkg is part of Platform Ci for builds so this is only
+# used for code analysis.
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+    ## options defined .pytool/Plugin/CompilerPlugin
+    "CompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+    "HostUnitTestCompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/CharEncodingCheck
+    "CharEncodingCheck": {
+        "IgnoreFiles": []
+    },
+
+    ## options defined .pytool/Plugin/DependencyCheck
+    "DependencyCheck": {
+        "AcceptableDependencies": [
+            "MdePkg/MdePkg.dec",
+            "MdeModulePkg/MdeModulePkg.dec",
+            "OvmfPkg/OvmfPkg.dec",
+            "NetworkPkg/NetworkPkg.dec",
+            "SecurityPkg/SecurityPkg.dec",
+            "UefiCpuPkg/UefiCpuPkg.dec",
+            "ShellPkg/ShellPkg.dec",
+            "EmbeddedPkg/EmbeddedPkg.dec",
+            "SourceLevelDebugPkg/SourceLevelDebugPkg.dec"
+        ],
+        # For host based unit tests
+        "AcceptableDependencies-HOST_APPLICATION":[
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+        ],
+        # For UEFI shell based apps
+        "AcceptableDependencies-UEFI_APPLICATION":[],
+        "IgnoreInf": []
+    },
+
+    ## options defined .pytool/Plugin/DscCompleteCheck
+    "DscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": ""  # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+    "HostUnitTestDscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/GuidCheck
+    "GuidCheck": {
+        "IgnoreGuidName": ["ResetVector", "XenResetVector"], # Expected duplication for gEfiFirmwareVolumeTopFileGuid
+        "IgnoreGuidValue": [],
+        "IgnoreFoldersAndFiles": [],
+        "IgnoreDuplicates": [],
+    },
+
+    ## options defined .pytool/Plugin/LibraryClassCheck
+    "LibraryClassCheck": {
+        "IgnoreHeaderFile": []
+    },
+
+    ## options defined .pytool/Plugin/SpellCheck
+    "SpellCheck": {
+        "AuditOnly": True,           # Fails right now with over 270 errors
+        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
+        "ExtendWords": [
+
+        ],           # words to extend to the dictionary for this package
+        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
+        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+    }
+}
diff --git a/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
new file mode 100644
index 000000000000..a47d273217ab
--- /dev/null
+++ b/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -0,0 +1,133 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: OVMF
+# OS: Ubuntu
+# Toolchain: GCC5
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'OvmfPkg'
+      vm_image: 'ubuntu-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE QEMU_HEADLESS=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          OVMF_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_FULL_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_FULL_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_FULL_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: GCC5
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        extra_install_step:
+        - bash: sudo apt-get install qemu
+          displayName: Install qemu
+          condition: and(gt(variables.pkg_count, 0), succeeded())
diff --git a/OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml b/OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
new file mode 100644
index 000000000000..02ed233fdb60
--- /dev/null
+++ b/OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
@@ -0,0 +1,138 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: OVMF
+# OS: Windows
+# Toolchain: VS2019
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'OvmfPkg'
+      vm_image: 'windows-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE QEMU_HEADLESS=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          OVMF_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_FULL_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_FULL_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    # This currently creates a very large image which is too big for the FDF declared range
+    #   Ovmf maintainers suggest to skip this build for now.
+    #
+    #       OVMF_IA32X64_FULL_NOOPT:
+    #         Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+    #         Build.Arch: "IA32,X64"
+    #         Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+    #         Build.Target: "NOOPT"
+    #         Run.Flags: $(run_flags)
+    #         Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: VS2019
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        extra_install_step:
+        - powershell: choco install qemu; Write-Host "##vso[task.prependpath]c:\Program Files\qemu"
+          displayName: Install QEMU and Set QEMU on path # friendly name displayed in the UI
+          condition: and(gt(variables.pkg_count, 0), succeeded())
+
diff --git a/OvmfPkg/PlatformCI/PlatformBuild.py b/OvmfPkg/PlatformCI/PlatformBuild.py
new file mode 100644
index 000000000000..627bb7b992db
--- /dev/null
+++ b/OvmfPkg/PlatformCI/PlatformBuild.py
@@ -0,0 +1,254 @@
+# @file
+# Script to Build OVMF UEFI firmware
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+import logging
+import io
+
+from edk2toolext.environment import shell_environment
+from edk2toolext.environment.uefi_build import UefiBuilder
+from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
+from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
+from edk2toolext.invocables.edk2_update import UpdateSettingsManager
+from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
+from edk2toollib.utility_functions import RunCmd
+
+
+    # ####################################################################################### #
+    #                                Common Configuration                                     #
+    # ####################################################################################### #
+class CommonPlatform():
+    ''' Common settings for this platform.  Define static data here and use
+        for the different parts of stuart
+    '''
+    PackagesSupported = ("OvmfPkg",)
+    ArchSupported = ("IA32", "X64")
+    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
+    Scopes = ('ovmf', 'edk2-build')
+    WorkspaceRoot = os.path.realpath(os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
+
+    @classmethod
+    def GetDscName(cls, ArchCsv: str) -> str:
+        ''' return the DSC given the architectures requested.
+
+        ArchCsv: csv string containing all architectures to build
+        '''
+        dsc = "OvmfPkg"
+        if "IA32" in ArchCsv.upper().split(","):
+            dsc += "Ia32"
+        if "X64" in ArchCsv.upper().split(","):
+            dsc += "X64"
+        dsc += ".dsc"
+        return dsc
+
+
+    # ####################################################################################### #
+    #                         Configuration for Update & Setup                                #
+    # ####################################################################################### #
+class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
+
+    def GetPackagesSupported(self):
+        ''' return iterable of edk2 packages supported by this build.
+        These should be edk2 workspace relative paths '''
+        return CommonPlatform.PackagesSupported
+
+    def GetArchitecturesSupported(self):
+        ''' return iterable of edk2 architectures supported by this build '''
+        return CommonPlatform.ArchSupported
+
+    def GetTargetsSupported(self):
+        ''' return iterable of edk2 target tags supported by this build '''
+        return CommonPlatform.TargetsSupported
+
+    def GetRequiredSubmodules(self):
+        ''' return iterable containing RequiredSubmodule objects.
+        If no RequiredSubmodules return an empty iterable
+        '''
+        rs = []
+
+        # intentionally declare this one with recursive false to avoid overhead
+        rs.append(RequiredSubmodule(
+            "CryptoPkg/Library/OpensslLib/openssl", False))
+
+        # To avoid maintenance of this file for every new submodule
+        # lets just parse the .gitmodules and add each if not already in list.
+        # The GetRequiredSubmodules is designed to allow a build to optimize
+        # the desired submodules but it isn't necessary for this repository.
+        result = io.StringIO()
+        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
+        # Cmd output is expected to look like:
+        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
+        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
+        if ret == 0:
+            for line in result.getvalue().splitlines():
+                _, _, path = line.partition(" ")
+                if path is not None:
+                    if path not in [x.path for x in rs]:
+                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
+        return rs
+
+    def SetArchitectures(self, list_of_requested_architectures):
+        ''' Confirm the requests architecture list is valid and configure SettingsManager
+        to run only the requested architectures.
+
+        Raise Exception if a list_of_requested_architectures is not supported
+        '''
+        unsupported = set(list_of_requested_architectures) - set(self.GetArchitecturesSupported())
+        if(len(unsupported) > 0):
+            errorString = ( "Unsupported Architecture Requested: " + " ".join(unsupported))
+            logging.critical( errorString )
+            raise Exception( errorString )
+        self.ActualArchitectures = list_of_requested_architectures
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
+        ''' Filter other cases that this package should be built
+        based on changed files. This should cover things that can't
+        be detected as dependencies. '''
+        build_these_packages = []
+        possible_packages = potentialPackagesList.copy()
+        for f in changedFilesList:
+            # BaseTools files that might change the build
+            if "BaseTools" in f:
+                if os.path.splitext(f) not in [".txt", ".md"]:
+                    build_these_packages = possible_packages
+                    break
+
+            # if the azure pipeline platform template file changed
+            if "platform-build-run-steps.yml" in f:
+                build_these_packages = possible_packages
+                break
+
+        return build_these_packages
+
+    def GetPlatformDscAndConfig(self) -> tuple:
+        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
+        any of the changes will be built in the dsc.
+
+        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
+        '''
+        dsc = CommonPlatform.GetDscName(",".join(self.ActualArchitectures))
+        return (f"OvmfPkg/{dsc}", {})
+
+
+    # ####################################################################################### #
+    #                         Actual Configuration for Platform Build                         #
+    # ####################################################################################### #
+class PlatformBuilder( UefiBuilder, BuildSettingsManager):
+    def __init__(self):
+        UefiBuilder.__init__(self)
+
+    def AddCommandLineOptions(self, parserObj):
+        ''' Add command line options to the argparser '''
+        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="IA32,X64",
+            help="Optional - CSV of architecture to build.  IA32 will use IA32 for Pei & Dxe. "
+            "X64 will use X64 for both PEI and DXE.  IA32,X64 will use IA32 for PEI and "
+            "X64 for DXE. default is IA32,X64")
+
+    def RetrieveCommandLineOptions(self, args):
+        '''  Retrieve command line options from the argparser '''
+
+        shell_environment.GetBuildVars().SetValue("TARGET_ARCH"," ".join(args.build_arch.upper().split(",")), "From CmdLine")
+        dsc = CommonPlatform.GetDscName(args.build_arch)
+        shell_environment.GetBuildVars().SetValue("ACTIVE_PLATFORM", f"OvmfPkg/{dsc}", "From CmdLine")
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetPackagesPath(self):
+        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
+        return ()
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def GetName(self):
+        ''' Get the name of the repo, platform, or product being build '''
+        ''' Used for naming the log file, among others '''
+        # check the startup nsh flag and if set then rename the log file.
+        # this helps in CI so we don't overwrite the build log since running
+        # uses the stuart_build command.
+        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
+            return "OvmfPkg_With_Run"
+        return "OvmfPkg"
+
+    def GetLoggingLevel(self, loggerType):
+        ''' Get the logging level for a given type
+        base == lowest logging level supported
+        con  == Screen logging
+        txt  == plain text file logging
+        md   == markdown file logging
+        '''
+        return logging.DEBUG
+
+    def SetPlatformEnv(self):
+        logging.debug("PlatformBuilder SetPlatformEnv")
+        self.env.SetValue("PRODUCT_NAME", "OVMF", "Platform Hardcoded")
+        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
+        self.env.SetValue("QEMU_HEADLESS", "FALSE", "Default to false")
+        return 0
+
+    def PlatformPreBuild(self):
+        return 0
+
+    def PlatformPostBuild(self):
+        return 0
+
+    def FlashRomImage(self):
+        VirtualDrive = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), "VirtualDrive")
+        os.makedirs(VirtualDrive, exist_ok=True)
+        OutputPath_FV = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), "FV")
+
+        #
+        # QEMU must be on the path
+        #
+        cmd = "qemu-system-x86_64"
+        args  = "-debugcon stdio"                                           # write messages to stdio
+        args += " -global isa-debugcon.iobase=0x402"                        # debug messages out thru virtual io port
+        args += " -net none"                                                # turn off network
+        args += f" -drive file=fat:rw:{VirtualDrive},format=raw,media=disk" # Mount disk with startup.nsh
+
+        if (self.env.GetValue("QEMU_HEADLESS").upper() == "TRUE"):
+            args += " -display none"  # no graphics
+
+        if (self.env.GetBuildValue("SMM_REQUIRE") == "1"):
+            args += " -machine q35,smm=on" #,accel=(tcg|kvm)"
+            #args += " -m ..."
+            #args += " -smp ..."
+            args += " -global driver=cfi.pflash01,property=secure,value=on"
+            args += " -drive if=pflash,format=raw,unit=0,file=" + os.path.join(OutputPath_FV, "OVMF_CODE.fd") + ",readonly=on"
+            args += " -drive if=pflash,format=raw,unit=1,file=" + os.path.join(OutputPath_FV, "OVMF_VARS.fd")
+        else:
+            args += " -pflash " + os.path.join(OutputPath_FV, "OVMF.fd")    # path to firmware
+
+
+        if (self.env.GetValue("MAKE_STARTUP_NSH").upper() == "TRUE"):
+            f = open(os.path.join(VirtualDrive, "startup.nsh"), "w")
+            f.write("BOOT SUCCESS !!! \n")
+            ## add commands here
+            f.write("reset -s\n")
+            f.close()
+
+        ret = RunCmd(cmd, args)
+
+        if ret == 0xc0000005:
+            #for some reason getting a c0000005 on successful return
+            return 0
+
+        return ret
+
+
+
diff --git a/OvmfPkg/PlatformCI/iasl_ext_dep.yaml b/OvmfPkg/PlatformCI/iasl_ext_dep.yaml
new file mode 100644
index 000000000000..cbee0e5a5a92
--- /dev/null
+++ b/OvmfPkg/PlatformCI/iasl_ext_dep.yaml
@@ -0,0 +1,21 @@
+## @file
+# Download iasl executable tool from a nuget.org package
+# - package contains different binaries based on host
+# Add the folder with the tool to the path
+#
+# This is only downloaded for scope ovmf thus
+# should have no impact on the asl compiler used by any
+# other given platform to build.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+  "id": "iasl-ovmf-1",
+  "scope": "ovmf",
+  "type": "nuget",
+  "name": "iasl",
+  "source": "https://api.nuget.org/v3/index.json",
+  "version": "20190215.0.0",
+  "flags": ["set_path", "host_specific"],
+}
diff --git a/OvmfPkg/README.rst b/OvmfPkg/README.rst
new file mode 100644
index 000000000000..926e0f7d7f8d
--- /dev/null
+++ b/OvmfPkg/README.rst
@@ -0,0 +1,211 @@
+=======
+OvmfPkg
+=======
+
+This README.rst summarizes the current state of Azure DevOps Platform CI
+for OvmfPkg. It also describes how to *build* OvmfPkg locally using the
+Pytools build system. For general documentation on OvmfPkg, refer
+to the `README <./README>`_.
+
+Platform CI Current Status
+---------------------------
+
+IA32 Configuration
+``````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
+`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
+=============== ============= ============= =============
+
+X64 Configuration
+`````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
+`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
+=============== ============= ============= =============
+
+IA32X64 Configuration
+`````````````````````
+PEI phase is 32-bit while DXE phase is 64-bit
+
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap3264d|     |ap3264r|     |ap3264n|
+`Ubuntu GCC5`_  |ap3264du|    |ap3264ru|    |ap3264nu|
+=============== ============= ============= =============
+
+
+IA32X64 FULL Configuration
+``````````````````````````
+PEI phase is 32-bit while DXE phase is 64-bit
+
+Additional Build flags:
+  * SECURE_BOOT_ENABLE=1
+  * SMM_REQUIRE=1
+  * TPM_ENABLE=1
+  * TPM_CONFIG_ENABLE=1
+  * NETWORK_TLS_ENABLE=1
+  * NETWORK_IP6_ENABLE=1
+  * NETWORK_HTTP_BOOT_ENABLE=1
+
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap3264fd|    |ap3264fr|    |ap3264fn|
+`Ubuntu GCC5`_  |ap3264fdu|   |ap3264fru|   |ap3264fru|
+=============== ============= ============= =============
+
+Setup
+-----
+
+The Usual EDK2 Build Setup
+``````````````````````````
+
+- `Python 3.8.x - Download & Install <https://www.python.org/downloads/>`_
+- `GIT - Download & Install <https://git-scm.com/download/>`_
+- `GIT - Configure for EDK II <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#github-help>`_
+- `QEMU - Download, Install, and add to your path <https://www.qemu.org/download/>`_
+- `EDKII Source - Download/Checkout from Github <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#download>`_
+
+**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
+
+Differences from EDK Classic Build Setup
+````````````````````````````````````````
+
+- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
+
+  - This replaces `edksetup Rebuild`" from the classic build system
+  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems-ToolChain-Matrix>`_,
+    defaults to `VS2017` if not specified
+
+- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is handled by the Pytools build system
+
+Install & Configure Pytools for OvmfPkg
+```````````````````````````````````````
+
+* Install Pytools
+
+  .. code-block:: bash
+
+    pip install --upgrade -r pip-requirements.txt
+
+* Initialize & Update Submodules
+
+  .. code-block:: bash
+
+    stuart_setup -c OvmfPkg/PlatformCI/PlatformBuild.py
+
+* Initialize & Update Dependencies (e.g. iASL & NASM)
+
+  .. code-block:: bash
+
+    stuart_update -c OvmfPkg/PlatformCI/PlatformBuild.py
+
+Building
+--------
+
+OVMF has `3 versions <https://github.com/tianocore/tianocore.github.io/wiki/How-to-build-OVMF#choosing-which-version-of-ovmf-to-build>`_.
+To build them using Pytools:
+
+First set the `TOOL_CHAIN_TAG` via environment variable, Conf/target.txt, or pass it on the command-lines below using `TOOL_CHAIN_TAG=<value>` syntax.
+
+===================== ===============
+Platform              Commandline
+===================== ===============
+OvmfPkgIa32X64.dsc    `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]` |br| `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py -a IA32,X64 [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]`
+OvmfPkgIa32.dsc       `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py -a IA32 [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]`
+OvmfPkgX64.dsc        `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py -a X64 [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]`
+===================== ===============
+
+**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is **not** required. This environment
+is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
+
+Custom Build Options
+````````````````````
+
+**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
+combination with the `--FlashOnly` feature to run QEMU to the UEFI shell and then execute the contents of startup.nsh.
+
+**QEMU_HEADLESS=TRUE** Since CI servers run headless QEMU must be told to run with no display otherwise an error
+occurs. Locally you don't need to set this.
+
+Passing Build Defines
+`````````````````````
+To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
+stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
+For example, to enable the Intel E1000 NIC, instead of the traditional "-D E1000_ENABLE", the stuart_build
+command-line would be:
+
+.. code-block:: bash
+
+  stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py BLD_*_E1000_ENABLE=1
+
+Running QEMU Emulator
+---------------------
+
+QEMU can be automatically launched using stuart_build.  This makes path management and quick verification easy.
+QEMU must be added to your path.  On Windows this is a manual process and not part of the QEMU installer.
+
+1. To run as part of the build but after building add the `--FlashRom` parameter.
+2. To run after the build process standalone use your build command mentioned above plus `--FlashOnly`.
+
+**NOTE:** Logging the execution output will be in the normal stuart log as well as to your console.
+
+References
+----------
+- `Installing Pytools <https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md#installing>`_
+- For each workspace, consider creating & using a `Python Virtual Environment <https://docs.python.org/3/library/venv.html>`_
+
+  * `Sample Layout <https://microsoft.github.io/mu/CodeDevelopment/prerequisites/#workspace-virtual-environment-setup-process>`_
+
+- `stuart_build commandline parser <https://github.com/tianocore/edk2-pytool-extensions/blob/56f6a7aee09995c2f22da4765e8b0a29c1cbf5de/edk2toolext/edk2_invocable.py#L109>`_
+
+
+
+
+.. ===================================================================
+.. This is a bunch of directives to make the README file more readable
+.. ===================================================================
+.. role:: raw-html(raw)
+    :format: html
+
+.. _Bugzilla 2661: https://bugzilla.tianocore.org/show_bug.cgi?id=2661
+
+.. _Win VS2019:  https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=38&branchName=master/
+.. _Ubuntu GCC5: https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=37&branchName=master
+
+.. |ap32d| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32_DEBUG
+.. |ap32du| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32_DEBUG
+.. |ap32r| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32_RELEASE
+.. |ap32ru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32_RELEASE
+.. |ap32n| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32_NOOPT
+.. |ap32nu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32_NOOPT
+
+.. |ap64d| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_X64_DEBUG
+.. |ap64du| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_X64_DEBUG
+.. |ap64r| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_X64_RELEASE
+.. |ap64ru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_X64_RELEASE
+.. |ap64n| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_X64_NOOPT
+.. |ap64nu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_X64_NOOPT
+
+
+.. |ap3264d| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_DEBUG
+.. |ap3264du| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_DEBUG
+.. |ap3264r| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_RELEASE
+.. |ap3264ru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_RELEASE
+.. |ap3264n| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_NOOPT
+.. |ap3264nu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_NOOPT
+
+.. |ap3264fd| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_FULL_DEBUG
+.. |ap3264fdu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_FULL_DEBUG
+.. |ap3264fr| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_FULL_RELEASE
+.. |ap3264fru| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_FULL_RELEASE
+.. |ap3264fn| replace:: Fails - Wontfix - `Bugzilla 2661`_
+.. |ap3264fnu| image:: https://dev.azure.com/tianocore/edk2-ci-play/_apis/build/status/OVMF/OVMF%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=Platform_CI%20OVMF_IA32X64_FULL_NOOPT
+
+.. |br| replace:: :raw-html:`<br />`
-- 
2.16.3.windows.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 5/6] .pytool: Update CI Settings to support Emulator, ArmVirt, and Ovmf packages
       [not found] <20200420191216.24572-1-michael.kubacki@outlook.com>
                   ` (3 preceding siblings ...)
  2020-04-20 19:12 ` [PATCH v2 4/6] OvmfPkg: " Michael Kubacki
@ 2020-04-20 19:12 ` Michael Kubacki
  2020-04-24 20:21   ` [EXTERNAL] " Bret Barkelew
  2020-04-20 19:12 ` [PATCH v2 6/6] .azurepipelines: Update Core CI build matrix to include platforms Michael Kubacki
  5 siblings, 1 reply; 16+ messages in thread
From: Michael Kubacki @ 2020-04-20 19:12 UTC (permalink / raw)
  To: devel; +Cc: Sean Brogan, Bret Barkelew, Michael D Kinney, Liming Gao

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570

Update pytools configuration to enable EmulatorPkg, ArmVirtPkg,
and OvmfPkg.

Update documentation for the status of those packages.
Remove future work items that are now complete.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 .pytool/CISettings.py                      |  7 +++++--
 .pytool/Plugin/SpellCheck/cspell.base.yaml | 14 ++++++++++++++
 .pytool/Readme.md                          | 10 ++++------
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py
index e373d17a6c34..7a8bd3380383 100644
--- a/.pytool/CISettings.py
+++ b/.pytool/CISettings.py
@@ -39,7 +39,9 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
         ''' return iterable of edk2 packages supported by this build.
         These should be edk2 workspace relative paths '''
 
-        return ("MdePkg",
+        return ("ArmVirtPkg",
+                "EmulatorPkg",
+                "MdePkg",
                 "MdeModulePkg",
                 "NetworkPkg",
                 "PcAtChipsetPkg",
@@ -49,7 +51,8 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
                 "ShellPkg",
                 "FatPkg",
                 "CryptoPkg",
-                "UnitTestFrameworkPkg"
+                "UnitTestFrameworkPkg",
+                "OvmfPkg"
                 )
 
     def GetArchitecturesSupported(self):
diff --git a/.pytool/Plugin/SpellCheck/cspell.base.yaml b/.pytool/Plugin/SpellCheck/cspell.base.yaml
index aa15170c013c..1ce5f6991104 100644
--- a/.pytool/Plugin/SpellCheck/cspell.base.yaml
+++ b/.pytool/Plugin/SpellCheck/cspell.base.yaml
@@ -164,5 +164,19 @@
         "Sdhci",
         "inmodule",
         "RISCV",
+        "edksetup",
+        "iscsi",
+        "nvdata",
+        "pytools",
+        "NTDDI",
+        "Wnonportable",
+        "CLANGPDB",
+        "nologo",
+        "lldmap",
+        "ASMLINK",
+        "NODEFAULTLIB",
+        "vcruntimed",
+        "ucrtd",
+        "msvcrtd",
     ]
 }
diff --git a/.pytool/Readme.md b/.pytool/Readme.md
index 135d283fe223..c7dce3b64ca0 100644
--- a/.pytool/Readme.md
+++ b/.pytool/Readme.md
@@ -6,11 +6,11 @@
 | :----               | :-----                   | :----                             | :---         |
 | ArmPkg              |
 | ArmPlatformPkg      |
-| ArmVirtPkg          |
+| ArmVirtPkg          | SEE PACKAGE README | SEE PACKAGE README |
 | CryptoPkg           | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
 | DynamicTablesPkg    |
 | EmbeddedPkg         |
-| EmulatorPkg         |
+| EmulatorPkg         | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
 | FatPkg              | :heavy_check_mark: | :heavy_check_mark: |
 | FmpDevicePkg        | :heavy_check_mark: | :heavy_check_mark: |
 | IntelFsp2Pkg        |
@@ -18,7 +18,7 @@
 | MdeModulePkg        | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode
 | MdePkg              | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
 | NetworkPkg          | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
-| OvmfPkg             |
+| OvmfPkg             | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
 | PcAtChipsetPkg      | :heavy_check_mark: | :heavy_check_mark: |
 | SecurityPkg         | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
 | ShellPkg            | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC
@@ -77,7 +77,7 @@ per package configuration which comes from this file.
 ## Running CI locally
 
 The EDKII Tools environment (and by extension the ci) is designed to support
-easily and consistantly running locally and in a cloud ci environment.  To do
+easily and consistently running locally and in a cloud ci environment.  To do
 that a few steps should be followed.  Details of EDKII Tools can be found in the
 [docs folder here](https://github.com/tianocore/edk2-pytool-extensions/tree/master/docs)
 
@@ -216,8 +216,6 @@ few standard scopes.
 * Visual Studio AARCH64 and ARM support
 * BaseTools C tools CI/PR and binary release process
 * BaseTools Python tools CI/PR process
-* Host based unit testing
 * Extensible private/closed source platform reporting
-* Platform builds, validation
 * UEFI SCTs
 * Other automation
-- 
2.16.3.windows.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 6/6] .azurepipelines: Update Core CI build matrix to include platforms
       [not found] <20200420191216.24572-1-michael.kubacki@outlook.com>
                   ` (4 preceding siblings ...)
  2020-04-20 19:12 ` [PATCH v2 5/6] .pytool: Update CI Settings to support Emulator, ArmVirt, and Ovmf packages Michael Kubacki
@ 2020-04-20 19:12 ` Michael Kubacki
  2020-04-24 20:21   ` [EXTERNAL] " Bret Barkelew
  5 siblings, 1 reply; 16+ messages in thread
From: Michael Kubacki @ 2020-04-20 19:12 UTC (permalink / raw)
  To: devel; +Cc: Sean Brogan, Bret Barkelew, Michael D Kinney, Liming Gao

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570

Add ArmVirtPkg to Core CI matrix
Add EmulatorPkg to Core CI matrix
Add OvmfPkg to Core CI matrix

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 .azurepipelines/templates/pr-gate-build-job.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/.azurepipelines/templates/pr-gate-build-job.yml b/.azurepipelines/templates/pr-gate-build-job.yml
index 61868554d43c..a9f89aa68451 100644
--- a/.azurepipelines/templates/pr-gate-build-job.yml
+++ b/.azurepipelines/templates/pr-gate-build-job.yml
@@ -44,6 +44,11 @@ jobs:
       TARGET_SECURITY:
         Build.Pkgs: 'SecurityPkg'
         Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
+      TARGET_PLATFORMS:
+        # For Platforms only check code. Leave it to Platform CI
+        # to build them.
+        Build.Pkgs: 'ArmVirtPkg,EmulatorPkg,OvmfPkg'
+        Build.Targets: 'NO-TARGET'
 
   workspace:
     clean: all
-- 
2.16.3.windows.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
  2020-04-20 19:12 ` [PATCH v2 3/6] EmulatorPkg: " Michael Kubacki
@ 2020-04-21 14:36   ` Liming Gao
  2020-04-24 20:21     ` Bret Barkelew
  2020-04-21 14:43   ` Ni, Ray
  2020-04-24 20:22   ` [EXTERNAL] " Bret Barkelew
  2 siblings, 1 reply; 16+ messages in thread
From: Liming Gao @ 2020-04-21 14:36 UTC (permalink / raw)
  To: devel@edk2.groups.io, michael.kubacki@outlook.com, Ni, Ray
  Cc: Justen, Jordan L, Andrew Fish

Sean:
  I see some comments on Ovmf. If you make the change in Ovmf, please also update EmulatorPkg. I would like to keep the consistent style in EmulatorPkg/OvmfPkg. 
  This change is good to me. Reviewed-by: Liming Gao <liming.gao@intel.com>

Ray:
  If you have no comment, can you give Ack-by for this change?

Thanks
Liming
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael Kubacki
> Sent: Tuesday, April 21, 2020 3:12 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
> 
> From: Sean Brogan <sean.brogan@microsoft.com>
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570
> 
> Add new Azure Pipeline definitions to build and run EmulatorPkg with:
>   * Ubuntu GCC5
>   * Windows VS2019
> Add PyTool based build of EmulatorPkg
> Add EmulatorPkg.ci.yaml for Core CI
> Add ReadMe.rst for status, details and instructions
> 
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Andrew Fish <afish@apple.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> ---
>  EmulatorPkg/EmulatorPkg.ci.yaml                           |  85 ++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    |  95 +++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml |  85 ++++++
>  EmulatorPkg/PlatformCI/PlatformBuild.py                   | 272 ++++++++++++++++++++
>  EmulatorPkg/README.rst                                    | 175 +++++++++++++
>  5 files changed, 712 insertions(+)
> 
> diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
> new file mode 100644
> index 000000000000..81f81780ec76
> --- /dev/null
> +++ b/EmulatorPkg/EmulatorPkg.ci.yaml
> @@ -0,0 +1,85 @@
> +## @file
> +# Core CI configuration for EmulatorPkg
> +#
> +# EmulatorPkg is part of Platform Ci for builds so this is only
> +# used for code analysis.
> +#
> +# Copyright (c) Microsoft Corporation
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +{
> +    ## options defined .pytool/Plugin/CompilerPlugin
> +    "CompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
> +    "HostUnitTestCompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/CharEncodingCheck
> +    "CharEncodingCheck": {
> +        "IgnoreFiles": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DependencyCheck
> +    "DependencyCheck": {
> +        "AcceptableDependencies": [
> +            # For this platform all packages are allowed???
> +            "MdePkg/MdePkg.dec",
> +            "MdeModulePkg/MdeModulePkg.dec",
> +            "EmulatorPkg/EmulatorPkg.dec",
> +            "NetworkPkg/NetworkPkg.dec",
> +            "EmbeddedPkg/EmbeddedPkg.dec", ## is this one OK??
> +        ],
> +        # For host based unit tests
> +        "AcceptableDependencies-HOST_APPLICATION":[
> +            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
> +        ],
> +        # For UEFI shell based apps
> +        "AcceptableDependencies-UEFI_APPLICATION":[],
> +        "IgnoreInf": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DscCompleteCheck
> +    "DscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": ""  # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
> +    "HostUnitTestDscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/GuidCheck
> +    "GuidCheck": {
> +        "IgnoreGuidName": [],
> +        "IgnoreGuidValue": [],
> +        "IgnoreFoldersAndFiles": [],
> +        "IgnoreDuplicates": [],
> +    },
> +
> +    ## options defined .pytool/Plugin/LibraryClassCheck
> +    "LibraryClassCheck": {
> +        "IgnoreHeaderFile": []
> +    },
> +
> +    ## options defined .pytool/Plugin/SpellCheck
> +    "SpellCheck": {
> +        "AuditOnly": True,           # Fails right now with over 270 errors
> +        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
> +        "ExtendWords": [
> +            "setjump",
> +            "plong",
> +            "lparam",
> +            "lpdword",
> +            "lpthread",
> +            "lresult",
> +        ],           # words to extend to the dictionary for this package
> +        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
> +        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
> +    }
> +}
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
> new file mode 100644
> index 000000000000..12ef8226ff54
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
> @@ -0,0 +1,95 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EmulatorPkg
> +# OS: Ubuntu
> +# Toolchain: GCC5
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'ubuntu-latest'
> +      should_run: false
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: GCC5
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> +        # Add steps to install some IA32 only dependencies
> +        extra_install_step:
> +        - bash: sudo dpkg --add-architecture i386
> +          displayName: Add i386 to dpkg
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get update
> +          displayName: do apt-get update
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +          displayName: Add additional i386 packages
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-
> VS2019.yml
> new file mode 100644
> index 000000000000..a5baf4b6064b
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> @@ -0,0 +1,85 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EMULATORPKG
> +# OS: Windows
> +# Toolchain: VS2019
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'windows-latest'
> +      should_run: true
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: VS2019
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> diff --git a/EmulatorPkg/PlatformCI/PlatformBuild.py b/EmulatorPkg/PlatformCI/PlatformBuild.py
> new file mode 100644
> index 000000000000..6defbf6ef148
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/PlatformBuild.py
> @@ -0,0 +1,272 @@
> +# @file
> +# Script to Build EmulatorPkg UEFI firmware
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import os
> +import logging
> +import io
> +
> +from edk2toolext.environment import shell_environment
> +from edk2toolext.environment.uefi_build import UefiBuilder
> +from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
> +from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
> +from edk2toolext.invocables.edk2_update import UpdateSettingsManager
> +from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
> +from edk2toollib.utility_functions import RunCmd
> +from edk2toollib.utility_functions import GetHostInfo
> +
> +# ####################################################################################### #
> +#                                Common Configuration                                     #
> +# ####################################################################################### #
> +
> +
> +class CommonPlatform():
> +    ''' Common settings for this platform.  Define static data here and use
> +        for the different parts of stuart
> +    '''
> +    PackagesSupported = ("EmulatorPkg",)
> +    ArchSupported = ("X64", "IA32")
> +    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
> +    Scopes = ('emulatorpkg', 'edk2-build')
> +    WorkspaceRoot = os.path.realpath(os.path.join(
> +        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
> +
> +    # ####################################################################################### #
> +    #                         Configuration for Update & Setup                                #
> +    # ####################################################################################### #
> +
> +
> +class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
> +
> +    def GetPackagesSupported(self):
> +        ''' return iterable of edk2 packages supported by this build.
> +        These should be edk2 workspace relative paths '''
> +        return CommonPlatform.PackagesSupported
> +
> +    def GetArchitecturesSupported(self):
> +        ''' return iterable of edk2 architectures supported by this build '''
> +        return CommonPlatform.ArchSupported
> +
> +    def GetTargetsSupported(self):
> +        ''' return iterable of edk2 target tags supported by this build '''
> +        return CommonPlatform.TargetsSupported
> +
> +    def GetRequiredSubmodules(self):
> +        ''' return iterable containing RequiredSubmodule objects.
> +        If no RequiredSubmodules return an empty iterable
> +        '''
> +        rs = []
> +        # intentionally declare this one with recursive false to avoid overhead
> +        rs.append(RequiredSubmodule(
> +            "CryptoPkg/Library/OpensslLib/openssl", False))
> +
> +        # To avoid maintenance of this file for every new submodule
> +        # lets just parse the .gitmodules and add each if not already in list.
> +        # The GetRequiredSubmodules is designed to allow a build to optimize
> +        # the desired submodules but it isn't necessary for this repository.
> +        result = io.StringIO()
> +        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
> +        # Cmd output is expected to look like:
> +        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
> +        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
> +        if ret == 0:
> +            for line in result.getvalue().splitlines():
> +                _, _, path = line.partition(" ")
> +                if path is not None:
> +                    if path not in [x.path for x in rs]:
> +                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
> +        return rs
> +
> +    def SetArchitectures(self, list_of_requested_architectures):
> +        ''' Confirm the requests architecture list is valid and configure SettingsManager
> +        to run only the requested architectures.
> +
> +        Raise Exception if a list_of_requested_architectures is not supported
> +        '''
> +        unsupported = set(list_of_requested_architectures) - \
> +            set(self.GetArchitecturesSupported())
> +        if(len(unsupported) > 0):
> +            errorString = (
> +                "Unsupported Architecture Requested: " + " ".join(unsupported))
> +            logging.critical(errorString)
> +            raise Exception(errorString)
> +        self.ActualArchitectures = list_of_requested_architectures
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
> +        ''' Filter other cases that this package should be built
> +        based on changed files. This should cover things that can't
> +        be detected as dependencies. '''
> +        build_these_packages = []
> +        possible_packages = potentialPackagesList.copy()
> +        for f in changedFilesList:
> +            # BaseTools files that might change the build
> +            if "BaseTools" in f:
> +                if os.path.splitext(f) not in [".txt", ".md"]:
> +                    build_these_packages = possible_packages
> +                    break
> +            # if the azure pipeline platform template file changed
> +            if "platform-build-run-steps.yml" in f:
> +                build_these_packages = possible_packages
> +                break
> +        return build_these_packages
> +
> +    def GetPlatformDscAndConfig(self) -> tuple:
> +        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
> +        any of the changes will be built in the dsc.
> +
> +        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
> +        '''
> +        return (os.path.join("EmulatorPkg", "EmulatorPkg.dsc"), {})
> +
> +    # ####################################################################################### #
> +    #                         Actual Configuration for Platform Build                         #
> +    # ####################################################################################### #
> +
> +
> +class PlatformBuilder(UefiBuilder, BuildSettingsManager):
> +    def __init__(self):
> +        UefiBuilder.__init__(self)
> +
> +    def AddCommandLineOptions(self, parserObj):
> +        ''' Add command line options to the argparser '''
> +        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="X64",
> +                               help="Optional - architecture to build.  IA32 will use IA32 for Pei & Dxe. "
> +                               "X64 will use X64 for both PEI and DXE.")
> +
> +    def RetrieveCommandLineOptions(self, args):
> +        '''  Retrieve command line options from the argparser '''
> +
> +        shell_environment.GetBuildVars().SetValue(
> +            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
> +        shell_environment.GetBuildVars().SetValue(
> +            "ACTIVE_PLATFORM", "EmulatorPkg/EmulatorPkg.dsc", "From CmdLine")
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetPackagesPath(self):
> +        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
> +        return ()
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def GetName(self):
> +        ''' Get the name of the repo, platform, or product being build '''
> +        ''' Used for naming the log file, among others '''
> +
> +        # check the startup nsh flag and if set then rename the log file.
> +        # this helps in CI so we don't overwrite the build log since running
> +        # uses the stuart_build command.
> +        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
> +            return "EmulatorPkg_With_Run"
> +        return "EmulatorPkg"
> +
> +    def GetLoggingLevel(self, loggerType):
> +        ''' Get the logging level for a given type
> +        base == lowest logging level supported
> +        con  == Screen logging
> +        txt  == plain text file logging
> +        md   == markdown file logging
> +        '''
> +        return logging.DEBUG
> +
> +    def SetPlatformEnv(self):
> +        logging.debug("PlatformBuilder SetPlatformEnv")
> +        self.env.SetValue("PRODUCT_NAME", "EmulatorPkg", "Platform Hardcoded")
> +        self.env.SetValue("TOOL_CHAIN_TAG", "VS2019", "Default Toolchain")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building VS2019 or VS2017
> +        if self.env.GetValue("TOOL_CHAIN_TAG") == "VS2019" or self.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":
> +            key = self.env.GetValue("TOOL_CHAIN_TAG") + "_HOST"
> +            if self.env.GetValue("TARGET_ARCH") == "IA32":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x86")
> +            elif self.env.GetValue("TARGET_ARCH") == "X64":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x64")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building on linux.
> +        if GetHostInfo().os.upper() == "LINUX":
> +            self.ConfigureLinuxDLinkPath()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            self.env.SetValue("BLD_*_WIN_HOST_BUILD", "TRUE",
> +                              "Trigger Windows host build")
> +
> +        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
> +
> +        # I don't see what this does but it is in build.sh
> +        key = "BLD_*_BUILD_" + self.env.GetValue("TARGET_ARCH")
> +        self.env.SetValue(key, "TRUE", "match script in build.sh")
> +        return 0
> +
> +    def PlatformPreBuild(self):
> +        return 0
> +
> +    def PlatformPostBuild(self):
> +        return 0
> +
> +    def FlashRomImage(self):
> +        ''' Use the FlashRom Function to run the emulator.  This gives an easy stuart command line to
> +        activate the emulator. '''
> +
> +        OutputPath = os.path.join(self.env.GetValue(
> +            "BUILD_OUTPUT_BASE"), self.env.GetValue("TARGET_ARCH"))
> +
> +        if (self.env.GetValue("MAKE_STARTUP_NSH") == "TRUE"):
> +            f = open(os.path.join(OutputPath, "startup.nsh"), "w")
> +            f.write("BOOT SUCCESS !!! \n")
> +            # add commands here
> +            f.write("reset\n")
> +            f.close()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            cmd = "WinHost.exe"
> +        elif GetHostInfo().os.upper() == "LINUX":
> +            cmd = "./Host"
> +        else:
> +            logging.critical("Unsupported Host")
> +            return -1
> +        return RunCmd(cmd, "", workingdir=OutputPath)
> +
> +    def ConfigureLinuxDLinkPath(self):
> +        '''
> +        logic copied from build.sh to setup the correct libraries
> +        '''
> +        if self.env.GetValue("TARGET_ARCH") == "IA32":
> +            LIB_NAMES = ["ld-linux.so.2", "libdl.so.2 crt1.o", "crti.o crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/i386-linux-gnu",
> +                                "/usr/lib32", "/lib32", "/usr/lib", "/lib"]
> +        elif self.env.GetValue("TARGET_ARCH") == "X64":
> +            LIB_NAMES = ["ld-linux-x86-64.so.2",
> +                         "libdl.so.2", "crt1.o", "crti.o", "crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/x86_64-linux-gnu",
> +                                "/usr/lib64", "/lib64", "/usr/lib", "/lib"]
> +
> +        HOST_DLINK_PATHS = ""
> +        for lname in LIB_NAMES:
> +            logging.debug(f"Looking for {lname}")
> +            for dname in LIB_SEARCH_PATHS:
> +                logging.debug(f"In {dname}")
> +                if os.path.isfile(os.path.join(dname, lname)):
> +                    logging.debug(f"Found {lname} in {dname}")
> +                    HOST_DLINK_PATHS += os.path.join(
> +                        os.path.join(dname, lname)) + os.pathsep
> +                    break
> +        HOST_DLINK_PATHS = HOST_DLINK_PATHS.rstrip(os.pathsep)
> +        logging.critical(f"Setting HOST_DLINK_PATHS to {HOST_DLINK_PATHS}")
> +        shell_environment.ShellEnvironment().set_shell_var(
> +            "HOST_DLINK_PATHS", HOST_DLINK_PATHS)
> diff --git a/EmulatorPkg/README.rst b/EmulatorPkg/README.rst
> new file mode 100644
> index 000000000000..d1aa0a367965
> --- /dev/null
> +++ b/EmulatorPkg/README.rst
> @@ -0,0 +1,175 @@
> +===========
> +EmulatorPkg
> +===========
> +
> +This README.rst summarizes the current state of Azure DevOps Platform CI
> +for EmulatorPkg. It also describes how to *build* EmulatorPkg locally using the
> +Pytools build system. For general documentation on EmulatorPkg, refer
> +to the `ReadMe <./Readme.md>`_.
> +
> +Platform CI Current Status
> +---------------------------
> +
> +IA32 Configuration
> +``````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
> +`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2668|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +X64 Configuration
> +`````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
> +`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2639|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +Setup
> +-----
> +
> +The Usual EDK2 Build Setup
> +``````````````````````````
> +
> +- `Python 3.8.x - Download & Install <https://www.python.org/downloads/>`_
> +- `GIT - Download & Install <https://git-scm.com/download/>`_
> +- `GIT - Configure for EDK II <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#github-help>`_
> +- `EDKII Source - Download/Checkout from Github <https://github.com/tianocore/tianocore.github.io/wiki/Windows-
> systems#download>`_
> +
> +**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
> +
> +Install the necessary development packages for your distribution
> +````````````````````````````````````````````````````````````````
> +
> +This varies by distribution, toolchain, and your configuration but here are a few hints.
> +
> +* For building ARCH IA32 on X64 Ubuntu 18.04 LTS these steps where needed.
> +
> +  .. code-block:: bash
> +
> +    sudo dpkg --add-architecture i386
> +    sudo apt-get update
> +    sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +
> +* For building Basetools and other host applications
> +
> +  .. code-block:: bash
> +
> +    sudo apt-get update
> +    sudo apt-get install gcc g++ make uuid-dev
> +
> +Differences from EDK Classic Build Setup
> +````````````````````````````````````````
> +
> +- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
> +
> +  - This replaces `edksetup Rebuild`" from the classic build system
> +  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix
> <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems-ToolChain-Matrix>`_,
> +    defaults to `VS2017` if not specified
> +
> +- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is
> +  handled by the Pytools build system
> +
> +Install & Configure Pytools for EmulatorPkg
> +```````````````````````````````````````````
> +
> +* Install Pytools
> +
> +  .. code-block:: bash
> +
> +    pip install --upgrade -r pip-requirements.txt
> +
> +* Initialize & Update Submodules
> +
> +  .. code-block:: bash
> +
> +    stuart_setup -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Initialize & Update Dependencies (e.g. iASL & NASM)
> +
> +  .. code-block:: bash
> +
> +    stuart_update -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Compile (IA32 or X64 supported)
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>] -a <TARGET_ARCH>
> +
> +* Running Emulator
> +
> +  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
> +  - or use the `--FlashOnly` feature to just run the emulator.
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> --FlashOnly
> +
> +**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is *not* required.
> +This environment is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
> +
> +Custom Build Options
> +````````````````````
> +
> +**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
> +combination with the `--FlashOnly` feature to run the emulator to the UEFI shell and then execute the
> +contents of startup.nsh.
> +
> +Passing Build Defines
> +`````````````````````
> +
> +To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
> +stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
> +For example, to enable the IP6 Network Stack, the stuart_build command-line would be:
> +
> +.. code-block:: bash
> +
> +  stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py BLD_*_NETWORK_IP6_ENABLE=1
> +
> +References
> +----------
> +
> +- `Installing Pytools <https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md#installing>`_
> +- For each workspace, consider creating & using a `Python Virtual Environment <https://docs.python.org/3/library/venv.html>`_
> +
> +  * `Sample Layout <https://microsoft.github.io/mu/CodeDevelopment/prerequisites/#workspace-virtual-environment-setup-
> process>`_
> +
> +- `stuart_build commandline parser <https://github.com/tianocore/edk2-pytool-
> extensions/blob/56f6a7aee09995c2f22da4765e8b0a29c1cbf5de/edk2toolext/edk2_invocable.py#L109>`_
> +
> +
> +.. ===================================================================
> +.. This is a bunch of directives to make the README file more readable
> +.. ===================================================================
> +
> +.. |TCBZ_2668| image:: https://img.shields.io/bugzilla/2668?baseUrl=https%3A%2F%2Fbugzilla.tianocore.org
> +.. _TCBZ_2668: https://bugzilla.tianocore.org/show_bug.cgi?id=2668
> +
> +.. |TCBZ_2639| image:: https://img.shields.io/bugzilla/2639?baseUrl=https%3A%2F%2Fbugzilla.tianocore.org
> +.. _TCBZ_2639: https://bugzilla.tianocore.org/show_bug.cgi?id=2639
> +
> +.. _Win VS2019:  https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=40&branchName=master
> +.. _Ubuntu GCC5: https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=39&branchName=master
> +
> +.. |ap32d| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configurati
> on=Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32du| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32r| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configurati
> on=Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32ru| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32n| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configurati
> on=Platform_CI%20EmulatorPkg_IA32_NOOPT
> +.. |ap32nu| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_IA32_NOOPT
> +
> +.. |ap64d| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64du| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64r| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64ru| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64n| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_NOOPT
> +.. |ap64nu| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_NOOPT
> --
> 2.16.3.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
  2020-04-20 19:12 ` [PATCH v2 3/6] EmulatorPkg: " Michael Kubacki
  2020-04-21 14:36   ` [edk2-devel] " Liming Gao
@ 2020-04-21 14:43   ` Ni, Ray
  2020-04-24 20:21     ` Bret Barkelew
  2020-04-24 20:22   ` [EXTERNAL] " Bret Barkelew
  2 siblings, 1 reply; 16+ messages in thread
From: Ni, Ray @ 2020-04-21 14:43 UTC (permalink / raw)
  To: devel@edk2.groups.io, michael.kubacki@outlook.com
  Cc: Justen, Jordan L, Andrew Fish

Acked-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael Kubacki
> Sent: Tuesday, April 21, 2020 3:12 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
> 
> From: Sean Brogan <sean.brogan@microsoft.com>
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2570
> 
> Add new Azure Pipeline definitions to build and run EmulatorPkg with:
>   * Ubuntu GCC5
>   * Windows VS2019
> Add PyTool based build of EmulatorPkg
> Add EmulatorPkg.ci.yaml for Core CI
> Add ReadMe.rst for status, details and instructions
> 
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Andrew Fish <afish@apple.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> ---
>  EmulatorPkg/EmulatorPkg.ci.yaml                           |  85 ++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    |  95 +++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml |  85 ++++++
>  EmulatorPkg/PlatformCI/PlatformBuild.py                   | 272 ++++++++++++++++++++
>  EmulatorPkg/README.rst                                    | 175 +++++++++++++
>  5 files changed, 712 insertions(+)
> 
> diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
> new file mode 100644
> index 000000000000..81f81780ec76
> --- /dev/null
> +++ b/EmulatorPkg/EmulatorPkg.ci.yaml
> @@ -0,0 +1,85 @@
> +## @file
> +# Core CI configuration for EmulatorPkg
> +#
> +# EmulatorPkg is part of Platform Ci for builds so this is only
> +# used for code analysis.
> +#
> +# Copyright (c) Microsoft Corporation
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +{
> +    ## options defined .pytool/Plugin/CompilerPlugin
> +    "CompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
> +    "HostUnitTestCompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/CharEncodingCheck
> +    "CharEncodingCheck": {
> +        "IgnoreFiles": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DependencyCheck
> +    "DependencyCheck": {
> +        "AcceptableDependencies": [
> +            # For this platform all packages are allowed???
> +            "MdePkg/MdePkg.dec",
> +            "MdeModulePkg/MdeModulePkg.dec",
> +            "EmulatorPkg/EmulatorPkg.dec",
> +            "NetworkPkg/NetworkPkg.dec",
> +            "EmbeddedPkg/EmbeddedPkg.dec", ## is this one OK??
> +        ],
> +        # For host based unit tests
> +        "AcceptableDependencies-HOST_APPLICATION":[
> +            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
> +        ],
> +        # For UEFI shell based apps
> +        "AcceptableDependencies-UEFI_APPLICATION":[],
> +        "IgnoreInf": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DscCompleteCheck
> +    "DscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": ""  # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
> +    "HostUnitTestDscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/GuidCheck
> +    "GuidCheck": {
> +        "IgnoreGuidName": [],
> +        "IgnoreGuidValue": [],
> +        "IgnoreFoldersAndFiles": [],
> +        "IgnoreDuplicates": [],
> +    },
> +
> +    ## options defined .pytool/Plugin/LibraryClassCheck
> +    "LibraryClassCheck": {
> +        "IgnoreHeaderFile": []
> +    },
> +
> +    ## options defined .pytool/Plugin/SpellCheck
> +    "SpellCheck": {
> +        "AuditOnly": True,           # Fails right now with over 270 errors
> +        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
> +        "ExtendWords": [
> +            "setjump",
> +            "plong",
> +            "lparam",
> +            "lpdword",
> +            "lpthread",
> +            "lresult",
> +        ],           # words to extend to the dictionary for this package
> +        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
> +        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
> +    }
> +}
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-
> GCC5.yml
> new file mode 100644
> index 000000000000..12ef8226ff54
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
> @@ -0,0 +1,95 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EmulatorPkg
> +# OS: Ubuntu
> +# Toolchain: GCC5
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'ubuntu-latest'
> +      should_run: false
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: GCC5
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> +        # Add steps to install some IA32 only dependencies
> +        extra_install_step:
> +        - bash: sudo dpkg --add-architecture i386
> +          displayName: Add i386 to dpkg
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get update
> +          displayName: do apt-get update
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +          displayName: Add additional i386 packages
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> new file mode 100644
> index 000000000000..a5baf4b6064b
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> @@ -0,0 +1,85 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EMULATORPKG
> +# OS: Windows
> +# Toolchain: VS2019
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'windows-latest'
> +      should_run: true
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: VS2019
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> diff --git a/EmulatorPkg/PlatformCI/PlatformBuild.py b/EmulatorPkg/PlatformCI/PlatformBuild.py
> new file mode 100644
> index 000000000000..6defbf6ef148
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/PlatformBuild.py
> @@ -0,0 +1,272 @@
> +# @file
> +# Script to Build EmulatorPkg UEFI firmware
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import os
> +import logging
> +import io
> +
> +from edk2toolext.environment import shell_environment
> +from edk2toolext.environment.uefi_build import UefiBuilder
> +from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
> +from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
> +from edk2toolext.invocables.edk2_update import UpdateSettingsManager
> +from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
> +from edk2toollib.utility_functions import RunCmd
> +from edk2toollib.utility_functions import GetHostInfo
> +
> +# ####################################################################################### #
> +#                                Common Configuration                                     #
> +# ####################################################################################### #
> +
> +
> +class CommonPlatform():
> +    ''' Common settings for this platform.  Define static data here and use
> +        for the different parts of stuart
> +    '''
> +    PackagesSupported = ("EmulatorPkg",)
> +    ArchSupported = ("X64", "IA32")
> +    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
> +    Scopes = ('emulatorpkg', 'edk2-build')
> +    WorkspaceRoot = os.path.realpath(os.path.join(
> +        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
> +
> +    # ####################################################################################### #
> +    #                         Configuration for Update & Setup                                #
> +    # ####################################################################################### #
> +
> +
> +class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
> +
> +    def GetPackagesSupported(self):
> +        ''' return iterable of edk2 packages supported by this build.
> +        These should be edk2 workspace relative paths '''
> +        return CommonPlatform.PackagesSupported
> +
> +    def GetArchitecturesSupported(self):
> +        ''' return iterable of edk2 architectures supported by this build '''
> +        return CommonPlatform.ArchSupported
> +
> +    def GetTargetsSupported(self):
> +        ''' return iterable of edk2 target tags supported by this build '''
> +        return CommonPlatform.TargetsSupported
> +
> +    def GetRequiredSubmodules(self):
> +        ''' return iterable containing RequiredSubmodule objects.
> +        If no RequiredSubmodules return an empty iterable
> +        '''
> +        rs = []
> +        # intentionally declare this one with recursive false to avoid overhead
> +        rs.append(RequiredSubmodule(
> +            "CryptoPkg/Library/OpensslLib/openssl", False))
> +
> +        # To avoid maintenance of this file for every new submodule
> +        # lets just parse the .gitmodules and add each if not already in list.
> +        # The GetRequiredSubmodules is designed to allow a build to optimize
> +        # the desired submodules but it isn't necessary for this repository.
> +        result = io.StringIO()
> +        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(),
> outstream=result)
> +        # Cmd output is expected to look like:
> +        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
> +        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
> +        if ret == 0:
> +            for line in result.getvalue().splitlines():
> +                _, _, path = line.partition(" ")
> +                if path is not None:
> +                    if path not in [x.path for x in rs]:
> +                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
> +        return rs
> +
> +    def SetArchitectures(self, list_of_requested_architectures):
> +        ''' Confirm the requests architecture list is valid and configure SettingsManager
> +        to run only the requested architectures.
> +
> +        Raise Exception if a list_of_requested_architectures is not supported
> +        '''
> +        unsupported = set(list_of_requested_architectures) - \
> +            set(self.GetArchitecturesSupported())
> +        if(len(unsupported) > 0):
> +            errorString = (
> +                "Unsupported Architecture Requested: " + " ".join(unsupported))
> +            logging.critical(errorString)
> +            raise Exception(errorString)
> +        self.ActualArchitectures = list_of_requested_architectures
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
> +        ''' Filter other cases that this package should be built
> +        based on changed files. This should cover things that can't
> +        be detected as dependencies. '''
> +        build_these_packages = []
> +        possible_packages = potentialPackagesList.copy()
> +        for f in changedFilesList:
> +            # BaseTools files that might change the build
> +            if "BaseTools" in f:
> +                if os.path.splitext(f) not in [".txt", ".md"]:
> +                    build_these_packages = possible_packages
> +                    break
> +            # if the azure pipeline platform template file changed
> +            if "platform-build-run-steps.yml" in f:
> +                build_these_packages = possible_packages
> +                break
> +        return build_these_packages
> +
> +    def GetPlatformDscAndConfig(self) -> tuple:
> +        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
> +        any of the changes will be built in the dsc.
> +
> +        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
> +        '''
> +        return (os.path.join("EmulatorPkg", "EmulatorPkg.dsc"), {})
> +
> +    # ####################################################################################### #
> +    #                         Actual Configuration for Platform Build                         #
> +    # ####################################################################################### #
> +
> +
> +class PlatformBuilder(UefiBuilder, BuildSettingsManager):
> +    def __init__(self):
> +        UefiBuilder.__init__(self)
> +
> +    def AddCommandLineOptions(self, parserObj):
> +        ''' Add command line options to the argparser '''
> +        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="X64",
> +                               help="Optional - architecture to build.  IA32 will use IA32 for Pei & Dxe. "
> +                               "X64 will use X64 for both PEI and DXE.")
> +
> +    def RetrieveCommandLineOptions(self, args):
> +        '''  Retrieve command line options from the argparser '''
> +
> +        shell_environment.GetBuildVars().SetValue(
> +            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
> +        shell_environment.GetBuildVars().SetValue(
> +            "ACTIVE_PLATFORM", "EmulatorPkg/EmulatorPkg.dsc", "From CmdLine")
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetPackagesPath(self):
> +        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
> +        return ()
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def GetName(self):
> +        ''' Get the name of the repo, platform, or product being build '''
> +        ''' Used for naming the log file, among others '''
> +
> +        # check the startup nsh flag and if set then rename the log file.
> +        # this helps in CI so we don't overwrite the build log since running
> +        # uses the stuart_build command.
> +        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
> +            return "EmulatorPkg_With_Run"
> +        return "EmulatorPkg"
> +
> +    def GetLoggingLevel(self, loggerType):
> +        ''' Get the logging level for a given type
> +        base == lowest logging level supported
> +        con  == Screen logging
> +        txt  == plain text file logging
> +        md   == markdown file logging
> +        '''
> +        return logging.DEBUG
> +
> +    def SetPlatformEnv(self):
> +        logging.debug("PlatformBuilder SetPlatformEnv")
> +        self.env.SetValue("PRODUCT_NAME", "EmulatorPkg", "Platform Hardcoded")
> +        self.env.SetValue("TOOL_CHAIN_TAG", "VS2019", "Default Toolchain")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building VS2019 or VS2017
> +        if self.env.GetValue("TOOL_CHAIN_TAG") == "VS2019" or self.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":
> +            key = self.env.GetValue("TOOL_CHAIN_TAG") + "_HOST"
> +            if self.env.GetValue("TARGET_ARCH") == "IA32":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x86")
> +            elif self.env.GetValue("TARGET_ARCH") == "X64":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x64")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building on linux.
> +        if GetHostInfo().os.upper() == "LINUX":
> +            self.ConfigureLinuxDLinkPath()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            self.env.SetValue("BLD_*_WIN_HOST_BUILD", "TRUE",
> +                              "Trigger Windows host build")
> +
> +        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
> +
> +        # I don't see what this does but it is in build.sh
> +        key = "BLD_*_BUILD_" + self.env.GetValue("TARGET_ARCH")
> +        self.env.SetValue(key, "TRUE", "match script in build.sh")
> +        return 0
> +
> +    def PlatformPreBuild(self):
> +        return 0
> +
> +    def PlatformPostBuild(self):
> +        return 0
> +
> +    def FlashRomImage(self):
> +        ''' Use the FlashRom Function to run the emulator.  This gives an easy stuart command line to
> +        activate the emulator. '''
> +
> +        OutputPath = os.path.join(self.env.GetValue(
> +            "BUILD_OUTPUT_BASE"), self.env.GetValue("TARGET_ARCH"))
> +
> +        if (self.env.GetValue("MAKE_STARTUP_NSH") == "TRUE"):
> +            f = open(os.path.join(OutputPath, "startup.nsh"), "w")
> +            f.write("BOOT SUCCESS !!! \n")
> +            # add commands here
> +            f.write("reset\n")
> +            f.close()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            cmd = "WinHost.exe"
> +        elif GetHostInfo().os.upper() == "LINUX":
> +            cmd = "./Host"
> +        else:
> +            logging.critical("Unsupported Host")
> +            return -1
> +        return RunCmd(cmd, "", workingdir=OutputPath)
> +
> +    def ConfigureLinuxDLinkPath(self):
> +        '''
> +        logic copied from build.sh to setup the correct libraries
> +        '''
> +        if self.env.GetValue("TARGET_ARCH") == "IA32":
> +            LIB_NAMES = ["ld-linux.so.2", "libdl.so.2 crt1.o", "crti.o crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/i386-linux-gnu",
> +                                "/usr/lib32", "/lib32", "/usr/lib", "/lib"]
> +        elif self.env.GetValue("TARGET_ARCH") == "X64":
> +            LIB_NAMES = ["ld-linux-x86-64.so.2",
> +                         "libdl.so.2", "crt1.o", "crti.o", "crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/x86_64-linux-gnu",
> +                                "/usr/lib64", "/lib64", "/usr/lib", "/lib"]
> +
> +        HOST_DLINK_PATHS = ""
> +        for lname in LIB_NAMES:
> +            logging.debug(f"Looking for {lname}")
> +            for dname in LIB_SEARCH_PATHS:
> +                logging.debug(f"In {dname}")
> +                if os.path.isfile(os.path.join(dname, lname)):
> +                    logging.debug(f"Found {lname} in {dname}")
> +                    HOST_DLINK_PATHS += os.path.join(
> +                        os.path.join(dname, lname)) + os.pathsep
> +                    break
> +        HOST_DLINK_PATHS = HOST_DLINK_PATHS.rstrip(os.pathsep)
> +        logging.critical(f"Setting HOST_DLINK_PATHS to {HOST_DLINK_PATHS}")
> +        shell_environment.ShellEnvironment().set_shell_var(
> +            "HOST_DLINK_PATHS", HOST_DLINK_PATHS)
> diff --git a/EmulatorPkg/README.rst b/EmulatorPkg/README.rst
> new file mode 100644
> index 000000000000..d1aa0a367965
> --- /dev/null
> +++ b/EmulatorPkg/README.rst
> @@ -0,0 +1,175 @@
> +===========
> +EmulatorPkg
> +===========
> +
> +This README.rst summarizes the current state of Azure DevOps Platform CI
> +for EmulatorPkg. It also describes how to *build* EmulatorPkg locally using the
> +Pytools build system. For general documentation on EmulatorPkg, refer
> +to the `ReadMe <./Readme.md>`_.
> +
> +Platform CI Current Status
> +---------------------------
> +
> +IA32 Configuration
> +``````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
> +`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2668|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +X64 Configuration
> +`````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
> +`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2639|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +Setup
> +-----
> +
> +The Usual EDK2 Build Setup
> +``````````````````````````
> +
> +- `Python 3.8.x - Download & Install <https://www.python.org/downloads/>`_
> +- `GIT - Download & Install <https://git-scm.com/download/>`_
> +- `GIT - Configure for EDK II <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems#github-help>`_
> +- `EDKII Source - Download/Checkout from Github <https://github.com/tianocore/tianocore.github.io/wiki/Windows-
> systems#download>`_
> +
> +**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
> +
> +Install the necessary development packages for your distribution
> +````````````````````````````````````````````````````````````````
> +
> +This varies by distribution, toolchain, and your configuration but here are a few hints.
> +
> +* For building ARCH IA32 on X64 Ubuntu 18.04 LTS these steps where needed.
> +
> +  .. code-block:: bash
> +
> +    sudo dpkg --add-architecture i386
> +    sudo apt-get update
> +    sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +
> +* For building Basetools and other host applications
> +
> +  .. code-block:: bash
> +
> +    sudo apt-get update
> +    sudo apt-get install gcc g++ make uuid-dev
> +
> +Differences from EDK Classic Build Setup
> +````````````````````````````````````````
> +
> +- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
> +
> +  - This replaces `edksetup Rebuild`" from the classic build system
> +  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix
> <https://github.com/tianocore/tianocore.github.io/wiki/Windows-systems-ToolChain-Matrix>`_,
> +    defaults to `VS2017` if not specified
> +
> +- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is
> +  handled by the Pytools build system
> +
> +Install & Configure Pytools for EmulatorPkg
> +```````````````````````````````````````````
> +
> +* Install Pytools
> +
> +  .. code-block:: bash
> +
> +    pip install --upgrade -r pip-requirements.txt
> +
> +* Initialize & Update Submodules
> +
> +  .. code-block:: bash
> +
> +    stuart_setup -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Initialize & Update Dependencies (e.g. iASL & NASM)
> +
> +  .. code-block:: bash
> +
> +    stuart_update -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Compile (IA32 or X64 supported)
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>] -a <TARGET_ARCH>
> +
> +* Running Emulator
> +
> +  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
> +  - or use the `--FlashOnly` feature to just run the emulator.
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> -
> -FlashOnly
> +
> +**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is *not* required.
> +This environment is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
> +
> +Custom Build Options
> +````````````````````
> +
> +**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
> +combination with the `--FlashOnly` feature to run the emulator to the UEFI shell and then execute the
> +contents of startup.nsh.
> +
> +Passing Build Defines
> +`````````````````````
> +
> +To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
> +stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
> +For example, to enable the IP6 Network Stack, the stuart_build command-line would be:
> +
> +.. code-block:: bash
> +
> +  stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py BLD_*_NETWORK_IP6_ENABLE=1
> +
> +References
> +----------
> +
> +- `Installing Pytools <https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md#installing>`_
> +- For each workspace, consider creating & using a `Python Virtual Environment
> <https://docs.python.org/3/library/venv.html>`_
> +
> +  * `Sample Layout <https://microsoft.github.io/mu/CodeDevelopment/prerequisites/#workspace-virtual-environment-
> setup-process>`_
> +
> +- `stuart_build commandline parser <https://github.com/tianocore/edk2-pytool-
> extensions/blob/56f6a7aee09995c2f22da4765e8b0a29c1cbf5de/edk2toolext/edk2_invocable.py#L109>`_
> +
> +
> +.. ===================================================================
> +.. This is a bunch of directives to make the README file more readable
> +.. ===================================================================
> +
> +.. |TCBZ_2668| image:: https://img.shields.io/bugzilla/2668?baseUrl=https%3A%2F%2Fbugzilla.tianocore.org
> +.. _TCBZ_2668: https://bugzilla.tianocore.org/show_bug.cgi?id=2668
> +
> +.. |TCBZ_2639| image:: https://img.shields.io/bugzilla/2639?baseUrl=https%3A%2F%2Fbugzilla.tianocore.org
> +.. _TCBZ_2639: https://bugzilla.tianocore.org/show_bug.cgi?id=2639
> +
> +.. _Win VS2019:  https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=40&branchName=master
> +.. _Ubuntu GCC5: https://dev.azure.com/tianocore/edk2-ci-play/_build/latest?definitionId=39&branchName=master
> +
> +.. |ap32d| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&
> configuration=Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32du| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32r| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&
> configuration=Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32ru| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32n| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&
> configuration=Platform_CI%20EmulatorPkg_IA32_NOOPT
> +.. |ap32nu| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_IA32_NOOPT
> +
> +.. |ap64d| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64du| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64r| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64ru| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64n| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_NOOPT
> +.. |ap64nu| image:: https://dev.azure.com/tianocore/edk2-ci-
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_NOOPT
> --
> 2.16.3.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [EXTERNAL] [PATCH v2 6/6] .azurepipelines: Update Core CI build matrix to include platforms
  2020-04-20 19:12 ` [PATCH v2 6/6] .azurepipelines: Update Core CI build matrix to include platforms Michael Kubacki
@ 2020-04-24 20:21   ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:21 UTC (permalink / raw)
  To: michael.kubacki@outlook.com, devel@edk2.groups.io
  Cc: Sean Brogan, Kinney, Michael D, Liming Gao

[-- Attachment #1: Type: text/plain, Size: 2111 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: michael.kubacki@outlook.com <michael.kubacki@outlook.com>
Sent: Monday, April 20, 2020 12:12:16 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Liming Gao <liming.gao@intel.com>
Subject: [EXTERNAL] [PATCH v2 6/6] .azurepipelines: Update Core CI build matrix to include platforms

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C35a2a66b86534606737108d7e55edd1f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067914318497&amp;sdata=pzMfmnS84BV9p1xTmXFAyWyy%2F8RI%2FZ8XaXCxMHf6sB8%3D&amp;reserved=0

Add ArmVirtPkg to Core CI matrix
Add EmulatorPkg to Core CI matrix
Add OvmfPkg to Core CI matrix

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 .azurepipelines/templates/pr-gate-build-job.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/.azurepipelines/templates/pr-gate-build-job.yml b/.azurepipelines/templates/pr-gate-build-job.yml
index 61868554d43c..a9f89aa68451 100644
--- a/.azurepipelines/templates/pr-gate-build-job.yml
+++ b/.azurepipelines/templates/pr-gate-build-job.yml
@@ -44,6 +44,11 @@ jobs:
       TARGET_SECURITY:
         Build.Pkgs: 'SecurityPkg'
         Build.Targets: 'DEBUG,RELEASE,NO-TARGET'
+      TARGET_PLATFORMS:
+        # For Platforms only check code. Leave it to Platform CI
+        # to build them.
+        Build.Pkgs: 'ArmVirtPkg,EmulatorPkg,OvmfPkg'
+        Build.Targets: 'NO-TARGET'

   workspace:
     clean: all
--
2.16.3.windows.1


[-- Attachment #2: Type: text/html, Size: 4349 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
  2020-04-21 14:43   ` Ni, Ray
@ 2020-04-24 20:21     ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:21 UTC (permalink / raw)
  To: devel@edk2.groups.io, ray.ni@intel.com,
	michael.kubacki@outlook.com
  Cc: Justen, Jordan L, Andrew Fish

[-- Attachment #1: Type: text/plain, Size: 43865 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Ni, Ray via groups.io <ray.ni=intel.com@groups.io>
Sent: Tuesday, April 21, 2020 7:43:29 AM
To: devel@edk2.groups.io <devel@edk2.groups.io>; michael.kubacki@outlook.com <michael.kubacki@outlook.com>
Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>
Subject: [EXTERNAL] Re: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI

Acked-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael Kubacki
> Sent: Tuesday, April 21, 2020 3:12 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
>
> From: Sean Brogan <sean.brogan@microsoft.com>
>
> REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=JvB7nU6x2k0pBImPCBErmajsH%2B%2FVfbZdrVV%2BZlKfwL0%3D&amp;reserved=0
>
> Add new Azure Pipeline definitions to build and run EmulatorPkg with:
>   * Ubuntu GCC5
>   * Windows VS2019
> Add PyTool based build of EmulatorPkg
> Add EmulatorPkg.ci.yaml for Core CI
> Add ReadMe.rst for status, details and instructions
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Andrew Fish <afish@apple.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> ---
>  EmulatorPkg/EmulatorPkg.ci.yaml                           |  85 ++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    |  95 +++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml |  85 ++++++
>  EmulatorPkg/PlatformCI/PlatformBuild.py                   | 272 ++++++++++++++++++++
>  EmulatorPkg/README.rst                                    | 175 +++++++++++++
>  5 files changed, 712 insertions(+)
>
> diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
> new file mode 100644
> index 000000000000..81f81780ec76
> --- /dev/null
> +++ b/EmulatorPkg/EmulatorPkg.ci.yaml
> @@ -0,0 +1,85 @@
> +## @file
> +# Core CI configuration for EmulatorPkg
> +#
> +# EmulatorPkg is part of Platform Ci for builds so this is only
> +# used for code analysis.
> +#
> +# Copyright (c) Microsoft Corporation
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +{
> +    ## options defined .pytool/Plugin/CompilerPlugin
> +    "CompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
> +    "HostUnitTestCompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/CharEncodingCheck
> +    "CharEncodingCheck": {
> +        "IgnoreFiles": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DependencyCheck
> +    "DependencyCheck": {
> +        "AcceptableDependencies": [
> +            # For this platform all packages are allowed???
> +            "MdePkg/MdePkg.dec",
> +            "MdeModulePkg/MdeModulePkg.dec",
> +            "EmulatorPkg/EmulatorPkg.dec",
> +            "NetworkPkg/NetworkPkg.dec",
> +            "EmbeddedPkg/EmbeddedPkg.dec", ## is this one OK??
> +        ],
> +        # For host based unit tests
> +        "AcceptableDependencies-HOST_APPLICATION":[
> +            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
> +        ],
> +        # For UEFI shell based apps
> +        "AcceptableDependencies-UEFI_APPLICATION":[],
> +        "IgnoreInf": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DscCompleteCheck
> +    "DscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": ""  # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
> +    "HostUnitTestDscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/GuidCheck
> +    "GuidCheck": {
> +        "IgnoreGuidName": [],
> +        "IgnoreGuidValue": [],
> +        "IgnoreFoldersAndFiles": [],
> +        "IgnoreDuplicates": [],
> +    },
> +
> +    ## options defined .pytool/Plugin/LibraryClassCheck
> +    "LibraryClassCheck": {
> +        "IgnoreHeaderFile": []
> +    },
> +
> +    ## options defined .pytool/Plugin/SpellCheck
> +    "SpellCheck": {
> +        "AuditOnly": True,           # Fails right now with over 270 errors
> +        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
> +        "ExtendWords": [
> +            "setjump",
> +            "plong",
> +            "lparam",
> +            "lpdword",
> +            "lpthread",
> +            "lresult",
> +        ],           # words to extend to the dictionary for this package
> +        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
> +        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
> +    }
> +}
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-
> GCC5.yml
> new file mode 100644
> index 000000000000..12ef8226ff54
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
> @@ -0,0 +1,95 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EmulatorPkg
> +# OS: Ubuntu
> +# Toolchain: GCC5
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'ubuntu-latest'
> +      should_run: false
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: GCC5
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> +        # Add steps to install some IA32 only dependencies
> +        extra_install_step:
> +        - bash: sudo dpkg --add-architecture i386
> +          displayName: Add i386 to dpkg
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get update
> +          displayName: do apt-get update
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +          displayName: Add additional i386 packages
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> new file mode 100644
> index 000000000000..a5baf4b6064b
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> @@ -0,0 +1,85 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EMULATORPKG
> +# OS: Windows
> +# Toolchain: VS2019
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'windows-latest'
> +      should_run: true
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: VS2019
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> diff --git a/EmulatorPkg/PlatformCI/PlatformBuild.py b/EmulatorPkg/PlatformCI/PlatformBuild.py
> new file mode 100644
> index 000000000000..6defbf6ef148
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/PlatformBuild.py
> @@ -0,0 +1,272 @@
> +# @file
> +# Script to Build EmulatorPkg UEFI firmware
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import os
> +import logging
> +import io
> +
> +from edk2toolext.environment import shell_environment
> +from edk2toolext.environment.uefi_build import UefiBuilder
> +from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
> +from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
> +from edk2toolext.invocables.edk2_update import UpdateSettingsManager
> +from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
> +from edk2toollib.utility_functions import RunCmd
> +from edk2toollib.utility_functions import GetHostInfo
> +
> +# ####################################################################################### #
> +#                                Common Configuration                                     #
> +# ####################################################################################### #
> +
> +
> +class CommonPlatform():
> +    ''' Common settings for this platform.  Define static data here and use
> +        for the different parts of stuart
> +    '''
> +    PackagesSupported = ("EmulatorPkg",)
> +    ArchSupported = ("X64", "IA32")
> +    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
> +    Scopes = ('emulatorpkg', 'edk2-build')
> +    WorkspaceRoot = os.path.realpath(os.path.join(
> +        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
> +
> +    # ####################################################################################### #
> +    #                         Configuration for Update & Setup                                #
> +    # ####################################################################################### #
> +
> +
> +class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
> +
> +    def GetPackagesSupported(self):
> +        ''' return iterable of edk2 packages supported by this build.
> +        These should be edk2 workspace relative paths '''
> +        return CommonPlatform.PackagesSupported
> +
> +    def GetArchitecturesSupported(self):
> +        ''' return iterable of edk2 architectures supported by this build '''
> +        return CommonPlatform.ArchSupported
> +
> +    def GetTargetsSupported(self):
> +        ''' return iterable of edk2 target tags supported by this build '''
> +        return CommonPlatform.TargetsSupported
> +
> +    def GetRequiredSubmodules(self):
> +        ''' return iterable containing RequiredSubmodule objects.
> +        If no RequiredSubmodules return an empty iterable
> +        '''
> +        rs = []
> +        # intentionally declare this one with recursive false to avoid overhead
> +        rs.append(RequiredSubmodule(
> +            "CryptoPkg/Library/OpensslLib/openssl", False))
> +
> +        # To avoid maintenance of this file for every new submodule
> +        # lets just parse the .gitmodules and add each if not already in list.
> +        # The GetRequiredSubmodules is designed to allow a build to optimize
> +        # the desired submodules but it isn't necessary for this repository.
> +        result = io.StringIO()
> +        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(),
> outstream=result)
> +        # Cmd output is expected to look like:
> +        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
> +        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
> +        if ret == 0:
> +            for line in result.getvalue().splitlines():
> +                _, _, path = line.partition(" ")
> +                if path is not None:
> +                    if path not in [x.path for x in rs]:
> +                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
> +        return rs
> +
> +    def SetArchitectures(self, list_of_requested_architectures):
> +        ''' Confirm the requests architecture list is valid and configure SettingsManager
> +        to run only the requested architectures.
> +
> +        Raise Exception if a list_of_requested_architectures is not supported
> +        '''
> +        unsupported = set(list_of_requested_architectures) - \
> +            set(self.GetArchitecturesSupported())
> +        if(len(unsupported) > 0):
> +            errorString = (
> +                "Unsupported Architecture Requested: " + " ".join(unsupported))
> +            logging.critical(errorString)
> +            raise Exception(errorString)
> +        self.ActualArchitectures = list_of_requested_architectures
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
> +        ''' Filter other cases that this package should be built
> +        based on changed files. This should cover things that can't
> +        be detected as dependencies. '''
> +        build_these_packages = []
> +        possible_packages = potentialPackagesList.copy()
> +        for f in changedFilesList:
> +            # BaseTools files that might change the build
> +            if "BaseTools" in f:
> +                if os.path.splitext(f) not in [".txt", ".md"]:
> +                    build_these_packages = possible_packages
> +                    break
> +            # if the azure pipeline platform template file changed
> +            if "platform-build-run-steps.yml" in f:
> +                build_these_packages = possible_packages
> +                break
> +        return build_these_packages
> +
> +    def GetPlatformDscAndConfig(self) -> tuple:
> +        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
> +        any of the changes will be built in the dsc.
> +
> +        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
> +        '''
> +        return (os.path.join("EmulatorPkg", "EmulatorPkg.dsc"), {})
> +
> +    # ####################################################################################### #
> +    #                         Actual Configuration for Platform Build                         #
> +    # ####################################################################################### #
> +
> +
> +class PlatformBuilder(UefiBuilder, BuildSettingsManager):
> +    def __init__(self):
> +        UefiBuilder.__init__(self)
> +
> +    def AddCommandLineOptions(self, parserObj):
> +        ''' Add command line options to the argparser '''
> +        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="X64",
> +                               help="Optional - architecture to build.  IA32 will use IA32 for Pei & Dxe. "
> +                               "X64 will use X64 for both PEI and DXE.")
> +
> +    def RetrieveCommandLineOptions(self, args):
> +        '''  Retrieve command line options from the argparser '''
> +
> +        shell_environment.GetBuildVars().SetValue(
> +            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
> +        shell_environment.GetBuildVars().SetValue(
> +            "ACTIVE_PLATFORM", "EmulatorPkg/EmulatorPkg.dsc", "From CmdLine")
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetPackagesPath(self):
> +        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
> +        return ()
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def GetName(self):
> +        ''' Get the name of the repo, platform, or product being build '''
> +        ''' Used for naming the log file, among others '''
> +
> +        # check the startup nsh flag and if set then rename the log file.
> +        # this helps in CI so we don't overwrite the build log since running
> +        # uses the stuart_build command.
> +        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
> +            return "EmulatorPkg_With_Run"
> +        return "EmulatorPkg"
> +
> +    def GetLoggingLevel(self, loggerType):
> +        ''' Get the logging level for a given type
> +        base == lowest logging level supported
> +        con  == Screen logging
> +        txt  == plain text file logging
> +        md   == markdown file logging
> +        '''
> +        return logging.DEBUG
> +
> +    def SetPlatformEnv(self):
> +        logging.debug("PlatformBuilder SetPlatformEnv")
> +        self.env.SetValue("PRODUCT_NAME", "EmulatorPkg", "Platform Hardcoded")
> +        self.env.SetValue("TOOL_CHAIN_TAG", "VS2019", "Default Toolchain")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building VS2019 or VS2017
> +        if self.env.GetValue("TOOL_CHAIN_TAG") == "VS2019" or self.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":
> +            key = self.env.GetValue("TOOL_CHAIN_TAG") + "_HOST"
> +            if self.env.GetValue("TARGET_ARCH") == "IA32":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x86")
> +            elif self.env.GetValue("TARGET_ARCH") == "X64":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x64")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building on linux.
> +        if GetHostInfo().os.upper() == "LINUX":
> +            self.ConfigureLinuxDLinkPath()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            self.env.SetValue("BLD_*_WIN_HOST_BUILD", "TRUE",
> +                              "Trigger Windows host build")
> +
> +        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
> +
> +        # I don't see what this does but it is in build.sh
> +        key = "BLD_*_BUILD_" + self.env.GetValue("TARGET_ARCH")
> +        self.env.SetValue(key, "TRUE", "match script in build.sh")
> +        return 0
> +
> +    def PlatformPreBuild(self):
> +        return 0
> +
> +    def PlatformPostBuild(self):
> +        return 0
> +
> +    def FlashRomImage(self):
> +        ''' Use the FlashRom Function to run the emulator.  This gives an easy stuart command line to
> +        activate the emulator. '''
> +
> +        OutputPath = os.path.join(self.env.GetValue(
> +            "BUILD_OUTPUT_BASE"), self.env.GetValue("TARGET_ARCH"))
> +
> +        if (self.env.GetValue("MAKE_STARTUP_NSH") == "TRUE"):
> +            f = open(os.path.join(OutputPath, "startup.nsh"), "w")
> +            f.write("BOOT SUCCESS !!! \n")
> +            # add commands here
> +            f.write("reset\n")
> +            f.close()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            cmd = "WinHost.exe"
> +        elif GetHostInfo().os.upper() == "LINUX":
> +            cmd = "./Host"
> +        else:
> +            logging.critical("Unsupported Host")
> +            return -1
> +        return RunCmd(cmd, "", workingdir=OutputPath)
> +
> +    def ConfigureLinuxDLinkPath(self):
> +        '''
> +        logic copied from build.sh to setup the correct libraries
> +        '''
> +        if self.env.GetValue("TARGET_ARCH") == "IA32":
> +            LIB_NAMES = ["ld-linux.so.2", "libdl.so.2 crt1.o", "crti.o crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/i386-linux-gnu",
> +                                "/usr/lib32", "/lib32", "/usr/lib", "/lib"]
> +        elif self.env.GetValue("TARGET_ARCH") == "X64":
> +            LIB_NAMES = ["ld-linux-x86-64.so.2",
> +                         "libdl.so.2", "crt1.o", "crti.o", "crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/x86_64-linux-gnu",
> +                                "/usr/lib64", "/lib64", "/usr/lib", "/lib"]
> +
> +        HOST_DLINK_PATHS = ""
> +        for lname in LIB_NAMES:
> +            logging.debug(f"Looking for {lname}")
> +            for dname in LIB_SEARCH_PATHS:
> +                logging.debug(f"In {dname}")
> +                if os.path.isfile(os.path.join(dname, lname)):
> +                    logging.debug(f"Found {lname} in {dname}")
> +                    HOST_DLINK_PATHS += os.path.join(
> +                        os.path.join(dname, lname)) + os.pathsep
> +                    break
> +        HOST_DLINK_PATHS = HOST_DLINK_PATHS.rstrip(os.pathsep)
> +        logging.critical(f"Setting HOST_DLINK_PATHS to {HOST_DLINK_PATHS}")
> +        shell_environment.ShellEnvironment().set_shell_var(
> +            "HOST_DLINK_PATHS", HOST_DLINK_PATHS)
> diff --git a/EmulatorPkg/README.rst b/EmulatorPkg/README.rst
> new file mode 100644
> index 000000000000..d1aa0a367965
> --- /dev/null
> +++ b/EmulatorPkg/README.rst
> @@ -0,0 +1,175 @@
> +===========
> +EmulatorPkg
> +===========
> +
> +This README.rst summarizes the current state of Azure DevOps Platform CI
> +for EmulatorPkg. It also describes how to *build* EmulatorPkg locally using the
> +Pytools build system. For general documentation on EmulatorPkg, refer
> +to the `ReadMe <./Readme.md>`_.
> +
> +Platform CI Current Status
> +---------------------------
> +
> +IA32 Configuration
> +``````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
> +`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2668|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +X64 Configuration
> +`````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
> +`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2639|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +Setup
> +-----
> +
> +The Usual EDK2 Build Setup
> +``````````````````````````
> +
> +- `Python 3.8.x - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.python.org%2Fdownloads%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=VQCxpGl5SSb8cV9%2FGJzhlNbjRH0NCPEyebD1jNIi4mg%3D&amp;reserved=0>`_
> +- `GIT - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit-scm.com%2Fdownload%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=ETH89vbrr4DNOQWyMi6s4BGQ7CL1KRtB%2BLETtHrtuCw%3D&amp;reserved=0>`_
> +- `GIT - Configure for EDK II <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23github-help&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=agu3dYNpQ26bcBKomU8xYDt07dn4iCUfcUX8SBNUR8E%3D&amp;reserved=0>`_
> +- `EDKII Source - Download/Checkout from Github <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=5%2F7rt81jwBZK%2FzlF0zYsn8wmxPOojGQQDJu7N43SCIs%3D&amp;reserved=0
> systems#download>`_
> +
> +**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
> +
> +Install the necessary development packages for your distribution
> +````````````````````````````````````````````````````````````````
> +
> +This varies by distribution, toolchain, and your configuration but here are a few hints.
> +
> +* For building ARCH IA32 on X64 Ubuntu 18.04 LTS these steps where needed.
> +
> +  .. code-block:: bash
> +
> +    sudo dpkg --add-architecture i386
> +    sudo apt-get update
> +    sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +
> +* For building Basetools and other host applications
> +
> +  .. code-block:: bash
> +
> +    sudo apt-get update
> +    sudo apt-get install gcc g++ make uuid-dev
> +
> +Differences from EDK Classic Build Setup
> +````````````````````````````````````````
> +
> +- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
> +
> +  - This replaces `edksetup Rebuild`" from the classic build system
> +  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix
> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems-ToolChain-Matrix&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=MYUTaXbL0eEbWohyPCpmnTpmHJ5bUTTI6383se7diM0%3D&amp;reserved=0>`_,
> +    defaults to `VS2017` if not specified
> +
> +- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is
> +  handled by the Pytools build system
> +
> +Install & Configure Pytools for EmulatorPkg
> +```````````````````````````````````````````
> +
> +* Install Pytools
> +
> +  .. code-block:: bash
> +
> +    pip install --upgrade -r pip-requirements.txt
> +
> +* Initialize & Update Submodules
> +
> +  .. code-block:: bash
> +
> +    stuart_setup -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Initialize & Update Dependencies (e.g. iASL & NASM)
> +
> +  .. code-block:: bash
> +
> +    stuart_update -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Compile (IA32 or X64 supported)
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>] -a <TARGET_ARCH>
> +
> +* Running Emulator
> +
> +  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
> +  - or use the `--FlashOnly` feature to just run the emulator.
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> -
> -FlashOnly
> +
> +**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is *not* required.
> +This environment is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
> +
> +Custom Build Options
> +````````````````````
> +
> +**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
> +combination with the `--FlashOnly` feature to run the emulator to the UEFI shell and then execute the
> +contents of startup.nsh.
> +
> +Passing Build Defines
> +`````````````````````
> +
> +To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
> +stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
> +For example, to enable the IP6 Network Stack, the stuart_build command-line would be:
> +
> +.. code-block:: bash
> +
> +  stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py BLD_*_NETWORK_IP6_ENABLE=1
> +
> +References
> +----------
> +
> +- `Installing Pytools <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2Fmaster%2Fdocs%2Fusing.md%23installing&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=vc5uDCwe6uLeqJNZQPZuHlOezbhYwTxjbQdYNecml%2FI%3D&amp;reserved=0>`_
> +- For each workspace, consider creating & using a `Python Virtual Environment
> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fvenv.html&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=AoWeAOJy70ek22KQdmEq4TKpY67Ttaqw%2Fiddjhm4cqI%3D&amp;reserved=0>`_
> +
> +  * `Sample Layout <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmicrosoft.github.io%2Fmu%2FCodeDevelopment%2Fprerequisites%2F%23workspace-virtual-environment-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=ALAB0us06CAqkVYNq4ZOzWuYIn6tZjwYKxb7RcBX%2Bys%3D&amp;reserved=0
> setup-process>`_
> +
> +- `stuart_build commandline parser <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=XqDNZzsH04%2FQt6VYb%2FfD69OS4W3tO84iQtaJBwQAb9c%3D&amp;reserved=0
> extensions/blob/56f6a7aee09995c2f22da4765e8b0a29c1cbf5de/edk2toolext/edk2_invocable.py#L109>`_
> +
> +
> +.. ===================================================================
> +.. This is a bunch of directives to make the README file more readable
> +.. ===================================================================
> +
> +.. |TCBZ_2668| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fimg.shields.io%2Fbugzilla%2F2668%3FbaseUrl%3Dhttps%253A%252F%252Fbugzilla.tianocore.org&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=6iEnYBmAs18nzJ62x2Ak60wBDE0VrRNiQXFu6ZLHvhI%3D&amp;reserved=0
> +.. _TCBZ_2668: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2668&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=Ow3JWtPspqE6GYD%2BUrxa0UWarmRUfE8kRQDL5LofMxA%3D&amp;reserved=0
> +
> +.. |TCBZ_2639| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fimg.shields.io%2Fbugzilla%2F2639%3FbaseUrl%3Dhttps%253A%252F%252Fbugzilla.tianocore.org&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344287401&amp;sdata=c893bcidlionAC%2FJzdpv0Alw6lSr6yYZe40OsfdcdoI%3D&amp;reserved=0
> +.. _TCBZ_2639: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2639&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=tWjybrNQ%2F9vWty6iiVRzZX8wU1v7OYTxCfMU6A7BDLc%3D&amp;reserved=0
> +
> +.. _Win VS2019:  https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D40%26branchName%3Dmaster&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=m3nzV%2BgjDym6nfIb%2BawSDhjMqUarBd52ibHYwYQv%2Fu0%3D&amp;reserved=0
> +.. _Ubuntu GCC5: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D39%26branchName%3Dmaster&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=kN6eOFHL761YeuxmVT%2F7IBSc650ZpOmrERK3h4K8Mik%3D&amp;reserved=0
> +
> +.. |ap32d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&
> configuration=Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&
> configuration=Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&
> configuration=Platform_CI%20EmulatorPkg_IA32_NOOPT
> +.. |ap32nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_IA32_NOOPT
> +
> +.. |ap64d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_NOOPT
> +.. |ap64nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cff0c73d3359d43cffe9c08d7e6026919%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230770344297383&amp;sdata=jZPE0l0CLb635yfNSIZrIycrNbvUjb%2BUgN%2Fmtrcozvw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&con
> figuration=Platform_CI%20EmulatorPkg_X64_NOOPT
> --
> 2.16.3.windows.1
>
>
>





[-- Attachment #2: Type: text/html, Size: 84772 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
  2020-04-21 14:36   ` [edk2-devel] " Liming Gao
@ 2020-04-24 20:21     ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:21 UTC (permalink / raw)
  To: devel@edk2.groups.io, liming.gao@intel.com,
	michael.kubacki@outlook.com, Ni, Ray
  Cc: Justen, Jordan L, Andrew Fish

[-- Attachment #1: Type: text/plain, Size: 44122 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Liming Gao via groups.io <liming.gao=intel.com@groups.io>
Sent: Tuesday, April 21, 2020 7:36:29 AM
To: devel@edk2.groups.io <devel@edk2.groups.io>; michael.kubacki@outlook.com <michael.kubacki@outlook.com>; Ni, Ray <ray.ni@intel.com>
Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>
Subject: [EXTERNAL] Re: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI

Sean:
  I see some comments on Ovmf. If you make the change in Ovmf, please also update EmulatorPkg. I would like to keep the consistent style in EmulatorPkg/OvmfPkg.
  This change is good to me. Reviewed-by: Liming Gao <liming.gao@intel.com>

Ray:
  If you have no comment, can you give Ack-by for this change?

Thanks
Liming
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael Kubacki
> Sent: Tuesday, April 21, 2020 3:12 AM
> To: devel@edk2.groups.io
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
>
> From: Sean Brogan <sean.brogan@microsoft.com>
>
> REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=pCu5hHjwcDLOBNmjxZzzBOKxI8Yso0IzZg%2Bp343H3v0%3D&amp;reserved=0
>
> Add new Azure Pipeline definitions to build and run EmulatorPkg with:
>   * Ubuntu GCC5
>   * Windows VS2019
> Add PyTool based build of EmulatorPkg
> Add EmulatorPkg.ci.yaml for Core CI
> Add ReadMe.rst for status, details and instructions
>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Andrew Fish <afish@apple.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
> ---
>  EmulatorPkg/EmulatorPkg.ci.yaml                           |  85 ++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    |  95 +++++++
>  EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml |  85 ++++++
>  EmulatorPkg/PlatformCI/PlatformBuild.py                   | 272 ++++++++++++++++++++
>  EmulatorPkg/README.rst                                    | 175 +++++++++++++
>  5 files changed, 712 insertions(+)
>
> diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
> new file mode 100644
> index 000000000000..81f81780ec76
> --- /dev/null
> +++ b/EmulatorPkg/EmulatorPkg.ci.yaml
> @@ -0,0 +1,85 @@
> +## @file
> +# Core CI configuration for EmulatorPkg
> +#
> +# EmulatorPkg is part of Platform Ci for builds so this is only
> +# used for code analysis.
> +#
> +# Copyright (c) Microsoft Corporation
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +{
> +    ## options defined .pytool/Plugin/CompilerPlugin
> +    "CompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
> +    "HostUnitTestCompilerPlugin": {
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/CharEncodingCheck
> +    "CharEncodingCheck": {
> +        "IgnoreFiles": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DependencyCheck
> +    "DependencyCheck": {
> +        "AcceptableDependencies": [
> +            # For this platform all packages are allowed???
> +            "MdePkg/MdePkg.dec",
> +            "MdeModulePkg/MdeModulePkg.dec",
> +            "EmulatorPkg/EmulatorPkg.dec",
> +            "NetworkPkg/NetworkPkg.dec",
> +            "EmbeddedPkg/EmbeddedPkg.dec", ## is this one OK??
> +        ],
> +        # For host based unit tests
> +        "AcceptableDependencies-HOST_APPLICATION":[
> +            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
> +        ],
> +        # For UEFI shell based apps
> +        "AcceptableDependencies-UEFI_APPLICATION":[],
> +        "IgnoreInf": []
> +    },
> +
> +    ## options defined .pytool/Plugin/DscCompleteCheck
> +    "DscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": ""  # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
> +    "HostUnitTestDscCompleteCheck": {
> +        "IgnoreInf": [""],
> +        "DscPath": "" # Don't support this test
> +    },
> +
> +    ## options defined .pytool/Plugin/GuidCheck
> +    "GuidCheck": {
> +        "IgnoreGuidName": [],
> +        "IgnoreGuidValue": [],
> +        "IgnoreFoldersAndFiles": [],
> +        "IgnoreDuplicates": [],
> +    },
> +
> +    ## options defined .pytool/Plugin/LibraryClassCheck
> +    "LibraryClassCheck": {
> +        "IgnoreHeaderFile": []
> +    },
> +
> +    ## options defined .pytool/Plugin/SpellCheck
> +    "SpellCheck": {
> +        "AuditOnly": True,           # Fails right now with over 270 errors
> +        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
> +        "ExtendWords": [
> +            "setjump",
> +            "plong",
> +            "lparam",
> +            "lpdword",
> +            "lpthread",
> +            "lresult",
> +        ],           # words to extend to the dictionary for this package
> +        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
> +        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
> +    }
> +}
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
> new file mode 100644
> index 000000000000..12ef8226ff54
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
> @@ -0,0 +1,95 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EmulatorPkg
> +# OS: Ubuntu
> +# Toolchain: GCC5
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'ubuntu-latest'
> +      should_run: false
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: GCC5
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> +        # Add steps to install some IA32 only dependencies
> +        extra_install_step:
> +        - bash: sudo dpkg --add-architecture i386
> +          displayName: Add i386 to dpkg
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get update
> +          displayName: do apt-get update
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> +        - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +          displayName: Add additional i386 packages
> +          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
> diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-
> VS2019.yml
> new file mode 100644
> index 000000000000..a5baf4b6064b
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
> @@ -0,0 +1,85 @@
> +## @file
> +# Azure Pipeline build file for building a platform.
> +#
> +# Platform: EMULATORPKG
> +# OS: Windows
> +# Toolchain: VS2019
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +trigger:
> +  - master
> +pr:
> +  - master
> +
> +jobs:
> +  - job: Platform_CI
> +    variables:
> +      package: 'EmulatorPkg'
> +      vm_image: 'windows-latest'
> +      should_run: true
> +      run_flags: "MAKE_STARTUP_NSH=TRUE"
> +
> +    #Use matrix to speed up the build process
> +    strategy:
> +        matrix:
> +          EmulatorPkg_X64_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_X64_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "X64"
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_DEBUG:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "DEBUG"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_RELEASE:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "RELEASE"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +          EmulatorPkg_IA32_NOOPT:
> +            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
> +            Build.Arch: "IA32 "
> +            Build.Flags: ""
> +            Build.Target: "NOOPT"
> +            Run.Flags: $(run_flags)
> +            Run: $(should_run)
> +
> +    workspace:
> +      clean: all
> +
> +    pool:
> +      vmImage: $(vm_image)
> +
> +    steps:
> +    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
> +      parameters:
> +        tool_chain_tag: VS2019
> +        build_pkg: $(package)
> +        build_target: $(Build.Target)
> +        build_arch: $(Build.Arch)
> +        build_file: $(Build.File)
> +        build_flags: $(Build.Flags)
> +        run_flags: $(Run.Flags)
> diff --git a/EmulatorPkg/PlatformCI/PlatformBuild.py b/EmulatorPkg/PlatformCI/PlatformBuild.py
> new file mode 100644
> index 000000000000..6defbf6ef148
> --- /dev/null
> +++ b/EmulatorPkg/PlatformCI/PlatformBuild.py
> @@ -0,0 +1,272 @@
> +# @file
> +# Script to Build EmulatorPkg UEFI firmware
> +#
> +# Copyright (c) Microsoft Corporation.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +import os
> +import logging
> +import io
> +
> +from edk2toolext.environment import shell_environment
> +from edk2toolext.environment.uefi_build import UefiBuilder
> +from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
> +from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
> +from edk2toolext.invocables.edk2_update import UpdateSettingsManager
> +from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
> +from edk2toollib.utility_functions import RunCmd
> +from edk2toollib.utility_functions import GetHostInfo
> +
> +# ####################################################################################### #
> +#                                Common Configuration                                     #
> +# ####################################################################################### #
> +
> +
> +class CommonPlatform():
> +    ''' Common settings for this platform.  Define static data here and use
> +        for the different parts of stuart
> +    '''
> +    PackagesSupported = ("EmulatorPkg",)
> +    ArchSupported = ("X64", "IA32")
> +    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
> +    Scopes = ('emulatorpkg', 'edk2-build')
> +    WorkspaceRoot = os.path.realpath(os.path.join(
> +        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
> +
> +    # ####################################################################################### #
> +    #                         Configuration for Update & Setup                                #
> +    # ####################################################################################### #
> +
> +
> +class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
> +
> +    def GetPackagesSupported(self):
> +        ''' return iterable of edk2 packages supported by this build.
> +        These should be edk2 workspace relative paths '''
> +        return CommonPlatform.PackagesSupported
> +
> +    def GetArchitecturesSupported(self):
> +        ''' return iterable of edk2 architectures supported by this build '''
> +        return CommonPlatform.ArchSupported
> +
> +    def GetTargetsSupported(self):
> +        ''' return iterable of edk2 target tags supported by this build '''
> +        return CommonPlatform.TargetsSupported
> +
> +    def GetRequiredSubmodules(self):
> +        ''' return iterable containing RequiredSubmodule objects.
> +        If no RequiredSubmodules return an empty iterable
> +        '''
> +        rs = []
> +        # intentionally declare this one with recursive false to avoid overhead
> +        rs.append(RequiredSubmodule(
> +            "CryptoPkg/Library/OpensslLib/openssl", False))
> +
> +        # To avoid maintenance of this file for every new submodule
> +        # lets just parse the .gitmodules and add each if not already in list.
> +        # The GetRequiredSubmodules is designed to allow a build to optimize
> +        # the desired submodules but it isn't necessary for this repository.
> +        result = io.StringIO()
> +        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
> +        # Cmd output is expected to look like:
> +        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
> +        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
> +        if ret == 0:
> +            for line in result.getvalue().splitlines():
> +                _, _, path = line.partition(" ")
> +                if path is not None:
> +                    if path not in [x.path for x in rs]:
> +                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
> +        return rs
> +
> +    def SetArchitectures(self, list_of_requested_architectures):
> +        ''' Confirm the requests architecture list is valid and configure SettingsManager
> +        to run only the requested architectures.
> +
> +        Raise Exception if a list_of_requested_architectures is not supported
> +        '''
> +        unsupported = set(list_of_requested_architectures) - \
> +            set(self.GetArchitecturesSupported())
> +        if(len(unsupported) > 0):
> +            errorString = (
> +                "Unsupported Architecture Requested: " + " ".join(unsupported))
> +            logging.critical(errorString)
> +            raise Exception(errorString)
> +        self.ActualArchitectures = list_of_requested_architectures
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
> +        ''' Filter other cases that this package should be built
> +        based on changed files. This should cover things that can't
> +        be detected as dependencies. '''
> +        build_these_packages = []
> +        possible_packages = potentialPackagesList.copy()
> +        for f in changedFilesList:
> +            # BaseTools files that might change the build
> +            if "BaseTools" in f:
> +                if os.path.splitext(f) not in [".txt", ".md"]:
> +                    build_these_packages = possible_packages
> +                    break
> +            # if the azure pipeline platform template file changed
> +            if "platform-build-run-steps.yml" in f:
> +                build_these_packages = possible_packages
> +                break
> +        return build_these_packages
> +
> +    def GetPlatformDscAndConfig(self) -> tuple:
> +        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
> +        any of the changes will be built in the dsc.
> +
> +        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
> +        '''
> +        return (os.path.join("EmulatorPkg", "EmulatorPkg.dsc"), {})
> +
> +    # ####################################################################################### #
> +    #                         Actual Configuration for Platform Build                         #
> +    # ####################################################################################### #
> +
> +
> +class PlatformBuilder(UefiBuilder, BuildSettingsManager):
> +    def __init__(self):
> +        UefiBuilder.__init__(self)
> +
> +    def AddCommandLineOptions(self, parserObj):
> +        ''' Add command line options to the argparser '''
> +        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="X64",
> +                               help="Optional - architecture to build.  IA32 will use IA32 for Pei & Dxe. "
> +                               "X64 will use X64 for both PEI and DXE.")
> +
> +    def RetrieveCommandLineOptions(self, args):
> +        '''  Retrieve command line options from the argparser '''
> +
> +        shell_environment.GetBuildVars().SetValue(
> +            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
> +        shell_environment.GetBuildVars().SetValue(
> +            "ACTIVE_PLATFORM", "EmulatorPkg/EmulatorPkg.dsc", "From CmdLine")
> +
> +    def GetWorkspaceRoot(self):
> +        ''' get WorkspacePath '''
> +        return CommonPlatform.WorkspaceRoot
> +
> +    def GetPackagesPath(self):
> +        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
> +        return ()
> +
> +    def GetActiveScopes(self):
> +        ''' return tuple containing scopes that should be active for this process '''
> +        return CommonPlatform.Scopes
> +
> +    def GetName(self):
> +        ''' Get the name of the repo, platform, or product being build '''
> +        ''' Used for naming the log file, among others '''
> +
> +        # check the startup nsh flag and if set then rename the log file.
> +        # this helps in CI so we don't overwrite the build log since running
> +        # uses the stuart_build command.
> +        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
> +            return "EmulatorPkg_With_Run"
> +        return "EmulatorPkg"
> +
> +    def GetLoggingLevel(self, loggerType):
> +        ''' Get the logging level for a given type
> +        base == lowest logging level supported
> +        con  == Screen logging
> +        txt  == plain text file logging
> +        md   == markdown file logging
> +        '''
> +        return logging.DEBUG
> +
> +    def SetPlatformEnv(self):
> +        logging.debug("PlatformBuilder SetPlatformEnv")
> +        self.env.SetValue("PRODUCT_NAME", "EmulatorPkg", "Platform Hardcoded")
> +        self.env.SetValue("TOOL_CHAIN_TAG", "VS2019", "Default Toolchain")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building VS2019 or VS2017
> +        if self.env.GetValue("TOOL_CHAIN_TAG") == "VS2019" or self.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":
> +            key = self.env.GetValue("TOOL_CHAIN_TAG") + "_HOST"
> +            if self.env.GetValue("TARGET_ARCH") == "IA32":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x86")
> +            elif self.env.GetValue("TARGET_ARCH") == "X64":
> +                shell_environment.ShellEnvironment().set_shell_var(key, "x64")
> +
> +        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
> +        # requested to be built when building on linux.
> +        if GetHostInfo().os.upper() == "LINUX":
> +            self.ConfigureLinuxDLinkPath()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            self.env.SetValue("BLD_*_WIN_HOST_BUILD", "TRUE",
> +                              "Trigger Windows host build")
> +
> +        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
> +
> +        # I don't see what this does but it is in build.sh
> +        key = "BLD_*_BUILD_" + self.env.GetValue("TARGET_ARCH")
> +        self.env.SetValue(key, "TRUE", "match script in build.sh")
> +        return 0
> +
> +    def PlatformPreBuild(self):
> +        return 0
> +
> +    def PlatformPostBuild(self):
> +        return 0
> +
> +    def FlashRomImage(self):
> +        ''' Use the FlashRom Function to run the emulator.  This gives an easy stuart command line to
> +        activate the emulator. '''
> +
> +        OutputPath = os.path.join(self.env.GetValue(
> +            "BUILD_OUTPUT_BASE"), self.env.GetValue("TARGET_ARCH"))
> +
> +        if (self.env.GetValue("MAKE_STARTUP_NSH") == "TRUE"):
> +            f = open(os.path.join(OutputPath, "startup.nsh"), "w")
> +            f.write("BOOT SUCCESS !!! \n")
> +            # add commands here
> +            f.write("reset\n")
> +            f.close()
> +
> +        if GetHostInfo().os.upper() == "WINDOWS":
> +            cmd = "WinHost.exe"
> +        elif GetHostInfo().os.upper() == "LINUX":
> +            cmd = "./Host"
> +        else:
> +            logging.critical("Unsupported Host")
> +            return -1
> +        return RunCmd(cmd, "", workingdir=OutputPath)
> +
> +    def ConfigureLinuxDLinkPath(self):
> +        '''
> +        logic copied from build.sh to setup the correct libraries
> +        '''
> +        if self.env.GetValue("TARGET_ARCH") == "IA32":
> +            LIB_NAMES = ["ld-linux.so.2", "libdl.so.2 crt1.o", "crti.o crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/i386-linux-gnu",
> +                                "/usr/lib32", "/lib32", "/usr/lib", "/lib"]
> +        elif self.env.GetValue("TARGET_ARCH") == "X64":
> +            LIB_NAMES = ["ld-linux-x86-64.so.2",
> +                         "libdl.so.2", "crt1.o", "crti.o", "crtn.o"]
> +            LIB_SEARCH_PATHS = ["/usr/lib/x86_64-linux-gnu",
> +                                "/usr/lib64", "/lib64", "/usr/lib", "/lib"]
> +
> +        HOST_DLINK_PATHS = ""
> +        for lname in LIB_NAMES:
> +            logging.debug(f"Looking for {lname}")
> +            for dname in LIB_SEARCH_PATHS:
> +                logging.debug(f"In {dname}")
> +                if os.path.isfile(os.path.join(dname, lname)):
> +                    logging.debug(f"Found {lname} in {dname}")
> +                    HOST_DLINK_PATHS += os.path.join(
> +                        os.path.join(dname, lname)) + os.pathsep
> +                    break
> +        HOST_DLINK_PATHS = HOST_DLINK_PATHS.rstrip(os.pathsep)
> +        logging.critical(f"Setting HOST_DLINK_PATHS to {HOST_DLINK_PATHS}")
> +        shell_environment.ShellEnvironment().set_shell_var(
> +            "HOST_DLINK_PATHS", HOST_DLINK_PATHS)
> diff --git a/EmulatorPkg/README.rst b/EmulatorPkg/README.rst
> new file mode 100644
> index 000000000000..d1aa0a367965
> --- /dev/null
> +++ b/EmulatorPkg/README.rst
> @@ -0,0 +1,175 @@
> +===========
> +EmulatorPkg
> +===========
> +
> +This README.rst summarizes the current state of Azure DevOps Platform CI
> +for EmulatorPkg. It also describes how to *build* EmulatorPkg locally using the
> +Pytools build system. For general documentation on EmulatorPkg, refer
> +to the `ReadMe <./Readme.md>`_.
> +
> +Platform CI Current Status
> +---------------------------
> +
> +IA32 Configuration
> +``````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
> +`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2668|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +X64 Configuration
> +`````````````````
> +=============== ============= ============= =============
> + Toolchain      DEBUG         RELEASE       NOOPT
> +=============== ============= ============= =============
> +`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
> +`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
> +=============== ============= ============= =============
> +
> +|TCBZ_2639|_ - Ubuntu GCC5 Segfaults during execution.  The builds
> +only compile for Ubuntu GCC5 (not run to shell).
> +
> +Setup
> +-----
> +
> +The Usual EDK2 Build Setup
> +``````````````````````````
> +
> +- `Python 3.8.x - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.python.org%2Fdownloads%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=%2Fq29UVMlCD9AS8rSUH0BUPUW3NaJpxkm7VS1YMrB424%3D&amp;reserved=0>`_
> +- `GIT - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit-scm.com%2Fdownload%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=MIiVZlpGg9XIgBQlpPJq8DiPI6FuT7cgqgTzj1D%2FEwk%3D&amp;reserved=0>`_
> +- `GIT - Configure for EDK II <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23github-help&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=1nvAH1RUWUudowSRLvn2mZMi9Yq0aVeyI3TYg9xCWtA%3D&amp;reserved=0>`_
> +- `EDKII Source - Download/Checkout from Github <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=tJe2emY3XuC5%2BJR0ywqoaXMQFKm8CetxCxbjCyFiX70%3D&amp;reserved=0
> systems#download>`_
> +
> +**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
> +
> +Install the necessary development packages for your distribution
> +````````````````````````````````````````````````````````````````
> +
> +This varies by distribution, toolchain, and your configuration but here are a few hints.
> +
> +* For building ARCH IA32 on X64 Ubuntu 18.04 LTS these steps where needed.
> +
> +  .. code-block:: bash
> +
> +    sudo dpkg --add-architecture i386
> +    sudo apt-get update
> +    sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
> +
> +* For building Basetools and other host applications
> +
> +  .. code-block:: bash
> +
> +    sudo apt-get update
> +    sudo apt-get install gcc g++ make uuid-dev
> +
> +Differences from EDK Classic Build Setup
> +````````````````````````````````````````
> +
> +- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
> +
> +  - This replaces `edksetup Rebuild`" from the classic build system
> +  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix
> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems-ToolChain-Matrix&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=SM5IdEUHpyQLLQhKiywhG42F7PvC6hR9Gfo%2FD5y2870%3D&amp;reserved=0>`_,
> +    defaults to `VS2017` if not specified
> +
> +- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is
> +  handled by the Pytools build system
> +
> +Install & Configure Pytools for EmulatorPkg
> +```````````````````````````````````````````
> +
> +* Install Pytools
> +
> +  .. code-block:: bash
> +
> +    pip install --upgrade -r pip-requirements.txt
> +
> +* Initialize & Update Submodules
> +
> +  .. code-block:: bash
> +
> +    stuart_setup -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Initialize & Update Dependencies (e.g. iASL & NASM)
> +
> +  .. code-block:: bash
> +
> +    stuart_update -c EmulatorPkg/PlatformCI/PlatformBuild.py
> +
> +* Compile (IA32 or X64 supported)
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>] -a <TARGET_ARCH>
> +
> +* Running Emulator
> +
> +  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
> +  - or use the `--FlashOnly` feature to just run the emulator.
> +
> +  .. code-block:: bash
> +
> +    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> --FlashOnly
> +
> +**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is *not* required.
> +This environment is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
> +
> +Custom Build Options
> +````````````````````
> +
> +**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
> +combination with the `--FlashOnly` feature to run the emulator to the UEFI shell and then execute the
> +contents of startup.nsh.
> +
> +Passing Build Defines
> +`````````````````````
> +
> +To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
> +stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
> +For example, to enable the IP6 Network Stack, the stuart_build command-line would be:
> +
> +.. code-block:: bash
> +
> +  stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py BLD_*_NETWORK_IP6_ENABLE=1
> +
> +References
> +----------
> +
> +- `Installing Pytools <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2Fmaster%2Fdocs%2Fusing.md%23installing&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=I14xQJ9U4Ep8sBFgW6LOTGlOIlqEINP558Kgi8Er6AM%3D&amp;reserved=0>`_
> +- For each workspace, consider creating & using a `Python Virtual Environment <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fvenv.html&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=xWDB1uVaRhOxHsfru7wCki8nuXfY4xB%2Fk3ta5zHs1qI%3D&amp;reserved=0>`_
> +
> +  * `Sample Layout <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmicrosoft.github.io%2Fmu%2FCodeDevelopment%2Fprerequisites%2F%23workspace-virtual-environment-setup-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=ZAxyuKbZDjYK5AIlmvNKnBZUZEp45nVTpqO9eMbyKjk%3D&amp;reserved=0
> process>`_
> +
> +- `stuart_build commandline parser <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=px8QGh%2BeOSAKZbGkpuN3UxVWDxXlXt1m2JLYY4sQoQI%3D&amp;reserved=0
> extensions/blob/56f6a7aee09995c2f22da4765e8b0a29c1cbf5de/edk2toolext/edk2_invocable.py#L109>`_
> +
> +
> +.. ===================================================================
> +.. This is a bunch of directives to make the README file more readable
> +.. ===================================================================
> +
> +.. |TCBZ_2668| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fimg.shields.io%2Fbugzilla%2F2668%3FbaseUrl%3Dhttps%253A%252F%252Fbugzilla.tianocore.org&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=Y%2FkpWziEaD%2FNxg2xmR7qSAf%2BhYN0GjIl51fgyUwQF0c%3D&amp;reserved=0
> +.. _TCBZ_2668: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2668&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=8cQF13gRnPOWP2pXwq256rLl2wFdTMLiucd0Xt8544I%3D&amp;reserved=0
> +
> +.. |TCBZ_2639| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fimg.shields.io%2Fbugzilla%2F2639%3FbaseUrl%3Dhttps%253A%252F%252Fbugzilla.tianocore.org&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006138775&amp;sdata=iBhLUOcFykBEvbC0C4ntnB7u5lX3pYW2DlQCGJoqeWE%3D&amp;reserved=0
> +.. _TCBZ_2639: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2639&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=olU%2BBSw995DJFFjIwAa7IsEnrbwnwXDK1w1cNQ5cL6I%3D&amp;reserved=0
> +
> +.. _Win VS2019:  https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D40%26branchName%3Dmaster&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=ZcS35qz%2BxXUfOPWWxCUIOya1S0TkfnVbREQoVfIGLZ0%3D&amp;reserved=0
> +.. _Ubuntu GCC5: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D39%26branchName%3Dmaster&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=M6PVd2dLSX5G9Nq0PI2YirmnB6n2Xf7n7goPSlnvtDs%3D&amp;reserved=0
> +
> +.. |ap32d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configurati
> on=Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_IA32_DEBUG
> +.. |ap32r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configurati
> on=Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_IA32_RELEASE
> +.. |ap32n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Windows%20VS2019?branchName=master&jobName=Platform_CI&configurati
> on=Platform_CI%20EmulatorPkg_IA32_NOOPT
> +.. |ap32nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_IA32_NOOPT
> +
> +.. |ap64d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_DEBUG
> +.. |ap64r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_RELEASE
> +.. |ap64n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_NOOPT
> +.. |ap64nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cda746308e0184e5d75fe08d7e601664b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230766006148770&amp;sdata=uhKrJBCC8ADSD7gqXNrrPDtfltbqFAxbrt7w0DctFWw%3D&amp;reserved=0
> play/_apis/build/status/EmulatorPkg/EmulatorPkg%20Ubuntu%20GCC5?branchName=master&jobName=Platform_CI&configuration=
> Platform_CI%20EmulatorPkg_X64_NOOPT
> --
> 2.16.3.windows.1
>
>
>





[-- Attachment #2: Type: text/html, Size: 85341 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [EXTERNAL] [PATCH v2 5/6] .pytool: Update CI Settings to support Emulator, ArmVirt, and Ovmf packages
  2020-04-20 19:12 ` [PATCH v2 5/6] .pytool: Update CI Settings to support Emulator, ArmVirt, and Ovmf packages Michael Kubacki
@ 2020-04-24 20:21   ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:21 UTC (permalink / raw)
  To: michael.kubacki@outlook.com, devel@edk2.groups.io
  Cc: Sean Brogan, Kinney, Michael D, Liming Gao

[-- Attachment #1: Type: text/plain, Size: 6089 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: michael.kubacki@outlook.com <michael.kubacki@outlook.com>
Sent: Monday, April 20, 2020 12:12:15 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Liming Gao <liming.gao@intel.com>
Subject: [EXTERNAL] [PATCH v2 5/6] .pytool: Update CI Settings to support Emulator, ArmVirt, and Ovmf packages

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cfcddced9f97b4eb3047908d7e55edc0f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067892859716&amp;sdata=jC3zSf4H9z%2FfX0EDnIhKc0nB9oITgNHh8d5y25LEPUs%3D&amp;reserved=0

Update pytools configuration to enable EmulatorPkg, ArmVirtPkg,
and OvmfPkg.

Update documentation for the status of those packages.
Remove future work items that are now complete.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 .pytool/CISettings.py                      |  7 +++++--
 .pytool/Plugin/SpellCheck/cspell.base.yaml | 14 ++++++++++++++
 .pytool/Readme.md                          | 10 ++++------
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py
index e373d17a6c34..7a8bd3380383 100644
--- a/.pytool/CISettings.py
+++ b/.pytool/CISettings.py
@@ -39,7 +39,9 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
         ''' return iterable of edk2 packages supported by this build.
         These should be edk2 workspace relative paths '''

-        return ("MdePkg",
+        return ("ArmVirtPkg",
+                "EmulatorPkg",
+                "MdePkg",
                 "MdeModulePkg",
                 "NetworkPkg",
                 "PcAtChipsetPkg",
@@ -49,7 +51,8 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
                 "ShellPkg",
                 "FatPkg",
                 "CryptoPkg",
-                "UnitTestFrameworkPkg"
+                "UnitTestFrameworkPkg",
+                "OvmfPkg"
                 )

     def GetArchitecturesSupported(self):
diff --git a/.pytool/Plugin/SpellCheck/cspell.base.yaml b/.pytool/Plugin/SpellCheck/cspell.base.yaml
index aa15170c013c..1ce5f6991104 100644
--- a/.pytool/Plugin/SpellCheck/cspell.base.yaml
+++ b/.pytool/Plugin/SpellCheck/cspell.base.yaml
@@ -164,5 +164,19 @@
         "Sdhci",
         "inmodule",
         "RISCV",
+        "edksetup",
+        "iscsi",
+        "nvdata",
+        "pytools",
+        "NTDDI",
+        "Wnonportable",
+        "CLANGPDB",
+        "nologo",
+        "lldmap",
+        "ASMLINK",
+        "NODEFAULTLIB",
+        "vcruntimed",
+        "ucrtd",
+        "msvcrtd",
     ]
 }
diff --git a/.pytool/Readme.md b/.pytool/Readme.md
index 135d283fe223..c7dce3b64ca0 100644
--- a/.pytool/Readme.md
+++ b/.pytool/Readme.md
@@ -6,11 +6,11 @@
 | :----               | :-----                   | :----                             | :---         |
 | ArmPkg              |
 | ArmPlatformPkg      |
-| ArmVirtPkg          |
+| ArmVirtPkg          | SEE PACKAGE README | SEE PACKAGE README |
 | CryptoPkg           | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
 | DynamicTablesPkg    |
 | EmbeddedPkg         |
-| EmulatorPkg         |
+| EmulatorPkg         | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
 | FatPkg              | :heavy_check_mark: | :heavy_check_mark: |
 | FmpDevicePkg        | :heavy_check_mark: | :heavy_check_mark: |
 | IntelFsp2Pkg        |
@@ -18,7 +18,7 @@
 | MdeModulePkg        | :heavy_check_mark: | :heavy_check_mark: | DxeIpl dependency on ArmPkg, Depends on StandaloneMmPkg, Spell checking in audit mode
 | MdePkg              | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
 | NetworkPkg          | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
-| OvmfPkg             |
+| OvmfPkg             | SEE PACKAGE README | SEE PACKAGE README | Spell checking in audit mode
 | PcAtChipsetPkg      | :heavy_check_mark: | :heavy_check_mark: |
 | SecurityPkg         | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode
 | ShellPkg            | :heavy_check_mark: | :heavy_check_mark: | Spell checking in audit mode, 3 modules are not being built by DSC
@@ -77,7 +77,7 @@ per package configuration which comes from this file.
 ## Running CI locally

 The EDKII Tools environment (and by extension the ci) is designed to support
-easily and consistantly running locally and in a cloud ci environment.  To do
+easily and consistently running locally and in a cloud ci environment.  To do
 that a few steps should be followed.  Details of EDKII Tools can be found in the
 [docs folder here](https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Ftree%2Fmaster%2Fdocs&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cfcddced9f97b4eb3047908d7e55edc0f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067892869711&amp;sdata=b2q62LS4ywLkYm5qr2JRo7LDTLd0r1vgE%2BG3fULp5Gw%3D&amp;reserved=0)

@@ -216,8 +216,6 @@ few standard scopes.
 * Visual Studio AARCH64 and ARM support
 * BaseTools C tools CI/PR and binary release process
 * BaseTools Python tools CI/PR process
-* Host based unit testing
 * Extensible private/closed source platform reporting
-* Platform builds, validation
 * UEFI SCTs
 * Other automation
--
2.16.3.windows.1


[-- Attachment #2: Type: text/html, Size: 12607 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [EXTERNAL] [edk2-devel] [PATCH v2 4/6] OvmfPkg: Add Platform CI and configuration for Core CI
  2020-04-20 19:12 ` [PATCH v2 4/6] OvmfPkg: " Michael Kubacki
@ 2020-04-24 20:22   ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:22 UTC (permalink / raw)
  To: devel@edk2.groups.io, michael.kubacki@outlook.com
  Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel

[-- Attachment #1: Type: text/plain, Size: 52839 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Michael Kubacki via groups.io <michael.kubacki=outlook.com@groups.io>
Sent: Monday, April 20, 2020 12:12:14 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Jordan Justen <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>
Subject: [EXTERNAL] [edk2-devel] [PATCH v2 4/6] OvmfPkg: Add Platform CI and configuration for Core CI

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886270375&amp;sdata=o9bzrzAgNtEoNczkjtAgS6F2EOsl3J07NIaBPJgvVew%3D&amp;reserved=0

Add new Azure Pipeline definitions to build and run OvmfPkg with:
  * Ubuntu GCC5
  * Windows VS2019
Add PyTool based build of OvmfPkg
Add extdep for managing the iasl dependency
Add OvmfPkg.ci.yaml for Core CI
Add README.rst for status, details and instructions

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 OvmfPkg/OvmfPkg.ci.yaml                               |  83 +++++++
 OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    | 133 ++++++++++
 OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml | 138 +++++++++++
 OvmfPkg/PlatformCI/PlatformBuild.py                   | 254 ++++++++++++++++++++
 OvmfPkg/PlatformCI/iasl_ext_dep.yaml                  |  21 ++
 OvmfPkg/README.rst                                    | 211 ++++++++++++++++
 6 files changed, 840 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.ci.yaml b/OvmfPkg/OvmfPkg.ci.yaml
new file mode 100644
index 000000000000..98992f0429ff
--- /dev/null
+++ b/OvmfPkg/OvmfPkg.ci.yaml
@@ -0,0 +1,83 @@
+## @file
+# Core CI configuration for OvmfPkg
+#
+# OvmfPkg is part of Platform Ci for builds so this is only
+# used for code analysis.
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+    ## options defined .pytool/Plugin/CompilerPlugin
+    "CompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+    "HostUnitTestCompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/CharEncodingCheck
+    "CharEncodingCheck": {
+        "IgnoreFiles": []
+    },
+
+    ## options defined .pytool/Plugin/DependencyCheck
+    "DependencyCheck": {
+        "AcceptableDependencies": [
+            "MdePkg/MdePkg.dec",
+            "MdeModulePkg/MdeModulePkg.dec",
+            "OvmfPkg/OvmfPkg.dec",
+            "NetworkPkg/NetworkPkg.dec",
+            "SecurityPkg/SecurityPkg.dec",
+            "UefiCpuPkg/UefiCpuPkg.dec",
+            "ShellPkg/ShellPkg.dec",
+            "EmbeddedPkg/EmbeddedPkg.dec",
+            "SourceLevelDebugPkg/SourceLevelDebugPkg.dec"
+        ],
+        # For host based unit tests
+        "AcceptableDependencies-HOST_APPLICATION":[
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+        ],
+        # For UEFI shell based apps
+        "AcceptableDependencies-UEFI_APPLICATION":[],
+        "IgnoreInf": []
+    },
+
+    ## options defined .pytool/Plugin/DscCompleteCheck
+    "DscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": ""  # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+    "HostUnitTestDscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/GuidCheck
+    "GuidCheck": {
+        "IgnoreGuidName": ["ResetVector", "XenResetVector"], # Expected duplication for gEfiFirmwareVolumeTopFileGuid
+        "IgnoreGuidValue": [],
+        "IgnoreFoldersAndFiles": [],
+        "IgnoreDuplicates": [],
+    },
+
+    ## options defined .pytool/Plugin/LibraryClassCheck
+    "LibraryClassCheck": {
+        "IgnoreHeaderFile": []
+    },
+
+    ## options defined .pytool/Plugin/SpellCheck
+    "SpellCheck": {
+        "AuditOnly": True,           # Fails right now with over 270 errors
+        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
+        "ExtendWords": [
+
+        ],           # words to extend to the dictionary for this package
+        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
+        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+    }
+}
diff --git a/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
new file mode 100644
index 000000000000..a47d273217ab
--- /dev/null
+++ b/OvmfPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -0,0 +1,133 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: OVMF
+# OS: Ubuntu
+# Toolchain: GCC5
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'OvmfPkg'
+      vm_image: 'ubuntu-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE QEMU_HEADLESS=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          OVMF_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_FULL_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_FULL_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_FULL_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: GCC5
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        extra_install_step:
+        - bash: sudo apt-get install qemu
+          displayName: Install qemu
+          condition: and(gt(variables.pkg_count, 0), succeeded())
diff --git a/OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml b/OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
new file mode 100644
index 000000000000..02ed233fdb60
--- /dev/null
+++ b/OvmfPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
@@ -0,0 +1,138 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: OVMF
+# OS: Windows
+# Toolchain: VS2019
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'OvmfPkg'
+      vm_image: 'windows-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE QEMU_HEADLESS=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          OVMF_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+          OVMF_IA32X64_FULL_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          OVMF_IA32X64_FULL_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32,X64"
+            Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    # This currently creates a very large image which is too big for the FDF declared range
+    #   Ovmf maintainers suggest to skip this build for now.
+    #
+    #       OVMF_IA32X64_FULL_NOOPT:
+    #         Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+    #         Build.Arch: "IA32,X64"
+    #         Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=1 BLD_*_SMM_REQUIRE=1 BLD_*_TPM_ENABLE=1 BLD_*_TPM_CONFIG_ENABLE=1 BLD_*_NETWORK_TLS_ENABLE=1 BLD_*_NETWORK_IP6_ENABLE=1 BLD_*_NETWORK_HTTP_BOOT_ENABLE=1"
+    #         Build.Target: "NOOPT"
+    #         Run.Flags: $(run_flags)
+    #         Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: VS2019
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        extra_install_step:
+        - powershell: choco install qemu; Write-Host "##vso[task.prependpath]c:\Program Files\qemu"
+          displayName: Install QEMU and Set QEMU on path # friendly name displayed in the UI
+          condition: and(gt(variables.pkg_count, 0), succeeded())
+
diff --git a/OvmfPkg/PlatformCI/PlatformBuild.py b/OvmfPkg/PlatformCI/PlatformBuild.py
new file mode 100644
index 000000000000..627bb7b992db
--- /dev/null
+++ b/OvmfPkg/PlatformCI/PlatformBuild.py
@@ -0,0 +1,254 @@
+# @file
+# Script to Build OVMF UEFI firmware
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+import logging
+import io
+
+from edk2toolext.environment import shell_environment
+from edk2toolext.environment.uefi_build import UefiBuilder
+from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
+from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
+from edk2toolext.invocables.edk2_update import UpdateSettingsManager
+from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
+from edk2toollib.utility_functions import RunCmd
+
+
+    # ####################################################################################### #
+    #                                Common Configuration                                     #
+    # ####################################################################################### #
+class CommonPlatform():
+    ''' Common settings for this platform.  Define static data here and use
+        for the different parts of stuart
+    '''
+    PackagesSupported = ("OvmfPkg",)
+    ArchSupported = ("IA32", "X64")
+    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
+    Scopes = ('ovmf', 'edk2-build')
+    WorkspaceRoot = os.path.realpath(os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
+
+    @classmethod
+    def GetDscName(cls, ArchCsv: str) -> str:
+        ''' return the DSC given the architectures requested.
+
+        ArchCsv: csv string containing all architectures to build
+        '''
+        dsc = "OvmfPkg"
+        if "IA32" in ArchCsv.upper().split(","):
+            dsc += "Ia32"
+        if "X64" in ArchCsv.upper().split(","):
+            dsc += "X64"
+        dsc += ".dsc"
+        return dsc
+
+
+    # ####################################################################################### #
+    #                         Configuration for Update & Setup                                #
+    # ####################################################################################### #
+class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
+
+    def GetPackagesSupported(self):
+        ''' return iterable of edk2 packages supported by this build.
+        These should be edk2 workspace relative paths '''
+        return CommonPlatform.PackagesSupported
+
+    def GetArchitecturesSupported(self):
+        ''' return iterable of edk2 architectures supported by this build '''
+        return CommonPlatform.ArchSupported
+
+    def GetTargetsSupported(self):
+        ''' return iterable of edk2 target tags supported by this build '''
+        return CommonPlatform.TargetsSupported
+
+    def GetRequiredSubmodules(self):
+        ''' return iterable containing RequiredSubmodule objects.
+        If no RequiredSubmodules return an empty iterable
+        '''
+        rs = []
+
+        # intentionally declare this one with recursive false to avoid overhead
+        rs.append(RequiredSubmodule(
+            "CryptoPkg/Library/OpensslLib/openssl", False))
+
+        # To avoid maintenance of this file for every new submodule
+        # lets just parse the .gitmodules and add each if not already in list.
+        # The GetRequiredSubmodules is designed to allow a build to optimize
+        # the desired submodules but it isn't necessary for this repository.
+        result = io.StringIO()
+        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
+        # Cmd output is expected to look like:
+        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
+        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
+        if ret == 0:
+            for line in result.getvalue().splitlines():
+                _, _, path = line.partition(" ")
+                if path is not None:
+                    if path not in [x.path for x in rs]:
+                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
+        return rs
+
+    def SetArchitectures(self, list_of_requested_architectures):
+        ''' Confirm the requests architecture list is valid and configure SettingsManager
+        to run only the requested architectures.
+
+        Raise Exception if a list_of_requested_architectures is not supported
+        '''
+        unsupported = set(list_of_requested_architectures) - set(self.GetArchitecturesSupported())
+        if(len(unsupported) > 0):
+            errorString = ( "Unsupported Architecture Requested: " + " ".join(unsupported))
+            logging.critical( errorString )
+            raise Exception( errorString )
+        self.ActualArchitectures = list_of_requested_architectures
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
+        ''' Filter other cases that this package should be built
+        based on changed files. This should cover things that can't
+        be detected as dependencies. '''
+        build_these_packages = []
+        possible_packages = potentialPackagesList.copy()
+        for f in changedFilesList:
+            # BaseTools files that might change the build
+            if "BaseTools" in f:
+                if os.path.splitext(f) not in [".txt", ".md"]:
+                    build_these_packages = possible_packages
+                    break
+
+            # if the azure pipeline platform template file changed
+            if "platform-build-run-steps.yml" in f:
+                build_these_packages = possible_packages
+                break
+
+        return build_these_packages
+
+    def GetPlatformDscAndConfig(self) -> tuple:
+        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
+        any of the changes will be built in the dsc.
+
+        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
+        '''
+        dsc = CommonPlatform.GetDscName(",".join(self.ActualArchitectures))
+        return (f"OvmfPkg/{dsc}", {})
+
+
+    # ####################################################################################### #
+    #                         Actual Configuration for Platform Build                         #
+    # ####################################################################################### #
+class PlatformBuilder( UefiBuilder, BuildSettingsManager):
+    def __init__(self):
+        UefiBuilder.__init__(self)
+
+    def AddCommandLineOptions(self, parserObj):
+        ''' Add command line options to the argparser '''
+        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="IA32,X64",
+            help="Optional - CSV of architecture to build.  IA32 will use IA32 for Pei & Dxe. "
+            "X64 will use X64 for both PEI and DXE.  IA32,X64 will use IA32 for PEI and "
+            "X64 for DXE. default is IA32,X64")
+
+    def RetrieveCommandLineOptions(self, args):
+        '''  Retrieve command line options from the argparser '''
+
+        shell_environment.GetBuildVars().SetValue("TARGET_ARCH"," ".join(args.build_arch.upper().split(",")), "From CmdLine")
+        dsc = CommonPlatform.GetDscName(args.build_arch)
+        shell_environment.GetBuildVars().SetValue("ACTIVE_PLATFORM", f"OvmfPkg/{dsc}", "From CmdLine")
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetPackagesPath(self):
+        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
+        return ()
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def GetName(self):
+        ''' Get the name of the repo, platform, or product being build '''
+        ''' Used for naming the log file, among others '''
+        # check the startup nsh flag and if set then rename the log file.
+        # this helps in CI so we don't overwrite the build log since running
+        # uses the stuart_build command.
+        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
+            return "OvmfPkg_With_Run"
+        return "OvmfPkg"
+
+    def GetLoggingLevel(self, loggerType):
+        ''' Get the logging level for a given type
+        base == lowest logging level supported
+        con  == Screen logging
+        txt  == plain text file logging
+        md   == markdown file logging
+        '''
+        return logging.DEBUG
+
+    def SetPlatformEnv(self):
+        logging.debug("PlatformBuilder SetPlatformEnv")
+        self.env.SetValue("PRODUCT_NAME", "OVMF", "Platform Hardcoded")
+        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
+        self.env.SetValue("QEMU_HEADLESS", "FALSE", "Default to false")
+        return 0
+
+    def PlatformPreBuild(self):
+        return 0
+
+    def PlatformPostBuild(self):
+        return 0
+
+    def FlashRomImage(self):
+        VirtualDrive = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), "VirtualDrive")
+        os.makedirs(VirtualDrive, exist_ok=True)
+        OutputPath_FV = os.path.join(self.env.GetValue("BUILD_OUTPUT_BASE"), "FV")
+
+        #
+        # QEMU must be on the path
+        #
+        cmd = "qemu-system-x86_64"
+        args  = "-debugcon stdio"                                           # write messages to stdio
+        args += " -global isa-debugcon.iobase=0x402"                        # debug messages out thru virtual io port
+        args += " -net none"                                                # turn off network
+        args += f" -drive file=fat:rw:{VirtualDrive},format=raw,media=disk" # Mount disk with startup.nsh
+
+        if (self.env.GetValue("QEMU_HEADLESS").upper() == "TRUE"):
+            args += " -display none"  # no graphics
+
+        if (self.env.GetBuildValue("SMM_REQUIRE") == "1"):
+            args += " -machine q35,smm=on" #,accel=(tcg|kvm)"
+            #args += " -m ..."
+            #args += " -smp ..."
+            args += " -global driver=cfi.pflash01,property=secure,value=on"
+            args += " -drive if=pflash,format=raw,unit=0,file=" + os.path.join(OutputPath_FV, "OVMF_CODE.fd") + ",readonly=on"
+            args += " -drive if=pflash,format=raw,unit=1,file=" + os.path.join(OutputPath_FV, "OVMF_VARS.fd")
+        else:
+            args += " -pflash " + os.path.join(OutputPath_FV, "OVMF.fd")    # path to firmware
+
+
+        if (self.env.GetValue("MAKE_STARTUP_NSH").upper() == "TRUE"):
+            f = open(os.path.join(VirtualDrive, "startup.nsh"), "w")
+            f.write("BOOT SUCCESS !!! \n")
+            ## add commands here
+            f.write("reset -s\n")
+            f.close()
+
+        ret = RunCmd(cmd, args)
+
+        if ret == 0xc0000005:
+            #for some reason getting a c0000005 on successful return
+            return 0
+
+        return ret
+
+
+
diff --git a/OvmfPkg/PlatformCI/iasl_ext_dep.yaml b/OvmfPkg/PlatformCI/iasl_ext_dep.yaml
new file mode 100644
index 000000000000..cbee0e5a5a92
--- /dev/null
+++ b/OvmfPkg/PlatformCI/iasl_ext_dep.yaml
@@ -0,0 +1,21 @@
+## @file
+# Download iasl executable tool from a nuget.org package
+# - package contains different binaries based on host
+# Add the folder with the tool to the path
+#
+# This is only downloaded for scope ovmf thus
+# should have no impact on the asl compiler used by any
+# other given platform to build.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+  "id": "iasl-ovmf-1",
+  "scope": "ovmf",
+  "type": "nuget",
+  "name": "iasl",
+  "source": "https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapi.nuget.org%2Fv3%2Findex.json&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886270375&amp;sdata=QdUtNmDSJrCc0JwfLV3c0YYZhpV%2FMjW8U3C%2BJSxuZjg%3D&amp;reserved=0",
+  "version": "20190215.0.0",
+  "flags": ["set_path", "host_specific"],
+}
diff --git a/OvmfPkg/README.rst b/OvmfPkg/README.rst
new file mode 100644
index 000000000000..926e0f7d7f8d
--- /dev/null
+++ b/OvmfPkg/README.rst
@@ -0,0 +1,211 @@
+=======
+OvmfPkg
+=======
+
+This README.rst summarizes the current state of Azure DevOps Platform CI
+for OvmfPkg. It also describes how to *build* OvmfPkg locally using the
+Pytools build system. For general documentation on OvmfPkg, refer
+to the `README <./README>`_.
+
+Platform CI Current Status
+---------------------------
+
+IA32 Configuration
+``````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
+`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
+=============== ============= ============= =============
+
+X64 Configuration
+`````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
+`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
+=============== ============= ============= =============
+
+IA32X64 Configuration
+`````````````````````
+PEI phase is 32-bit while DXE phase is 64-bit
+
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap3264d|     |ap3264r|     |ap3264n|
+`Ubuntu GCC5`_  |ap3264du|    |ap3264ru|    |ap3264nu|
+=============== ============= ============= =============
+
+
+IA32X64 FULL Configuration
+``````````````````````````
+PEI phase is 32-bit while DXE phase is 64-bit
+
+Additional Build flags:
+  * SECURE_BOOT_ENABLE=1
+  * SMM_REQUIRE=1
+  * TPM_ENABLE=1
+  * TPM_CONFIG_ENABLE=1
+  * NETWORK_TLS_ENABLE=1
+  * NETWORK_IP6_ENABLE=1
+  * NETWORK_HTTP_BOOT_ENABLE=1
+
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap3264fd|    |ap3264fr|    |ap3264fn|
+`Ubuntu GCC5`_  |ap3264fdu|   |ap3264fru|   |ap3264fru|
+=============== ============= ============= =============
+
+Setup
+-----
+
+The Usual EDK2 Build Setup
+``````````````````````````
+
+- `Python 3.8.x - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.python.org%2Fdownloads%2F&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=sB2OjUBiT%2BjBG9RQABgd7qCesN2PXflfsrHqziZJx%2Bs%3D&amp;reserved=0>`_
+- `GIT - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit-scm.com%2Fdownload%2F&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=Onl5a91Z43gDAef70eT6XtkV%2FUZrF1mC0s9L9RWKK0U%3D&amp;reserved=0>`_
+- `GIT - Configure for EDK II <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23github-help&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=3NJhPhGa7ZKg7IsxyM%2BLaCQjpit6tZYX5v4vHjEJ%2BDU%3D&amp;reserved=0>`_
+- `QEMU - Download, Install, and add to your path <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.qemu.org%2Fdownload%2F&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=a2o9B0bufxw2ypq5reon4I45Bj07dTas9X0jXIdqSDs%3D&amp;reserved=0>`_
+- `EDKII Source - Download/Checkout from Github <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23download&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=L2q6SwvP5sysw2qveY7VV1SZbfhMohglt0WakRDF8Tg%3D&amp;reserved=0>`_
+
+**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
+
+Differences from EDK Classic Build Setup
+````````````````````````````````````````
+
+- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
+
+  - This replaces `edksetup Rebuild`" from the classic build system
+  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems-ToolChain-Matrix&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=Vzph3oNqf8TJa6MjiCl2ZvBMnMN25o5uh1rm5Cktjfc%3D&amp;reserved=0>`_,
+    defaults to `VS2017` if not specified
+
+- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is handled by the Pytools build system
+
+Install & Configure Pytools for OvmfPkg
+```````````````````````````````````````
+
+* Install Pytools
+
+  .. code-block:: bash
+
+    pip install --upgrade -r pip-requirements.txt
+
+* Initialize & Update Submodules
+
+  .. code-block:: bash
+
+    stuart_setup -c OvmfPkg/PlatformCI/PlatformBuild.py
+
+* Initialize & Update Dependencies (e.g. iASL & NASM)
+
+  .. code-block:: bash
+
+    stuart_update -c OvmfPkg/PlatformCI/PlatformBuild.py
+
+Building
+--------
+
+OVMF has `3 versions <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FHow-to-build-OVMF%23choosing-which-version-of-ovmf-to-build&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=CqKIsrIXmwpmIgl1Pga4ru3gTymQpucnqjY5anQrDpY%3D&amp;reserved=0>`_.
+To build them using Pytools:
+
+First set the `TOOL_CHAIN_TAG` via environment variable, Conf/target.txt, or pass it on the command-lines below using `TOOL_CHAIN_TAG=<value>` syntax.
+
+===================== ===============
+Platform              Commandline
+===================== ===============
+OvmfPkgIa32X64.dsc    `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]` |br| `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py -a IA32,X64 [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]`
+OvmfPkgIa32.dsc       `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py -a IA32 [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]`
+OvmfPkgX64.dsc        `stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py -a X64 [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>]`
+===================== ===============
+
+**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is **not** required. This environment
+is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
+
+Custom Build Options
+````````````````````
+
+**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
+combination with the `--FlashOnly` feature to run QEMU to the UEFI shell and then execute the contents of startup.nsh.
+
+**QEMU_HEADLESS=TRUE** Since CI servers run headless QEMU must be told to run with no display otherwise an error
+occurs. Locally you don't need to set this.
+
+Passing Build Defines
+`````````````````````
+To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
+stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
+For example, to enable the Intel E1000 NIC, instead of the traditional "-D E1000_ENABLE", the stuart_build
+command-line would be:
+
+.. code-block:: bash
+
+  stuart_build -c OvmfPkg/PlatformCI/PlatformBuild.py BLD_*_E1000_ENABLE=1
+
+Running QEMU Emulator
+---------------------
+
+QEMU can be automatically launched using stuart_build.  This makes path management and quick verification easy.
+QEMU must be added to your path.  On Windows this is a manual process and not part of the QEMU installer.
+
+1. To run as part of the build but after building add the `--FlashRom` parameter.
+2. To run after the build process standalone use your build command mentioned above plus `--FlashOnly`.
+
+**NOTE:** Logging the execution output will be in the normal stuart log as well as to your console.
+
+References
+----------
+- `Installing Pytools <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2Fmaster%2Fdocs%2Fusing.md%23installing&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=xTeOZR2Wo1JVUtzZybMO96N6wnzmudCQ1QpQtJCLyv0%3D&amp;reserved=0>`_
+- For each workspace, consider creating & using a `Python Virtual Environment <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fvenv.html&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=Oww2tijR8D4WjfbaiXS%2FhRxIog%2BUiMkwfZ70rLbulh0%3D&amp;reserved=0>`_
+
+  * `Sample Layout <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmicrosoft.github.io%2Fmu%2FCodeDevelopment%2Fprerequisites%2F%23workspace-virtual-environment-setup-process&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=Cv5%2BfburJ9Fr%2FqW7GAXIaq9UoglfqfeyJrLxdYliEuM%3D&amp;reserved=0>`_
+
+- `stuart_build commandline parser <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2F56f6a7aee09995c2f22da4765e8b0a29c1cbf5de%2Fedk2toolext%2Fedk2_invocable.py%23L109&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=JryF4zaktb8gYs%2Flp%2BnuRPGPEJtEkLcbcvROqxgyI3g%3D&amp;reserved=0>`_
+
+
+
+
+.. ===================================================================
+.. This is a bunch of directives to make the README file more readable
+.. ===================================================================
+.. role:: raw-html(raw)
+    :format: html
+
+.. _Bugzilla 2661: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2661&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=uMy2xprjL5gcSs9NC%2FnwrffumV3RmQzfKzlsRzUHhN8%3D&amp;reserved=0
+
+.. _Win VS2019:  https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D38%26branchName%3Dmaster%2F&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=ZsVOT2rFeQhJfbdzg8K3ot7Ooh%2BwQkH6XvDBdT1PfTY%3D&amp;reserved=0
+.. _Ubuntu GCC5: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D37%26branchName%3Dmaster&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=7vI3ytuEhSzyJ24ZyaxAH9d4Br9HnDUV2ql49k6knrU%3D&amp;reserved=0
+
+.. |ap32d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=VezJlKAAYKvAgSMOiYxj4odO5rzGDxZHhfGFhR7KLHw%3D&amp;reserved=0
+.. |ap32du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=bEeR62FvQePMo6ZevGHajSWX0g2vwJj97gGDxw%2Bz9eE%3D&amp;reserved=0
+.. |ap32r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=VAy9LXyH0R75TgavVg6z3MK8ys0MhQA2fC%2Bsts2DqIg%3D&amp;reserved=0
+.. |ap32ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=6CfdAyRFv1PX%2B3pEaUAaaLUSgWw2wTyDKcU2GSF5IJE%3D&amp;reserved=0
+.. |ap32n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32_NOOPT&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=l6f3jyjtKbNeATzpW5MLH3fUMYRpBNzGGDcHZOXF8oI%3D&amp;reserved=0
+.. |ap32nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32_NOOPT&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886280331&amp;sdata=BlFW8gd7voq9V6ZBHFStHX2%2B8tsH05NMTM4La%2BFMA7U%3D&amp;reserved=0
+
+.. |ap64d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_X64_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=W0ikoZbzYBhbTDT1aLM%2FAKOkOZwM2%2BWjPSwpytoah%2Fs%3D&amp;reserved=0
+.. |ap64du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_X64_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=Fh0yOqPV87Uf%2FaaNmIKqHfTbhSzZXZJC4aWziHkWMy8%3D&amp;reserved=0
+.. |ap64r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_X64_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=3LYcbNMo7BiGBGreA1NJbtJwksXEB88wkb2fXuX75fI%3D&amp;reserved=0
+.. |ap64ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_X64_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=ZNggPKnlEmzG9kpBv0jE%2FqSdPuEn5p7p1N97jysotQg%3D&amp;reserved=0
+.. |ap64n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_X64_NOOPT&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=xicm5tRW0D2xQfv%2BJUdI6N%2B9qlYvACVGBgD5zxZjS1Q%3D&amp;reserved=0
+.. |ap64nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_X64_NOOPT&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=sL2jMaBDeLk2QEHfL61khUpfl4wjbnnsOM%2FFiJYpijk%3D&amp;reserved=0
+
+
+.. |ap3264d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=IbElDszvh%2FuYu1a%2FJBguHGIIu5ox0Pa%2Fh%2FdidHdp8g0%3D&amp;reserved=0
+.. |ap3264du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=QcHGE1NKDZ%2F7DL44kJ5BTWpBcMIJLYHk41r4VD9gblU%3D&amp;reserved=0
+.. |ap3264r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=EInMEA4FmN20iq4iYggu4YV8%2BkKVK4dw%2FuqD4%2B1aQkU%3D&amp;reserved=0
+.. |ap3264ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=pvBls59ZcFWZyD88bn4PvpT6RMArdqYAk3Q%2FRnR51Ro%3D&amp;reserved=0
+.. |ap3264n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_NOOPT&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=8quyJSMtcpxkrL3aDuGo5UyfHP0cJYDMtfuzR3xmhaU%3D&amp;reserved=0
+.. |ap3264nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_NOOPT&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=ICaiYJG1JTXewiv5vcw5801u3asvnEDKXg2DcPsHmt8%3D&amp;reserved=0
+
+.. |ap3264fd| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_FULL_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=cI36u7Pbtn6l7SWQilTeZJciBQJ4wgcz9CNhSk9kX7g%3D&amp;reserved=0
+.. |ap3264fdu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_FULL_DEBUG&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=sdu7m75D3KS3LjmJ8wzKcPpgZY%2B%2BGmFvQpemdU3gi8Q%3D&amp;reserved=0
+.. |ap3264fr| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_FULL_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=WmsgrgrRE%2Bgj%2F%2FyZ%2FoerLsjteN6YxaWzqanQWTbHtJ8%3D&amp;reserved=0
+.. |ap3264fru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_FULL_RELEASE&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=sIRFirFSFm0kNPSLMgk0g2pMRV75IOyHEYJ4ybJv5l0%3D&amp;reserved=0
+.. |ap3264fn| replace:: Fails - Wontfix - `Bugzilla 2661`_
+.. |ap3264fnu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FOVMF%2FOVMF%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520OVMF_IA32X64_FULL_NOOPT&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7C65b8b6d15c7f432a603108d7e55edbb9%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067886290287&amp;sdata=D0oT%2FpwwgCxlVKP%2Bix9WJlhfwKFQEfVDNaw4e%2BZRJF8%3D&amp;reserved=0
+
+.. |br| replace:: :raw-html:`<br />`
--
2.16.3.windows.1





[-- Attachment #2: Type: text/html, Size: 105435 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [EXTERNAL] [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI
  2020-04-20 19:12 ` [PATCH v2 3/6] EmulatorPkg: " Michael Kubacki
  2020-04-21 14:36   ` [edk2-devel] " Liming Gao
  2020-04-21 14:43   ` Ni, Ray
@ 2020-04-24 20:22   ` Bret Barkelew
  2 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:22 UTC (permalink / raw)
  To: devel@edk2.groups.io, michael.kubacki@outlook.com
  Cc: Jordan Justen, Andrew Fish, Ray Ni

[-- Attachment #1: Type: text/plain, Size: 42081 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Michael Kubacki via groups.io <michael.kubacki=outlook.com@groups.io>
Sent: Monday, April 20, 2020 12:12:13 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Jordan Justen <jordan.l.justen@intel.com>; Andrew Fish <afish@apple.com>; Ray Ni <ray.ni@intel.com>
Subject: [EXTERNAL] [edk2-devel] [PATCH v2 3/6] EmulatorPkg: Add Platform CI and configuration for Core CI

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846856524&amp;sdata=sD1c4yU98JcgeHNncveZX%2BA%2BfP211%2F8JZloAyO7%2BrUg%3D&amp;reserved=0

Add new Azure Pipeline definitions to build and run EmulatorPkg with:
  * Ubuntu GCC5
  * Windows VS2019
Add PyTool based build of EmulatorPkg
Add EmulatorPkg.ci.yaml for Core CI
Add ReadMe.rst for status, details and instructions

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 EmulatorPkg/EmulatorPkg.ci.yaml                           |  85 ++++++
 EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml    |  95 +++++++
 EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml |  85 ++++++
 EmulatorPkg/PlatformCI/PlatformBuild.py                   | 272 ++++++++++++++++++++
 EmulatorPkg/README.rst                                    | 175 +++++++++++++
 5 files changed, 712 insertions(+)

diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
new file mode 100644
index 000000000000..81f81780ec76
--- /dev/null
+++ b/EmulatorPkg/EmulatorPkg.ci.yaml
@@ -0,0 +1,85 @@
+## @file
+# Core CI configuration for EmulatorPkg
+#
+# EmulatorPkg is part of Platform Ci for builds so this is only
+# used for code analysis.
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+    ## options defined .pytool/Plugin/CompilerPlugin
+    "CompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+    "HostUnitTestCompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/CharEncodingCheck
+    "CharEncodingCheck": {
+        "IgnoreFiles": []
+    },
+
+    ## options defined .pytool/Plugin/DependencyCheck
+    "DependencyCheck": {
+        "AcceptableDependencies": [
+            # For this platform all packages are allowed???
+            "MdePkg/MdePkg.dec",
+            "MdeModulePkg/MdeModulePkg.dec",
+            "EmulatorPkg/EmulatorPkg.dec",
+            "NetworkPkg/NetworkPkg.dec",
+            "EmbeddedPkg/EmbeddedPkg.dec", ## is this one OK??
+        ],
+        # For host based unit tests
+        "AcceptableDependencies-HOST_APPLICATION":[
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+        ],
+        # For UEFI shell based apps
+        "AcceptableDependencies-UEFI_APPLICATION":[],
+        "IgnoreInf": []
+    },
+
+    ## options defined .pytool/Plugin/DscCompleteCheck
+    "DscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": ""  # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+    "HostUnitTestDscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/GuidCheck
+    "GuidCheck": {
+        "IgnoreGuidName": [],
+        "IgnoreGuidValue": [],
+        "IgnoreFoldersAndFiles": [],
+        "IgnoreDuplicates": [],
+    },
+
+    ## options defined .pytool/Plugin/LibraryClassCheck
+    "LibraryClassCheck": {
+        "IgnoreHeaderFile": []
+    },
+
+    ## options defined .pytool/Plugin/SpellCheck
+    "SpellCheck": {
+        "AuditOnly": True,           # Fails right now with over 270 errors
+        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
+        "ExtendWords": [
+            "setjump",
+            "plong",
+            "lparam",
+            "lpdword",
+            "lpthread",
+            "lresult",
+        ],           # words to extend to the dictionary for this package
+        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
+        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+    }
+}
diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
new file mode 100644
index 000000000000..12ef8226ff54
--- /dev/null
+++ b/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -0,0 +1,95 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: EmulatorPkg
+# OS: Ubuntu
+# Toolchain: GCC5
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'EmulatorPkg'
+      vm_image: 'ubuntu-latest'
+      should_run: false
+      run_flags: "MAKE_STARTUP_NSH=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          EmulatorPkg_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: GCC5
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        # Add steps to install some IA32 only dependencies
+        extra_install_step:
+        - bash: sudo dpkg --add-architecture i386
+          displayName: Add i386 to dpkg
+          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
+        - bash: sudo apt-get update
+          displayName: do apt-get update
+          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
+        - bash: sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
+          displayName: Add additional i386 packages
+          condition: and(gt(variables.pkg_count, 0), eq(variables['Build.Arch'], 'IA32'), succeeded())
diff --git a/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
new file mode 100644
index 000000000000..a5baf4b6064b
--- /dev/null
+++ b/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml
@@ -0,0 +1,85 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: EMULATORPKG
+# OS: Windows
+# Toolchain: VS2019
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'EmulatorPkg'
+      vm_image: 'windows-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          EmulatorPkg_X64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_X64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "X64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32 "
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32 "
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          EmulatorPkg_IA32_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "IA32 "
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: VS2019
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
diff --git a/EmulatorPkg/PlatformCI/PlatformBuild.py b/EmulatorPkg/PlatformCI/PlatformBuild.py
new file mode 100644
index 000000000000..6defbf6ef148
--- /dev/null
+++ b/EmulatorPkg/PlatformCI/PlatformBuild.py
@@ -0,0 +1,272 @@
+# @file
+# Script to Build EmulatorPkg UEFI firmware
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+import logging
+import io
+
+from edk2toolext.environment import shell_environment
+from edk2toolext.environment.uefi_build import UefiBuilder
+from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
+from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
+from edk2toolext.invocables.edk2_update import UpdateSettingsManager
+from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
+from edk2toollib.utility_functions import RunCmd
+from edk2toollib.utility_functions import GetHostInfo
+
+# ####################################################################################### #
+#                                Common Configuration                                     #
+# ####################################################################################### #
+
+
+class CommonPlatform():
+    ''' Common settings for this platform.  Define static data here and use
+        for the different parts of stuart
+    '''
+    PackagesSupported = ("EmulatorPkg",)
+    ArchSupported = ("X64", "IA32")
+    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
+    Scopes = ('emulatorpkg', 'edk2-build')
+    WorkspaceRoot = os.path.realpath(os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
+
+    # ####################################################################################### #
+    #                         Configuration for Update & Setup                                #
+    # ####################################################################################### #
+
+
+class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
+
+    def GetPackagesSupported(self):
+        ''' return iterable of edk2 packages supported by this build.
+        These should be edk2 workspace relative paths '''
+        return CommonPlatform.PackagesSupported
+
+    def GetArchitecturesSupported(self):
+        ''' return iterable of edk2 architectures supported by this build '''
+        return CommonPlatform.ArchSupported
+
+    def GetTargetsSupported(self):
+        ''' return iterable of edk2 target tags supported by this build '''
+        return CommonPlatform.TargetsSupported
+
+    def GetRequiredSubmodules(self):
+        ''' return iterable containing RequiredSubmodule objects.
+        If no RequiredSubmodules return an empty iterable
+        '''
+        rs = []
+        # intentionally declare this one with recursive false to avoid overhead
+        rs.append(RequiredSubmodule(
+            "CryptoPkg/Library/OpensslLib/openssl", False))
+
+        # To avoid maintenance of this file for every new submodule
+        # lets just parse the .gitmodules and add each if not already in list.
+        # The GetRequiredSubmodules is designed to allow a build to optimize
+        # the desired submodules but it isn't necessary for this repository.
+        result = io.StringIO()
+        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
+        # Cmd output is expected to look like:
+        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
+        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
+        if ret == 0:
+            for line in result.getvalue().splitlines():
+                _, _, path = line.partition(" ")
+                if path is not None:
+                    if path not in [x.path for x in rs]:
+                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
+        return rs
+
+    def SetArchitectures(self, list_of_requested_architectures):
+        ''' Confirm the requests architecture list is valid and configure SettingsManager
+        to run only the requested architectures.
+
+        Raise Exception if a list_of_requested_architectures is not supported
+        '''
+        unsupported = set(list_of_requested_architectures) - \
+            set(self.GetArchitecturesSupported())
+        if(len(unsupported) > 0):
+            errorString = (
+                "Unsupported Architecture Requested: " + " ".join(unsupported))
+            logging.critical(errorString)
+            raise Exception(errorString)
+        self.ActualArchitectures = list_of_requested_architectures
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
+        ''' Filter other cases that this package should be built
+        based on changed files. This should cover things that can't
+        be detected as dependencies. '''
+        build_these_packages = []
+        possible_packages = potentialPackagesList.copy()
+        for f in changedFilesList:
+            # BaseTools files that might change the build
+            if "BaseTools" in f:
+                if os.path.splitext(f) not in [".txt", ".md"]:
+                    build_these_packages = possible_packages
+                    break
+            # if the azure pipeline platform template file changed
+            if "platform-build-run-steps.yml" in f:
+                build_these_packages = possible_packages
+                break
+        return build_these_packages
+
+    def GetPlatformDscAndConfig(self) -> tuple:
+        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
+        any of the changes will be built in the dsc.
+
+        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
+        '''
+        return (os.path.join("EmulatorPkg", "EmulatorPkg.dsc"), {})
+
+    # ####################################################################################### #
+    #                         Actual Configuration for Platform Build                         #
+    # ####################################################################################### #
+
+
+class PlatformBuilder(UefiBuilder, BuildSettingsManager):
+    def __init__(self):
+        UefiBuilder.__init__(self)
+
+    def AddCommandLineOptions(self, parserObj):
+        ''' Add command line options to the argparser '''
+        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="X64",
+                               help="Optional - architecture to build.  IA32 will use IA32 for Pei & Dxe. "
+                               "X64 will use X64 for both PEI and DXE.")
+
+    def RetrieveCommandLineOptions(self, args):
+        '''  Retrieve command line options from the argparser '''
+
+        shell_environment.GetBuildVars().SetValue(
+            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
+        shell_environment.GetBuildVars().SetValue(
+            "ACTIVE_PLATFORM", "EmulatorPkg/EmulatorPkg.dsc", "From CmdLine")
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetPackagesPath(self):
+        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
+        return ()
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        return CommonPlatform.Scopes
+
+    def GetName(self):
+        ''' Get the name of the repo, platform, or product being build '''
+        ''' Used for naming the log file, among others '''
+
+        # check the startup nsh flag and if set then rename the log file.
+        # this helps in CI so we don't overwrite the build log since running
+        # uses the stuart_build command.
+        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
+            return "EmulatorPkg_With_Run"
+        return "EmulatorPkg"
+
+    def GetLoggingLevel(self, loggerType):
+        ''' Get the logging level for a given type
+        base == lowest logging level supported
+        con  == Screen logging
+        txt  == plain text file logging
+        md   == markdown file logging
+        '''
+        return logging.DEBUG
+
+    def SetPlatformEnv(self):
+        logging.debug("PlatformBuilder SetPlatformEnv")
+        self.env.SetValue("PRODUCT_NAME", "EmulatorPkg", "Platform Hardcoded")
+        self.env.SetValue("TOOL_CHAIN_TAG", "VS2019", "Default Toolchain")
+
+        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
+        # requested to be built when building VS2019 or VS2017
+        if self.env.GetValue("TOOL_CHAIN_TAG") == "VS2019" or self.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":
+            key = self.env.GetValue("TOOL_CHAIN_TAG") + "_HOST"
+            if self.env.GetValue("TARGET_ARCH") == "IA32":
+                shell_environment.ShellEnvironment().set_shell_var(key, "x86")
+            elif self.env.GetValue("TARGET_ARCH") == "X64":
+                shell_environment.ShellEnvironment().set_shell_var(key, "x64")
+
+        # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture
+        # requested to be built when building on linux.
+        if GetHostInfo().os.upper() == "LINUX":
+            self.ConfigureLinuxDLinkPath()
+
+        if GetHostInfo().os.upper() == "WINDOWS":
+            self.env.SetValue("BLD_*_WIN_HOST_BUILD", "TRUE",
+                              "Trigger Windows host build")
+
+        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
+
+        # I don't see what this does but it is in build.sh
+        key = "BLD_*_BUILD_" + self.env.GetValue("TARGET_ARCH")
+        self.env.SetValue(key, "TRUE", "match script in build.sh")
+        return 0
+
+    def PlatformPreBuild(self):
+        return 0
+
+    def PlatformPostBuild(self):
+        return 0
+
+    def FlashRomImage(self):
+        ''' Use the FlashRom Function to run the emulator.  This gives an easy stuart command line to
+        activate the emulator. '''
+
+        OutputPath = os.path.join(self.env.GetValue(
+            "BUILD_OUTPUT_BASE"), self.env.GetValue("TARGET_ARCH"))
+
+        if (self.env.GetValue("MAKE_STARTUP_NSH") == "TRUE"):
+            f = open(os.path.join(OutputPath, "startup.nsh"), "w")
+            f.write("BOOT SUCCESS !!! \n")
+            # add commands here
+            f.write("reset\n")
+            f.close()
+
+        if GetHostInfo().os.upper() == "WINDOWS":
+            cmd = "WinHost.exe"
+        elif GetHostInfo().os.upper() == "LINUX":
+            cmd = "./Host"
+        else:
+            logging.critical("Unsupported Host")
+            return -1
+        return RunCmd(cmd, "", workingdir=OutputPath)
+
+    def ConfigureLinuxDLinkPath(self):
+        '''
+        logic copied from build.sh to setup the correct libraries
+        '''
+        if self.env.GetValue("TARGET_ARCH") == "IA32":
+            LIB_NAMES = ["ld-linux.so.2", "libdl.so.2 crt1.o", "crti.o crtn.o"]
+            LIB_SEARCH_PATHS = ["/usr/lib/i386-linux-gnu",
+                                "/usr/lib32", "/lib32", "/usr/lib", "/lib"]
+        elif self.env.GetValue("TARGET_ARCH") == "X64":
+            LIB_NAMES = ["ld-linux-x86-64.so.2",
+                         "libdl.so.2", "crt1.o", "crti.o", "crtn.o"]
+            LIB_SEARCH_PATHS = ["/usr/lib/x86_64-linux-gnu",
+                                "/usr/lib64", "/lib64", "/usr/lib", "/lib"]
+
+        HOST_DLINK_PATHS = ""
+        for lname in LIB_NAMES:
+            logging.debug(f"Looking for {lname}")
+            for dname in LIB_SEARCH_PATHS:
+                logging.debug(f"In {dname}")
+                if os.path.isfile(os.path.join(dname, lname)):
+                    logging.debug(f"Found {lname} in {dname}")
+                    HOST_DLINK_PATHS += os.path.join(
+                        os.path.join(dname, lname)) + os.pathsep
+                    break
+        HOST_DLINK_PATHS = HOST_DLINK_PATHS.rstrip(os.pathsep)
+        logging.critical(f"Setting HOST_DLINK_PATHS to {HOST_DLINK_PATHS}")
+        shell_environment.ShellEnvironment().set_shell_var(
+            "HOST_DLINK_PATHS", HOST_DLINK_PATHS)
diff --git a/EmulatorPkg/README.rst b/EmulatorPkg/README.rst
new file mode 100644
index 000000000000..d1aa0a367965
--- /dev/null
+++ b/EmulatorPkg/README.rst
@@ -0,0 +1,175 @@
+===========
+EmulatorPkg
+===========
+
+This README.rst summarizes the current state of Azure DevOps Platform CI
+for EmulatorPkg. It also describes how to *build* EmulatorPkg locally using the
+Pytools build system. For general documentation on EmulatorPkg, refer
+to the `ReadMe <./Readme.md>`_.
+
+Platform CI Current Status
+---------------------------
+
+IA32 Configuration
+``````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap32d|       |ap32r|       |ap32n|
+`Ubuntu GCC5`_  |ap32du|      |ap32ru|      |ap32nu|
+=============== ============= ============= =============
+
+|TCBZ_2668|_ - Ubuntu GCC5 Segfaults during execution.  The builds
+only compile for Ubuntu GCC5 (not run to shell).
+
+X64 Configuration
+`````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Win VS2019`_   |ap64d|       |ap64r|       |ap64n|
+`Ubuntu GCC5`_  |ap64du|      |ap64ru|      |ap64nu|
+=============== ============= ============= =============
+
+|TCBZ_2639|_ - Ubuntu GCC5 Segfaults during execution.  The builds
+only compile for Ubuntu GCC5 (not run to shell).
+
+Setup
+-----
+
+The Usual EDK2 Build Setup
+``````````````````````````
+
+- `Python 3.8.x - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.python.org%2Fdownloads%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=Vjf04Z3oIDa91k4spCGkxMDrF5swmbNUnpCaji6RbIU%3D&amp;reserved=0>`_
+- `GIT - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit-scm.com%2Fdownload%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=YjKDYF7%2BznyPzZ3cZLDhaGV8zdD76%2BslDoOAWoYEUkk%3D&amp;reserved=0>`_
+- `GIT - Configure for EDK II <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23github-help&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=4BR3zol%2FCC6G%2BiSHGCC3%2FkJqcXNVteeGVkc%2Bs3eDjgQ%3D&amp;reserved=0>`_
+- `EDKII Source - Download/Checkout from Github <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23download&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=zyCa6iThiL9Tdhfr55RbsBvPtclAwzlgzEgWHCzCdA4%3D&amp;reserved=0>`_
+
+**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
+
+Install the necessary development packages for your distribution
+````````````````````````````````````````````````````````````````
+
+This varies by distribution, toolchain, and your configuration but here are a few hints.
+
+* For building ARCH IA32 on X64 Ubuntu 18.04 LTS these steps where needed.
+
+  .. code-block:: bash
+
+    sudo dpkg --add-architecture i386
+    sudo apt-get update
+    sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev
+
+* For building Basetools and other host applications
+
+  .. code-block:: bash
+
+    sudo apt-get update
+    sudo apt-get install gcc g++ make uuid-dev
+
+Differences from EDK Classic Build Setup
+````````````````````````````````````````
+
+- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
+
+  - This replaces `edksetup Rebuild`" from the classic build system
+  - For Windows `<ToolChainTag>` examples, refer to `Windows ToolChain Matrix <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems-ToolChain-Matrix&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=kdd51pesL8Yqtay%2BXxF%2B7nzFUNuKxhl2LwZaF6RNUWI%3D&amp;reserved=0>`_,
+    defaults to `VS2017` if not specified
+
+- **No Action:** edksetup, Submodule initialization and manual setup of NASM and iASL are **not** required, it is
+  handled by the Pytools build system
+
+Install & Configure Pytools for EmulatorPkg
+```````````````````````````````````````````
+
+* Install Pytools
+
+  .. code-block:: bash
+
+    pip install --upgrade -r pip-requirements.txt
+
+* Initialize & Update Submodules
+
+  .. code-block:: bash
+
+    stuart_setup -c EmulatorPkg/PlatformCI/PlatformBuild.py
+
+* Initialize & Update Dependencies (e.g. iASL & NASM)
+
+  .. code-block:: bash
+
+    stuart_update -c EmulatorPkg/PlatformCI/PlatformBuild.py
+
+* Compile (IA32 or X64 supported)
+
+  .. code-block:: bash
+
+    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py [TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG>] -a <TARGET_ARCH>
+
+* Running Emulator
+
+  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
+  - or use the `--FlashOnly` feature to just run the emulator.
+
+  .. code-block:: bash
+
+    stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> --FlashOnly
+
+**NOTE:** configuring ACTIVE_PLATFORM and TARGET_ARCH in Conf/target.txt is *not* required.
+This environment is set by PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
+
+Custom Build Options
+````````````````````
+
+**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in
+combination with the `--FlashOnly` feature to run the emulator to the UEFI shell and then execute the
+contents of startup.nsh.
+
+Passing Build Defines
+`````````````````````
+
+To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the command-line.
+stuart_build currently requires values to be assigned, so add a `=1` suffix for bare defines.
+For example, to enable the IP6 Network Stack, the stuart_build command-line would be:
+
+.. code-block:: bash
+
+  stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py BLD_*_NETWORK_IP6_ENABLE=1
+
+References
+----------
+
+- `Installing Pytools <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2Fmaster%2Fdocs%2Fusing.md%23installing&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=CZsEm5tFfggyMkWtc7VdpHWfbvrh0EzMLxGNlI%2FnSos%3D&amp;reserved=0>`_
+- For each workspace, consider creating & using a `Python Virtual Environment <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fvenv.html&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=eA05o6eWi136%2FE2TdlesAoGEE2ijYkr75lvWQsHIUA8%3D&amp;reserved=0>`_
+
+  * `Sample Layout <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmicrosoft.github.io%2Fmu%2FCodeDevelopment%2Fprerequisites%2F%23workspace-virtual-environment-setup-process&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=qW%2FM8UCTr1IcHfzuQqbDfDVyCmmzOqxyMgXltbaNltU%3D&amp;reserved=0>`_
+
+- `stuart_build commandline parser <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2F56f6a7aee09995c2f22da4765e8b0a29c1cbf5de%2Fedk2toolext%2Fedk2_invocable.py%23L109&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=scBBDXAhn%2BtnVDXTNLWHkv%2FHT4BGaxVPTh6Hj3CU5yg%3D&amp;reserved=0>`_
+
+
+.. ===================================================================
+.. This is a bunch of directives to make the README file more readable
+.. ===================================================================
+
+.. |TCBZ_2668| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fimg.shields.io%2Fbugzilla%2F2668%3FbaseUrl%3Dhttps%253A%252F%252Fbugzilla.tianocore.org&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=%2F4beWFJGZt3Y6Dwoy6kncF1LBqlIPI00HTgExl2sIIA%3D&amp;reserved=0
+.. _TCBZ_2668: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2668&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=rd0kLIJUxWe64zS47%2BEjvqr7ZuhIdQv18W06Gc3%2FHDk%3D&amp;reserved=0
+
+.. |TCBZ_2639| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fimg.shields.io%2Fbugzilla%2F2639%3FbaseUrl%3Dhttps%253A%252F%252Fbugzilla.tianocore.org&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=FrC7IHjytho3X9PW%2BGootElj1K%2B0o%2B5QCCG5lufqncY%3D&amp;reserved=0
+.. _TCBZ_2639: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2639&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=MSvMhRRPL%2FIMq8wOQlvStw0Dzq%2BmtGBsdDLPCf6UEic%3D&amp;reserved=0
+
+.. _Win VS2019:  https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D40%26branchName%3Dmaster&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=raTqUt0KjgAFwO%2FsB9VY5yGtqRHYUntKZk3ENp2Nh8o%3D&amp;reserved=0
+.. _Ubuntu GCC5: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D39%26branchName%3Dmaster&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=dXUMFuAjB1njpE5Krr9aX8W1pCrqygffF18jMEvp5nM%3D&amp;reserved=0
+
+.. |ap32d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_IA32_DEBUG&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=VaYoGOdbPTWreXMVOyDuLmJfTeSNnHnPvsTXSnrTJyA%3D&amp;reserved=0
+.. |ap32du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_IA32_DEBUG&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846866478&amp;sdata=tHIiLKT23FXzpQenoVNNjgqWfNXd45kCqs%2FROIJRD1o%3D&amp;reserved=0
+.. |ap32r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_IA32_RELEASE&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=uHhvdU6zwyAoq2NaFzRRf1af99Caj166ZwNgMaqLd1M%3D&amp;reserved=0
+.. |ap32ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_IA32_RELEASE&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=PJat%2F3WWl0gXk5CcvUxlzVpHtYYNxTcRwhn7rQ7Ke%2B0%3D&amp;reserved=0
+.. |ap32n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Windows%2520VS2019%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_IA32_NOOPT&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=9NuYzTrU3ejU%2FR7rG%2B5Q88%2F8dkPeDYQgRoAoGjkjUTQ%3D&amp;reserved=0
+.. |ap32nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_IA32_NOOPT&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=9K8HEeu3921Sq5Fqh1dCOhwLv0lZb3iIr4CAukyxl8s%3D&amp;reserved=0
+
+.. |ap64d| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_X64_DEBUG&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=B3Qa3vLBgmPTN8HbU2zch5y%2F0A06fwD91Yq7VD9urx8%3D&amp;reserved=0
+.. |ap64du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_X64_DEBUG&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=B3Qa3vLBgmPTN8HbU2zch5y%2F0A06fwD91Yq7VD9urx8%3D&amp;reserved=0
+.. |ap64r| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_X64_RELEASE&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=xqgwH4hsdvKNFm%2FgmhxDLy007VbWBBOhgrgEgbcJGOw%3D&amp;reserved=0
+.. |ap64ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_X64_RELEASE&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=xqgwH4hsdvKNFm%2FgmhxDLy007VbWBBOhgrgEgbcJGOw%3D&amp;reserved=0
+.. |ap64n| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_X64_NOOPT&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=hInPpx3zQpbIZ1uwgW43py4pFJlS%2BvOtbYtnTokzhJk%3D&amp;reserved=0
+.. |ap64nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FEmulatorPkg%2FEmulatorPkg%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520EmulatorPkg_X64_NOOPT&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C60f1628fdb874f6eef3108d7e55ed95e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067846876439&amp;sdata=hInPpx3zQpbIZ1uwgW43py4pFJlS%2BvOtbYtnTokzhJk%3D&amp;reserved=0
--
2.16.3.windows.1





[-- Attachment #2: Type: text/html, Size: 83859 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [EXTERNAL] [edk2-devel] [PATCH v2 1/6] .azurepipelines: Add Platform CI template
  2020-04-20 19:12 ` [PATCH v2 1/6] .azurepipelines: Add Platform CI template Michael Kubacki
@ 2020-04-24 20:22   ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:22 UTC (permalink / raw)
  To: devel@edk2.groups.io, michael.kubacki@outlook.com
  Cc: Sean Brogan, Kinney, Michael D, Liming Gao

[-- Attachment #1: Type: text/plain, Size: 13691 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Michael Kubacki via groups.io <michael.kubacki=outlook.com@groups.io>
Sent: Monday, April 20, 2020 12:12:11 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Liming Gao <liming.gao@intel.com>
Subject: [EXTERNAL] [edk2-devel] [PATCH v2 1/6] .azurepipelines: Add Platform CI template

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7Cbd31ac9439e54096f31808d7e55ed649%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067792915138&amp;sdata=emu31XA%2FKpr%2FSD4gy4DbcjYVj1PYaDMaaWk8GGtJwUU%3D&amp;reserved=0

Add template for Platform CI steps for a Pytools based build.
Add README to describe the template and how to use it.
Add helpful information for working with azurepipelines, templates, and
lessons learned.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 .azurepipelines/ReadMe.md                              |  50 ++++++++
 .azurepipelines/templates/ReadMe.md                    |  59 +++++++++
 .azurepipelines/templates/platform-build-run-steps.yml | 134 ++++++++++++++++++++
 3 files changed, 243 insertions(+)

diff --git a/.azurepipelines/ReadMe.md b/.azurepipelines/ReadMe.md
new file mode 100644
index 000000000000..cf57d282c197
--- /dev/null
+++ b/.azurepipelines/ReadMe.md
@@ -0,0 +1,50 @@
+# Azure DevOps Pipelines
+
+These yml files are used to provide CI builds using the Azure DevOps Pipeline Service.
+Most of the CI leverages edk2-pytools to support cross platform building and execution.
+
+## Core CI
+
+Focused on building and testing all packages in Edk2 without an actual target platform.
+
+See `.pytools/ReadMe.py` for more details
+
+## Platform CI
+
+Focused on building a single target platform and confirming functionality on that platform.
+
+## Conventions
+
+* Files extension should be *.yml.  *.yaml is also supported but in Edk2 we use those for our package configuration.
+* Platform CI files should be in the `<PlatformPkg>/.azurepipelines` folder.
+* Core CI files are in the root folder.
+* Shared templates are in the `templates` folder.
+* Top level CI files should be named `<host os>-<tool_chain_tag>.yml`
+
+## Links
+
+* Basic Azure Landing Site - https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fpipelines%2F%3Fview%3Dazure-devops&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7Cbd31ac9439e54096f31808d7e55ed649%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067792915138&amp;sdata=XPGqra1YU6OrOTx6cWKyKfETYLlvTrNm%2BoLmzv66fQ8%3D&amp;reserved=0
+* Pipeline jobs - https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fpipelines%2Fprocess%2Fphases%3Fview%3Dazure-devops%26tabs%3Dyaml&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7Cbd31ac9439e54096f31808d7e55ed649%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067792915138&amp;sdata=FtXq1ps15kp5Vwjl95BksV0XOFV6X4oA2nxw9w983u0%3D&amp;reserved=0
+* Pipeline yml scheme - https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fpipelines%2Fyaml-schema%3Fview%3Dazure-devops%26tabs%3Dschema%252Cparameter-schema&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7Cbd31ac9439e54096f31808d7e55ed649%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067792915138&amp;sdata=T%2FqPGOWIgIN4TS%2BK116FWgdN3irKc4%2BlVqxG5LCpKwA%3D&amp;reserved=0
+* Pipeline expression - https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fpipelines%2Fprocess%2Fexpressions%3Fview%3Dazure-devops&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7Cbd31ac9439e54096f31808d7e55ed649%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067792915138&amp;sdata=x5V2xgJQRV31fZ7pJbiuHXjAuOxAHTdHgYvtNvB%2F6Tc%3D&amp;reserved=0
+* PyTools - https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7Cbd31ac9439e54096f31808d7e55ed649%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067792915138&amp;sdata=uqzx7GHM7ahuQKGgm%2FWt2C5%2B9nQyQOCQLFpQkOiBt7M%3D&amp;reserved=0 and https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-library&amp;data=02%7C01%7Cbret.barkelew%40microsoft.com%7Cbd31ac9439e54096f31808d7e55ed649%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067792915138&amp;sdata=bL9qDvlEe4kAgM08xI%2FncpOiMBtyn8wA35M5j57tDgI%3D&amp;reserved=0
+
+## Lessons Learned
+
+### Templates and parameters
+
+They are great but evil.  If they are used as part of determining the steps of a build they must resolve before the build starts.  They can not use variables set in a yml or determined as part of a matrix.  If they are used in a step then they can be bound late.
+
+### File matching patterns
+
+On Linux this can hang if there are too many files in the search list.
+
+### Templates and file splitting
+
+Suggestion is to do one big yaml file that does what you want for one of your targets.  Then do the second one and find the deltas.  From that you can start to figure out the right split of files, steps, jobs.
+
+### Conditional steps
+
+If you want the step to show up in the log but not run, use a step conditional. This is great when a platform doesn't currently support a feature but you want the builders to know that the features exists and maybe someday it will.
+
+If you want the step to not show up use a template step conditional wrapper.  Beware this will be evaluated early (at build start).  This can hide things not needed on a given OS for example.
diff --git a/.azurepipelines/templates/ReadMe.md b/.azurepipelines/templates/ReadMe.md
new file mode 100644
index 000000000000..fa433e3ef597
--- /dev/null
+++ b/.azurepipelines/templates/ReadMe.md
@@ -0,0 +1,59 @@
+# CI Templates
+
+This folder contains azure pipeline yml templates for "Core" and "Platform" Continuous Integration and PR validation.
+
+## Common CI templates
+
+### basetools-build-steps.yml
+
+This template compiles the Edk2 basetools from source.  The steps in this template are
+conditional and will only run if variable `pkg_count` is greater than 0.
+
+It also has two conditional steps only used when the toolchain contains GCC. These two steps
+use `apt` to update the system packages and add those necessary for Edk2 builds.
+
+## Core CI templates
+
+### pr-gate-build-job.yml
+
+This templates contains the jobs and most importantly the matrix of which packages and
+targets to run for Core CI.
+
+### pr-gate-steps.yml
+
+This template is the main Core CI template.  It controls all the steps run and is responsible for most functionality of the Core CI process.  This template sets
+the `pkg_count` variable using the `stuart_pr_eval` tool when the
+build type is "pull request"
+
+### spell-check-prereq-steps.yml
+
+This template installs the node based tools used by the spell checker plugin. The steps
+in this template are conditional and will only run if variable `pkg_count` is greater than 0.
+
+## Platform CI templates
+
+### platform-build-run-steps.yml
+
+This template makes heavy use of pytools to build and run a platform in the Edk2 repo
+
+Also uses basetools-build-steps.yml to compile basetools
+
+#### Special Notes
+
+* For a build type of pull request it will conditionally build if the patches change files that impact the platform.
+  * uses `stuart_pr_eval` to determine impact
+* For manual builds or CI builds it will always build the platform
+* It compiles basetools from source
+* Will use `stuart_build --FlashOnly` to attempt to run the built image if the `Run` parameter is set.
+* See the parameters block for expected configuration options
+* Parameter `extra_install_step` allows the caller to insert extra steps.  This is useful if additional dependencies, tools, or other things need to be installed.  Here is an example of installing qemu on Windows.
+
+    ``` yaml
+    steps:
+    - template: ../../.azurepipelines/templates/build-run-steps.yml
+      parameters:
+        extra_install_step:
+        - powershell: choco install qemu; Write-Host "##vso[task.prependpath]c:\Program Files\qemu"
+          displayName: Install QEMU and Set QEMU on path # friendly name displayed in the UI
+          condition: and(gt(variables.pkg_count, 0), succeeded())
+    ```
diff --git a/.azurepipelines/templates/platform-build-run-steps.yml b/.azurepipelines/templates/platform-build-run-steps.yml
new file mode 100644
index 000000000000..ebf674bfc7d8
--- /dev/null
+++ b/.azurepipelines/templates/platform-build-run-steps.yml
@@ -0,0 +1,134 @@
+
+## @file
+# File steps.yml
+#
+# template file containing the steps to build
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+parameters:
+- name: tool_chain_tag
+  type: string
+  default: ''
+- name: build_pkg
+  type: string
+  default: ''
+- name: build_target
+  type: string
+  default: ''
+- name: build_arch
+  type: string
+  default: ''
+- name: build_file
+  type: string
+  default: ''
+- name: build_flags
+  type: string
+  default: ''
+- name: run_flags
+  type: string
+  default: ''
+
+- name: extra_install_step
+  type: stepList
+  default: []
+
+steps:
+- checkout: self
+  clean: true
+  fetchDepth: 1
+
+- task: UsePythonVersion@0
+  inputs:
+    versionSpec: "3.8.x"
+    architecture: "x64"
+
+- script: pip install -r pip-requirements.txt --upgrade
+  displayName: 'Install/Upgrade pip modules'
+
+# Set default
+- bash: echo "##vso[task.setvariable variable=pkg_count]${{ 1 }}"
+
+# trim the package list if this is a PR
+- task: CmdLine@1
+  displayName: Check if ${{ parameters.build_pkg }} need testing
+  inputs:
+    filename: stuart_pr_eval
+    arguments: -c ${{ parameters.build_file }} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} --pr-target origin/$(System.PullRequest.targetBranch) --output-count-format-string "##vso[task.setvariable variable=pkg_count;isOutpout=true]{pkgcount}"
+  condition: eq(variables['Build.Reason'], 'PullRequest')
+
+ # Setup repo
+- task: CmdLine@1
+  displayName: Setup
+  inputs:
+    filename: stuart_setup
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
+  condition: and(gt(variables.pkg_count, 0), succeeded())
+
+# Stuart Update
+- task: CmdLine@1
+  displayName: Update
+  inputs:
+    filename: stuart_update
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} -t ${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
+  condition: and(gt(variables.pkg_count, 0), succeeded())
+
+# build basetools
+#   do this after setup and update so that code base dependencies
+#   are all resolved.
+- template: basetools-build-steps.yml
+  parameters:
+    tool_chain_tag: ${{ parameters.tool_chain_tag }}
+
+# Potential Extra steps
+- ${{ parameters.extra_install_step }}
+
+# Build
+- task: CmdLine@1
+  displayName: Build
+  inputs:
+    filename: stuart_build
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}}
+  condition: and(gt(variables.pkg_count, 0), succeeded())
+
+# Run
+- task: CmdLine@1
+  displayName: Run to shell
+  inputs:
+    filename: stuart_build
+    arguments: -c ${{ parameters.build_file }} TOOL_CHAIN_TAG=${{ parameters.tool_chain_tag}} TARGET=${{ parameters.build_target}} -a ${{ parameters.build_arch}} ${{ parameters.build_flags}} ${{ parameters.run_flags }} --FlashOnly
+  condition: and(and(gt(variables.pkg_count, 0), succeeded()), eq(variables['Run'], true))
+  timeoutInMinutes: 1
+
+# Copy the build logs to the artifact staging directory
+- task: CopyFiles@2
+  displayName: "Copy build logs"
+  inputs:
+    targetFolder: "$(Build.ArtifactStagingDirectory)"
+    SourceFolder: "Build"
+    contents: |
+      BUILDLOG_*.txt
+      BUILDLOG_*.md
+      CI_*.txt
+      CI_*.md
+      CISETUP.txt
+      SETUPLOG.txt
+      UPDATE_LOG.txt
+      PREVALLOG.txt
+      TestSuites.xml
+      **/BUILD_TOOLS_REPORT.html
+      **/OVERRIDELOG.TXT
+      BASETOOLS_BUILD*.*
+    flattenFolders: true
+  condition: succeededOrFailed()
+
+# Publish build artifacts to Azure Artifacts/TFS or a file share
+- task: PublishBuildArtifacts@1
+  continueOnError: true
+  displayName: "Publish build logs"
+  inputs:
+    pathtoPublish: "$(Build.ArtifactStagingDirectory)"
+    artifactName: "Build Logs $(System.JobName)"
+  condition: succeededOrFailed()
--
2.16.3.windows.1





[-- Attachment #2: Type: text/html, Size: 21790 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [EXTERNAL] [edk2-devel] [PATCH v2 2/6] ArmVirtPkg: Add Platform CI and configuration for Core CI
  2020-04-20 19:12 ` [PATCH v2 2/6] ArmVirtPkg: Add Platform CI and configuration for Core CI Michael Kubacki
@ 2020-04-24 20:22   ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2020-04-24 20:22 UTC (permalink / raw)
  To: devel@edk2.groups.io, michael.kubacki@outlook.com
  Cc: Laszlo Ersek, Ard Biesheuvel, Leif Lindholm

[-- Attachment #1: Type: text/plain, Size: 34004 bytes --]

Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>

- Bret

________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Michael Kubacki via groups.io <michael.kubacki=outlook.com@groups.io>
Sent: Monday, April 20, 2020 12:12:12 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Laszlo Ersek <lersek@redhat.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Leif Lindholm <leif@nuviainc.com>
Subject: [EXTERNAL] [edk2-devel] [PATCH v2 2/6] ArmVirtPkg: Add Platform CI and configuration for Core CI

From: Sean Brogan <sean.brogan@microsoft.com>

REF:https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2570&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=a6fVczCTqMGlZeTFwe6IRGnJE48jL00qa1W9qo1RU0A%3D&amp;reserved=0

Add new Azure Pipeline definitions to build and run ArmVirtPkg with:
  * Ubuntu GCC5
Add PyTool based build of ArmVirtPkg
Add extdep for managing the iasl dependency
Add ArmVirtPkg.ci.yaml for Core CI
Add ReadMe.rst for status, details, and instructions

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Signed-off-by: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
---
 ArmVirtPkg/ArmVirtPkg.ci.yaml                         | 103 ++++++++
 ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml |  89 +++++++
 ArmVirtPkg/PlatformCI/PlatformBuild.py                | 276 ++++++++++++++++++++
 ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml               |  21 ++
 ArmVirtPkg/ReadMe.rst                                 | 139 ++++++++++
 5 files changed, 628 insertions(+)

diff --git a/ArmVirtPkg/ArmVirtPkg.ci.yaml b/ArmVirtPkg/ArmVirtPkg.ci.yaml
new file mode 100644
index 000000000000..4553725ee528
--- /dev/null
+++ b/ArmVirtPkg/ArmVirtPkg.ci.yaml
@@ -0,0 +1,103 @@
+## @file
+# Core CI configuration for ArmVirtPkg
+#
+# ArmVirtPkg is part of Platform Ci for builds so this is only
+# used for code analysis.
+#
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+    ## options defined .pytool/Plugin/CompilerPlugin
+    "CompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+    "HostUnitTestCompilerPlugin": {
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/CharEncodingCheck
+    "CharEncodingCheck": {
+        "IgnoreFiles": []
+    },
+
+    ## options defined .pytool/Plugin/DependencyCheck
+    "DependencyCheck": {
+        "AcceptableDependencies": [
+            "MdePkg/MdePkg.dec",
+            "MdeModulePkg/MdeModulePkg.dec",
+            "ArmVirtPkg/ArmVirtPkg.dec",
+            "NetworkPkg/NetworkPkg.dec",
+            "ArmPkg/ArmPkg.dec",
+            "OvmfPkg/OvmfPkg.dec",
+            "EmbeddedPkg/EmbeddedPkg.dec",
+            "ArmPlatformPkg/ArmPlatformPkg.dec",
+            "SecurityPkg/SecurityPkg.dec",
+            "ShellPkg/ShellPkg.dec"  #Is this ok?
+        ],
+        # For host based unit tests
+        "AcceptableDependencies-HOST_APPLICATION":[
+            "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+        ],
+        # For UEFI shell based apps
+        "AcceptableDependencies-UEFI_APPLICATION":[
+
+        ],
+        "IgnoreInf": []
+    },
+
+    ## options defined .pytool/Plugin/DscCompleteCheck
+    "DscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": ""  # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+    "HostUnitTestDscCompleteCheck": {
+        "IgnoreInf": [""],
+        "DscPath": "" # Don't support this test
+    },
+
+    ## options defined .pytool/Plugin/GuidCheck
+    "GuidCheck": {
+        "IgnoreGuidName": [],
+        "IgnoreGuidValue": [],
+        "IgnoreFoldersAndFiles": [],
+        "IgnoreDuplicates": [],
+    },
+
+    ## options defined .pytool/Plugin/LibraryClassCheck
+    "LibraryClassCheck": {
+        "IgnoreHeaderFile": []
+    },
+
+    ## options defined .pytool/Plugin/SpellCheck
+    "SpellCheck": {
+        "AuditOnly": False,           # Fails right now with over 270 errors
+        "IgnoreFiles": [],           # use gitignore syntax to ignore errors in matching files
+        "ExtendWords": [
+            "setjump",
+            "plong",
+            "lparam",
+            "lpdword",
+            "lpthread",
+            "lresult",
+            "bootable",
+            "bsymbolic",
+            "endiannness",
+            "fvmain",
+            "multiboot",
+            "qemu's",
+            "ramdisk",
+            "ramfb",
+            "unbootable",
+            "virt's",
+            "werror",
+            "xenio"
+        ],           # words to extend to the dictionary for this package
+        "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
+        "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+    }
+}
diff --git a/ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
new file mode 100644
index 000000000000..b9452ec5bfaf
--- /dev/null
+++ b/ArmVirtPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml
@@ -0,0 +1,89 @@
+## @file
+# Azure Pipeline build file for building a platform.
+#
+# Platform: ArmVirtQemu
+# OS: Ubuntu
+# Toolchain: GCC5
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+trigger:
+  - master
+pr:
+  - master
+
+jobs:
+  - job: Platform_CI
+    variables:
+      package: 'ArmVirtPkg'
+      vm_image: 'ubuntu-latest'
+      should_run: true
+      run_flags: "MAKE_STARTUP_NSH=TRUE QEMU_HEADLESS=TRUE"
+
+    #Use matrix to speed up the build process
+    strategy:
+        matrix:
+          QEMU_AARCH64_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "AARCH64"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_AARCH64_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "AARCH64"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_AARCH64_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "AARCH64"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_ARM_DEBUG:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "ARM"
+            Build.Flags: ""
+            Build.Target: "DEBUG"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_ARM_RELEASE:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "ARM"
+            Build.Flags: ""
+            Build.Target: "RELEASE"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+          QEMU_ARM_NOOPT:
+            Build.File: "$(package)/PlatformCI/PlatformBuild.py"
+            Build.Arch: "ARM"
+            Build.Flags: ""
+            Build.Target: "NOOPT"
+            Run.Flags: $(run_flags)
+            Run: $(should_run)
+
+    workspace:
+      clean: all
+
+    pool:
+      vmImage: $(vm_image)
+
+    steps:
+    - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml
+      parameters:
+        tool_chain_tag: GCC5
+        build_pkg: $(package)
+        build_target: $(Build.Target)
+        build_arch: $(Build.Arch)
+        build_file: $(Build.File)
+        build_flags: $(Build.Flags)
+        run_flags: $(Run.Flags)
+        extra_install_step:
+        - bash: sudo apt-get install qemu
+          displayName: Install qemu
+          condition: and(gt(variables.pkg_count, 0), succeeded())
diff --git a/ArmVirtPkg/PlatformCI/PlatformBuild.py b/ArmVirtPkg/PlatformCI/PlatformBuild.py
new file mode 100644
index 000000000000..dff653e919eb
--- /dev/null
+++ b/ArmVirtPkg/PlatformCI/PlatformBuild.py
@@ -0,0 +1,276 @@
+# @file
+# Script to Build ArmVirtPkg UEFI firmware
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+import logging
+import io
+
+from edk2toolext.environment import shell_environment
+from edk2toolext.environment.uefi_build import UefiBuilder
+from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager
+from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule
+from edk2toolext.invocables.edk2_update import UpdateSettingsManager
+from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager
+from edk2toollib.utility_functions import RunCmd
+from edk2toollib.utility_functions import GetHostInfo
+
+# ####################################################################################### #
+#                                Common Configuration                                     #
+# ####################################################################################### #
+
+
+class CommonPlatform():
+    ''' Common settings for this platform.  Define static data here and use
+        for the different parts of stuart
+    '''
+    PackagesSupported = ("ArmVirtPkg",)
+    ArchSupported = ("AARCH64", "ARM")
+    TargetsSupported = ("DEBUG", "RELEASE", "NOOPT")
+    Scopes = ('armvirt', 'edk2-build')
+    WorkspaceRoot = os.path.realpath(os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), "..", ".."))
+
+    # ####################################################################################### #
+    #                         Configuration for Update & Setup                                #
+    # ####################################################################################### #
+
+
+class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager):
+
+    def GetPackagesSupported(self):
+        ''' return iterable of edk2 packages supported by this build.
+        These should be edk2 workspace relative paths '''
+        return CommonPlatform.PackagesSupported
+
+    def GetArchitecturesSupported(self):
+        ''' return iterable of edk2 architectures supported by this build '''
+        return CommonPlatform.ArchSupported
+
+    def GetTargetsSupported(self):
+        ''' return iterable of edk2 target tags supported by this build '''
+        return CommonPlatform.TargetsSupported
+
+    def GetRequiredSubmodules(self):
+        ''' return iterable containing RequiredSubmodule objects.
+        If no RequiredSubmodules return an empty iterable
+        '''
+        rs = []
+
+        # intentionally declare this one with recursive false to avoid overhead
+        rs.append(RequiredSubmodule(
+            "CryptoPkg/Library/OpensslLib/openssl", False))
+
+        # To avoid maintenance of this file for every new submodule
+        # lets just parse the .gitmodules and add each if not already in list.
+        # The GetRequiredSubmodules is designed to allow a build to optimize
+        # the desired submodules but it isn't necessary for this repository.
+        result = io.StringIO()
+        ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result)
+        # Cmd output is expected to look like:
+        # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl
+        # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
+        if ret == 0:
+            for line in result.getvalue().splitlines():
+                _, _, path = line.partition(" ")
+                if path is not None:
+                    if path not in [x.path for x in rs]:
+                        rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know
+        return rs
+
+    def SetArchitectures(self, list_of_requested_architectures):
+        ''' Confirm the requests architecture list is valid and configure SettingsManager
+        to run only the requested architectures.
+
+        Raise Exception if a list_of_requested_architectures is not supported
+        '''
+        unsupported = set(list_of_requested_architectures) - \
+            set(self.GetArchitecturesSupported())
+        if(len(unsupported) > 0):
+            errorString = (
+                "Unsupported Architecture Requested: " + " ".join(unsupported))
+            logging.critical(errorString)
+            raise Exception(errorString)
+        self.ActualArchitectures = list_of_requested_architectures
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+
+        scopes = CommonPlatform.Scopes
+        ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
+
+        if GetHostInfo().os.upper() == "LINUX" and ActualToolChainTag.upper().startswith("GCC"):
+            if "AARCH64" in self.ActualArchitectures:
+                scopes += ("gcc_aarch64_linux",)
+            if "ARM" in self.ActualArchitectures:
+                scopes += ("gcc_arm_linux",)
+        return scopes
+
+    def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list:
+        ''' Filter other cases that this package should be built
+        based on changed files. This should cover things that can't
+        be detected as dependencies. '''
+        build_these_packages = []
+        possible_packages = potentialPackagesList.copy()
+        for f in changedFilesList:
+            # BaseTools files that might change the build
+            if "BaseTools" in f:
+                if os.path.splitext(f) not in [".txt", ".md"]:
+                    build_these_packages = possible_packages
+                    break
+
+            # if the azure pipeline platform template file changed
+            if "platform-build-run-steps.yml" in f:
+                build_these_packages = possible_packages
+                break
+
+
+        return build_these_packages
+
+    def GetPlatformDscAndConfig(self) -> tuple:
+        ''' If a platform desires to provide its DSC then Policy 4 will evaluate if
+        any of the changes will be built in the dsc.
+
+        The tuple should be (<workspace relative path to dsc file>, <input dictionary of dsc key value pairs>)
+        '''
+        return (os.path.join("ArmVirtPkg", "ArmVirtQemu.dsc"), {})
+
+
+    # ####################################################################################### #
+    #                         Actual Configuration for Platform Build                         #
+    # ####################################################################################### #
+
+
+class PlatformBuilder(UefiBuilder, BuildSettingsManager):
+    def __init__(self):
+        UefiBuilder.__init__(self)
+
+    def AddCommandLineOptions(self, parserObj):
+        ''' Add command line options to the argparser '''
+        parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="AARCH64",
+                               help="Optional - Architecture to build.  Default = AARCH64")
+
+    def RetrieveCommandLineOptions(self, args):
+        '''  Retrieve command line options from the argparser '''
+
+        shell_environment.GetBuildVars().SetValue(
+            "TARGET_ARCH", args.build_arch.upper(), "From CmdLine")
+
+        shell_environment.GetBuildVars().SetValue(
+            "ACTIVE_PLATFORM", "ArmVirtPkg/ArmVirtQemu.dsc", "From CmdLine")
+
+    def GetWorkspaceRoot(self):
+        ''' get WorkspacePath '''
+        return CommonPlatform.WorkspaceRoot
+
+    def GetPackagesPath(self):
+        ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath '''
+        return ()
+
+    def GetActiveScopes(self):
+        ''' return tuple containing scopes that should be active for this process '''
+        scopes = CommonPlatform.Scopes
+        ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
+        Arch = shell_environment.GetBuildVars().GetValue("TARGET_ARCH", "")
+
+        if GetHostInfo().os.upper() == "LINUX" and ActualToolChainTag.upper().startswith("GCC"):
+            if "AARCH64" == Arch:
+                scopes += ("gcc_aarch64_linux",)
+            elif "ARM" == Arch:
+                scopes += ("gcc_arm_linux",)
+        return scopes
+
+    def GetName(self):
+        ''' Get the name of the repo, platform, or product being build '''
+        ''' Used for naming the log file, among others '''
+        # check the startup nsh flag and if set then rename the log file.
+        # this helps in CI so we don't overwrite the build log since running
+        # uses the stuart_build command.
+        if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"):
+            return "ArmVirtPkg_With_Run"
+        return "ArmVirtPkg"
+
+    def GetLoggingLevel(self, loggerType):
+        ''' Get the logging level for a given type
+        base == lowest logging level supported
+        con  == Screen logging
+        txt  == plain text file logging
+        md   == markdown file logging
+        '''
+        return logging.DEBUG
+
+    def SetPlatformEnv(self):
+        logging.debug("PlatformBuilder SetPlatformEnv")
+        self.env.SetValue("PRODUCT_NAME", "ArmVirtQemu", "Platform Hardcoded")
+        self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false")
+        self.env.SetValue("QEMU_HEADLESS", "FALSE", "Default to false")
+        return 0
+
+    def PlatformPreBuild(self):
+        return 0
+
+    def PlatformPostBuild(self):
+        return 0
+
+    def FlashRomImage(self):
+        VirtualDrive = os.path.join(self.env.GetValue(
+            "BUILD_OUTPUT_BASE"), "VirtualDrive")
+        os.makedirs(VirtualDrive, exist_ok=True)
+        OutputPath_FV = os.path.join(
+            self.env.GetValue("BUILD_OUTPUT_BASE"), "FV")
+        Built_FV = os.path.join(OutputPath_FV, "QEMU_EFI.fd")
+
+        # pad fd to 64mb
+        with open(Built_FV, "ab") as fvfile:
+            fvfile.seek(0, os.SEEK_END)
+            additional = b'\0' * ((64 * 1024 * 1024)-fvfile.tell())
+            fvfile.write(additional)
+
+        # QEMU must be on that path
+
+        # Unique Command and Args parameters per ARCH
+        if (self.env.GetValue("TARGET_ARCH").upper() == "AARCH64"):
+            cmd = "qemu-system-aarch64"
+            args = "-M virt"
+            args += " -cpu cortex-a57"                                          # emulate cpu
+        elif(self.env.GetValue("TARGET_ARCH").upper() == "ARM"):
+            cmd = "qemu-system-arm"
+            args = "-M virt"
+            args += " -cpu cortex-a15"                                          # emulate cpu
+        else:
+            raise NotImplementedError()
+
+        # Common Args
+        args += " -pflash " + Built_FV                                     # path to fw
+        args += " -m 1024"                                                  # 1gb memory
+        # turn off network
+        args += " -net none"
+        # Serial messages out
+        args += " -serial stdio"
+        # Mount disk with startup.nsh
+        args += f" -drive file=fat:rw:{VirtualDrive},format=raw,media=disk"
+
+        # Conditional Args
+        if (self.env.GetValue("QEMU_HEADLESS").upper() == "TRUE"):
+            args += " -display none"  # no graphics
+
+        if (self.env.GetValue("MAKE_STARTUP_NSH").upper() == "TRUE"):
+            f = open(os.path.join(VirtualDrive, "startup.nsh"), "w")
+            f.write("BOOT SUCCESS !!! \n")
+            # add commands here
+            f.write("reset -s\n")
+            f.close()
+
+        ret = RunCmd(cmd, args)
+
+        if ret == 0xc0000005:
+            # for some reason getting a c0000005 on successful return
+            return 0
+
+        return ret
diff --git a/ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml b/ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml
new file mode 100644
index 000000000000..8869ed3ecef1
--- /dev/null
+++ b/ArmVirtPkg/PlatformCI/iasl_ext_dep.yaml
@@ -0,0 +1,21 @@
+## @file
+# Download iasl executable tool from a nuget.org package
+# - package contains different binaries based on host
+# Add the folder with the tool to the path
+#
+# This is only downloaded for scope armvirt thus
+# should have no impact on the asl compiler used by any
+# other platform build
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+  "id": "iasl-armvirt-1",
+  "scope": "armvirt",
+  "type": "nuget",
+  "name": "iasl",
+  "source": "https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapi.nuget.org%2Fv3%2Findex.json&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=qlLxPSG8b46gi3efOGuAekE3IXWn%2F0fFib0ryThdnSs%3D&amp;reserved=0",
+  "version": "20190215.0.0",
+  "flags": ["set_path", "host_specific"],
+}
diff --git a/ArmVirtPkg/ReadMe.rst b/ArmVirtPkg/ReadMe.rst
new file mode 100644
index 000000000000..6149bff7032d
--- /dev/null
+++ b/ArmVirtPkg/ReadMe.rst
@@ -0,0 +1,139 @@
+==========
+ArmVirtPkg
+==========
+
+This ReadMe.rst summarizes the current state of Azure DevOps based Platform CI
+for ArmVirtPkg. It also describes how to *build* ArmVirtPkg locally using the Pytools build system.
+
+Platform CI Current Status
+--------------------------
+
+AARCH64 Configuration
+`````````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Ubuntu GCC5`_  |apAArch64du| |apAArch64ru| |apAArch64nu|
+=============== ============= ============= =============
+
+ARM Configuration
+`````````````````
+=============== ============= ============= =============
+ Toolchain      DEBUG         RELEASE       NOOPT
+=============== ============= ============= =============
+`Ubuntu GCC5`_  |apArmdu|     |apArmru|     |apArmnu|
+=============== ============= ============= =============
+
+Setup
+-----
+
+The Usual EDK2 Build Setup
+``````````````````````````
+
+- `Python 3.8.x - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.python.org%2Fdownloads%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=gwuWIPhl4PqU3XTw6jU3ABBaR%2BCmTC24e17Fd0ZiuTU%3D&amp;reserved=0>`_
+- `GIT - Download & Install <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit-scm.com%2Fdownload%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=Quy06b0GasA9Ag%2BS5VlgNJ9bYgEKmV7ABkRPCwfl6Gw%3D&amp;reserved=0>`_
+- `GIT - Configure for EDK II <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23github-help&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=wFBQ7CGdPSZp6pHv6fTW9oYb1B%2BUK3diHsviATPWVSI%3D&amp;reserved=0>`_
+- `QEMU - Download, Install, and add to your path <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.qemu.org%2Fdownload%2F&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=VKtIDDMygxYY97DzwENxknWIltDw4fyrsJ4GEj7MFlM%3D&amp;reserved=0>`_
+- `EDKII Source - Download/Checkout from Github <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FWindows-systems%23download&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=VB95DDiiFsmvpVwOT2G7PMnumUcIXsAD7YmE%2BWPQaSE%3D&amp;reserved=0>`_
+
+**NOTE:** Do *not* follow the EDK II Compile Tools and Build instructions, see below...
+
+Differences from EDK Classic Build Setup
+````````````````````````````````````````
+
+- Build BaseTools using `python BaseTools/Edk2ToolsBuild.py [-t <ToolChainTag>]`
+
+  - This replaces `edksetup Rebuild`" from the classic build system
+
+- **No Action:** edksetup, Submodule initialization and manual installation of NASM and iASL are **not**
+  required, it is handled by the Pytools build system.
+
+Building with Pytools for ArmVirtPkg
+````````````````````````````````````
+
+* Install Pytools
+
+  .. code-block:: bash
+
+    pip install --upgrade -r pip-requirements.txt
+
+* Initialize & Update Submodules
+
+  .. code-block:: bash
+
+    stuart_setup -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+* Initialize & Update Dependencies (e.g. iASL & NASM)
+
+  .. code-block:: bash
+
+    stuart_update -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+* Compile
+
+  .. code-block:: bash
+
+    stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
+
+* Running Emulator
+
+  - You can add `--FlashRom` to the end of your build command and the emulator will run after the build is complete.
+  - or use the `--FlashOnly` feature to just run the emulator.
+
+  .. code-block:: bash
+
+    stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH> --FlashOnly
+
+Notes
+`````
+
+1. Including the expected build architecture and toolchain to the *stuart_update* command is critical. This is because there
+   are extra scopes and tools that will be resolved during the update step that need to match your build step.
+2. Configuring *ACTIVE_PLATFORM* and *TARGET_ARCH* in Conf/target.txt is *not* required. This environment is set by
+   PlatformBuild.py based upon the `[-a <TARGET_ARCH>]` parameter.
+3. QEMU must be on your path.  On Windows this is a manual process and not part of the QEMU installer.
+
+**NOTE:** Logging the execution output will be in the normal stuart log as well as to your console.
+
+Custom Build Options
+````````````````````
+
+**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is used in CI in combination
+with the `--FlashOnly` feature to run QEMU to the UEFI shell and then execute the contents of startup.nsh.
+
+**QEMU_HEADLESS=TRUE** Since CI servers run headless QEMU must be told to run with no display otherwise an error occurs.
+Locally you don't need to set this.
+
+Passing Build Defines
+`````````````````````
+To pass build defines through stuart_build, prepend `BLD_*_` to the define name and pass it on the commandline. stuart_build currently
+requires values to be assigned, so add a `=1` suffix for bare defines.
+For example, to enable TPM2 support, instead of the traditional "-D TPM2_ENABLE=TRUE", the stuart_build command-line would be:
+
+.. code-block:: bash
+
+  stuart_build -c ArmVirtPkg/PlatformCI/PlatformBuild.py BLD_*_TPM2_ENABLE=TRUE
+
+References
+----------
+- `Installing Pytools <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2Fmaster%2Fdocs%2Fusing.md%23installing&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=ZVcDVndxMu%2FMS8P%2BVgq4mNjR%2FEBk4Y14D9eCgM9srl8%3D&amp;reserved=0>`_
+- For each workspace, consider creating & using a `Python Virtual Environment <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fvenv.html&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=Lg0mroOCdLdORiehCi4xX93PbBQy8vDUrjOvNXA1JJU%3D&amp;reserved=0>`_
+
+  * `Sample Layout <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmicrosoft.github.io%2Fmu%2FCodeDevelopment%2Fprerequisites%2F%23workspace-virtual-environment-setup-process&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=jc9S0%2BDc0k724g5zsmWIDxtKF49RuZyHp2nsebowFXs%3D&amp;reserved=0>`_
+
+- `stuart_build commandline parser <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-pytool-extensions%2Fblob%2F56f6a7aee09995c2f22da4765e8b0a29c1cbf5de%2Fedk2toolext%2Fedk2_invocable.py%23L109&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830885007&amp;sdata=RsQxmP7nIewfcb67uRjn0C8SCCifKxTENQ3sT7gYX9w%3D&amp;reserved=0>`_
+
+
+.. ===================================================================
+.. This is a bunch of directives to make the README file more readable
+.. ===================================================================
+
+.. _Ubuntu GCC5: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_build%2Flatest%3FdefinitionId%3D41%26branchName%3Dmaster&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830894972&amp;sdata=JrL3ua6Tqg6KBegP6Pm6Gir3cnZg%2BPHXeQRpygTKE8U%3D&amp;reserved=0
+
+.. |apAArch64du| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FArmVirtPkg%2FArmVirtQemu%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520QEMU_AARCH64_DEBUG&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830894972&amp;sdata=MLqtonE66Cdhyr6Fbf1n5ycJ0%2FGKynqUoKuydXxt3gI%3D&amp;reserved=0
+.. |apAArch64ru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FArmVirtPkg%2FArmVirtQemu%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520QEMU_AARCH64_RELEASE&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830894972&amp;sdata=C5yR%2FQ4AxHRTHSKt6rIm5b1zsr37q5YMq1wcsPbpP4g%3D&amp;reserved=0
+.. |apAArch64nu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FArmVirtPkg%2FArmVirtQemu%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520QEMU_AARCH64_NOOPT&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830894972&amp;sdata=3vVM69IyS5Bz2gHzC3X1ntFyj00ySv5sswPYgnZfg9c%3D&amp;reserved=0
+
+.. |apArmdu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FArmVirtPkg%2FArmVirtQemu%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520QEMU_ARM_DEBUG&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830894972&amp;sdata=O8qCEy9sZ%2B7c2Xsslr4z4%2F0tJH1iRrj4Oh6C%2Fke9dH4%3D&amp;reserved=0
+.. |apArmru| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FArmVirtPkg%2FArmVirtQemu%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520QEMU_ARM_RELEASE&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830894972&amp;sdata=o8TQJPCSac6GkYzKeKWFI6Z7jk5EUk8p9lVUqjOm7%2FI%3D&amp;reserved=0
+.. |apArmnu| image:: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdev.azure.com%2Ftianocore%2Fedk2-ci-play%2F_apis%2Fbuild%2Fstatus%2FArmVirtPkg%2FArmVirtQemu%2520Ubuntu%2520GCC5%3FbranchName%3Dmaster%26jobName%3DPlatform_CI%26configuration%3DPlatform_CI%2520QEMU_ARM_NOOPT&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7Cc40ddb755edc46ef3b2608d7e55ed80d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637230067830894972&amp;sdata=RWG%2BWyS%2FOsPb0HTXHjZuYVgjXqswoJRC5ZEj5eCXrCQ%3D&amp;reserved=0
--
2.16.3.windows.1





[-- Attachment #2: Type: text/html, Size: 67629 bytes --]

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2020-04-24 20:22 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20200420191216.24572-1-michael.kubacki@outlook.com>
2020-04-20 19:12 ` [PATCH v2 1/6] .azurepipelines: Add Platform CI template Michael Kubacki
2020-04-24 20:22   ` [EXTERNAL] [edk2-devel] " Bret Barkelew
2020-04-20 19:12 ` [PATCH v2 2/6] ArmVirtPkg: Add Platform CI and configuration for Core CI Michael Kubacki
2020-04-24 20:22   ` [EXTERNAL] [edk2-devel] " Bret Barkelew
2020-04-20 19:12 ` [PATCH v2 3/6] EmulatorPkg: " Michael Kubacki
2020-04-21 14:36   ` [edk2-devel] " Liming Gao
2020-04-24 20:21     ` Bret Barkelew
2020-04-21 14:43   ` Ni, Ray
2020-04-24 20:21     ` Bret Barkelew
2020-04-24 20:22   ` [EXTERNAL] " Bret Barkelew
2020-04-20 19:12 ` [PATCH v2 4/6] OvmfPkg: " Michael Kubacki
2020-04-24 20:22   ` [EXTERNAL] [edk2-devel] " Bret Barkelew
2020-04-20 19:12 ` [PATCH v2 5/6] .pytool: Update CI Settings to support Emulator, ArmVirt, and Ovmf packages Michael Kubacki
2020-04-24 20:21   ` [EXTERNAL] " Bret Barkelew
2020-04-20 19:12 ` [PATCH v2 6/6] .azurepipelines: Update Core CI build matrix to include platforms Michael Kubacki
2020-04-24 20:21   ` [EXTERNAL] " Bret Barkelew

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox