public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script.
@ 2019-05-03 23:19 Agyeman, Prince
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added " Agyeman, Prince
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Agyeman, Prince @ 2019-05-03 23:19 UTC (permalink / raw)
  To: devel
  Cc: Michael Kubacki, Nate DeSimone, Ankit Sinha, Michael D Kinney,
	Isaac W Oram, Liming Gao

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Isaac W Oram <isaac.w.oram@intel.com>
Cc: Liming Gao <liming.gao@intel.com>

Contributed-under: TianoCore Contribution Agreement 0.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>


changes from v2:
- fixed pep8 violations
- implemented v2 review recommendations
- added clean flag to clean specified platform

Overview:
WORKSPACE
    |
    |------edk2
    |------edk2-non-osi
    |------edk2-platforms
    |       |--Platform
    |       |---Intel
    |       |        |------build.cfg: Default build settings. These are overridden by
    |       |        |                 platform specific settings (build_config.cfg) and
    |       |        |                 then command-line settings.
    |       |        |
    |       |        |------build_bios.py: Main build script. Generic pre-build, build,
    |       |        |                     post-build, and clean functions.
    |       |        |
    |       |        |------ClevoOpenBoardPkg
    |       |        |        |------N1xxWU
    |       |        |                |---build_config.cfg: N1xxWU specific build
    |       |        |                                      settings environment variables.
    |       |        |
    |       |        |------KabylakeOpenBoardPkg
    |       |        |        |------KabylakeRvp3
    |       |        |                  |---build_config.cfg: KabylakeRvp3 specific
    |       |        |                  |                     build settings, environment variables.
    |       |        |                  |---build_board.py: Optional board-specific pre-build, build
    |       |        |                                      and clean post-build functions.
    |       |        |------PurleyOpenBoardPkg
    |       |        |       |------BoardMtOlympus
    |       |        |                |---build_config.cfg: BoardMtOlympus specific
    |       |        |                                      build settings, environment variables.
    |       |        |                |---build_board.py: Optional board-specific pre-build,
    |       |        |                |                   build, post-build and clean functions.
    |------FSP


-------------------
Details:
-------------------
What it is
----------
These patches add python BIOS build scripts and build configuration
files to build platforms under Intel/Platform.


Why
----
The reason behind this implementation is to use a cross platform build
script to build minplaform BIOS.


How it is done
----------------
The python files:
-----------------
build_bios.py: The main build file. This script sets up the edk2 build 
enviroment using the default build.cfg settings and platform
specific settings. It uses the configurations found in the build.cfg file to
locate the platforms that are configured to use this build script.
The path to each of the platform settings can be found under the "PLATFORMS"
field within the build.cfg file. The platform specific settings are
located in the platform's main directory.
Example edk2-platforms/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg.

The build_bios.py script contains the four main functions:
- pre_build: Sets up the edk2 build enviroment variables, target.txt file
- build: Uses the configurations to Build BIOS
- post_build: Does post build processes like cleaning up files
             generated during the build process
- clean: Cleans up the build directory.

There are four addtional functions that dynamically import
functions from the board's Optional/Additional python script if
specified in board settings file's ADDITIONAL_SCRIPTS
These four functions are the pre_build_board, build_board, post_build_board, clean_ex functions


Board additional (Optional) python build script:
------------------------------------------------
These are python scripts located in the board's main directory,
An example Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
If added, its path must be specified in board's settings file,
under the field ADDITIONAL_SCRIPTS.
Example ADDITIONAL_SCRIPTS = PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
If specified, the build_board, pre_build_board, post_build_board, clean_ex must be
defined even if they are not use


The config files
-----------------
build.cfg:
-----------
This is file contains the default BIOS build configuration.

The default configurations are defined under the "DEFAULT_CONFIG" section of the file.
Each of these can be overridden by the board specific setting as defined in
the board's build config file. All paths must be separated by forward slashes.
All the paths in the main build.cfg are relative to the minplaform WORKSPACE.
Example:
--------
[DEFAULT_CONFIG]
    MIN_PACKAGE_TOOLS = edk2-platforms/Platform/Intel/MinPlatformPkg/Tools

The PLATFORMS field in the build.cfg file informs build_bios.py about the
available platforms that can be built with the build_bios.py.
The path to the board specific config file must be relative to location of
build_bios.py, Platform/Intel. It is in the format Boardname = BoardPath

Example:
--------
[PLATFORMS]
    KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg


Board Specific Build Settings file:
----------------------------------------
This file is located in the board's main directory.
The CONFIG field contains all the build enviroment variables.
These values will override any the were specific under
DEFAULT_CONFIG in the default build.cfg file.
Example is Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg


Building BIOS
-------------

python build_bios.py -p BOARDNAME -t TOOLCHAIN 

usage: build_bios.py [-h] --platform {N1xxWU,KabylakeRvp3,BoardMtOlympus}
                    [--toolchain TOOLCHAIN] [--DEBUG] [--RELEASE]
                    [--TEST_RELEASE] [--RELEASE_PDB] [--list] [--cleanall]
                    [--capsule] [--silent] [--performance] [--fsp]
Build Help

optional arguments:
  -h, --help            show this help message and exit
  --platform {N1xxWU,KabylakeRvp3,BoardMtOlympus}, -p {N1xxWU,KabylakeRvp3,BoardMtOlympus}
                        the platform to build
  --toolchain TOOLCHAIN, -t TOOLCHAIN
                        using the Tool Chain Tagname to build the
                        platform, overriding target.txt's TOOL_CHAIN_TAG
                        definition
  --DEBUG, -d           debug flag
  --RELEASE, -r         release flag
  --TEST_RELEASE, -tr   test release flag
  --RELEASE_PDB, -rp    release flag
  --list, -l            lists available platforms
  --cleanall            cleans all
  --clean               cleans specific platform 
  --capsule             capsule build enabled
  --silent              silent build enabled
  --performance         performance build enabled
  --fsp                 fsp build enabled

Agyeman (2):
  Platform/Intel: Added python build script.
  Updated the build instructions to include the python script build
    instructions

 .../ClevoOpenBoardPkg/N1xxWU/build_config.cfg |  33 +
 .../KabylakeRvp3/build_board.py               |  68 ++
 .../KabylakeRvp3/build_config.cfg             |  34 +
 .../BoardMtOlympus/build_board.py             | 177 ++++
 .../BoardMtOlympus/build_config.cfg           |  32 +
 Platform/Intel/build.cfg                      |  56 +
 Platform/Intel/build_bios.py                  | 976 ++++++++++++++++++
 ReadMe.md                                     |  76 ++
 8 files changed, 1452 insertions(+)
 create mode 100644 Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
 create mode 100644 Platform/Intel/build.cfg
 create mode 100644 Platform/Intel/build_bios.py

-- 
2.19.1.windows.1


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

* [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added python build script.
  2019-05-03 23:19 [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Agyeman, Prince
@ 2019-05-03 23:19 ` Agyeman, Prince
  2019-05-04  0:36   ` [edk2-devel] " Nate DeSimone
  2019-05-04  2:14   ` Kubacki, Michael A
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions Agyeman, Prince
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 9+ messages in thread
From: Agyeman, Prince @ 2019-05-03 23:19 UTC (permalink / raw)
  To: devel
  Cc: Michael Kubacki, Nate DeSimone, Ankit Sinha, Michael D Kinney,
	Isaac W Oram, Liming Gao, Bowen Zhou, Shifei A Lu

This change allows building all the platforms in Platform/Intel with
a single python script. This script works with python 2.7
and python 3.7

Files Added:

* build_bios.py: the main build script
  build.cfg: contains general/default build settings
* ClevoOpenBoardPkg/N1xxWU/build_config.cfg: contains N1xxWU specific
  build settings
* KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py : contains sample
  custom build script
* KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg: contains
  KabylakeRvp3 build settings
* PurleyOpenBoardPkg/BoardMtOlympus/build_board.py: contains
  BoardMtOlympus custom build script
* PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg: contains
  BoardMtOlympus custom build settings

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Isaac W Oram <isaac.w.oram@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Bowen Zhou<bowen.zhou@intel.com>
Cc: Shifei A Lu <shifei.a.lu@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>
---
 .../ClevoOpenBoardPkg/N1xxWU/build_config.cfg |  33 +
 .../KabylakeRvp3/build_board.py               |  68 ++
 .../KabylakeRvp3/build_config.cfg             |  34 +
 .../BoardMtOlympus/build_board.py             | 177 ++++
 .../BoardMtOlympus/build_config.cfg           |  32 +
 Platform/Intel/build.cfg                      |  56 +
 Platform/Intel/build_bios.py                  | 976 ++++++++++++++++++
 7 files changed, 1376 insertions(+)
 create mode 100644 Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
 create mode 100644 Platform/Intel/build.cfg
 create mode 100644 Platform/Intel/build_bios.py

diff --git a/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
new file mode 100644
index 0000000000..ee1261e700
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
@@ -0,0 +1,33 @@
+# @ build_config.cfg
+# This is the N1xxWU board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = ClevoOpenBoardPkg
+PROJECT = ClevoOpenBoardPkg/N1xxWU
+BOARD = N1xxWU
+FLASH_MAP_FDF = ClevoOpenBoardPkg/N1xxWU/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = ClevoOpenBoardPkg/N1xxWU/OpenBoardPkgPcd.dsc
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = TRUE
+FSP_BIN_PKG = KabylakeFspBinPkg
+FSP_PKG_NAME = KabylakeFspPkg
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
new file mode 100644
index 0000000000..726ad85874
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
@@ -0,0 +1,68 @@
+# @ build_board.py
+# This is a sample code provides Optional dynamic imports
+# of build functions to the BuildBios.py script
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+"""
+This module serves as a sample implementation of the build extension
+scripts
+"""
+
+
+def pre_build_ex(config, functions):
+    """Additional Pre BIOS build function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: nothing
+    """
+    print("pre_build_ex")
+    return None
+
+
+def build_ex(config, functions):
+    """Additional BIOS build function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("build_ex")
+    return None
+
+
+def post_build_ex(config, functions):
+    """Additional Post BIOS build function
+
+    :param config: The environment variables to be used in the post
+        build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("post_build_ex")
+    return None
+
+
+def clean_ex(config, functions):
+    """Additional clean function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("clean_ex")
+    return None
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
new file mode 100644
index 0000000000..5ea61dceb8
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
@@ -0,0 +1,34 @@
+# @ build_config.cfg
+# This is the KabylakeRvp3 board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = KabylakeOpenBoardPkg
+PROJECT = KabylakeOpenBoardPkg/KabylakeRvp3
+BOARD = KabylakeRvp3
+FLASH_MAP_FDF = KabylakeOpenBoardPkg/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc
+ADDITIONAL_SCRIPTS = KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = TRUE
+FSP_BIN_PKG = KabylakeFspBinPkg
+FSP_PKG_NAME = KabylakeFspPkg
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
diff --git a/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
new file mode 100644
index 0000000000..0dda929a00
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
@@ -0,0 +1,177 @@
+# @ build_board.py
+# This adds additional functions to the build_bios.py
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+"""
+This module serves as an additional build steps for the Mt Olympus board
+"""
+
+import os
+import sys
+
+
+def pre_build_ex(config, functions):
+    """Additional Pre BIOS build function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: nothing
+    """
+    print("Info: re-generating PlatformOffset header files")
+
+    execute_script = functions.get("execute_script")
+
+    command = ["build", "-D", "MAX_SOCKET=" + config.get("MAX_SOCKET", "1"),
+               "-m",
+               os.path.join(config["PLATFORM_BOARD_PACKAGE"],
+                            "Acpi", "BoardAcpiDxe", "Dsdt.inf"),
+               "-y",
+               config.get("PRE_BUILD_REPORT",
+                          os.path.join(config["WORKSPACE"],
+                                       "preBuildReport.txt")),
+               "--log=" + config.get("PRE_BUILD_LOG",
+                                     os.path.join(config["WORKSPACE"],
+                                                  "prebuild.log"))]
+
+    _, _, _, code = execute_script(command, config)
+    if code != 0:
+        print(" ".join(command))
+        print("Error re-generating PlatformOffset header files")
+        sys.exit(1)
+
+    config["AML_FILTER"] = "\"PSYS\" .MCTL\" .FIX[0-9,A-Z]\""
+    print("AML_FILTER= ", config.get("AML_FILTER"))
+
+    # build the command with arguments
+    command = ["python",
+               os.path.join(config["MIN_PACKAGE_TOOLS"],
+                            "AmlGenOffset",
+                            "AmlGenOffset.py"),
+               "-d", "--aml_filter", config["AML_FILTER"],
+               "-o", os.path.join(config["WORKSPACE_PLATFORM"],
+                                  config["PLATFORM_BOARD_PACKAGE"],
+                                  "Acpi", "BoardAcpiDxe",
+                                  "AmlOffsetTable.c"),
+               os.path.join(config["BUILD_X64"],
+                            "PurleyOpenBoardPkg",
+                            "Acpi",
+                            "BoardAcpiDxe",
+                            "DSDT",
+                            "OUTPUT",
+                            "Dsdt", "WFPPlatform.offset.h")]
+
+    # execute the command
+    _, _, _, code = execute_script(command, config)
+    if code != 0:
+        print(" ".join(command))
+        print("Error re-generating PlatformOffset header files")
+        sys.exit(1)
+
+    print("GenOffset done")
+    return config
+
+
+def build_ex(config, functions):
+    """Additional BIOS build function
+
+    :param config: The environment variables to be used in
+    the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("build_ex")
+    return None
+
+
+def post_build_ex(config, functions):
+    """Additional Post BIOS build function
+
+    :param config: The environment variables to be used in the post
+        build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("post_build_ex")
+
+    execute_script = functions.get("execute_script")
+
+    if not execute_script:
+        print("post_build_ex Error")
+        sys.exit(1)
+
+    common_patch_command = [os.path.join(config["PYTHON_HOME"], "python"),
+                            os.path.join(config["MIN_PACKAGE_TOOLS"],
+                                         "PatchFv", "PatchBinFv.py"),
+                            config["TARGET"],
+                            os.path.join(config["WORKSPACE_SILICON_BIN"],
+                                         "PurleySiliconBinPkg"),
+                            os.path.join(config["WORKSPACE"],
+                                         "BuildReport.log")]
+
+    fvs_to_patch = ["FvTempMemorySilicon",
+                    "FvPreMemorySilicon",
+                    "FvPostMemorySilicon",
+                    "FvLateSilicon"]
+    for fv in fvs_to_patch:
+        patch_command = common_patch_command + [fv]
+        _, _, _, code = execute_script(patch_command, config)
+        if code != 0:
+            print(" ".join(patch_command))
+            print("Patch Error!")
+            sys.exit(1)
+
+    common_rebase_command = [os.path.join(config["PYTHON_HOME"], "python"),
+                             os.path.join(config["MIN_PACKAGE_TOOLS"],
+                                          "PatchFv", "RebaseBinFv.py"),
+                             config["TARGET"],
+                             os.path.join(config["WORKSPACE_SILICON_BIN"],
+                                          "PurleySiliconBinPkg"),
+                             os.path.join(config["WORKSPACE"],
+                                          "BuildReport.log")]
+
+    rebase_command = common_rebase_command +\
+        ["FvPreMemorySilicon",
+         "gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase"]
+
+    _, _, _, code = execute_script(rebase_command, config)
+    if code != 0:
+        print(" ".join(rebase_command))
+        print("Patch Error!")
+        sys.exit(1)
+
+    rebase_command = common_rebase_command +\
+        ["FvPostMemorySilicon",
+         "gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase"]
+
+    _, _, _, code = execute_script(rebase_command, config)
+    if code != 0:
+        print(" ".join(rebase_command))
+        print("Patch Error!")
+        sys.exit(1)
+
+    return None
+
+
+def clean_ex(config, functions):
+    """Additional clean function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("clean_ex")
+    return None
diff --git a/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
new file mode 100644
index 0000000000..dcf19d658d
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
@@ -0,0 +1,32 @@
+# @ build_config.cfg
+# This is the main/default build configuration file
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = PurleyOpenBoardPkg
+PROJECT = PurleyOpenBoardPkg/BoardMtOlympus
+BOARD = BoardMtOlympus
+FLASH_MAP_FDF = PurleyOpenBoardPkg/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = PurleyOpenBoardPkg/BoardMtOlympus/PlatformPkg.dsc
+BOARD_PKG_PCD_DSC = PurleyOpenBoardPkg/BoardMtOlympus/PlatformPkgPcd.dsc
+ADDITIONAL_SCRIPTS = PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
+PRE_BUILD_LOG = prebuild.log
+PRE_BUILD_REPORT = prebuildReport.log
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = FALSE
+MAX_SOCKET = 2
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg
new file mode 100644
index 0000000000..b6c0cca4f7
--- /dev/null
+++ b/Platform/Intel/build.cfg
@@ -0,0 +1,56 @@
+# @ build.cfg
+# This is the main/default build configuration file
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[DEFAULT_CONFIG]
+WORKSPACE =
+WORKSPACE_FSP_BIN = FSP
+EDK_TOOLS_BIN = edk2-BaseTools-win32
+EDK_BASETOOLS = BaseTools
+WORKSPACE_PLATFORM = edk2-platforms/Platform/Intel
+WORKSPACE_SILICON = edk2-platforms/Silicon/Intel
+WORKSPACE_PLATFORM_BIN =
+WORKSPACE_SILICON_BIN = edk2-non-osi/Silicon/Intel
+MIN_PACKAGE_TOOLS = edk2-platforms/Platform/Intel/MinPlatformPkg/Tools
+PACKAGES_PATH =
+EDK_SETUP_OPTION =
+BASE_TOOLS_PATH = edk2/BaseTools
+EDK_TOOLS_PATH = edk2/BaseTools
+openssl_path =
+PLATFORM_BOARD_PACKAGE =
+BIOS_SIZE_OPTION = -DBIOS_SIZE_OPTION=SIZE_70
+WORKSPACE_CORE = edk2
+EFI_SOURCE = edk2
+PATHEXT = .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
+PROMPT = $P$G
+PLATFORM_PACKAGE = MinPlatformPkg
+BOARD =
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = FALSE
+FSP_BIN_PKG =
+FSP_PKG_NAME =
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
+REBUILD_MODE =
+BUILD_ROM_ONLY =
+NUMBER_OF_PROCESSORS = 1
+
+
+[PLATFORMS]
+# board_name = path_to_board_build_config.cfg
+KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
+N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
+BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
diff --git a/Platform/Intel/build_bios.py b/Platform/Intel/build_bios.py
new file mode 100644
index 0000000000..2edf340e0c
--- /dev/null
+++ b/Platform/Intel/build_bios.py
@@ -0,0 +1,976 @@
+
+# @ build_bios.py
+# Builds BIOS using configuration files and dynamically
+# imported functions from board directory
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+"""
+This module builds BIOS using configuration files and dynamically
+imported functions from board directory
+"""
+
+
+import os
+import re
+import sys
+import signal
+import shutil
+import argparse
+import traceback
+import subprocess
+from importlib import import_module
+
+try:
+    # python 2.7
+    import ConfigParser as configparser
+except ImportError:
+    # python 3
+    import configparser
+
+
+def pre_build(build_config, build_type="DEBUG", silent=False, toolchain=None):
+    """Sets the environment variables that shall be used for the build
+
+        :param build_config: The build configuration as defined in the JOSN
+            configuration files
+        :type build_config: Dictionary
+        :param build_type: The build target, DEBUG, RELEASE, RELEASE_PDB,
+            TEST_RELEASE
+        :type build_type: String
+        :param silent: Enables build in silent mode
+        :type silent: Boolean
+        :param toolchain: Specifies the tool chain tag to use for the build
+        :type toolchain: String
+        :returns: The updated environment variables
+        :rtype: Dictionary
+    """
+
+    # get current environment variables
+    config = os.environ.copy()
+
+    # patch the build config
+    build_config = patch_config(build_config)
+
+    # update the current config with the build config
+    config.update(build_config)
+
+    # make the config and build python 2.7 compartible
+    config = py_27_fix(config)
+
+    # Set WORKSPACE environment.
+    config["WORKSPACE"] = os.path.abspath(os.path.join("..", "..", "..", ""))
+    print("Set WORKSPACE as: {}".format(config["WORKSPACE"]))
+
+    # Check whether Git has been installed and been added to system path.
+    try:
+        subprocess.Popen(["git", "--help"], stdout=subprocess.PIPE)
+    except OSError:
+        print("The 'git' command is not recognized.")
+        print("Please make sure that Git is installed\
+                and has been added to system path.")
+        sys.exit(1)
+
+    # Create the Conf directory under WORKSPACE
+    if not os.path.isdir(os.path.join(config["WORKSPACE"], "Conf")):
+        try:
+            # create directory
+            os.makedirs(os.path.join(config["WORKSPACE"], "Conf"))
+            # copy files to it
+            config_template_path = os.path.join(config["WORKSPACE"],
+                                                config["BASE_TOOLS_PATH"],
+                                                "Conf")
+            config_path = os.path.join(config["WORKSPACE"], "Conf")
+            shutil.copyfile(config_template_path +
+                            os.sep + "target.template",
+                            config_path + os.sep + "target.txt")
+            shutil.copyfile(config_template_path +
+                            os.sep + "tools_def.template",
+                            config_path + os.sep + "tools_def.txt")
+            shutil.copyfile(config_template_path +
+                            os.sep + "build_rule.template",
+                            config_path + os.sep + "build_rule.txt")
+        except OSError:
+            print("Error while creating Conf")
+            sys.exit(1)
+
+    # Set other environments.
+    # Basic Rule:
+    # Platform override Silicon override Core
+    # Source override Binary
+    config["WORKSPACE_PLATFORM"] = os.path.join(config["WORKSPACE"],
+                                                config["WORKSPACE_PLATFORM"])
+    config["WORKSPACE_SILICON"] = os.path.join(config["WORKSPACE"],
+                                               config["WORKSPACE_SILICON"])
+    config["WORKSPACE_PLATFORM_BIN"] = \
+        os.path.join(config["WORKSPACE"], config["WORKSPACE_PLATFORM_BIN"])
+    config["WORKSPACE_SILICON_BIN"] = \
+        os.path.join(config["WORKSPACE"], config["WORKSPACE_SILICON_BIN"])
+    config["WORKSPACE_FSP_BIN"] = os.path.join(config["WORKSPACE"],
+                                               config["WORKSPACE_FSP_BIN"])
+
+    # add to package path
+    config["PACKAGES_PATH"] = config["WORKSPACE_PLATFORM"]
+    config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON"]
+    config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON_BIN"]
+    config["PACKAGES_PATH"] += os.pathsep + \
+        os.path.join(config["WORKSPACE"], "FSP")
+    config["PACKAGES_PATH"] += os.pathsep + \
+        os.path.join(config["WORKSPACE"], "edk2")
+    config["PACKAGES_PATH"] += os.pathsep + os.path.join(config["WORKSPACE"])
+    config["EDK_TOOLS_PATH"] = os.path.join(config["WORKSPACE"],
+                                            config["EDK_TOOLS_PATH"])
+    config["BASE_TOOLS_PATH"] = config["EDK_TOOLS_PATH"]
+    config["EDK_TOOLS_BIN"] = os.path.join(config["WORKSPACE"],
+                                           config["EDK_TOOLS_BIN"])
+    config["PLATFORM_FSP_BIN_PACKAGE"] = \
+        os.path.join(config['WORKSPACE_FSP_BIN'], config['FSP_BIN_PKG'])
+    config['PROJECT_DSC'] = os.path.join(config["WORKSPACE_PLATFORM"],
+                                         config['PROJECT_DSC'])
+    config['BOARD_PKG_PCD_DSC'] = os.path.join(config["WORKSPACE_PLATFORM"],
+                                               config['BOARD_PKG_PCD_DSC'])
+    config["CONF_PATH"] = os.path.join(config["WORKSPACE"], "Conf")
+
+    # get the python path
+    if os.environ.get("PYTHON_HOME") is None:
+        config["PYTHON_HOME"] = None
+        if os.environ.get("PYTHONPATH") is not None:
+            config["PYTHON_HOME"] = os.environ.get("PYTHONPATH")
+        else:
+            print("PYTHONPATH environment variable is not found")
+            sys.exit(1)
+
+    # if python is installed, disable the binary base tools.
+    # python is installed if this code is running :)
+    if config.get("PYTHON_HOME") is not None:
+        if config.get("EDK_TOOLS_BIN") is not None:
+            del config["EDK_TOOLS_BIN"]
+
+    # Run edk setup and  update config
+    if os.name == 'nt':
+        edk2_setup_cmd = [os.path.join(config["EFI_SOURCE"], "edksetup"),
+                        "Rebuild"]
+
+        if config.get("EDK_SETUP_OPTION") and \
+        config["EDK_SETUP_OPTION"] != " ":
+            edk2_setup_cmd.append(config["EDK_SETUP_OPTION"])
+
+        _, _, result, return_code = execute_script(edk2_setup_cmd,
+                                                config,
+                                                collect_env=True,
+                                                shell=True)
+        if return_code == 0 and result is not None and isinstance(result,
+                                                                dict):
+            config.update(result)
+
+    # nmake BaseTools source
+    # and enable BaseTools source build
+    shell = True
+    command = ["nmake", "-f", os.path.join(config["BASE_TOOLS_PATH"],
+                                           "Makefile")]
+    if os.name == "posix":  # linux
+        shell = False
+        command = ["make", "-C", os.path.join(config["BASE_TOOLS_PATH"])]
+
+    _, _, result, return_code = execute_script(command, config, shell=shell)
+    if return_code != 0:
+        build_failed(config)
+
+    config["SILENT_MODE"] = 'TRUE' if silent else 'FALSE'
+
+    print("==============================================")
+
+    if os.path.isfile(os.path.join(config['WORKSPACE'], "Prep.log")):
+        os.remove(os.path.join(config['WORKSPACE'], "Prep.log"))
+
+    config["PROJECT"] = os.path.join(config["PLATFORM_BOARD_PACKAGE"],
+                                     config["BOARD"])
+
+    # Setup Build
+    # @todo: Need better TOOL_CHAIN_TAG detection
+    if toolchain is not None:
+        config["TOOL_CHAIN_TAG"] = toolchain
+    elif config.get("TOOL_CHAIN_TAG") is None:
+        if os.name == 'nt':
+            config["TOOL_CHAIN_TAG"] = "VS2015"
+        else:
+            config["TOOL_CHAIN_TAG"] = "GCC5"
+
+    # echo Show CL revision
+    config["PrepRELEASE"] = build_type
+
+    if build_type == "DEBUG":
+        config["TARGET"] = 'DEBUG'
+        config["TARGET_SHORT"] = 'D'
+    else:
+        config["TARGET"] = 'RELEASE'
+        config["TARGET_SHORT"] = 'R'
+
+    # set BUILD_DIR_PATH path
+    config["BUILD_DIR_PATH"] = os.path.join(config["WORKSPACE"],
+                                            'Build',
+                                            config["PROJECT"],
+                                            "{}_{}".format(
+                                                config["TARGET"],
+                                                config["TOOL_CHAIN_TAG"]))
+    # set BUILD_DIR path
+    config["BUILD_DIR"] = os.path.join('Build',
+                                       config["PROJECT"],
+                                       "{}_{}".format(
+                                           config["TARGET"],
+                                           config["TOOL_CHAIN_TAG"]))
+
+    config["BUILD_X64"] = os.path.join(config["BUILD_DIR_PATH"], 'X64')
+    config["BUILD_IA32"] = os.path.join(config["BUILD_DIR_PATH"], 'IA32')
+
+    if not os.path.isdir(config["BUILD_DIR_PATH"]):
+        try:
+            os.makedirs(config["BUILD_DIR_PATH"])
+        except OSError:
+            print("Error while creating Build folder")
+            sys.exit(1)
+
+    # Set FSP_WRAPPER_BUILD
+    if config['FSP_WRAPPER_BUILD'] == "TRUE":
+        # Create dummy Fsp_Rebased_S_padded.fd to build the BiosInfo.inf
+        # if it is wrapper build, due to the SECTION inclusion
+        open(os.path.join(config["WORKSPACE_FSP_BIN"],
+                          config["FSP_BIN_PKG"],
+                          "Fsp_Rebased_S_padded.fd"), 'w').close()
+
+    if not os.path.isdir(config["BUILD_X64"]):
+        try:
+            os.mkdir(config["BUILD_X64"])
+        except OSError:
+            print("Error while creating {}".format(config["BUILD_X64"]))
+            sys.exit(1)
+
+    # update config file with changes
+    update_target_file(config)
+
+    # Additional pre build scripts for this platform
+    result = pre_build_ex(config)
+    if result is not None and isinstance(result, dict):
+        config.update(result)
+
+    # print user settings
+    print("BIOS_SIZE_OPTION     = {}".format(config["BIOS_SIZE_OPTION"]))
+    print("EFI_SOURCE           = {}".format(config["EFI_SOURCE"]))
+    print("TARGET               = {}".format(config["TARGET"]))
+    print("TARGET_ARCH          = {}".format("IA32 X64"))
+    print("TOOL_CHAIN_TAG       = {}".format(config["TOOL_CHAIN_TAG"]))
+    print("WORKSPACE            = {}".format(config["WORKSPACE"]))
+    print("WORKSPACE_CORE       = {}".format(config["WORKSPACE_CORE"]))
+    print("EXT_BUILD_FLAGS      = {}".format(config["EXT_BUILD_FLAGS"]))
+
+    return config
+
+
+def build(config):
+    """Builds the BIOS image
+
+        :param config: The environment variables to be used
+            in the build process
+        :type config: Dictionary
+        :returns: nothing
+    """
+
+    if config["FSP_WRAPPER_BUILD"] == "TRUE":
+        pattern = "Fsp_Rebased.*\\.fd$"
+        file_dir = os.path.join(config['WORKSPACE_FSP_BIN'],
+                                config['FSP_BIN_PKG'])
+        for item in os.listdir(file_dir):
+            if re.search(pattern, item):
+                os.remove(os.path.join(file_dir, item))
+
+        command = [os.path.join(config['PYTHON_HOME'], "python"),
+                   os.path.join(config['WORKSPACE_PLATFORM'],
+                                config['PLATFORM_PACKAGE'],
+                                'Tools', 'Fsp',
+                                'RebaseAndPatchFspBinBaseAddress.py'),
+                   os.path.join(config['WORKSPACE_PLATFORM'],
+                                config['FLASH_MAP_FDF']),
+                   os.path.join(config['WORKSPACE_FSP_BIN'],
+                                config['FSP_BIN_PKG']),
+                   "Fsp.fd",
+                   os.path.join(config['WORKSPACE_PLATFORM'],
+                                config['PROJECT'],
+                                config['BOARD_PKG_PCD_DSC']),
+                   "0x0"]
+
+        _, _, _, return_code = execute_script(command, config, shell=False)
+
+        if return_code != 0:
+            print("ERROR:RebaseAndPatchFspBinBaseAddress failed")
+            sys.exit(return_code)
+
+        # create Fsp_Rebased.fd which is Fsp_Rebased_S.fd +
+        # Fsp_Rebased_M + Fsp_Rebased_T
+        with open(os.path.join(file_dir, "Fsp_Rebased_S.fd"), 'rb') as fsp_s, \
+                open(os.path.join(file_dir,
+                                  "Fsp_Rebased_M.fd"), 'rb') as fsp_m, \
+                open(os.path.join(file_dir,
+                                  "Fsp_Rebased_T.fd"), 'rb') as fsp_t:
+
+            fsp_rebased = fsp_s.read() + fsp_m.read() + fsp_t.read()
+            with open(os.path.join(file_dir,
+                                   "Fsp_Rebased.fd"), 'wb') as new_fsp:
+                new_fsp.write(fsp_rebased)
+
+        if not os.path.isfile(os.path.join(file_dir, "Fsp_Rebased.fd")):
+            print("!!! ERROR:failed to create fsp!!!")
+            sys.exit(1)
+
+    # Output the build variables the user has selected.
+    print("==========================================")
+    print(" User Selected build options:")
+    print(" SILENT_MODE    = ", config.get("SILENT_MODE"))
+    print(" REBUILD_MODE   = ", config.get("REBUILD_MODE"))
+    print(" BUILD_ROM_ONLY = ", config.get("BUILD_ROM_ONLY"))
+    print("==========================================")
+
+    command = ["build", "-n", config["NUMBER_OF_PROCESSORS"]]
+
+    if config["REBUILD_MODE"] and config["REBUILD_MODE"] != "":
+        command.append(config["REBUILD_MODE"])
+
+    if config["EXT_BUILD_FLAGS"] and config["EXT_BUILD_FLAGS"] != "":
+        command.append(config["EXT_BUILD_FLAGS"])
+
+    if config.get("SILENT_MODE", "FALSE") == "TRUE":
+        command.append("--silent")
+        command.append("--quiet")
+
+    else:
+        command.append("--log=" + config.get("BUILD_LOG", "Build.log"))
+        command.append("--report-file=" +
+                       config.get("BUILD_REPORT", "BuildReport.log"))
+
+    if config.get("VERBOSE", "FALSE") == "TRUE":
+        command.append("--verbose")
+
+    if config.get("MAX_SOCKET") is not None:
+        command.append("-D")
+        command.append("MAX_SOCKET=" + config["MAX_SOCKET"])
+
+    _, _, _, exit_code = execute_script(command, config)
+    if exit_code != 0:
+        build_failed(config)
+
+    # Additional build scripts for this platform
+    result = build_ex(config)
+    if result is not None and isinstance(result, dict):
+        config.update(result)
+
+    return config
+
+
+def post_build(config):
+    """Post build process of BIOS image
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :returns: nothing
+    """
+    print("Running post_build to complete the build process.")
+
+    # Additional build scripts for this platform
+    result = post_build_ex(config)
+    if result is not None and isinstance(result, dict):
+        config.update(result)
+
+    # cleanup
+    pattern = "Fsp_Rebased.*\\.fd$"
+    file_dir = os.path.join(config['WORKSPACE_FSP_BIN'],
+                            config['FSP_BIN_PKG'])
+    for item in os.listdir(file_dir):
+        if re.search(pattern, item):
+            os.remove(os.path.join(file_dir, item))
+
+    if config.get("DYNAMIC_BUILD_INIT_FILES") is not None:
+        for item in config["DYNAMIC_BUILD_INIT_FILES"].split(","):
+            try:
+                os.remove(item)  # remove __init__.py
+                os.remove(item + "c")  # remove __init__.pyc as well
+            except OSError:
+                pass
+
+
+def build_failed(config):
+    """Displays results when build fails
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: nothing
+    """
+    print(" The EDKII BIOS Build has failed!")
+    # clean up
+    if config.get("DYNAMIC_BUILD_INIT_FILES") is not None:
+        for item in config["DYNAMIC_BUILD_INIT_FILES"].split(","):
+            if os.path.isfile(item):
+                try:
+                    os.remove(item)  # remove __init__.py
+                    os.remove(item + "c")  # remove __init__.pyc as well
+                except OSError:
+                    pass
+    sys.exit(1)
+
+
+def import_platform_lib(path, function):
+    """Imports custom functions for the platforms being built
+
+        :param path: the location of the custom build script to be executed
+        :type path: String
+        :param path: the function to be executed
+        :type path: String
+        :returns: nothing
+    """
+    if path.endswith(".py"):
+        path = path[:-3]
+    path = path.replace(os.sep, ".")
+    module = import_module(path)
+    lib = getattr(module, function)
+    return lib
+
+
+def pre_build_ex(config):
+    """ An extension of the pre_build process as defined platform
+        specific pre_build setup script
+
+        :param config: The environment variables used in the pre build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "pre_build_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print(config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def build_ex(config):
+    """ An extension of the build process as defined platform
+        specific build setup script
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "build_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print("error", config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def post_build_ex(config):
+    """ An extension of the post build process as defined platform
+        specific build setup script
+
+        :param config: The environment variables used in the post build
+            process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "post_build_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print(config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def clean_ex(config):
+    """ An extension of the platform cleanning
+
+        :param config: The environment variables used in the clean process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "clean_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print(config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def get_environment_variables(std_out_str, marker):
+    """Gets the environment variables from a process
+
+        :param std_out_str: The std_out pipe
+        :type std_out_str: String
+        :param marker: A begining and end mark of environment
+            variables printed to std_out
+        :type marker: String
+        :returns: The environment variables read from the process' std_out pipe
+        :rtype: Tuple
+    """
+    start_env_update = False
+    environment_vars = {}
+    out_put = ""
+    for line in std_out_str.split("\n"):
+        if start_env_update and len(line.split("=")) == 2:
+            key, value = line.split("=")
+            environment_vars[key] = value
+        else:
+            out_put += "\n" + line.replace(marker, "")
+
+        if marker in line:
+            if start_env_update:
+                start_env_update = False
+            else:
+                start_env_update = True
+    return (out_put, environment_vars)
+
+
+def execute_script(command, env_variables, collect_env=False,
+                   enable_std_pipe=False, shell=True):
+    """launches a process that executes a script/shell command passed to it
+
+        :param command: The command/script with its commandline
+            arguments to be executed
+        :type command:  List:String
+        :param env_variables: Environment variables passed to the process
+        :type env_variables: String
+        :param collect_env: Enables the collection of evironment variables
+            when process execution is done
+        :type collect_env: Boolean
+        :param enable_std_pipe: Enables process out to be piped to
+        :type enable_std_pipe: String
+        :returns: a tuple of std_out, stderr , environment variables,
+            return code
+        :rtype: Tuple: (std_out, stderr , enVar, return_code)
+    """
+
+    print("Calling " + " ".join(command))
+
+    env_marker = '-----env-----'
+    env = {}
+    kwarg = {"env": env_variables,
+             "universal_newlines": True,
+             "shell": shell,
+             "cwd": env_variables["WORKSPACE"]}
+
+    if enable_std_pipe or collect_env:
+        kwarg["stdout"] = subprocess.PIPE
+        kwarg["stderr"] = subprocess.PIPE
+
+    # collect environment variables
+    if collect_env:
+        # get the binary that prints environment variables based on os
+        if os.name == 'nt':
+            get_var_command = "set"
+        else:
+            get_var_command = "env"
+        # modify the command to print the environment variables
+        if isinstance(command, list):
+            command += ["&&", "echo", env_marker, "&&",
+                        get_var_command, "&&", "echo", env_marker]
+        else:
+            command += " " + " ".join(["&&", "echo", env_marker,
+                                       "&&", get_var_command,
+                                       "&&", "echo", env_marker])
+
+    # execute the command
+    execute = subprocess.Popen(command, **kwarg)
+    std_out, stderr = execute.communicate()
+    code = execute.returncode
+
+    # wait for process to be done
+    execute.wait()
+
+    # if collect enviroment variables
+    if collect_env:
+        # get the new environment variables
+        std_out, env = get_environment_variables(std_out, env_marker)
+    return (std_out, stderr, env, code)
+
+
+def patch_config(config):
+    """ An extension of the platform cleanning
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    new_config = {}
+    for key in config:
+        new_config[str(key)] = str(config[key].replace("/", os.sep))
+    return new_config
+
+
+def py_27_fix(config):
+    """  Prepares build for python 2.7 => build
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if not sys.version_info > (3, 0):
+        path_list = []
+        # create __init__.py in directories in this path
+        if config.get("ADDITIONAL_SCRIPTS"):
+            # get the directory
+            path_to_directory =\
+                os.path.dirname(config.get("ADDITIONAL_SCRIPTS"))
+            path = ""
+            for directories in path_to_directory.split(os.sep):
+                path += directories + os.sep
+                init_file = path + os.sep + "__init__.py"
+                if not os.path.isfile(init_file):
+                    open(init_file, 'w').close()
+                    path_list.append(init_file)
+            config["DYNAMIC_BUILD_INIT_FILES"] = ",".join(path_list)
+
+    return config
+
+
+def clean(build_config, board=False):
+    """Cleans the build workspace
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :param board: This flag specifies specific board clean
+        :type board: Bool
+        :returns: nothing
+    """
+
+    # patch the config
+    build_config = patch_config(build_config)
+
+    # get current environment variables
+    config = os.environ.copy()
+
+    # update it with the build variables
+    config.update(build_config)
+
+    if config.get('WORKSPACE') is None or not config.get('WORKSPACE'):
+        config["WORKSPACE"] =\
+                os.path.abspath(os.path.join("..", "..", "..", ""))
+
+    # build cleanall
+    print("Cleaning directories...")
+
+    if board:
+        platform_pkg = config.get("PLATFORM_BOARD_PACKAGE", None)
+        if platform_pkg is None or\
+            not os.path.isdir(os.path.join(config['WORKSPACE'],
+                                           "Build", platform_pkg)):
+            print("Platform package not found")
+            sys.exit(1)
+        else:
+            print("Removing " + os.path.join(config['WORKSPACE'],
+                                             "Build", platform_pkg))
+            shutil.rmtree(os.path.join(config['WORKSPACE'],
+                                       "Build", platform_pkg))
+
+    else:
+        if os.path.isdir(os.path.join(config['WORKSPACE'], "Build")):
+            print("Removing " + os.path.join(config['WORKSPACE'], "Build"))
+            shutil.rmtree(os.path.join(config['WORKSPACE'], "Build"))
+
+    if os.path.isdir(os.path.join(config['WORKSPACE'], "Conf")):
+        print("Removing " + os.path.join(config['WORKSPACE'], "Conf"))
+        shutil.rmtree(os.path.join(config['WORKSPACE'], "Conf"))
+
+    print("Cleaning files...")
+
+    if os.path.isfile(os.path.join(config['WORKSPACE'],
+                                   config.get("BUILD_REPORT",
+                                              "BuildReport.log"))):
+        print("Removing ", os.path.join(config['WORKSPACE'],
+                                        config.get("BUILD_REPORT",
+                                                   "BuildReport.log")))
+        os.remove(os.path.join(config['WORKSPACE'],
+                               config.get("BUILD_REPORT", "BuildReport.log")))
+
+    print("  All done...")
+
+    sys.exit(0)
+
+
+def update_target_file(config):
+    """Updates Conf's target file that will be used in the build
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: True if update was successful and False if update fails
+        :rtype: Boolean
+    """
+    contents = None
+    result = False
+    with open(os.path.join(config["CONF_PATH"], "target.txt"), 'r') as target:
+        contents = target.readlines()
+        options_list = ['ACTIVE_PLATFORM', 'TARGET',
+                        'TARGET_ARCH', 'TOOL_CHAIN_TAG', 'BUILD_RULE_CONF']
+        modified = []
+
+        # remove these options from the config file
+        for line in contents:
+            if line.replace(" ", "")[0] != '#' and\
+             any(opt in line for opt in options_list):
+                continue
+            modified.append(line)
+
+        # replace with config options provided
+        string = "{} = {}\n".format("ACTIVE_PLATFORM",
+                                    os.path.join(
+                                        config['WORKSPACE_PLATFORM'],
+                                        config['PLATFORM_BOARD_PACKAGE'],
+                                        config['BOARD'],
+                                        config['PROJECT_DSC']))
+        modified.append(string)
+
+        string = "{} = {}\n".format("TARGET", config['TARGET'])
+        modified.append(string)
+
+        string = "TARGET_ARCH = IA32 X64\n"
+        modified.append(string)
+
+        string = "{} = {}\n".format("TOOL_CHAIN_TAG", config['TOOL_CHAIN_TAG'])
+        modified.append(string)
+
+        string = "{} = {}\n".format("BUILD_RULE_CONF",
+                                    os.path.join("Conf", "build_rule.txt"))
+        modified.append(string)
+
+    if modified is not None:
+        with open(os.path.join(config["WORKSPACE"],
+                               "Conf", "target.txt"), 'w') as target:
+            for line in modified:
+                target.write(line)
+            result = True
+
+    return result
+
+
+def get_config():
+    """Reads the default projects config file
+
+        :returns: The config defined in the the Build.cfg file
+        :rtype: Dictionary
+    """
+    config_file = configparser.RawConfigParser()
+    config_file.optionxform = str
+    config_file.read('build.cfg')
+    config_dictionary = {}
+    for section in config_file.sections():
+        dictionary = dict(config_file.items(section))
+        config_dictionary[section] = dictionary
+    return config_dictionary
+
+
+def get_platform_config(platform_name, config_data):
+    """ Reads the platform specifig config file
+
+        param platform_name: The name of the platform to be built
+        :type platform_name: String
+        param configData: The environment variables to be
+            used in the build process
+        :type configData: Dictionary
+        :returns: The config defined in the the Build.cfg file
+        :rtype: Dictionary
+    """
+    config = {}
+
+    platform_data = config_data.get("PLATFORMS")
+    path = platform_data.get(platform_name)
+    config_file = configparser.RawConfigParser()
+    config_file.optionxform = str
+    config_file.read(path)
+    for section in config_file.sections():
+        config[section] = dict(config_file.items(section))
+
+    return config
+
+
+def get_cmd_config_arguments(arguments):
+    """Get commandline config arguments
+
+    param arguments: The environment variables to be used in the build process
+    :type arguments: argparse
+    :returns: The config dictionary built from the commandline arguments
+    :rtype: Dictionary
+    """
+    result = {}
+    if arguments.capsule is True:
+        result["CAPSULE_BUILD"] = "1"
+
+    if arguments.performance is True:
+        result["PERFORMANCE_BUILD"] = "TRUE"
+
+    if arguments.fsp is True:
+        result["FSP_WRAPPER_BUILD"] = "TRUE"
+
+    return result
+
+
+def get_cmd_arguments(build_config):
+    """ Get commandline inputs from user
+
+        param config_data: The environment variables to be
+            used in the build process
+        :type config_data: Dictionary
+        :returns: The commandline arguments input by the user
+        :rtype: argparse object
+    """
+
+    class PrintPlatforms(argparse.Action):
+        """ this is an argparse action that lists the available platforms
+        """
+        def __call__(self, parser, namespace, values, option_string=None):
+            print("Platforms:")
+            for key in build_config.get("PLATFORMS"):
+                print("    " + key)
+            setattr(namespace, self.dest, values)
+            sys.exit(0)
+
+    # get the build commands
+    parser = argparse.ArgumentParser(description="Build Help")
+    parser.add_argument('--platform', '-p', dest="platform",
+                        help='the platform to build',
+                        choices=build_config.get("PLATFORMS"),
+                        required=('-l' not in sys.argv and
+                                  '--cleanall' not in sys.argv))
+
+    parser.add_argument('--toolchain', '-t', dest="toolchain",
+                        help="using the Tool Chain Tagname to build \
+                            the platform,overriding \
+                            target.txt's TOOL_CHAIN_TAG definition")
+
+    parser.add_argument("--DEBUG", '-d', help="debug flag",
+                        action='store_const', dest="target",
+                        const="DEBUG", default="DEBUG")
+
+    parser.add_argument("--RELEASE", '-r', help="release flag",
+                        action='store_const',
+                        dest="target", const="RELEASE")
+
+    parser.add_argument("--TEST_RELEASE", '-tr', help="test Release flag",
+                        action='store_const',
+                        dest="target", const="TEST_RELEASE")
+
+    parser.add_argument("--RELEASE_PDB", '-rp', help="release flag",
+                        action='store_const', dest="target",
+                        const="RELEASE_PDB")
+
+    parser.add_argument('--list', '-l', action=PrintPlatforms,
+                        help='lists available platforms', nargs=0)
+
+    parser.add_argument('--cleanall', dest='clean_all',
+                        help='cleans all', action='store_true')
+
+    parser.add_argument('--clean', dest='clean',
+                        help='cleans specific platform', action='store_true')
+
+    parser.add_argument("--capsule", help="capsule build enabled",
+                        action='store_true', dest="capsule")
+
+    parser.add_argument("--silent", help="silent build enabled",
+                        action='store_true', dest="silent")
+
+    parser.add_argument("--performance", help="performance build enabled",
+                        action='store_true', dest="performance")
+
+    parser.add_argument("--fsp", help="fsp build enabled",
+                        action='store_true', dest="fsp")
+
+    return parser.parse_args()
+
+
+def keyboard_interruption(int_signal, int_frame):
+    """ Catches a keyboard interruption handler
+
+        param int_signal: The signal this handler is called with
+        :type int_signal: Signal
+        param int_frame: The signal this handler is called with
+        :type int_frame: frame
+        :rtype: nothing
+    """
+    print("Signal #: {} Frame: {}".format(int_signal, int_frame))
+    print("Quiting...")
+    sys.exit(0)
+
+
+def main():
+    """ The main function of this module
+        :rtype: nothing
+    """
+    # to quit the build
+    signal.signal(signal.SIGINT, keyboard_interruption)
+
+    # get general build configurations
+    build_config = get_config()
+
+    # get commandline parameters
+    arguments = get_cmd_arguments(build_config)
+
+    if arguments.clean_all:
+        clean(build_config.get("DEFAULT_CONFIG"))
+
+    # get platform specific config
+    platform_config = get_platform_config(arguments.platform, build_config)
+
+    # update general build config with platform specific config
+    config = build_config.get("DEFAULT_CONFIG")
+    config.update(platform_config.get("CONFIG"))
+
+    # if user selected clean
+    if arguments.clean:
+        clean(config, board=True)
+
+    # Override config with cmd arguments
+    cmd_config_args = get_cmd_config_arguments(arguments)
+    config.update(cmd_config_args)
+
+    # get pre_build configurations
+    config = pre_build(config,
+                       build_type=arguments.target,
+                       toolchain=arguments.toolchain,
+                       silent=arguments.silent)
+
+    # build selected platform
+    config = build(config)
+
+    # post build
+    post_build(config)
+
+
+if __name__ == "__main__":
+    try:
+        EXIT_CODE = 0
+        main()
+    except Exception as error:
+        EXIT_CODE = 1
+        traceback.print_exc()
+    sys.exit(EXIT_CODE)
-- 
2.19.1.windows.1


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

* [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions
  2019-05-03 23:19 [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Agyeman, Prince
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added " Agyeman, Prince
@ 2019-05-03 23:19 ` Agyeman, Prince
  2019-05-04  0:36   ` [edk2-devel] " Nate DeSimone
  2019-05-04  2:14   ` Kubacki, Michael A
  2019-05-04  0:36 ` [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Nate DeSimone
  2019-05-04  2:14 ` Kubacki, Michael A
  3 siblings, 2 replies; 9+ messages in thread
From: Agyeman, Prince @ 2019-05-03 23:19 UTC (permalink / raw)
  To: devel
  Cc: Michael Kubacki, Michael D Kinney, Nate DeSimone, Liming Gao,
	Ankit Sinha

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>
---
 ReadMe.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/ReadMe.md b/ReadMe.md
index 72e332a476..fbf735173f 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -105,6 +105,82 @@ return back to the minimum platform caller.
 
 ### Build
 
+**Building with the python script**
+
+1. Open command window, go to the workspace directory, e.g. c:\Kabylake.
+2. Type "cd edk2-platforms\Platform\Intel
+3. Type "python build_bios.py -p REPLACE_WITH_BOARD_NAME"
+
+* build_bios.py arguments:
+
+  | Argument              | Function                            |
+  | ----------------------|-------------------------------------|
+  | -h, --help            | show this help message and exit     |
+  | --platform, -p        | the platform to build               |
+  | --toolchain, -t       | tool Chain to use in build process  |
+  | --DEBUG, -d           | debug flag                          |
+  | --RELEASE, -r         | release flag                        |
+  | --TEST_RELEASE, -tr   | test Release flag                   |
+  | --RELEASE_PDB, -rp    | release flag                        |
+  | --list, -l            | lists available platforms           |
+  | --cleanall            | cleans all                          |
+  | --clean               | cleans specified platform           |
+  | --capsule             | capsule build enabled               |
+  | --silent              | silent build enabled                |
+  | --performance         | performance build enabled           |
+  | --fsp                 | fsp build enabled                   |
+  |                                                             |
+
+* For more information on build options
+  * ``Type "python build_bios.py -h"``
+
+* Note
+  * ``Python 2.7.16 and Python 3.7.3 compatible``
+  * ``These python build scripts have been tested on Windows due to`` [cross-platform limitations](#Known-limitations)
+
+* Configuration Files
+  * ``The edk2-platforms\Platform\Intel\build.cfg file contains the default settings used by build_bios.py``
+  * ``The default settings are under the DEFAULT_CONFIG section``
+  * ``Each board can have a settings file that will override the edk2-platforms\Platform\Intel\build.cfg settings``
+  * ``An example of a board specific settings:``
+    * ``edk2-platforms\Platform\Intel\KabylakeOpenBoardPkg\KabylakeRvp3\build_config.cfg``
+
+* Workspace view of the build scripts
+  * <pre>
+    WORKSPACE
+          |------edk2
+          |------edk2-non-osi
+          |------edk2-platforms
+          |       |---Platform
+          |       |    |--Intel
+          |       |        |------build.cfg: Default build settings. These are overridden by
+          |       |        |                 platform specific settings (build_config.cfg) and
+          |       |        |                 then command-line settings.
+          |       |        |
+          |       |        |------build_bios.py: Main build script. Generic pre-build, build,
+          |       |        |                     post-build, and clean functions.
+          |       |        |
+          |       |        |------ClevoOpenBoardPkg
+          |       |        |        |------N1xxWU
+          |       |        |                |---build_config.cfg: N1xxWU specific build
+          |       |        |                                      settings environment variables.
+          |       |        |
+          |       |        |------KabylakeOpenBoardPkg
+          |       |        |        |------KabylakeRvp3
+          |       |        |                  |---build_config.cfg: KabylakeRvp3 specific
+          |       |        |                  |                     build settings, environment variables.
+          |       |        |                  |---build_board.py: Optional board-specific pre-build, build
+          |       |        |                                      and clean post-build functions.
+          |       |        |------PurleyOpenBoardPkg
+          |       |        |       |------BoardMtOlympus
+          |       |        |                |---build_config.cfg: BoardMtOlympus specific
+          |       |        |                |                     build settings, environment variables.
+          |       |        |                |---build_board.py: Optional board-specific pre-build,
+          |       |        |                |                   build, post-build and clean functions.
+          |------FSP
+  </pre>
+
+**Building with the batch scripts**
 For KabylakeOpenBoardPkg
 1. Open command window, go to the workspace directory, e.g. c:\Kabylake.
 2. Type "cd edk2-platforms\Platform\Intel\KabylakeOpenBoardPkg\KabylakeRvp3".
-- 
2.19.1.windows.1


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

* Re: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script.
  2019-05-03 23:19 [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Agyeman, Prince
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added " Agyeman, Prince
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions Agyeman, Prince
@ 2019-05-04  0:36 ` Nate DeSimone
  2019-05-04  2:14 ` Kubacki, Michael A
  3 siblings, 0 replies; 9+ messages in thread
From: Nate DeSimone @ 2019-05-04  0:36 UTC (permalink / raw)
  To: devel@edk2.groups.io, Agyeman, Prince
  Cc: Kubacki, Michael A, Sinha, Ankit, Kinney, Michael D,
	Oram, Isaac W, Gao, Liming

Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Agyeman, Prince
Sent: Friday, May 3, 2019 4:19 PM
To: devel@edk2.groups.io
Cc: Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Oram, Isaac W <isaac.w.oram@intel.com>; Gao, Liming <liming.gao@intel.com>
Subject: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script.

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Isaac W Oram <isaac.w.oram@intel.com>
Cc: Liming Gao <liming.gao@intel.com>

Contributed-under: TianoCore Contribution Agreement 0.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>


changes from v2:
- fixed pep8 violations
- implemented v2 review recommendations
- added clean flag to clean specified platform

Overview:
WORKSPACE
    |
    |------edk2
    |------edk2-non-osi
    |------edk2-platforms
    |       |--Platform
    |       |---Intel
    |       |        |------build.cfg: Default build settings. These are overridden by
    |       |        |                 platform specific settings (build_config.cfg) and
    |       |        |                 then command-line settings.
    |       |        |
    |       |        |------build_bios.py: Main build script. Generic pre-build, build,
    |       |        |                     post-build, and clean functions.
    |       |        |
    |       |        |------ClevoOpenBoardPkg
    |       |        |        |------N1xxWU
    |       |        |                |---build_config.cfg: N1xxWU specific build
    |       |        |                                      settings environment variables.
    |       |        |
    |       |        |------KabylakeOpenBoardPkg
    |       |        |        |------KabylakeRvp3
    |       |        |                  |---build_config.cfg: KabylakeRvp3 specific
    |       |        |                  |                     build settings, environment variables.
    |       |        |                  |---build_board.py: Optional board-specific pre-build, build
    |       |        |                                      and clean post-build functions.
    |       |        |------PurleyOpenBoardPkg
    |       |        |       |------BoardMtOlympus
    |       |        |                |---build_config.cfg: BoardMtOlympus specific
    |       |        |                                      build settings, environment variables.
    |       |        |                |---build_board.py: Optional board-specific pre-build,
    |       |        |                |                   build, post-build and clean functions.
    |------FSP


-------------------
Details:
-------------------
What it is
----------
These patches add python BIOS build scripts and build configuration files to build platforms under Intel/Platform.


Why
----
The reason behind this implementation is to use a cross platform build script to build minplaform BIOS.


How it is done
----------------
The python files:
-----------------
build_bios.py: The main build file. This script sets up the edk2 build enviroment using the default build.cfg settings and platform specific settings. It uses the configurations found in the build.cfg file to locate the platforms that are configured to use this build script.
The path to each of the platform settings can be found under the "PLATFORMS"
field within the build.cfg file. The platform specific settings are located in the platform's main directory.
Example edk2-platforms/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg.

The build_bios.py script contains the four main functions:
- pre_build: Sets up the edk2 build enviroment variables, target.txt file
- build: Uses the configurations to Build BIOS
- post_build: Does post build processes like cleaning up files
             generated during the build process
- clean: Cleans up the build directory.

There are four addtional functions that dynamically import functions from the board's Optional/Additional python script if specified in board settings file's ADDITIONAL_SCRIPTS These four functions are the pre_build_board, build_board, post_build_board, clean_ex functions


Board additional (Optional) python build script:
------------------------------------------------
These are python scripts located in the board's main directory, An example Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
If added, its path must be specified in board's settings file, under the field ADDITIONAL_SCRIPTS.
Example ADDITIONAL_SCRIPTS = PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
If specified, the build_board, pre_build_board, post_build_board, clean_ex must be defined even if they are not use


The config files
-----------------
build.cfg:
-----------
This is file contains the default BIOS build configuration.

The default configurations are defined under the "DEFAULT_CONFIG" section of the file.
Each of these can be overridden by the board specific setting as defined in the board's build config file. All paths must be separated by forward slashes.
All the paths in the main build.cfg are relative to the minplaform WORKSPACE.
Example:
--------
[DEFAULT_CONFIG]
    MIN_PACKAGE_TOOLS = edk2-platforms/Platform/Intel/MinPlatformPkg/Tools

The PLATFORMS field in the build.cfg file informs build_bios.py about the available platforms that can be built with the build_bios.py.
The path to the board specific config file must be relative to location of build_bios.py, Platform/Intel. It is in the format Boardname = BoardPath

Example:
--------
[PLATFORMS]
    KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg


Board Specific Build Settings file:
----------------------------------------
This file is located in the board's main directory.
The CONFIG field contains all the build enviroment variables.
These values will override any the were specific under DEFAULT_CONFIG in the default build.cfg file.
Example is Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg


Building BIOS
-------------

python build_bios.py -p BOARDNAME -t TOOLCHAIN 

usage: build_bios.py [-h] --platform {N1xxWU,KabylakeRvp3,BoardMtOlympus}
                    [--toolchain TOOLCHAIN] [--DEBUG] [--RELEASE]
                    [--TEST_RELEASE] [--RELEASE_PDB] [--list] [--cleanall]
                    [--capsule] [--silent] [--performance] [--fsp] Build Help

optional arguments:
  -h, --help            show this help message and exit
  --platform {N1xxWU,KabylakeRvp3,BoardMtOlympus}, -p {N1xxWU,KabylakeRvp3,BoardMtOlympus}
                        the platform to build
  --toolchain TOOLCHAIN, -t TOOLCHAIN
                        using the Tool Chain Tagname to build the
                        platform, overriding target.txt's TOOL_CHAIN_TAG
                        definition
  --DEBUG, -d           debug flag
  --RELEASE, -r         release flag
  --TEST_RELEASE, -tr   test release flag
  --RELEASE_PDB, -rp    release flag
  --list, -l            lists available platforms
  --cleanall            cleans all
  --clean               cleans specific platform 
  --capsule             capsule build enabled
  --silent              silent build enabled
  --performance         performance build enabled
  --fsp                 fsp build enabled

Agyeman (2):
  Platform/Intel: Added python build script.
  Updated the build instructions to include the python script build
    instructions

 .../ClevoOpenBoardPkg/N1xxWU/build_config.cfg |  33 +
 .../KabylakeRvp3/build_board.py               |  68 ++
 .../KabylakeRvp3/build_config.cfg             |  34 +
 .../BoardMtOlympus/build_board.py             | 177 ++++
 .../BoardMtOlympus/build_config.cfg           |  32 +
 Platform/Intel/build.cfg                      |  56 +
 Platform/Intel/build_bios.py                  | 976 ++++++++++++++++++
 ReadMe.md                                     |  76 ++
 8 files changed, 1452 insertions(+)
 create mode 100644 Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
 create mode 100644 Platform/Intel/build.cfg  create mode 100644 Platform/Intel/build_bios.py

--
2.19.1.windows.1





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

* Re: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added python build script.
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added " Agyeman, Prince
@ 2019-05-04  0:36   ` Nate DeSimone
  2019-05-04  2:14   ` Kubacki, Michael A
  1 sibling, 0 replies; 9+ messages in thread
From: Nate DeSimone @ 2019-05-04  0:36 UTC (permalink / raw)
  To: devel@edk2.groups.io, Agyeman, Prince
  Cc: Kubacki, Michael A, Sinha, Ankit, Kinney, Michael D,
	Oram, Isaac W, Gao, Liming, Zhou, Bowen, Lu, Shifei A

Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Agyeman, Prince
Sent: Friday, May 3, 2019 4:19 PM
To: devel@edk2.groups.io
Cc: Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Oram, Isaac W <isaac.w.oram@intel.com>; Gao, Liming <liming.gao@intel.com>; Zhou, Bowen <bowen.zhou@intel.com>; Lu, Shifei A <shifei.a.lu@intel.com>
Subject: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added python build script.

This change allows building all the platforms in Platform/Intel with
a single python script. This script works with python 2.7
and python 3.7

Files Added:

* build_bios.py: the main build script
  build.cfg: contains general/default build settings
* ClevoOpenBoardPkg/N1xxWU/build_config.cfg: contains N1xxWU specific
  build settings
* KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py : contains sample
  custom build script
* KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg: contains
  KabylakeRvp3 build settings
* PurleyOpenBoardPkg/BoardMtOlympus/build_board.py: contains
  BoardMtOlympus custom build script
* PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg: contains
  BoardMtOlympus custom build settings

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Isaac W Oram <isaac.w.oram@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Bowen Zhou<bowen.zhou@intel.com>
Cc: Shifei A Lu <shifei.a.lu@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>
---
 .../ClevoOpenBoardPkg/N1xxWU/build_config.cfg |  33 +
 .../KabylakeRvp3/build_board.py               |  68 ++
 .../KabylakeRvp3/build_config.cfg             |  34 +
 .../BoardMtOlympus/build_board.py             | 177 ++++
 .../BoardMtOlympus/build_config.cfg           |  32 +
 Platform/Intel/build.cfg                      |  56 +
 Platform/Intel/build_bios.py                  | 976 ++++++++++++++++++
 7 files changed, 1376 insertions(+)
 create mode 100644 Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
 create mode 100644 Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
 create mode 100644 Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
 create mode 100644 Platform/Intel/build.cfg
 create mode 100644 Platform/Intel/build_bios.py

diff --git a/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
new file mode 100644
index 0000000000..ee1261e700
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
@@ -0,0 +1,33 @@
+# @ build_config.cfg
+# This is the N1xxWU board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = ClevoOpenBoardPkg
+PROJECT = ClevoOpenBoardPkg/N1xxWU
+BOARD = N1xxWU
+FLASH_MAP_FDF = ClevoOpenBoardPkg/N1xxWU/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = ClevoOpenBoardPkg/N1xxWU/OpenBoardPkgPcd.dsc
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = TRUE
+FSP_BIN_PKG = KabylakeFspBinPkg
+FSP_PKG_NAME = KabylakeFspPkg
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
new file mode 100644
index 0000000000..726ad85874
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
@@ -0,0 +1,68 @@
+# @ build_board.py
+# This is a sample code provides Optional dynamic imports
+# of build functions to the BuildBios.py script
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+"""
+This module serves as a sample implementation of the build extension
+scripts
+"""
+
+
+def pre_build_ex(config, functions):
+    """Additional Pre BIOS build function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: nothing
+    """
+    print("pre_build_ex")
+    return None
+
+
+def build_ex(config, functions):
+    """Additional BIOS build function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("build_ex")
+    return None
+
+
+def post_build_ex(config, functions):
+    """Additional Post BIOS build function
+
+    :param config: The environment variables to be used in the post
+        build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("post_build_ex")
+    return None
+
+
+def clean_ex(config, functions):
+    """Additional clean function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("clean_ex")
+    return None
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
new file mode 100644
index 0000000000..5ea61dceb8
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
@@ -0,0 +1,34 @@
+# @ build_config.cfg
+# This is the KabylakeRvp3 board specific build settings
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = KabylakeOpenBoardPkg
+PROJECT = KabylakeOpenBoardPkg/KabylakeRvp3
+BOARD = KabylakeRvp3
+FLASH_MAP_FDF = KabylakeOpenBoardPkg/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc
+BOARD_PKG_PCD_DSC = KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc
+ADDITIONAL_SCRIPTS = KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = TRUE
+FSP_BIN_PKG = KabylakeFspBinPkg
+FSP_PKG_NAME = KabylakeFspPkg
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
diff --git a/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
new file mode 100644
index 0000000000..0dda929a00
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
@@ -0,0 +1,177 @@
+# @ build_board.py
+# This adds additional functions to the build_bios.py
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+"""
+This module serves as an additional build steps for the Mt Olympus board
+"""
+
+import os
+import sys
+
+
+def pre_build_ex(config, functions):
+    """Additional Pre BIOS build function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: nothing
+    """
+    print("Info: re-generating PlatformOffset header files")
+
+    execute_script = functions.get("execute_script")
+
+    command = ["build", "-D", "MAX_SOCKET=" + config.get("MAX_SOCKET", "1"),
+               "-m",
+               os.path.join(config["PLATFORM_BOARD_PACKAGE"],
+                            "Acpi", "BoardAcpiDxe", "Dsdt.inf"),
+               "-y",
+               config.get("PRE_BUILD_REPORT",
+                          os.path.join(config["WORKSPACE"],
+                                       "preBuildReport.txt")),
+               "--log=" + config.get("PRE_BUILD_LOG",
+                                     os.path.join(config["WORKSPACE"],
+                                                  "prebuild.log"))]
+
+    _, _, _, code = execute_script(command, config)
+    if code != 0:
+        print(" ".join(command))
+        print("Error re-generating PlatformOffset header files")
+        sys.exit(1)
+
+    config["AML_FILTER"] = "\"PSYS\" .MCTL\" .FIX[0-9,A-Z]\""
+    print("AML_FILTER= ", config.get("AML_FILTER"))
+
+    # build the command with arguments
+    command = ["python",
+               os.path.join(config["MIN_PACKAGE_TOOLS"],
+                            "AmlGenOffset",
+                            "AmlGenOffset.py"),
+               "-d", "--aml_filter", config["AML_FILTER"],
+               "-o", os.path.join(config["WORKSPACE_PLATFORM"],
+                                  config["PLATFORM_BOARD_PACKAGE"],
+                                  "Acpi", "BoardAcpiDxe",
+                                  "AmlOffsetTable.c"),
+               os.path.join(config["BUILD_X64"],
+                            "PurleyOpenBoardPkg",
+                            "Acpi",
+                            "BoardAcpiDxe",
+                            "DSDT",
+                            "OUTPUT",
+                            "Dsdt", "WFPPlatform.offset.h")]
+
+    # execute the command
+    _, _, _, code = execute_script(command, config)
+    if code != 0:
+        print(" ".join(command))
+        print("Error re-generating PlatformOffset header files")
+        sys.exit(1)
+
+    print("GenOffset done")
+    return config
+
+
+def build_ex(config, functions):
+    """Additional BIOS build function
+
+    :param config: The environment variables to be used in
+    the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("build_ex")
+    return None
+
+
+def post_build_ex(config, functions):
+    """Additional Post BIOS build function
+
+    :param config: The environment variables to be used in the post
+        build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("post_build_ex")
+
+    execute_script = functions.get("execute_script")
+
+    if not execute_script:
+        print("post_build_ex Error")
+        sys.exit(1)
+
+    common_patch_command = [os.path.join(config["PYTHON_HOME"], "python"),
+                            os.path.join(config["MIN_PACKAGE_TOOLS"],
+                                         "PatchFv", "PatchBinFv.py"),
+                            config["TARGET"],
+                            os.path.join(config["WORKSPACE_SILICON_BIN"],
+                                         "PurleySiliconBinPkg"),
+                            os.path.join(config["WORKSPACE"],
+                                         "BuildReport.log")]
+
+    fvs_to_patch = ["FvTempMemorySilicon",
+                    "FvPreMemorySilicon",
+                    "FvPostMemorySilicon",
+                    "FvLateSilicon"]
+    for fv in fvs_to_patch:
+        patch_command = common_patch_command + [fv]
+        _, _, _, code = execute_script(patch_command, config)
+        if code != 0:
+            print(" ".join(patch_command))
+            print("Patch Error!")
+            sys.exit(1)
+
+    common_rebase_command = [os.path.join(config["PYTHON_HOME"], "python"),
+                             os.path.join(config["MIN_PACKAGE_TOOLS"],
+                                          "PatchFv", "RebaseBinFv.py"),
+                             config["TARGET"],
+                             os.path.join(config["WORKSPACE_SILICON_BIN"],
+                                          "PurleySiliconBinPkg"),
+                             os.path.join(config["WORKSPACE"],
+                                          "BuildReport.log")]
+
+    rebase_command = common_rebase_command +\
+        ["FvPreMemorySilicon",
+         "gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase"]
+
+    _, _, _, code = execute_script(rebase_command, config)
+    if code != 0:
+        print(" ".join(rebase_command))
+        print("Patch Error!")
+        sys.exit(1)
+
+    rebase_command = common_rebase_command +\
+        ["FvPostMemorySilicon",
+         "gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase"]
+
+    _, _, _, code = execute_script(rebase_command, config)
+    if code != 0:
+        print(" ".join(rebase_command))
+        print("Patch Error!")
+        sys.exit(1)
+
+    return None
+
+
+def clean_ex(config, functions):
+    """Additional clean function
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :param functions: A dictionary of function pointers
+    :type functions: Dictionary
+    :returns: config dictionary
+    :rtype: Dictionary
+    """
+    print("clean_ex")
+    return None
diff --git a/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
new file mode 100644
index 0000000000..dcf19d658d
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
@@ -0,0 +1,32 @@
+# @ build_config.cfg
+# This is the main/default build configuration file
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[CONFIG]
+WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
+EDK_SETUP_OPTION =
+openssl_path =
+PLATFORM_BOARD_PACKAGE = PurleyOpenBoardPkg
+PROJECT = PurleyOpenBoardPkg/BoardMtOlympus
+BOARD = BoardMtOlympus
+FLASH_MAP_FDF = PurleyOpenBoardPkg/Include/Fdf/FlashMapInclude.fdf
+PROJECT_DSC = PurleyOpenBoardPkg/BoardMtOlympus/PlatformPkg.dsc
+BOARD_PKG_PCD_DSC = PurleyOpenBoardPkg/BoardMtOlympus/PlatformPkgPcd.dsc
+ADDITIONAL_SCRIPTS = PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
+PRE_BUILD_LOG = prebuild.log
+PRE_BUILD_REPORT = prebuildReport.log
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = FALSE
+MAX_SOCKET = 2
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg
new file mode 100644
index 0000000000..b6c0cca4f7
--- /dev/null
+++ b/Platform/Intel/build.cfg
@@ -0,0 +1,56 @@
+# @ build.cfg
+# This is the main/default build configuration file
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+
+[DEFAULT_CONFIG]
+WORKSPACE =
+WORKSPACE_FSP_BIN = FSP
+EDK_TOOLS_BIN = edk2-BaseTools-win32
+EDK_BASETOOLS = BaseTools
+WORKSPACE_PLATFORM = edk2-platforms/Platform/Intel
+WORKSPACE_SILICON = edk2-platforms/Silicon/Intel
+WORKSPACE_PLATFORM_BIN =
+WORKSPACE_SILICON_BIN = edk2-non-osi/Silicon/Intel
+MIN_PACKAGE_TOOLS = edk2-platforms/Platform/Intel/MinPlatformPkg/Tools
+PACKAGES_PATH =
+EDK_SETUP_OPTION =
+BASE_TOOLS_PATH = edk2/BaseTools
+EDK_TOOLS_PATH = edk2/BaseTools
+openssl_path =
+PLATFORM_BOARD_PACKAGE =
+BIOS_SIZE_OPTION = -DBIOS_SIZE_OPTION=SIZE_70
+WORKSPACE_CORE = edk2
+EFI_SOURCE = edk2
+PATHEXT = .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
+PROMPT = $P$G
+PLATFORM_PACKAGE = MinPlatformPkg
+BOARD =
+PrepRELEASE = DEBUG
+SILENT_MODE = FALSE
+EXT_CONFIG_CLEAR =
+CapsuleBuild = FALSE
+EXT_BUILD_FLAGS =
+CAPSULE_BUILD = 0
+TARGET = DEBUG
+TARGET_SHORT = D
+PERFORMANCE_BUILD = FALSE
+FSP_WRAPPER_BUILD = FALSE
+FSP_BIN_PKG =
+FSP_PKG_NAME =
+FSP_BINARY_BUILD = FALSE
+FSP_TEST_RELEASE = FALSE
+SECURE_BOOT_ENABLE = FALSE
+REBUILD_MODE =
+BUILD_ROM_ONLY =
+NUMBER_OF_PROCESSORS = 1
+
+
+[PLATFORMS]
+# board_name = path_to_board_build_config.cfg
+KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
+N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
+BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
diff --git a/Platform/Intel/build_bios.py b/Platform/Intel/build_bios.py
new file mode 100644
index 0000000000..2edf340e0c
--- /dev/null
+++ b/Platform/Intel/build_bios.py
@@ -0,0 +1,976 @@
+
+# @ build_bios.py
+# Builds BIOS using configuration files and dynamically
+# imported functions from board directory
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+"""
+This module builds BIOS using configuration files and dynamically
+imported functions from board directory
+"""
+
+
+import os
+import re
+import sys
+import signal
+import shutil
+import argparse
+import traceback
+import subprocess
+from importlib import import_module
+
+try:
+    # python 2.7
+    import ConfigParser as configparser
+except ImportError:
+    # python 3
+    import configparser
+
+
+def pre_build(build_config, build_type="DEBUG", silent=False, toolchain=None):
+    """Sets the environment variables that shall be used for the build
+
+        :param build_config: The build configuration as defined in the JOSN
+            configuration files
+        :type build_config: Dictionary
+        :param build_type: The build target, DEBUG, RELEASE, RELEASE_PDB,
+            TEST_RELEASE
+        :type build_type: String
+        :param silent: Enables build in silent mode
+        :type silent: Boolean
+        :param toolchain: Specifies the tool chain tag to use for the build
+        :type toolchain: String
+        :returns: The updated environment variables
+        :rtype: Dictionary
+    """
+
+    # get current environment variables
+    config = os.environ.copy()
+
+    # patch the build config
+    build_config = patch_config(build_config)
+
+    # update the current config with the build config
+    config.update(build_config)
+
+    # make the config and build python 2.7 compartible
+    config = py_27_fix(config)
+
+    # Set WORKSPACE environment.
+    config["WORKSPACE"] = os.path.abspath(os.path.join("..", "..", "..", ""))
+    print("Set WORKSPACE as: {}".format(config["WORKSPACE"]))
+
+    # Check whether Git has been installed and been added to system path.
+    try:
+        subprocess.Popen(["git", "--help"], stdout=subprocess.PIPE)
+    except OSError:
+        print("The 'git' command is not recognized.")
+        print("Please make sure that Git is installed\
+                and has been added to system path.")
+        sys.exit(1)
+
+    # Create the Conf directory under WORKSPACE
+    if not os.path.isdir(os.path.join(config["WORKSPACE"], "Conf")):
+        try:
+            # create directory
+            os.makedirs(os.path.join(config["WORKSPACE"], "Conf"))
+            # copy files to it
+            config_template_path = os.path.join(config["WORKSPACE"],
+                                                config["BASE_TOOLS_PATH"],
+                                                "Conf")
+            config_path = os.path.join(config["WORKSPACE"], "Conf")
+            shutil.copyfile(config_template_path +
+                            os.sep + "target.template",
+                            config_path + os.sep + "target.txt")
+            shutil.copyfile(config_template_path +
+                            os.sep + "tools_def.template",
+                            config_path + os.sep + "tools_def.txt")
+            shutil.copyfile(config_template_path +
+                            os.sep + "build_rule.template",
+                            config_path + os.sep + "build_rule.txt")
+        except OSError:
+            print("Error while creating Conf")
+            sys.exit(1)
+
+    # Set other environments.
+    # Basic Rule:
+    # Platform override Silicon override Core
+    # Source override Binary
+    config["WORKSPACE_PLATFORM"] = os.path.join(config["WORKSPACE"],
+                                                config["WORKSPACE_PLATFORM"])
+    config["WORKSPACE_SILICON"] = os.path.join(config["WORKSPACE"],
+                                               config["WORKSPACE_SILICON"])
+    config["WORKSPACE_PLATFORM_BIN"] = \
+        os.path.join(config["WORKSPACE"], config["WORKSPACE_PLATFORM_BIN"])
+    config["WORKSPACE_SILICON_BIN"] = \
+        os.path.join(config["WORKSPACE"], config["WORKSPACE_SILICON_BIN"])
+    config["WORKSPACE_FSP_BIN"] = os.path.join(config["WORKSPACE"],
+                                               config["WORKSPACE_FSP_BIN"])
+
+    # add to package path
+    config["PACKAGES_PATH"] = config["WORKSPACE_PLATFORM"]
+    config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON"]
+    config["PACKAGES_PATH"] += os.pathsep + config["WORKSPACE_SILICON_BIN"]
+    config["PACKAGES_PATH"] += os.pathsep + \
+        os.path.join(config["WORKSPACE"], "FSP")
+    config["PACKAGES_PATH"] += os.pathsep + \
+        os.path.join(config["WORKSPACE"], "edk2")
+    config["PACKAGES_PATH"] += os.pathsep + os.path.join(config["WORKSPACE"])
+    config["EDK_TOOLS_PATH"] = os.path.join(config["WORKSPACE"],
+                                            config["EDK_TOOLS_PATH"])
+    config["BASE_TOOLS_PATH"] = config["EDK_TOOLS_PATH"]
+    config["EDK_TOOLS_BIN"] = os.path.join(config["WORKSPACE"],
+                                           config["EDK_TOOLS_BIN"])
+    config["PLATFORM_FSP_BIN_PACKAGE"] = \
+        os.path.join(config['WORKSPACE_FSP_BIN'], config['FSP_BIN_PKG'])
+    config['PROJECT_DSC'] = os.path.join(config["WORKSPACE_PLATFORM"],
+                                         config['PROJECT_DSC'])
+    config['BOARD_PKG_PCD_DSC'] = os.path.join(config["WORKSPACE_PLATFORM"],
+                                               config['BOARD_PKG_PCD_DSC'])
+    config["CONF_PATH"] = os.path.join(config["WORKSPACE"], "Conf")
+
+    # get the python path
+    if os.environ.get("PYTHON_HOME") is None:
+        config["PYTHON_HOME"] = None
+        if os.environ.get("PYTHONPATH") is not None:
+            config["PYTHON_HOME"] = os.environ.get("PYTHONPATH")
+        else:
+            print("PYTHONPATH environment variable is not found")
+            sys.exit(1)
+
+    # if python is installed, disable the binary base tools.
+    # python is installed if this code is running :)
+    if config.get("PYTHON_HOME") is not None:
+        if config.get("EDK_TOOLS_BIN") is not None:
+            del config["EDK_TOOLS_BIN"]
+
+    # Run edk setup and  update config
+    if os.name == 'nt':
+        edk2_setup_cmd = [os.path.join(config["EFI_SOURCE"], "edksetup"),
+                        "Rebuild"]
+
+        if config.get("EDK_SETUP_OPTION") and \
+        config["EDK_SETUP_OPTION"] != " ":
+            edk2_setup_cmd.append(config["EDK_SETUP_OPTION"])
+
+        _, _, result, return_code = execute_script(edk2_setup_cmd,
+                                                config,
+                                                collect_env=True,
+                                                shell=True)
+        if return_code == 0 and result is not None and isinstance(result,
+                                                                dict):
+            config.update(result)
+
+    # nmake BaseTools source
+    # and enable BaseTools source build
+    shell = True
+    command = ["nmake", "-f", os.path.join(config["BASE_TOOLS_PATH"],
+                                           "Makefile")]
+    if os.name == "posix":  # linux
+        shell = False
+        command = ["make", "-C", os.path.join(config["BASE_TOOLS_PATH"])]
+
+    _, _, result, return_code = execute_script(command, config, shell=shell)
+    if return_code != 0:
+        build_failed(config)
+
+    config["SILENT_MODE"] = 'TRUE' if silent else 'FALSE'
+
+    print("==============================================")
+
+    if os.path.isfile(os.path.join(config['WORKSPACE'], "Prep.log")):
+        os.remove(os.path.join(config['WORKSPACE'], "Prep.log"))
+
+    config["PROJECT"] = os.path.join(config["PLATFORM_BOARD_PACKAGE"],
+                                     config["BOARD"])
+
+    # Setup Build
+    # @todo: Need better TOOL_CHAIN_TAG detection
+    if toolchain is not None:
+        config["TOOL_CHAIN_TAG"] = toolchain
+    elif config.get("TOOL_CHAIN_TAG") is None:
+        if os.name == 'nt':
+            config["TOOL_CHAIN_TAG"] = "VS2015"
+        else:
+            config["TOOL_CHAIN_TAG"] = "GCC5"
+
+    # echo Show CL revision
+    config["PrepRELEASE"] = build_type
+
+    if build_type == "DEBUG":
+        config["TARGET"] = 'DEBUG'
+        config["TARGET_SHORT"] = 'D'
+    else:
+        config["TARGET"] = 'RELEASE'
+        config["TARGET_SHORT"] = 'R'
+
+    # set BUILD_DIR_PATH path
+    config["BUILD_DIR_PATH"] = os.path.join(config["WORKSPACE"],
+                                            'Build',
+                                            config["PROJECT"],
+                                            "{}_{}".format(
+                                                config["TARGET"],
+                                                config["TOOL_CHAIN_TAG"]))
+    # set BUILD_DIR path
+    config["BUILD_DIR"] = os.path.join('Build',
+                                       config["PROJECT"],
+                                       "{}_{}".format(
+                                           config["TARGET"],
+                                           config["TOOL_CHAIN_TAG"]))
+
+    config["BUILD_X64"] = os.path.join(config["BUILD_DIR_PATH"], 'X64')
+    config["BUILD_IA32"] = os.path.join(config["BUILD_DIR_PATH"], 'IA32')
+
+    if not os.path.isdir(config["BUILD_DIR_PATH"]):
+        try:
+            os.makedirs(config["BUILD_DIR_PATH"])
+        except OSError:
+            print("Error while creating Build folder")
+            sys.exit(1)
+
+    # Set FSP_WRAPPER_BUILD
+    if config['FSP_WRAPPER_BUILD'] == "TRUE":
+        # Create dummy Fsp_Rebased_S_padded.fd to build the BiosInfo.inf
+        # if it is wrapper build, due to the SECTION inclusion
+        open(os.path.join(config["WORKSPACE_FSP_BIN"],
+                          config["FSP_BIN_PKG"],
+                          "Fsp_Rebased_S_padded.fd"), 'w').close()
+
+    if not os.path.isdir(config["BUILD_X64"]):
+        try:
+            os.mkdir(config["BUILD_X64"])
+        except OSError:
+            print("Error while creating {}".format(config["BUILD_X64"]))
+            sys.exit(1)
+
+    # update config file with changes
+    update_target_file(config)
+
+    # Additional pre build scripts for this platform
+    result = pre_build_ex(config)
+    if result is not None and isinstance(result, dict):
+        config.update(result)
+
+    # print user settings
+    print("BIOS_SIZE_OPTION     = {}".format(config["BIOS_SIZE_OPTION"]))
+    print("EFI_SOURCE           = {}".format(config["EFI_SOURCE"]))
+    print("TARGET               = {}".format(config["TARGET"]))
+    print("TARGET_ARCH          = {}".format("IA32 X64"))
+    print("TOOL_CHAIN_TAG       = {}".format(config["TOOL_CHAIN_TAG"]))
+    print("WORKSPACE            = {}".format(config["WORKSPACE"]))
+    print("WORKSPACE_CORE       = {}".format(config["WORKSPACE_CORE"]))
+    print("EXT_BUILD_FLAGS      = {}".format(config["EXT_BUILD_FLAGS"]))
+
+    return config
+
+
+def build(config):
+    """Builds the BIOS image
+
+        :param config: The environment variables to be used
+            in the build process
+        :type config: Dictionary
+        :returns: nothing
+    """
+
+    if config["FSP_WRAPPER_BUILD"] == "TRUE":
+        pattern = "Fsp_Rebased.*\\.fd$"
+        file_dir = os.path.join(config['WORKSPACE_FSP_BIN'],
+                                config['FSP_BIN_PKG'])
+        for item in os.listdir(file_dir):
+            if re.search(pattern, item):
+                os.remove(os.path.join(file_dir, item))
+
+        command = [os.path.join(config['PYTHON_HOME'], "python"),
+                   os.path.join(config['WORKSPACE_PLATFORM'],
+                                config['PLATFORM_PACKAGE'],
+                                'Tools', 'Fsp',
+                                'RebaseAndPatchFspBinBaseAddress.py'),
+                   os.path.join(config['WORKSPACE_PLATFORM'],
+                                config['FLASH_MAP_FDF']),
+                   os.path.join(config['WORKSPACE_FSP_BIN'],
+                                config['FSP_BIN_PKG']),
+                   "Fsp.fd",
+                   os.path.join(config['WORKSPACE_PLATFORM'],
+                                config['PROJECT'],
+                                config['BOARD_PKG_PCD_DSC']),
+                   "0x0"]
+
+        _, _, _, return_code = execute_script(command, config, shell=False)
+
+        if return_code != 0:
+            print("ERROR:RebaseAndPatchFspBinBaseAddress failed")
+            sys.exit(return_code)
+
+        # create Fsp_Rebased.fd which is Fsp_Rebased_S.fd +
+        # Fsp_Rebased_M + Fsp_Rebased_T
+        with open(os.path.join(file_dir, "Fsp_Rebased_S.fd"), 'rb') as fsp_s, \
+                open(os.path.join(file_dir,
+                                  "Fsp_Rebased_M.fd"), 'rb') as fsp_m, \
+                open(os.path.join(file_dir,
+                                  "Fsp_Rebased_T.fd"), 'rb') as fsp_t:
+
+            fsp_rebased = fsp_s.read() + fsp_m.read() + fsp_t.read()
+            with open(os.path.join(file_dir,
+                                   "Fsp_Rebased.fd"), 'wb') as new_fsp:
+                new_fsp.write(fsp_rebased)
+
+        if not os.path.isfile(os.path.join(file_dir, "Fsp_Rebased.fd")):
+            print("!!! ERROR:failed to create fsp!!!")
+            sys.exit(1)
+
+    # Output the build variables the user has selected.
+    print("==========================================")
+    print(" User Selected build options:")
+    print(" SILENT_MODE    = ", config.get("SILENT_MODE"))
+    print(" REBUILD_MODE   = ", config.get("REBUILD_MODE"))
+    print(" BUILD_ROM_ONLY = ", config.get("BUILD_ROM_ONLY"))
+    print("==========================================")
+
+    command = ["build", "-n", config["NUMBER_OF_PROCESSORS"]]
+
+    if config["REBUILD_MODE"] and config["REBUILD_MODE"] != "":
+        command.append(config["REBUILD_MODE"])
+
+    if config["EXT_BUILD_FLAGS"] and config["EXT_BUILD_FLAGS"] != "":
+        command.append(config["EXT_BUILD_FLAGS"])
+
+    if config.get("SILENT_MODE", "FALSE") == "TRUE":
+        command.append("--silent")
+        command.append("--quiet")
+
+    else:
+        command.append("--log=" + config.get("BUILD_LOG", "Build.log"))
+        command.append("--report-file=" +
+                       config.get("BUILD_REPORT", "BuildReport.log"))
+
+    if config.get("VERBOSE", "FALSE") == "TRUE":
+        command.append("--verbose")
+
+    if config.get("MAX_SOCKET") is not None:
+        command.append("-D")
+        command.append("MAX_SOCKET=" + config["MAX_SOCKET"])
+
+    _, _, _, exit_code = execute_script(command, config)
+    if exit_code != 0:
+        build_failed(config)
+
+    # Additional build scripts for this platform
+    result = build_ex(config)
+    if result is not None and isinstance(result, dict):
+        config.update(result)
+
+    return config
+
+
+def post_build(config):
+    """Post build process of BIOS image
+
+    :param config: The environment variables to be used in the build process
+    :type config: Dictionary
+    :returns: nothing
+    """
+    print("Running post_build to complete the build process.")
+
+    # Additional build scripts for this platform
+    result = post_build_ex(config)
+    if result is not None and isinstance(result, dict):
+        config.update(result)
+
+    # cleanup
+    pattern = "Fsp_Rebased.*\\.fd$"
+    file_dir = os.path.join(config['WORKSPACE_FSP_BIN'],
+                            config['FSP_BIN_PKG'])
+    for item in os.listdir(file_dir):
+        if re.search(pattern, item):
+            os.remove(os.path.join(file_dir, item))
+
+    if config.get("DYNAMIC_BUILD_INIT_FILES") is not None:
+        for item in config["DYNAMIC_BUILD_INIT_FILES"].split(","):
+            try:
+                os.remove(item)  # remove __init__.py
+                os.remove(item + "c")  # remove __init__.pyc as well
+            except OSError:
+                pass
+
+
+def build_failed(config):
+    """Displays results when build fails
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: nothing
+    """
+    print(" The EDKII BIOS Build has failed!")
+    # clean up
+    if config.get("DYNAMIC_BUILD_INIT_FILES") is not None:
+        for item in config["DYNAMIC_BUILD_INIT_FILES"].split(","):
+            if os.path.isfile(item):
+                try:
+                    os.remove(item)  # remove __init__.py
+                    os.remove(item + "c")  # remove __init__.pyc as well
+                except OSError:
+                    pass
+    sys.exit(1)
+
+
+def import_platform_lib(path, function):
+    """Imports custom functions for the platforms being built
+
+        :param path: the location of the custom build script to be executed
+        :type path: String
+        :param path: the function to be executed
+        :type path: String
+        :returns: nothing
+    """
+    if path.endswith(".py"):
+        path = path[:-3]
+    path = path.replace(os.sep, ".")
+    module = import_module(path)
+    lib = getattr(module, function)
+    return lib
+
+
+def pre_build_ex(config):
+    """ An extension of the pre_build process as defined platform
+        specific pre_build setup script
+
+        :param config: The environment variables used in the pre build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "pre_build_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print(config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def build_ex(config):
+    """ An extension of the build process as defined platform
+        specific build setup script
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "build_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print("error", config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def post_build_ex(config):
+    """ An extension of the post build process as defined platform
+        specific build setup script
+
+        :param config: The environment variables used in the post build
+            process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "post_build_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print(config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def clean_ex(config):
+    """ An extension of the platform cleanning
+
+        :param config: The environment variables used in the clean process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if config.get("ADDITIONAL_SCRIPTS"):
+        try:
+            platform_function =\
+                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
+                                    "clean_ex")
+            functions = {"execute_script": execute_script}
+            return platform_function(config, functions)
+        except ImportError as error:
+            print(config["ADDITIONAL_SCRIPTS"], str(error))
+            build_failed(config)
+    return None
+
+
+def get_environment_variables(std_out_str, marker):
+    """Gets the environment variables from a process
+
+        :param std_out_str: The std_out pipe
+        :type std_out_str: String
+        :param marker: A begining and end mark of environment
+            variables printed to std_out
+        :type marker: String
+        :returns: The environment variables read from the process' std_out pipe
+        :rtype: Tuple
+    """
+    start_env_update = False
+    environment_vars = {}
+    out_put = ""
+    for line in std_out_str.split("\n"):
+        if start_env_update and len(line.split("=")) == 2:
+            key, value = line.split("=")
+            environment_vars[key] = value
+        else:
+            out_put += "\n" + line.replace(marker, "")
+
+        if marker in line:
+            if start_env_update:
+                start_env_update = False
+            else:
+                start_env_update = True
+    return (out_put, environment_vars)
+
+
+def execute_script(command, env_variables, collect_env=False,
+                   enable_std_pipe=False, shell=True):
+    """launches a process that executes a script/shell command passed to it
+
+        :param command: The command/script with its commandline
+            arguments to be executed
+        :type command:  List:String
+        :param env_variables: Environment variables passed to the process
+        :type env_variables: String
+        :param collect_env: Enables the collection of evironment variables
+            when process execution is done
+        :type collect_env: Boolean
+        :param enable_std_pipe: Enables process out to be piped to
+        :type enable_std_pipe: String
+        :returns: a tuple of std_out, stderr , environment variables,
+            return code
+        :rtype: Tuple: (std_out, stderr , enVar, return_code)
+    """
+
+    print("Calling " + " ".join(command))
+
+    env_marker = '-----env-----'
+    env = {}
+    kwarg = {"env": env_variables,
+             "universal_newlines": True,
+             "shell": shell,
+             "cwd": env_variables["WORKSPACE"]}
+
+    if enable_std_pipe or collect_env:
+        kwarg["stdout"] = subprocess.PIPE
+        kwarg["stderr"] = subprocess.PIPE
+
+    # collect environment variables
+    if collect_env:
+        # get the binary that prints environment variables based on os
+        if os.name == 'nt':
+            get_var_command = "set"
+        else:
+            get_var_command = "env"
+        # modify the command to print the environment variables
+        if isinstance(command, list):
+            command += ["&&", "echo", env_marker, "&&",
+                        get_var_command, "&&", "echo", env_marker]
+        else:
+            command += " " + " ".join(["&&", "echo", env_marker,
+                                       "&&", get_var_command,
+                                       "&&", "echo", env_marker])
+
+    # execute the command
+    execute = subprocess.Popen(command, **kwarg)
+    std_out, stderr = execute.communicate()
+    code = execute.returncode
+
+    # wait for process to be done
+    execute.wait()
+
+    # if collect enviroment variables
+    if collect_env:
+        # get the new environment variables
+        std_out, env = get_environment_variables(std_out, env_marker)
+    return (std_out, stderr, env, code)
+
+
+def patch_config(config):
+    """ An extension of the platform cleanning
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    new_config = {}
+    for key in config:
+        new_config[str(key)] = str(config[key].replace("/", os.sep))
+    return new_config
+
+
+def py_27_fix(config):
+    """  Prepares build for python 2.7 => build
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: config dictionary
+        :rtype: Dictionary
+    """
+    if not sys.version_info > (3, 0):
+        path_list = []
+        # create __init__.py in directories in this path
+        if config.get("ADDITIONAL_SCRIPTS"):
+            # get the directory
+            path_to_directory =\
+                os.path.dirname(config.get("ADDITIONAL_SCRIPTS"))
+            path = ""
+            for directories in path_to_directory.split(os.sep):
+                path += directories + os.sep
+                init_file = path + os.sep + "__init__.py"
+                if not os.path.isfile(init_file):
+                    open(init_file, 'w').close()
+                    path_list.append(init_file)
+            config["DYNAMIC_BUILD_INIT_FILES"] = ",".join(path_list)
+
+    return config
+
+
+def clean(build_config, board=False):
+    """Cleans the build workspace
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :param board: This flag specifies specific board clean
+        :type board: Bool
+        :returns: nothing
+    """
+
+    # patch the config
+    build_config = patch_config(build_config)
+
+    # get current environment variables
+    config = os.environ.copy()
+
+    # update it with the build variables
+    config.update(build_config)
+
+    if config.get('WORKSPACE') is None or not config.get('WORKSPACE'):
+        config["WORKSPACE"] =\
+                os.path.abspath(os.path.join("..", "..", "..", ""))
+
+    # build cleanall
+    print("Cleaning directories...")
+
+    if board:
+        platform_pkg = config.get("PLATFORM_BOARD_PACKAGE", None)
+        if platform_pkg is None or\
+            not os.path.isdir(os.path.join(config['WORKSPACE'],
+                                           "Build", platform_pkg)):
+            print("Platform package not found")
+            sys.exit(1)
+        else:
+            print("Removing " + os.path.join(config['WORKSPACE'],
+                                             "Build", platform_pkg))
+            shutil.rmtree(os.path.join(config['WORKSPACE'],
+                                       "Build", platform_pkg))
+
+    else:
+        if os.path.isdir(os.path.join(config['WORKSPACE'], "Build")):
+            print("Removing " + os.path.join(config['WORKSPACE'], "Build"))
+            shutil.rmtree(os.path.join(config['WORKSPACE'], "Build"))
+
+    if os.path.isdir(os.path.join(config['WORKSPACE'], "Conf")):
+        print("Removing " + os.path.join(config['WORKSPACE'], "Conf"))
+        shutil.rmtree(os.path.join(config['WORKSPACE'], "Conf"))
+
+    print("Cleaning files...")
+
+    if os.path.isfile(os.path.join(config['WORKSPACE'],
+                                   config.get("BUILD_REPORT",
+                                              "BuildReport.log"))):
+        print("Removing ", os.path.join(config['WORKSPACE'],
+                                        config.get("BUILD_REPORT",
+                                                   "BuildReport.log")))
+        os.remove(os.path.join(config['WORKSPACE'],
+                               config.get("BUILD_REPORT", "BuildReport.log")))
+
+    print("  All done...")
+
+    sys.exit(0)
+
+
+def update_target_file(config):
+    """Updates Conf's target file that will be used in the build
+
+        :param config: The environment variables used in the build process
+        :type config: Dictionary
+        :returns: True if update was successful and False if update fails
+        :rtype: Boolean
+    """
+    contents = None
+    result = False
+    with open(os.path.join(config["CONF_PATH"], "target.txt"), 'r') as target:
+        contents = target.readlines()
+        options_list = ['ACTIVE_PLATFORM', 'TARGET',
+                        'TARGET_ARCH', 'TOOL_CHAIN_TAG', 'BUILD_RULE_CONF']
+        modified = []
+
+        # remove these options from the config file
+        for line in contents:
+            if line.replace(" ", "")[0] != '#' and\
+             any(opt in line for opt in options_list):
+                continue
+            modified.append(line)
+
+        # replace with config options provided
+        string = "{} = {}\n".format("ACTIVE_PLATFORM",
+                                    os.path.join(
+                                        config['WORKSPACE_PLATFORM'],
+                                        config['PLATFORM_BOARD_PACKAGE'],
+                                        config['BOARD'],
+                                        config['PROJECT_DSC']))
+        modified.append(string)
+
+        string = "{} = {}\n".format("TARGET", config['TARGET'])
+        modified.append(string)
+
+        string = "TARGET_ARCH = IA32 X64\n"
+        modified.append(string)
+
+        string = "{} = {}\n".format("TOOL_CHAIN_TAG", config['TOOL_CHAIN_TAG'])
+        modified.append(string)
+
+        string = "{} = {}\n".format("BUILD_RULE_CONF",
+                                    os.path.join("Conf", "build_rule.txt"))
+        modified.append(string)
+
+    if modified is not None:
+        with open(os.path.join(config["WORKSPACE"],
+                               "Conf", "target.txt"), 'w') as target:
+            for line in modified:
+                target.write(line)
+            result = True
+
+    return result
+
+
+def get_config():
+    """Reads the default projects config file
+
+        :returns: The config defined in the the Build.cfg file
+        :rtype: Dictionary
+    """
+    config_file = configparser.RawConfigParser()
+    config_file.optionxform = str
+    config_file.read('build.cfg')
+    config_dictionary = {}
+    for section in config_file.sections():
+        dictionary = dict(config_file.items(section))
+        config_dictionary[section] = dictionary
+    return config_dictionary
+
+
+def get_platform_config(platform_name, config_data):
+    """ Reads the platform specifig config file
+
+        param platform_name: The name of the platform to be built
+        :type platform_name: String
+        param configData: The environment variables to be
+            used in the build process
+        :type configData: Dictionary
+        :returns: The config defined in the the Build.cfg file
+        :rtype: Dictionary
+    """
+    config = {}
+
+    platform_data = config_data.get("PLATFORMS")
+    path = platform_data.get(platform_name)
+    config_file = configparser.RawConfigParser()
+    config_file.optionxform = str
+    config_file.read(path)
+    for section in config_file.sections():
+        config[section] = dict(config_file.items(section))
+
+    return config
+
+
+def get_cmd_config_arguments(arguments):
+    """Get commandline config arguments
+
+    param arguments: The environment variables to be used in the build process
+    :type arguments: argparse
+    :returns: The config dictionary built from the commandline arguments
+    :rtype: Dictionary
+    """
+    result = {}
+    if arguments.capsule is True:
+        result["CAPSULE_BUILD"] = "1"
+
+    if arguments.performance is True:
+        result["PERFORMANCE_BUILD"] = "TRUE"
+
+    if arguments.fsp is True:
+        result["FSP_WRAPPER_BUILD"] = "TRUE"
+
+    return result
+
+
+def get_cmd_arguments(build_config):
+    """ Get commandline inputs from user
+
+        param config_data: The environment variables to be
+            used in the build process
+        :type config_data: Dictionary
+        :returns: The commandline arguments input by the user
+        :rtype: argparse object
+    """
+
+    class PrintPlatforms(argparse.Action):
+        """ this is an argparse action that lists the available platforms
+        """
+        def __call__(self, parser, namespace, values, option_string=None):
+            print("Platforms:")
+            for key in build_config.get("PLATFORMS"):
+                print("    " + key)
+            setattr(namespace, self.dest, values)
+            sys.exit(0)
+
+    # get the build commands
+    parser = argparse.ArgumentParser(description="Build Help")
+    parser.add_argument('--platform', '-p', dest="platform",
+                        help='the platform to build',
+                        choices=build_config.get("PLATFORMS"),
+                        required=('-l' not in sys.argv and
+                                  '--cleanall' not in sys.argv))
+
+    parser.add_argument('--toolchain', '-t', dest="toolchain",
+                        help="using the Tool Chain Tagname to build \
+                            the platform,overriding \
+                            target.txt's TOOL_CHAIN_TAG definition")
+
+    parser.add_argument("--DEBUG", '-d', help="debug flag",
+                        action='store_const', dest="target",
+                        const="DEBUG", default="DEBUG")
+
+    parser.add_argument("--RELEASE", '-r', help="release flag",
+                        action='store_const',
+                        dest="target", const="RELEASE")
+
+    parser.add_argument("--TEST_RELEASE", '-tr', help="test Release flag",
+                        action='store_const',
+                        dest="target", const="TEST_RELEASE")
+
+    parser.add_argument("--RELEASE_PDB", '-rp', help="release flag",
+                        action='store_const', dest="target",
+                        const="RELEASE_PDB")
+
+    parser.add_argument('--list', '-l', action=PrintPlatforms,
+                        help='lists available platforms', nargs=0)
+
+    parser.add_argument('--cleanall', dest='clean_all',
+                        help='cleans all', action='store_true')
+
+    parser.add_argument('--clean', dest='clean',
+                        help='cleans specific platform', action='store_true')
+
+    parser.add_argument("--capsule", help="capsule build enabled",
+                        action='store_true', dest="capsule")
+
+    parser.add_argument("--silent", help="silent build enabled",
+                        action='store_true', dest="silent")
+
+    parser.add_argument("--performance", help="performance build enabled",
+                        action='store_true', dest="performance")
+
+    parser.add_argument("--fsp", help="fsp build enabled",
+                        action='store_true', dest="fsp")
+
+    return parser.parse_args()
+
+
+def keyboard_interruption(int_signal, int_frame):
+    """ Catches a keyboard interruption handler
+
+        param int_signal: The signal this handler is called with
+        :type int_signal: Signal
+        param int_frame: The signal this handler is called with
+        :type int_frame: frame
+        :rtype: nothing
+    """
+    print("Signal #: {} Frame: {}".format(int_signal, int_frame))
+    print("Quiting...")
+    sys.exit(0)
+
+
+def main():
+    """ The main function of this module
+        :rtype: nothing
+    """
+    # to quit the build
+    signal.signal(signal.SIGINT, keyboard_interruption)
+
+    # get general build configurations
+    build_config = get_config()
+
+    # get commandline parameters
+    arguments = get_cmd_arguments(build_config)
+
+    if arguments.clean_all:
+        clean(build_config.get("DEFAULT_CONFIG"))
+
+    # get platform specific config
+    platform_config = get_platform_config(arguments.platform, build_config)
+
+    # update general build config with platform specific config
+    config = build_config.get("DEFAULT_CONFIG")
+    config.update(platform_config.get("CONFIG"))
+
+    # if user selected clean
+    if arguments.clean:
+        clean(config, board=True)
+
+    # Override config with cmd arguments
+    cmd_config_args = get_cmd_config_arguments(arguments)
+    config.update(cmd_config_args)
+
+    # get pre_build configurations
+    config = pre_build(config,
+                       build_type=arguments.target,
+                       toolchain=arguments.toolchain,
+                       silent=arguments.silent)
+
+    # build selected platform
+    config = build(config)
+
+    # post build
+    post_build(config)
+
+
+if __name__ == "__main__":
+    try:
+        EXIT_CODE = 0
+        main()
+    except Exception as error:
+        EXIT_CODE = 1
+        traceback.print_exc()
+    sys.exit(EXIT_CODE)
-- 
2.19.1.windows.1





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

* Re: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions Agyeman, Prince
@ 2019-05-04  0:36   ` Nate DeSimone
  2019-05-04  2:14   ` Kubacki, Michael A
  1 sibling, 0 replies; 9+ messages in thread
From: Nate DeSimone @ 2019-05-04  0:36 UTC (permalink / raw)
  To: devel@edk2.groups.io, Agyeman, Prince
  Cc: Kubacki, Michael A, Kinney, Michael D, Gao, Liming, Sinha, Ankit

Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Agyeman, Prince
Sent: Friday, May 3, 2019 4:19 PM
To: devel@edk2.groups.io
Cc: Kubacki, Michael A <michael.a.kubacki@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
Subject: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions

Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Agyeman <prince.agyeman@intel.com>
---
 ReadMe.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/ReadMe.md b/ReadMe.md
index 72e332a476..fbf735173f 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -105,6 +105,82 @@ return back to the minimum platform caller.
 
 ### Build
 
+**Building with the python script**
+
+1. Open command window, go to the workspace directory, e.g. c:\Kabylake.
+2. Type "cd edk2-platforms\Platform\Intel 3. Type "python build_bios.py 
+-p REPLACE_WITH_BOARD_NAME"
+
+* build_bios.py arguments:
+
+  | Argument              | Function                            |
+  | ----------------------|-------------------------------------|
+  | -h, --help            | show this help message and exit     |
+  | --platform, -p        | the platform to build               |
+  | --toolchain, -t       | tool Chain to use in build process  |
+  | --DEBUG, -d           | debug flag                          |
+  | --RELEASE, -r         | release flag                        |
+  | --TEST_RELEASE, -tr   | test Release flag                   |
+  | --RELEASE_PDB, -rp    | release flag                        |
+  | --list, -l            | lists available platforms           |
+  | --cleanall            | cleans all                          |
+  | --clean               | cleans specified platform           |
+  | --capsule             | capsule build enabled               |
+  | --silent              | silent build enabled                |
+  | --performance         | performance build enabled           |
+  | --fsp                 | fsp build enabled                   |
+  |                                                             |
+
+* For more information on build options
+  * ``Type "python build_bios.py -h"``
+
+* Note
+  * ``Python 2.7.16 and Python 3.7.3 compatible``
+  * ``These python build scripts have been tested on Windows due to`` 
+[cross-platform limitations](#Known-limitations)
+
+* Configuration Files
+  * ``The edk2-platforms\Platform\Intel\build.cfg file contains the 
+default settings used by build_bios.py``
+  * ``The default settings are under the DEFAULT_CONFIG section``
+  * ``Each board can have a settings file that will override the 
+edk2-platforms\Platform\Intel\build.cfg settings``
+  * ``An example of a board specific settings:``
+    * 
+``edk2-platforms\Platform\Intel\KabylakeOpenBoardPkg\KabylakeRvp3\build
+_config.cfg``
+
+* Workspace view of the build scripts
+  * <pre>
+    WORKSPACE
+          |------edk2
+          |------edk2-non-osi
+          |------edk2-platforms
+          |       |---Platform
+          |       |    |--Intel
+          |       |        |------build.cfg: Default build settings. These are overridden by
+          |       |        |                 platform specific settings (build_config.cfg) and
+          |       |        |                 then command-line settings.
+          |       |        |
+          |       |        |------build_bios.py: Main build script. Generic pre-build, build,
+          |       |        |                     post-build, and clean functions.
+          |       |        |
+          |       |        |------ClevoOpenBoardPkg
+          |       |        |        |------N1xxWU
+          |       |        |                |---build_config.cfg: N1xxWU specific build
+          |       |        |                                      settings environment variables.
+          |       |        |
+          |       |        |------KabylakeOpenBoardPkg
+          |       |        |        |------KabylakeRvp3
+          |       |        |                  |---build_config.cfg: KabylakeRvp3 specific
+          |       |        |                  |                     build settings, environment variables.
+          |       |        |                  |---build_board.py: Optional board-specific pre-build, build
+          |       |        |                                      and clean post-build functions.
+          |       |        |------PurleyOpenBoardPkg
+          |       |        |       |------BoardMtOlympus
+          |       |        |                |---build_config.cfg: BoardMtOlympus specific
+          |       |        |                |                     build settings, environment variables.
+          |       |        |                |---build_board.py: Optional board-specific pre-build,
+          |       |        |                |                   build, post-build and clean functions.
+          |------FSP
+  </pre>
+
+**Building with the batch scripts**
 For KabylakeOpenBoardPkg
 1. Open command window, go to the workspace directory, e.g. c:\Kabylake.
 2. Type "cd edk2-platforms\Platform\Intel\KabylakeOpenBoardPkg\KabylakeRvp3".
--
2.19.1.windows.1





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

* Re: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script.
  2019-05-03 23:19 [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Agyeman, Prince
                   ` (2 preceding siblings ...)
  2019-05-04  0:36 ` [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Nate DeSimone
@ 2019-05-04  2:14 ` Kubacki, Michael A
  3 siblings, 0 replies; 9+ messages in thread
From: Kubacki, Michael A @ 2019-05-04  2:14 UTC (permalink / raw)
  To: devel@edk2.groups.io, Agyeman, Prince
  Cc: Desimone, Nathaniel L, Sinha, Ankit, Kinney, Michael D,
	Oram, Isaac W, Gao, Liming

Reviewed-by: Michael Kubacki <michael.a.kubacki@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Agyeman, Prince
> Sent: Friday, May 3, 2019 4:19 PM
> To: devel@edk2.groups.io
> Cc: Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>;
> Oram, Isaac W <isaac.w.oram@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Subject: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2]
> Adding python build script.
> 
> Cc: Michael Kubacki <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Isaac W Oram <isaac.w.oram@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> 
> Contributed-under: TianoCore Contribution Agreement 0.1
> Signed-off-by: Agyeman <prince.agyeman@intel.com>
> 
> 
> changes from v2:
> - fixed pep8 violations
> - implemented v2 review recommendations
> - added clean flag to clean specified platform
> 
> Overview:
> WORKSPACE
>     |
>     |------edk2
>     |------edk2-non-osi
>     |------edk2-platforms
>     |       |--Platform
>     |       |---Intel
>     |       |        |------build.cfg: Default build settings. These are overridden by
>     |       |        |                 platform specific settings (build_config.cfg) and
>     |       |        |                 then command-line settings.
>     |       |        |
>     |       |        |------build_bios.py: Main build script. Generic pre-build, build,
>     |       |        |                     post-build, and clean functions.
>     |       |        |
>     |       |        |------ClevoOpenBoardPkg
>     |       |        |        |------N1xxWU
>     |       |        |                |---build_config.cfg: N1xxWU specific build
>     |       |        |                                      settings environment variables.
>     |       |        |
>     |       |        |------KabylakeOpenBoardPkg
>     |       |        |        |------KabylakeRvp3
>     |       |        |                  |---build_config.cfg: KabylakeRvp3 specific
>     |       |        |                  |                     build settings, environment variables.
>     |       |        |                  |---build_board.py: Optional board-specific pre-build,
> build
>     |       |        |                                      and clean post-build functions.
>     |       |        |------PurleyOpenBoardPkg
>     |       |        |       |------BoardMtOlympus
>     |       |        |                |---build_config.cfg: BoardMtOlympus specific
>     |       |        |                                      build settings, environment variables.
>     |       |        |                |---build_board.py: Optional board-specific pre-build,
>     |       |        |                |                   build, post-build and clean functions.
>     |------FSP
> 
> 
> -------------------
> Details:
> -------------------
> What it is
> ----------
> These patches add python BIOS build scripts and build configuration files to
> build platforms under Intel/Platform.
> 
> 
> Why
> ----
> The reason behind this implementation is to use a cross platform build script
> to build minplaform BIOS.
> 
> 
> How it is done
> ----------------
> The python files:
> -----------------
> build_bios.py: The main build file. This script sets up the edk2 build
> enviroment using the default build.cfg settings and platform specific settings.
> It uses the configurations found in the build.cfg file to locate the platforms
> that are configured to use this build script.
> The path to each of the platform settings can be found under the
> "PLATFORMS"
> field within the build.cfg file. The platform specific settings are located in the
> platform's main directory.
> Example edk2-
> platforms/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg.
> 
> The build_bios.py script contains the four main functions:
> - pre_build: Sets up the edk2 build enviroment variables, target.txt file
> - build: Uses the configurations to Build BIOS
> - post_build: Does post build processes like cleaning up files
>              generated during the build process
> - clean: Cleans up the build directory.
> 
> There are four addtional functions that dynamically import functions from
> the board's Optional/Additional python script if specified in board settings
> file's ADDITIONAL_SCRIPTS These four functions are the pre_build_board,
> build_board, post_build_board, clean_ex functions
> 
> 
> Board additional (Optional) python build script:
> ------------------------------------------------
> These are python scripts located in the board's main directory, An example
> Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
> If added, its path must be specified in board's settings file, under the field
> ADDITIONAL_SCRIPTS.
> Example ADDITIONAL_SCRIPTS =
> PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
> If specified, the build_board, pre_build_board, post_build_board, clean_ex
> must be defined even if they are not use
> 
> 
> The config files
> -----------------
> build.cfg:
> -----------
> This is file contains the default BIOS build configuration.
> 
> The default configurations are defined under the "DEFAULT_CONFIG" section
> of the file.
> Each of these can be overridden by the board specific setting as defined in
> the board's build config file. All paths must be separated by forward slashes.
> All the paths in the main build.cfg are relative to the minplaform
> WORKSPACE.
> Example:
> --------
> [DEFAULT_CONFIG]
>     MIN_PACKAGE_TOOLS = edk2-
> platforms/Platform/Intel/MinPlatformPkg/Tools
> 
> The PLATFORMS field in the build.cfg file informs build_bios.py about the
> available platforms that can be built with the build_bios.py.
> The path to the board specific config file must be relative to location of
> build_bios.py, Platform/Intel. It is in the format Boardname = BoardPath
> 
> Example:
> --------
> [PLATFORMS]
>     KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> 
> 
> Board Specific Build Settings file:
> ----------------------------------------
> This file is located in the board's main directory.
> The CONFIG field contains all the build enviroment variables.
> These values will override any the were specific under DEFAULT_CONFIG in
> the default build.cfg file.
> Example is Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> 
> 
> Building BIOS
> -------------
> 
> python build_bios.py -p BOARDNAME -t TOOLCHAIN
> 
> usage: build_bios.py [-h] --platform
> {N1xxWU,KabylakeRvp3,BoardMtOlympus}
>                     [--toolchain TOOLCHAIN] [--DEBUG] [--RELEASE]
>                     [--TEST_RELEASE] [--RELEASE_PDB] [--list] [--cleanall]
>                     [--capsule] [--silent] [--performance] [--fsp] Build Help
> 
> optional arguments:
>   -h, --help            show this help message and exit
>   --platform {N1xxWU,KabylakeRvp3,BoardMtOlympus}, -p
> {N1xxWU,KabylakeRvp3,BoardMtOlympus}
>                         the platform to build
>   --toolchain TOOLCHAIN, -t TOOLCHAIN
>                         using the Tool Chain Tagname to build the
>                         platform, overriding target.txt's TOOL_CHAIN_TAG
>                         definition
>   --DEBUG, -d           debug flag
>   --RELEASE, -r         release flag
>   --TEST_RELEASE, -tr   test release flag
>   --RELEASE_PDB, -rp    release flag
>   --list, -l            lists available platforms
>   --cleanall            cleans all
>   --clean               cleans specific platform
>   --capsule             capsule build enabled
>   --silent              silent build enabled
>   --performance         performance build enabled
>   --fsp                 fsp build enabled
> 
> Agyeman (2):
>   Platform/Intel: Added python build script.
>   Updated the build instructions to include the python script build
>     instructions
> 
>  .../ClevoOpenBoardPkg/N1xxWU/build_config.cfg |  33 +
>  .../KabylakeRvp3/build_board.py               |  68 ++
>  .../KabylakeRvp3/build_config.cfg             |  34 +
>  .../BoardMtOlympus/build_board.py             | 177 ++++
>  .../BoardMtOlympus/build_config.cfg           |  32 +
>  Platform/Intel/build.cfg                      |  56 +
>  Platform/Intel/build_bios.py                  | 976 ++++++++++++++++++
>  ReadMe.md                                     |  76 ++
>  8 files changed, 1452 insertions(+)
>  create mode 100644
> Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
>  create mode 100644
> Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
>  create mode 100644
> Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
>  create mode 100644
> Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
>  create mode 100644
> Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
>  create mode 100644 Platform/Intel/build.cfg  create mode 100644
> Platform/Intel/build_bios.py
> 
> --
> 2.19.1.windows.1
> 
> 
> 


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

* Re: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added python build script.
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added " Agyeman, Prince
  2019-05-04  0:36   ` [edk2-devel] " Nate DeSimone
@ 2019-05-04  2:14   ` Kubacki, Michael A
  1 sibling, 0 replies; 9+ messages in thread
From: Kubacki, Michael A @ 2019-05-04  2:14 UTC (permalink / raw)
  To: devel@edk2.groups.io, Agyeman, Prince
  Cc: Desimone, Nathaniel L, Sinha, Ankit, Kinney, Michael D,
	Oram, Isaac W, Gao, Liming, Zhou, Bowen, Lu, Shifei A

Reviewed-by: Michael Kubacki <michael.a.kubacki@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Agyeman, Prince
> Sent: Friday, May 3, 2019 4:19 PM
> To: devel@edk2.groups.io
> Cc: Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>;
> Oram, Isaac W <isaac.w.oram@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Zhou, Bowen <bowen.zhou@intel.com>; Lu, Shifei
> A <shifei.a.lu@intel.com>
> Subject: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2]
> Platform/Intel: Added python build script.
> 
> This change allows building all the platforms in Platform/Intel with
> a single python script. This script works with python 2.7
> and python 3.7
> 
> Files Added:
> 
> * build_bios.py: the main build script
>   build.cfg: contains general/default build settings
> * ClevoOpenBoardPkg/N1xxWU/build_config.cfg: contains N1xxWU specific
>   build settings
> * KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py : contains sample
>   custom build script
> * KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg: contains
>   KabylakeRvp3 build settings
> * PurleyOpenBoardPkg/BoardMtOlympus/build_board.py: contains
>   BoardMtOlympus custom build script
> * PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg: contains
>   BoardMtOlympus custom build settings
> 
> Cc: Michael Kubacki <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Isaac W Oram <isaac.w.oram@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Bowen Zhou<bowen.zhou@intel.com>
> Cc: Shifei A Lu <shifei.a.lu@intel.com>
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Agyeman <prince.agyeman@intel.com>
> ---
>  .../ClevoOpenBoardPkg/N1xxWU/build_config.cfg |  33 +
>  .../KabylakeRvp3/build_board.py               |  68 ++
>  .../KabylakeRvp3/build_config.cfg             |  34 +
>  .../BoardMtOlympus/build_board.py             | 177 ++++
>  .../BoardMtOlympus/build_config.cfg           |  32 +
>  Platform/Intel/build.cfg                      |  56 +
>  Platform/Intel/build_bios.py                  | 976 ++++++++++++++++++
>  7 files changed, 1376 insertions(+)
>  create mode 100644
> Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
>  create mode 100644
> Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
>  create mode 100644
> Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
>  create mode 100644
> Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
>  create mode 100644
> Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
>  create mode 100644 Platform/Intel/build.cfg
>  create mode 100644 Platform/Intel/build_bios.py
> 
> diff --git a/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> new file mode 100644
> index 0000000000..ee1261e700
> --- /dev/null
> +++ b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> @@ -0,0 +1,33 @@
> +# @ build_config.cfg
> +# This is the N1xxWU board specific build settings
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +
> +[CONFIG]
> +WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
> +EDK_SETUP_OPTION =
> +openssl_path =
> +PLATFORM_BOARD_PACKAGE = ClevoOpenBoardPkg
> +PROJECT = ClevoOpenBoardPkg/N1xxWU
> +BOARD = N1xxWU
> +FLASH_MAP_FDF =
> ClevoOpenBoardPkg/N1xxWU/Include/Fdf/FlashMapInclude.fdf
> +PROJECT_DSC = ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc
> +BOARD_PKG_PCD_DSC =
> ClevoOpenBoardPkg/N1xxWU/OpenBoardPkgPcd.dsc
> +PrepRELEASE = DEBUG
> +SILENT_MODE = FALSE
> +EXT_CONFIG_CLEAR =
> +CapsuleBuild = FALSE
> +EXT_BUILD_FLAGS =
> +CAPSULE_BUILD = 0
> +TARGET = DEBUG
> +TARGET_SHORT = D
> +PERFORMANCE_BUILD = FALSE
> +FSP_WRAPPER_BUILD = TRUE
> +FSP_BIN_PKG = KabylakeFspBinPkg
> +FSP_PKG_NAME = KabylakeFspPkg
> +FSP_BINARY_BUILD = FALSE
> +FSP_TEST_RELEASE = FALSE
> +SECURE_BOOT_ENABLE = FALSE
> diff --git
> a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
> b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
> new file mode 100644
> index 0000000000..726ad85874
> --- /dev/null
> +++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
> @@ -0,0 +1,68 @@
> +# @ build_board.py
> +# This is a sample code provides Optional dynamic imports
> +# of build functions to the BuildBios.py script
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +"""
> +This module serves as a sample implementation of the build extension
> +scripts
> +"""
> +
> +
> +def pre_build_ex(config, functions):
> +    """Additional Pre BIOS build function
> +
> +    :param config: The environment variables to be used in the build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: nothing
> +    """
> +    print("pre_build_ex")
> +    return None
> +
> +
> +def build_ex(config, functions):
> +    """Additional BIOS build function
> +
> +    :param config: The environment variables to be used in the build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: config dictionary
> +    :rtype: Dictionary
> +    """
> +    print("build_ex")
> +    return None
> +
> +
> +def post_build_ex(config, functions):
> +    """Additional Post BIOS build function
> +
> +    :param config: The environment variables to be used in the post
> +        build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: config dictionary
> +    :rtype: Dictionary
> +    """
> +    print("post_build_ex")
> +    return None
> +
> +
> +def clean_ex(config, functions):
> +    """Additional clean function
> +
> +    :param config: The environment variables to be used in the build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: config dictionary
> +    :rtype: Dictionary
> +    """
> +    print("clean_ex")
> +    return None
> diff --git
> a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> new file mode 100644
> index 0000000000..5ea61dceb8
> --- /dev/null
> +++
> b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> @@ -0,0 +1,34 @@
> +# @ build_config.cfg
> +# This is the KabylakeRvp3 board specific build settings
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +
> +[CONFIG]
> +WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
> +EDK_SETUP_OPTION =
> +openssl_path =
> +PLATFORM_BOARD_PACKAGE = KabylakeOpenBoardPkg
> +PROJECT = KabylakeOpenBoardPkg/KabylakeRvp3
> +BOARD = KabylakeRvp3
> +FLASH_MAP_FDF =
> KabylakeOpenBoardPkg/Include/Fdf/FlashMapInclude.fdf
> +PROJECT_DSC = KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc
> +BOARD_PKG_PCD_DSC =
> KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc
> +ADDITIONAL_SCRIPTS =
> KabylakeOpenBoardPkg/KabylakeRvp3/build_board.py
> +PrepRELEASE = DEBUG
> +SILENT_MODE = FALSE
> +EXT_CONFIG_CLEAR =
> +CapsuleBuild = FALSE
> +EXT_BUILD_FLAGS =
> +CAPSULE_BUILD = 0
> +TARGET = DEBUG
> +TARGET_SHORT = D
> +PERFORMANCE_BUILD = FALSE
> +FSP_WRAPPER_BUILD = TRUE
> +FSP_BIN_PKG = KabylakeFspBinPkg
> +FSP_PKG_NAME = KabylakeFspPkg
> +FSP_BINARY_BUILD = FALSE
> +FSP_TEST_RELEASE = FALSE
> +SECURE_BOOT_ENABLE = FALSE
> diff --git
> a/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
> b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
> new file mode 100644
> index 0000000000..0dda929a00
> --- /dev/null
> +++ b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
> @@ -0,0 +1,177 @@
> +# @ build_board.py
> +# This adds additional functions to the build_bios.py
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +"""
> +This module serves as an additional build steps for the Mt Olympus board
> +"""
> +
> +import os
> +import sys
> +
> +
> +def pre_build_ex(config, functions):
> +    """Additional Pre BIOS build function
> +
> +    :param config: The environment variables to be used in the build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: nothing
> +    """
> +    print("Info: re-generating PlatformOffset header files")
> +
> +    execute_script = functions.get("execute_script")
> +
> +    command = ["build", "-D", "MAX_SOCKET=" + config.get("MAX_SOCKET",
> "1"),
> +               "-m",
> +               os.path.join(config["PLATFORM_BOARD_PACKAGE"],
> +                            "Acpi", "BoardAcpiDxe", "Dsdt.inf"),
> +               "-y",
> +               config.get("PRE_BUILD_REPORT",
> +                          os.path.join(config["WORKSPACE"],
> +                                       "preBuildReport.txt")),
> +               "--log=" + config.get("PRE_BUILD_LOG",
> +                                     os.path.join(config["WORKSPACE"],
> +                                                  "prebuild.log"))]
> +
> +    _, _, _, code = execute_script(command, config)
> +    if code != 0:
> +        print(" ".join(command))
> +        print("Error re-generating PlatformOffset header files")
> +        sys.exit(1)
> +
> +    config["AML_FILTER"] = "\"PSYS\" .MCTL\" .FIX[0-9,A-Z]\""
> +    print("AML_FILTER= ", config.get("AML_FILTER"))
> +
> +    # build the command with arguments
> +    command = ["python",
> +               os.path.join(config["MIN_PACKAGE_TOOLS"],
> +                            "AmlGenOffset",
> +                            "AmlGenOffset.py"),
> +               "-d", "--aml_filter", config["AML_FILTER"],
> +               "-o", os.path.join(config["WORKSPACE_PLATFORM"],
> +                                  config["PLATFORM_BOARD_PACKAGE"],
> +                                  "Acpi", "BoardAcpiDxe",
> +                                  "AmlOffsetTable.c"),
> +               os.path.join(config["BUILD_X64"],
> +                            "PurleyOpenBoardPkg",
> +                            "Acpi",
> +                            "BoardAcpiDxe",
> +                            "DSDT",
> +                            "OUTPUT",
> +                            "Dsdt", "WFPPlatform.offset.h")]
> +
> +    # execute the command
> +    _, _, _, code = execute_script(command, config)
> +    if code != 0:
> +        print(" ".join(command))
> +        print("Error re-generating PlatformOffset header files")
> +        sys.exit(1)
> +
> +    print("GenOffset done")
> +    return config
> +
> +
> +def build_ex(config, functions):
> +    """Additional BIOS build function
> +
> +    :param config: The environment variables to be used in
> +    the build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: config dictionary
> +    :rtype: Dictionary
> +    """
> +    print("build_ex")
> +    return None
> +
> +
> +def post_build_ex(config, functions):
> +    """Additional Post BIOS build function
> +
> +    :param config: The environment variables to be used in the post
> +        build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: config dictionary
> +    :rtype: Dictionary
> +    """
> +    print("post_build_ex")
> +
> +    execute_script = functions.get("execute_script")
> +
> +    if not execute_script:
> +        print("post_build_ex Error")
> +        sys.exit(1)
> +
> +    common_patch_command = [os.path.join(config["PYTHON_HOME"],
> "python"),
> +                            os.path.join(config["MIN_PACKAGE_TOOLS"],
> +                                         "PatchFv", "PatchBinFv.py"),
> +                            config["TARGET"],
> +                            os.path.join(config["WORKSPACE_SILICON_BIN"],
> +                                         "PurleySiliconBinPkg"),
> +                            os.path.join(config["WORKSPACE"],
> +                                         "BuildReport.log")]
> +
> +    fvs_to_patch = ["FvTempMemorySilicon",
> +                    "FvPreMemorySilicon",
> +                    "FvPostMemorySilicon",
> +                    "FvLateSilicon"]
> +    for fv in fvs_to_patch:
> +        patch_command = common_patch_command + [fv]
> +        _, _, _, code = execute_script(patch_command, config)
> +        if code != 0:
> +            print(" ".join(patch_command))
> +            print("Patch Error!")
> +            sys.exit(1)
> +
> +    common_rebase_command = [os.path.join(config["PYTHON_HOME"],
> "python"),
> +                             os.path.join(config["MIN_PACKAGE_TOOLS"],
> +                                          "PatchFv", "RebaseBinFv.py"),
> +                             config["TARGET"],
> +                             os.path.join(config["WORKSPACE_SILICON_BIN"],
> +                                          "PurleySiliconBinPkg"),
> +                             os.path.join(config["WORKSPACE"],
> +                                          "BuildReport.log")]
> +
> +    rebase_command = common_rebase_command +\
> +        ["FvPreMemorySilicon",
> +         "gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspMBase"]
> +
> +    _, _, _, code = execute_script(rebase_command, config)
> +    if code != 0:
> +        print(" ".join(rebase_command))
> +        print("Patch Error!")
> +        sys.exit(1)
> +
> +    rebase_command = common_rebase_command +\
> +        ["FvPostMemorySilicon",
> +         "gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspSBase"]
> +
> +    _, _, _, code = execute_script(rebase_command, config)
> +    if code != 0:
> +        print(" ".join(rebase_command))
> +        print("Patch Error!")
> +        sys.exit(1)
> +
> +    return None
> +
> +
> +def clean_ex(config, functions):
> +    """Additional clean function
> +
> +    :param config: The environment variables to be used in the build process
> +    :type config: Dictionary
> +    :param functions: A dictionary of function pointers
> +    :type functions: Dictionary
> +    :returns: config dictionary
> +    :rtype: Dictionary
> +    """
> +    print("clean_ex")
> +    return None
> diff --git
> a/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> new file mode 100644
> index 0000000000..dcf19d658d
> --- /dev/null
> +++
> b/Platform/Intel/PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> @@ -0,0 +1,32 @@
> +# @ build_config.cfg
> +# This is the main/default build configuration file
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +
> +[CONFIG]
> +WORKSPACE_PLATFORM_BIN = WORKSPACE_PLATFORM_BIN
> +EDK_SETUP_OPTION =
> +openssl_path =
> +PLATFORM_BOARD_PACKAGE = PurleyOpenBoardPkg
> +PROJECT = PurleyOpenBoardPkg/BoardMtOlympus
> +BOARD = BoardMtOlympus
> +FLASH_MAP_FDF = PurleyOpenBoardPkg/Include/Fdf/FlashMapInclude.fdf
> +PROJECT_DSC = PurleyOpenBoardPkg/BoardMtOlympus/PlatformPkg.dsc
> +BOARD_PKG_PCD_DSC =
> PurleyOpenBoardPkg/BoardMtOlympus/PlatformPkgPcd.dsc
> +ADDITIONAL_SCRIPTS =
> PurleyOpenBoardPkg/BoardMtOlympus/build_board.py
> +PRE_BUILD_LOG = prebuild.log
> +PRE_BUILD_REPORT = prebuildReport.log
> +PrepRELEASE = DEBUG
> +SILENT_MODE = FALSE
> +EXT_CONFIG_CLEAR =
> +CapsuleBuild = FALSE
> +EXT_BUILD_FLAGS =
> +CAPSULE_BUILD = 0
> +TARGET = DEBUG
> +TARGET_SHORT = D
> +PERFORMANCE_BUILD = FALSE
> +FSP_WRAPPER_BUILD = FALSE
> +MAX_SOCKET = 2
> diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg
> new file mode 100644
> index 0000000000..b6c0cca4f7
> --- /dev/null
> +++ b/Platform/Intel/build.cfg
> @@ -0,0 +1,56 @@
> +# @ build.cfg
> +# This is the main/default build configuration file
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +
> +[DEFAULT_CONFIG]
> +WORKSPACE =
> +WORKSPACE_FSP_BIN = FSP
> +EDK_TOOLS_BIN = edk2-BaseTools-win32
> +EDK_BASETOOLS = BaseTools
> +WORKSPACE_PLATFORM = edk2-platforms/Platform/Intel
> +WORKSPACE_SILICON = edk2-platforms/Silicon/Intel
> +WORKSPACE_PLATFORM_BIN =
> +WORKSPACE_SILICON_BIN = edk2-non-osi/Silicon/Intel
> +MIN_PACKAGE_TOOLS = edk2-
> platforms/Platform/Intel/MinPlatformPkg/Tools
> +PACKAGES_PATH =
> +EDK_SETUP_OPTION =
> +BASE_TOOLS_PATH = edk2/BaseTools
> +EDK_TOOLS_PATH = edk2/BaseTools
> +openssl_path =
> +PLATFORM_BOARD_PACKAGE =
> +BIOS_SIZE_OPTION = -DBIOS_SIZE_OPTION=SIZE_70
> +WORKSPACE_CORE = edk2
> +EFI_SOURCE = edk2
> +PATHEXT = .COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
> +PROMPT = $P$G
> +PLATFORM_PACKAGE = MinPlatformPkg
> +BOARD =
> +PrepRELEASE = DEBUG
> +SILENT_MODE = FALSE
> +EXT_CONFIG_CLEAR =
> +CapsuleBuild = FALSE
> +EXT_BUILD_FLAGS =
> +CAPSULE_BUILD = 0
> +TARGET = DEBUG
> +TARGET_SHORT = D
> +PERFORMANCE_BUILD = FALSE
> +FSP_WRAPPER_BUILD = FALSE
> +FSP_BIN_PKG =
> +FSP_PKG_NAME =
> +FSP_BINARY_BUILD = FALSE
> +FSP_TEST_RELEASE = FALSE
> +SECURE_BOOT_ENABLE = FALSE
> +REBUILD_MODE =
> +BUILD_ROM_ONLY =
> +NUMBER_OF_PROCESSORS = 1
> +
> +
> +[PLATFORMS]
> +# board_name = path_to_board_build_config.cfg
> +KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> +N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> +BoardMtOlympus =
> PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> diff --git a/Platform/Intel/build_bios.py b/Platform/Intel/build_bios.py
> new file mode 100644
> index 0000000000..2edf340e0c
> --- /dev/null
> +++ b/Platform/Intel/build_bios.py
> @@ -0,0 +1,976 @@
> +
> +# @ build_bios.py
> +# Builds BIOS using configuration files and dynamically
> +# imported functions from board directory
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +
> +"""
> +This module builds BIOS using configuration files and dynamically
> +imported functions from board directory
> +"""
> +
> +
> +import os
> +import re
> +import sys
> +import signal
> +import shutil
> +import argparse
> +import traceback
> +import subprocess
> +from importlib import import_module
> +
> +try:
> +    # python 2.7
> +    import ConfigParser as configparser
> +except ImportError:
> +    # python 3
> +    import configparser
> +
> +
> +def pre_build(build_config, build_type="DEBUG", silent=False,
> toolchain=None):
> +    """Sets the environment variables that shall be used for the build
> +
> +        :param build_config: The build configuration as defined in the JOSN
> +            configuration files
> +        :type build_config: Dictionary
> +        :param build_type: The build target, DEBUG, RELEASE, RELEASE_PDB,
> +            TEST_RELEASE
> +        :type build_type: String
> +        :param silent: Enables build in silent mode
> +        :type silent: Boolean
> +        :param toolchain: Specifies the tool chain tag to use for the build
> +        :type toolchain: String
> +        :returns: The updated environment variables
> +        :rtype: Dictionary
> +    """
> +
> +    # get current environment variables
> +    config = os.environ.copy()
> +
> +    # patch the build config
> +    build_config = patch_config(build_config)
> +
> +    # update the current config with the build config
> +    config.update(build_config)
> +
> +    # make the config and build python 2.7 compartible
> +    config = py_27_fix(config)
> +
> +    # Set WORKSPACE environment.
> +    config["WORKSPACE"] = os.path.abspath(os.path.join("..", "..", "..", ""))
> +    print("Set WORKSPACE as: {}".format(config["WORKSPACE"]))
> +
> +    # Check whether Git has been installed and been added to system path.
> +    try:
> +        subprocess.Popen(["git", "--help"], stdout=subprocess.PIPE)
> +    except OSError:
> +        print("The 'git' command is not recognized.")
> +        print("Please make sure that Git is installed\
> +                and has been added to system path.")
> +        sys.exit(1)
> +
> +    # Create the Conf directory under WORKSPACE
> +    if not os.path.isdir(os.path.join(config["WORKSPACE"], "Conf")):
> +        try:
> +            # create directory
> +            os.makedirs(os.path.join(config["WORKSPACE"], "Conf"))
> +            # copy files to it
> +            config_template_path = os.path.join(config["WORKSPACE"],
> +                                                config["BASE_TOOLS_PATH"],
> +                                                "Conf")
> +            config_path = os.path.join(config["WORKSPACE"], "Conf")
> +            shutil.copyfile(config_template_path +
> +                            os.sep + "target.template",
> +                            config_path + os.sep + "target.txt")
> +            shutil.copyfile(config_template_path +
> +                            os.sep + "tools_def.template",
> +                            config_path + os.sep + "tools_def.txt")
> +            shutil.copyfile(config_template_path +
> +                            os.sep + "build_rule.template",
> +                            config_path + os.sep + "build_rule.txt")
> +        except OSError:
> +            print("Error while creating Conf")
> +            sys.exit(1)
> +
> +    # Set other environments.
> +    # Basic Rule:
> +    # Platform override Silicon override Core
> +    # Source override Binary
> +    config["WORKSPACE_PLATFORM"] = os.path.join(config["WORKSPACE"],
> +                                                config["WORKSPACE_PLATFORM"])
> +    config["WORKSPACE_SILICON"] = os.path.join(config["WORKSPACE"],
> +                                               config["WORKSPACE_SILICON"])
> +    config["WORKSPACE_PLATFORM_BIN"] = \
> +        os.path.join(config["WORKSPACE"],
> config["WORKSPACE_PLATFORM_BIN"])
> +    config["WORKSPACE_SILICON_BIN"] = \
> +        os.path.join(config["WORKSPACE"],
> config["WORKSPACE_SILICON_BIN"])
> +    config["WORKSPACE_FSP_BIN"] = os.path.join(config["WORKSPACE"],
> +                                               config["WORKSPACE_FSP_BIN"])
> +
> +    # add to package path
> +    config["PACKAGES_PATH"] = config["WORKSPACE_PLATFORM"]
> +    config["PACKAGES_PATH"] += os.pathsep +
> config["WORKSPACE_SILICON"]
> +    config["PACKAGES_PATH"] += os.pathsep +
> config["WORKSPACE_SILICON_BIN"]
> +    config["PACKAGES_PATH"] += os.pathsep + \
> +        os.path.join(config["WORKSPACE"], "FSP")
> +    config["PACKAGES_PATH"] += os.pathsep + \
> +        os.path.join(config["WORKSPACE"], "edk2")
> +    config["PACKAGES_PATH"] += os.pathsep +
> os.path.join(config["WORKSPACE"])
> +    config["EDK_TOOLS_PATH"] = os.path.join(config["WORKSPACE"],
> +                                            config["EDK_TOOLS_PATH"])
> +    config["BASE_TOOLS_PATH"] = config["EDK_TOOLS_PATH"]
> +    config["EDK_TOOLS_BIN"] = os.path.join(config["WORKSPACE"],
> +                                           config["EDK_TOOLS_BIN"])
> +    config["PLATFORM_FSP_BIN_PACKAGE"] = \
> +        os.path.join(config['WORKSPACE_FSP_BIN'], config['FSP_BIN_PKG'])
> +    config['PROJECT_DSC'] = os.path.join(config["WORKSPACE_PLATFORM"],
> +                                         config['PROJECT_DSC'])
> +    config['BOARD_PKG_PCD_DSC'] =
> os.path.join(config["WORKSPACE_PLATFORM"],
> +                                               config['BOARD_PKG_PCD_DSC'])
> +    config["CONF_PATH"] = os.path.join(config["WORKSPACE"], "Conf")
> +
> +    # get the python path
> +    if os.environ.get("PYTHON_HOME") is None:
> +        config["PYTHON_HOME"] = None
> +        if os.environ.get("PYTHONPATH") is not None:
> +            config["PYTHON_HOME"] = os.environ.get("PYTHONPATH")
> +        else:
> +            print("PYTHONPATH environment variable is not found")
> +            sys.exit(1)
> +
> +    # if python is installed, disable the binary base tools.
> +    # python is installed if this code is running :)
> +    if config.get("PYTHON_HOME") is not None:
> +        if config.get("EDK_TOOLS_BIN") is not None:
> +            del config["EDK_TOOLS_BIN"]
> +
> +    # Run edk setup and  update config
> +    if os.name == 'nt':
> +        edk2_setup_cmd = [os.path.join(config["EFI_SOURCE"], "edksetup"),
> +                        "Rebuild"]
> +
> +        if config.get("EDK_SETUP_OPTION") and \
> +        config["EDK_SETUP_OPTION"] != " ":
> +            edk2_setup_cmd.append(config["EDK_SETUP_OPTION"])
> +
> +        _, _, result, return_code = execute_script(edk2_setup_cmd,
> +                                                config,
> +                                                collect_env=True,
> +                                                shell=True)
> +        if return_code == 0 and result is not None and isinstance(result,
> +                                                                dict):
> +            config.update(result)
> +
> +    # nmake BaseTools source
> +    # and enable BaseTools source build
> +    shell = True
> +    command = ["nmake", "-f", os.path.join(config["BASE_TOOLS_PATH"],
> +                                           "Makefile")]
> +    if os.name == "posix":  # linux
> +        shell = False
> +        command = ["make", "-C", os.path.join(config["BASE_TOOLS_PATH"])]
> +
> +    _, _, result, return_code = execute_script(command, config, shell=shell)
> +    if return_code != 0:
> +        build_failed(config)
> +
> +    config["SILENT_MODE"] = 'TRUE' if silent else 'FALSE'
> +
> +    print("==============================================")
> +
> +    if os.path.isfile(os.path.join(config['WORKSPACE'], "Prep.log")):
> +        os.remove(os.path.join(config['WORKSPACE'], "Prep.log"))
> +
> +    config["PROJECT"] =
> os.path.join(config["PLATFORM_BOARD_PACKAGE"],
> +                                     config["BOARD"])
> +
> +    # Setup Build
> +    # @todo: Need better TOOL_CHAIN_TAG detection
> +    if toolchain is not None:
> +        config["TOOL_CHAIN_TAG"] = toolchain
> +    elif config.get("TOOL_CHAIN_TAG") is None:
> +        if os.name == 'nt':
> +            config["TOOL_CHAIN_TAG"] = "VS2015"
> +        else:
> +            config["TOOL_CHAIN_TAG"] = "GCC5"
> +
> +    # echo Show CL revision
> +    config["PrepRELEASE"] = build_type
> +
> +    if build_type == "DEBUG":
> +        config["TARGET"] = 'DEBUG'
> +        config["TARGET_SHORT"] = 'D'
> +    else:
> +        config["TARGET"] = 'RELEASE'
> +        config["TARGET_SHORT"] = 'R'
> +
> +    # set BUILD_DIR_PATH path
> +    config["BUILD_DIR_PATH"] = os.path.join(config["WORKSPACE"],
> +                                            'Build',
> +                                            config["PROJECT"],
> +                                            "{}_{}".format(
> +                                                config["TARGET"],
> +                                                config["TOOL_CHAIN_TAG"]))
> +    # set BUILD_DIR path
> +    config["BUILD_DIR"] = os.path.join('Build',
> +                                       config["PROJECT"],
> +                                       "{}_{}".format(
> +                                           config["TARGET"],
> +                                           config["TOOL_CHAIN_TAG"]))
> +
> +    config["BUILD_X64"] = os.path.join(config["BUILD_DIR_PATH"], 'X64')
> +    config["BUILD_IA32"] = os.path.join(config["BUILD_DIR_PATH"], 'IA32')
> +
> +    if not os.path.isdir(config["BUILD_DIR_PATH"]):
> +        try:
> +            os.makedirs(config["BUILD_DIR_PATH"])
> +        except OSError:
> +            print("Error while creating Build folder")
> +            sys.exit(1)
> +
> +    # Set FSP_WRAPPER_BUILD
> +    if config['FSP_WRAPPER_BUILD'] == "TRUE":
> +        # Create dummy Fsp_Rebased_S_padded.fd to build the BiosInfo.inf
> +        # if it is wrapper build, due to the SECTION inclusion
> +        open(os.path.join(config["WORKSPACE_FSP_BIN"],
> +                          config["FSP_BIN_PKG"],
> +                          "Fsp_Rebased_S_padded.fd"), 'w').close()
> +
> +    if not os.path.isdir(config["BUILD_X64"]):
> +        try:
> +            os.mkdir(config["BUILD_X64"])
> +        except OSError:
> +            print("Error while creating {}".format(config["BUILD_X64"]))
> +            sys.exit(1)
> +
> +    # update config file with changes
> +    update_target_file(config)
> +
> +    # Additional pre build scripts for this platform
> +    result = pre_build_ex(config)
> +    if result is not None and isinstance(result, dict):
> +        config.update(result)
> +
> +    # print user settings
> +    print("BIOS_SIZE_OPTION     = {}".format(config["BIOS_SIZE_OPTION"]))
> +    print("EFI_SOURCE           = {}".format(config["EFI_SOURCE"]))
> +    print("TARGET               = {}".format(config["TARGET"]))
> +    print("TARGET_ARCH          = {}".format("IA32 X64"))
> +    print("TOOL_CHAIN_TAG       = {}".format(config["TOOL_CHAIN_TAG"]))
> +    print("WORKSPACE            = {}".format(config["WORKSPACE"]))
> +    print("WORKSPACE_CORE       = {}".format(config["WORKSPACE_CORE"]))
> +    print("EXT_BUILD_FLAGS      = {}".format(config["EXT_BUILD_FLAGS"]))
> +
> +    return config
> +
> +
> +def build(config):
> +    """Builds the BIOS image
> +
> +        :param config: The environment variables to be used
> +            in the build process
> +        :type config: Dictionary
> +        :returns: nothing
> +    """
> +
> +    if config["FSP_WRAPPER_BUILD"] == "TRUE":
> +        pattern = "Fsp_Rebased.*\\.fd$"
> +        file_dir = os.path.join(config['WORKSPACE_FSP_BIN'],
> +                                config['FSP_BIN_PKG'])
> +        for item in os.listdir(file_dir):
> +            if re.search(pattern, item):
> +                os.remove(os.path.join(file_dir, item))
> +
> +        command = [os.path.join(config['PYTHON_HOME'], "python"),
> +                   os.path.join(config['WORKSPACE_PLATFORM'],
> +                                config['PLATFORM_PACKAGE'],
> +                                'Tools', 'Fsp',
> +                                'RebaseAndPatchFspBinBaseAddress.py'),
> +                   os.path.join(config['WORKSPACE_PLATFORM'],
> +                                config['FLASH_MAP_FDF']),
> +                   os.path.join(config['WORKSPACE_FSP_BIN'],
> +                                config['FSP_BIN_PKG']),
> +                   "Fsp.fd",
> +                   os.path.join(config['WORKSPACE_PLATFORM'],
> +                                config['PROJECT'],
> +                                config['BOARD_PKG_PCD_DSC']),
> +                   "0x0"]
> +
> +        _, _, _, return_code = execute_script(command, config, shell=False)
> +
> +        if return_code != 0:
> +            print("ERROR:RebaseAndPatchFspBinBaseAddress failed")
> +            sys.exit(return_code)
> +
> +        # create Fsp_Rebased.fd which is Fsp_Rebased_S.fd +
> +        # Fsp_Rebased_M + Fsp_Rebased_T
> +        with open(os.path.join(file_dir, "Fsp_Rebased_S.fd"), 'rb') as fsp_s, \
> +                open(os.path.join(file_dir,
> +                                  "Fsp_Rebased_M.fd"), 'rb') as fsp_m, \
> +                open(os.path.join(file_dir,
> +                                  "Fsp_Rebased_T.fd"), 'rb') as fsp_t:
> +
> +            fsp_rebased = fsp_s.read() + fsp_m.read() + fsp_t.read()
> +            with open(os.path.join(file_dir,
> +                                   "Fsp_Rebased.fd"), 'wb') as new_fsp:
> +                new_fsp.write(fsp_rebased)
> +
> +        if not os.path.isfile(os.path.join(file_dir, "Fsp_Rebased.fd")):
> +            print("!!! ERROR:failed to create fsp!!!")
> +            sys.exit(1)
> +
> +    # Output the build variables the user has selected.
> +    print("==========================================")
> +    print(" User Selected build options:")
> +    print(" SILENT_MODE    = ", config.get("SILENT_MODE"))
> +    print(" REBUILD_MODE   = ", config.get("REBUILD_MODE"))
> +    print(" BUILD_ROM_ONLY = ", config.get("BUILD_ROM_ONLY"))
> +    print("==========================================")
> +
> +    command = ["build", "-n", config["NUMBER_OF_PROCESSORS"]]
> +
> +    if config["REBUILD_MODE"] and config["REBUILD_MODE"] != "":
> +        command.append(config["REBUILD_MODE"])
> +
> +    if config["EXT_BUILD_FLAGS"] and config["EXT_BUILD_FLAGS"] != "":
> +        command.append(config["EXT_BUILD_FLAGS"])
> +
> +    if config.get("SILENT_MODE", "FALSE") == "TRUE":
> +        command.append("--silent")
> +        command.append("--quiet")
> +
> +    else:
> +        command.append("--log=" + config.get("BUILD_LOG", "Build.log"))
> +        command.append("--report-file=" +
> +                       config.get("BUILD_REPORT", "BuildReport.log"))
> +
> +    if config.get("VERBOSE", "FALSE") == "TRUE":
> +        command.append("--verbose")
> +
> +    if config.get("MAX_SOCKET") is not None:
> +        command.append("-D")
> +        command.append("MAX_SOCKET=" + config["MAX_SOCKET"])
> +
> +    _, _, _, exit_code = execute_script(command, config)
> +    if exit_code != 0:
> +        build_failed(config)
> +
> +    # Additional build scripts for this platform
> +    result = build_ex(config)
> +    if result is not None and isinstance(result, dict):
> +        config.update(result)
> +
> +    return config
> +
> +
> +def post_build(config):
> +    """Post build process of BIOS image
> +
> +    :param config: The environment variables to be used in the build process
> +    :type config: Dictionary
> +    :returns: nothing
> +    """
> +    print("Running post_build to complete the build process.")
> +
> +    # Additional build scripts for this platform
> +    result = post_build_ex(config)
> +    if result is not None and isinstance(result, dict):
> +        config.update(result)
> +
> +    # cleanup
> +    pattern = "Fsp_Rebased.*\\.fd$"
> +    file_dir = os.path.join(config['WORKSPACE_FSP_BIN'],
> +                            config['FSP_BIN_PKG'])
> +    for item in os.listdir(file_dir):
> +        if re.search(pattern, item):
> +            os.remove(os.path.join(file_dir, item))
> +
> +    if config.get("DYNAMIC_BUILD_INIT_FILES") is not None:
> +        for item in config["DYNAMIC_BUILD_INIT_FILES"].split(","):
> +            try:
> +                os.remove(item)  # remove __init__.py
> +                os.remove(item + "c")  # remove __init__.pyc as well
> +            except OSError:
> +                pass
> +
> +
> +def build_failed(config):
> +    """Displays results when build fails
> +
> +        :param config: The environment variables used in the build process
> +        :type config: Dictionary
> +        :returns: nothing
> +    """
> +    print(" The EDKII BIOS Build has failed!")
> +    # clean up
> +    if config.get("DYNAMIC_BUILD_INIT_FILES") is not None:
> +        for item in config["DYNAMIC_BUILD_INIT_FILES"].split(","):
> +            if os.path.isfile(item):
> +                try:
> +                    os.remove(item)  # remove __init__.py
> +                    os.remove(item + "c")  # remove __init__.pyc as well
> +                except OSError:
> +                    pass
> +    sys.exit(1)
> +
> +
> +def import_platform_lib(path, function):
> +    """Imports custom functions for the platforms being built
> +
> +        :param path: the location of the custom build script to be executed
> +        :type path: String
> +        :param path: the function to be executed
> +        :type path: String
> +        :returns: nothing
> +    """
> +    if path.endswith(".py"):
> +        path = path[:-3]
> +    path = path.replace(os.sep, ".")
> +    module = import_module(path)
> +    lib = getattr(module, function)
> +    return lib
> +
> +
> +def pre_build_ex(config):
> +    """ An extension of the pre_build process as defined platform
> +        specific pre_build setup script
> +
> +        :param config: The environment variables used in the pre build process
> +        :type config: Dictionary
> +        :returns: config dictionary
> +        :rtype: Dictionary
> +    """
> +    if config.get("ADDITIONAL_SCRIPTS"):
> +        try:
> +            platform_function =\
> +                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
> +                                    "pre_build_ex")
> +            functions = {"execute_script": execute_script}
> +            return platform_function(config, functions)
> +        except ImportError as error:
> +            print(config["ADDITIONAL_SCRIPTS"], str(error))
> +            build_failed(config)
> +    return None
> +
> +
> +def build_ex(config):
> +    """ An extension of the build process as defined platform
> +        specific build setup script
> +
> +        :param config: The environment variables used in the build process
> +        :type config: Dictionary
> +        :returns: config dictionary
> +        :rtype: Dictionary
> +    """
> +    if config.get("ADDITIONAL_SCRIPTS"):
> +        try:
> +            platform_function =\
> +                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
> +                                    "build_ex")
> +            functions = {"execute_script": execute_script}
> +            return platform_function(config, functions)
> +        except ImportError as error:
> +            print("error", config["ADDITIONAL_SCRIPTS"], str(error))
> +            build_failed(config)
> +    return None
> +
> +
> +def post_build_ex(config):
> +    """ An extension of the post build process as defined platform
> +        specific build setup script
> +
> +        :param config: The environment variables used in the post build
> +            process
> +        :type config: Dictionary
> +        :returns: config dictionary
> +        :rtype: Dictionary
> +    """
> +    if config.get("ADDITIONAL_SCRIPTS"):
> +        try:
> +            platform_function =\
> +                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
> +                                    "post_build_ex")
> +            functions = {"execute_script": execute_script}
> +            return platform_function(config, functions)
> +        except ImportError as error:
> +            print(config["ADDITIONAL_SCRIPTS"], str(error))
> +            build_failed(config)
> +    return None
> +
> +
> +def clean_ex(config):
> +    """ An extension of the platform cleanning
> +
> +        :param config: The environment variables used in the clean process
> +        :type config: Dictionary
> +        :returns: config dictionary
> +        :rtype: Dictionary
> +    """
> +    if config.get("ADDITIONAL_SCRIPTS"):
> +        try:
> +            platform_function =\
> +                import_platform_lib(config["ADDITIONAL_SCRIPTS"],
> +                                    "clean_ex")
> +            functions = {"execute_script": execute_script}
> +            return platform_function(config, functions)
> +        except ImportError as error:
> +            print(config["ADDITIONAL_SCRIPTS"], str(error))
> +            build_failed(config)
> +    return None
> +
> +
> +def get_environment_variables(std_out_str, marker):
> +    """Gets the environment variables from a process
> +
> +        :param std_out_str: The std_out pipe
> +        :type std_out_str: String
> +        :param marker: A begining and end mark of environment
> +            variables printed to std_out
> +        :type marker: String
> +        :returns: The environment variables read from the process' std_out
> pipe
> +        :rtype: Tuple
> +    """
> +    start_env_update = False
> +    environment_vars = {}
> +    out_put = ""
> +    for line in std_out_str.split("\n"):
> +        if start_env_update and len(line.split("=")) == 2:
> +            key, value = line.split("=")
> +            environment_vars[key] = value
> +        else:
> +            out_put += "\n" + line.replace(marker, "")
> +
> +        if marker in line:
> +            if start_env_update:
> +                start_env_update = False
> +            else:
> +                start_env_update = True
> +    return (out_put, environment_vars)
> +
> +
> +def execute_script(command, env_variables, collect_env=False,
> +                   enable_std_pipe=False, shell=True):
> +    """launches a process that executes a script/shell command passed to it
> +
> +        :param command: The command/script with its commandline
> +            arguments to be executed
> +        :type command:  List:String
> +        :param env_variables: Environment variables passed to the process
> +        :type env_variables: String
> +        :param collect_env: Enables the collection of evironment variables
> +            when process execution is done
> +        :type collect_env: Boolean
> +        :param enable_std_pipe: Enables process out to be piped to
> +        :type enable_std_pipe: String
> +        :returns: a tuple of std_out, stderr , environment variables,
> +            return code
> +        :rtype: Tuple: (std_out, stderr , enVar, return_code)
> +    """
> +
> +    print("Calling " + " ".join(command))
> +
> +    env_marker = '-----env-----'
> +    env = {}
> +    kwarg = {"env": env_variables,
> +             "universal_newlines": True,
> +             "shell": shell,
> +             "cwd": env_variables["WORKSPACE"]}
> +
> +    if enable_std_pipe or collect_env:
> +        kwarg["stdout"] = subprocess.PIPE
> +        kwarg["stderr"] = subprocess.PIPE
> +
> +    # collect environment variables
> +    if collect_env:
> +        # get the binary that prints environment variables based on os
> +        if os.name == 'nt':
> +            get_var_command = "set"
> +        else:
> +            get_var_command = "env"
> +        # modify the command to print the environment variables
> +        if isinstance(command, list):
> +            command += ["&&", "echo", env_marker, "&&",
> +                        get_var_command, "&&", "echo", env_marker]
> +        else:
> +            command += " " + " ".join(["&&", "echo", env_marker,
> +                                       "&&", get_var_command,
> +                                       "&&", "echo", env_marker])
> +
> +    # execute the command
> +    execute = subprocess.Popen(command, **kwarg)
> +    std_out, stderr = execute.communicate()
> +    code = execute.returncode
> +
> +    # wait for process to be done
> +    execute.wait()
> +
> +    # if collect enviroment variables
> +    if collect_env:
> +        # get the new environment variables
> +        std_out, env = get_environment_variables(std_out, env_marker)
> +    return (std_out, stderr, env, code)
> +
> +
> +def patch_config(config):
> +    """ An extension of the platform cleanning
> +
> +        :param config: The environment variables used in the build process
> +        :type config: Dictionary
> +        :returns: config dictionary
> +        :rtype: Dictionary
> +    """
> +    new_config = {}
> +    for key in config:
> +        new_config[str(key)] = str(config[key].replace("/", os.sep))
> +    return new_config
> +
> +
> +def py_27_fix(config):
> +    """  Prepares build for python 2.7 => build
> +        :param config: The environment variables used in the build process
> +        :type config: Dictionary
> +        :returns: config dictionary
> +        :rtype: Dictionary
> +    """
> +    if not sys.version_info > (3, 0):
> +        path_list = []
> +        # create __init__.py in directories in this path
> +        if config.get("ADDITIONAL_SCRIPTS"):
> +            # get the directory
> +            path_to_directory =\
> +                os.path.dirname(config.get("ADDITIONAL_SCRIPTS"))
> +            path = ""
> +            for directories in path_to_directory.split(os.sep):
> +                path += directories + os.sep
> +                init_file = path + os.sep + "__init__.py"
> +                if not os.path.isfile(init_file):
> +                    open(init_file, 'w').close()
> +                    path_list.append(init_file)
> +            config["DYNAMIC_BUILD_INIT_FILES"] = ",".join(path_list)
> +
> +    return config
> +
> +
> +def clean(build_config, board=False):
> +    """Cleans the build workspace
> +
> +        :param config: The environment variables used in the build process
> +        :type config: Dictionary
> +        :param board: This flag specifies specific board clean
> +        :type board: Bool
> +        :returns: nothing
> +    """
> +
> +    # patch the config
> +    build_config = patch_config(build_config)
> +
> +    # get current environment variables
> +    config = os.environ.copy()
> +
> +    # update it with the build variables
> +    config.update(build_config)
> +
> +    if config.get('WORKSPACE') is None or not config.get('WORKSPACE'):
> +        config["WORKSPACE"] =\
> +                os.path.abspath(os.path.join("..", "..", "..", ""))
> +
> +    # build cleanall
> +    print("Cleaning directories...")
> +
> +    if board:
> +        platform_pkg = config.get("PLATFORM_BOARD_PACKAGE", None)
> +        if platform_pkg is None or\
> +            not os.path.isdir(os.path.join(config['WORKSPACE'],
> +                                           "Build", platform_pkg)):
> +            print("Platform package not found")
> +            sys.exit(1)
> +        else:
> +            print("Removing " + os.path.join(config['WORKSPACE'],
> +                                             "Build", platform_pkg))
> +            shutil.rmtree(os.path.join(config['WORKSPACE'],
> +                                       "Build", platform_pkg))
> +
> +    else:
> +        if os.path.isdir(os.path.join(config['WORKSPACE'], "Build")):
> +            print("Removing " + os.path.join(config['WORKSPACE'], "Build"))
> +            shutil.rmtree(os.path.join(config['WORKSPACE'], "Build"))
> +
> +    if os.path.isdir(os.path.join(config['WORKSPACE'], "Conf")):
> +        print("Removing " + os.path.join(config['WORKSPACE'], "Conf"))
> +        shutil.rmtree(os.path.join(config['WORKSPACE'], "Conf"))
> +
> +    print("Cleaning files...")
> +
> +    if os.path.isfile(os.path.join(config['WORKSPACE'],
> +                                   config.get("BUILD_REPORT",
> +                                              "BuildReport.log"))):
> +        print("Removing ", os.path.join(config['WORKSPACE'],
> +                                        config.get("BUILD_REPORT",
> +                                                   "BuildReport.log")))
> +        os.remove(os.path.join(config['WORKSPACE'],
> +                               config.get("BUILD_REPORT", "BuildReport.log")))
> +
> +    print("  All done...")
> +
> +    sys.exit(0)
> +
> +
> +def update_target_file(config):
> +    """Updates Conf's target file that will be used in the build
> +
> +        :param config: The environment variables used in the build process
> +        :type config: Dictionary
> +        :returns: True if update was successful and False if update fails
> +        :rtype: Boolean
> +    """
> +    contents = None
> +    result = False
> +    with open(os.path.join(config["CONF_PATH"], "target.txt"), 'r') as target:
> +        contents = target.readlines()
> +        options_list = ['ACTIVE_PLATFORM', 'TARGET',
> +                        'TARGET_ARCH', 'TOOL_CHAIN_TAG', 'BUILD_RULE_CONF']
> +        modified = []
> +
> +        # remove these options from the config file
> +        for line in contents:
> +            if line.replace(" ", "")[0] != '#' and\
> +             any(opt in line for opt in options_list):
> +                continue
> +            modified.append(line)
> +
> +        # replace with config options provided
> +        string = "{} = {}\n".format("ACTIVE_PLATFORM",
> +                                    os.path.join(
> +                                        config['WORKSPACE_PLATFORM'],
> +                                        config['PLATFORM_BOARD_PACKAGE'],
> +                                        config['BOARD'],
> +                                        config['PROJECT_DSC']))
> +        modified.append(string)
> +
> +        string = "{} = {}\n".format("TARGET", config['TARGET'])
> +        modified.append(string)
> +
> +        string = "TARGET_ARCH = IA32 X64\n"
> +        modified.append(string)
> +
> +        string = "{} = {}\n".format("TOOL_CHAIN_TAG",
> config['TOOL_CHAIN_TAG'])
> +        modified.append(string)
> +
> +        string = "{} = {}\n".format("BUILD_RULE_CONF",
> +                                    os.path.join("Conf", "build_rule.txt"))
> +        modified.append(string)
> +
> +    if modified is not None:
> +        with open(os.path.join(config["WORKSPACE"],
> +                               "Conf", "target.txt"), 'w') as target:
> +            for line in modified:
> +                target.write(line)
> +            result = True
> +
> +    return result
> +
> +
> +def get_config():
> +    """Reads the default projects config file
> +
> +        :returns: The config defined in the the Build.cfg file
> +        :rtype: Dictionary
> +    """
> +    config_file = configparser.RawConfigParser()
> +    config_file.optionxform = str
> +    config_file.read('build.cfg')
> +    config_dictionary = {}
> +    for section in config_file.sections():
> +        dictionary = dict(config_file.items(section))
> +        config_dictionary[section] = dictionary
> +    return config_dictionary
> +
> +
> +def get_platform_config(platform_name, config_data):
> +    """ Reads the platform specifig config file
> +
> +        param platform_name: The name of the platform to be built
> +        :type platform_name: String
> +        param configData: The environment variables to be
> +            used in the build process
> +        :type configData: Dictionary
> +        :returns: The config defined in the the Build.cfg file
> +        :rtype: Dictionary
> +    """
> +    config = {}
> +
> +    platform_data = config_data.get("PLATFORMS")
> +    path = platform_data.get(platform_name)
> +    config_file = configparser.RawConfigParser()
> +    config_file.optionxform = str
> +    config_file.read(path)
> +    for section in config_file.sections():
> +        config[section] = dict(config_file.items(section))
> +
> +    return config
> +
> +
> +def get_cmd_config_arguments(arguments):
> +    """Get commandline config arguments
> +
> +    param arguments: The environment variables to be used in the build
> process
> +    :type arguments: argparse
> +    :returns: The config dictionary built from the commandline arguments
> +    :rtype: Dictionary
> +    """
> +    result = {}
> +    if arguments.capsule is True:
> +        result["CAPSULE_BUILD"] = "1"
> +
> +    if arguments.performance is True:
> +        result["PERFORMANCE_BUILD"] = "TRUE"
> +
> +    if arguments.fsp is True:
> +        result["FSP_WRAPPER_BUILD"] = "TRUE"
> +
> +    return result
> +
> +
> +def get_cmd_arguments(build_config):
> +    """ Get commandline inputs from user
> +
> +        param config_data: The environment variables to be
> +            used in the build process
> +        :type config_data: Dictionary
> +        :returns: The commandline arguments input by the user
> +        :rtype: argparse object
> +    """
> +
> +    class PrintPlatforms(argparse.Action):
> +        """ this is an argparse action that lists the available platforms
> +        """
> +        def __call__(self, parser, namespace, values, option_string=None):
> +            print("Platforms:")
> +            for key in build_config.get("PLATFORMS"):
> +                print("    " + key)
> +            setattr(namespace, self.dest, values)
> +            sys.exit(0)
> +
> +    # get the build commands
> +    parser = argparse.ArgumentParser(description="Build Help")
> +    parser.add_argument('--platform', '-p', dest="platform",
> +                        help='the platform to build',
> +                        choices=build_config.get("PLATFORMS"),
> +                        required=('-l' not in sys.argv and
> +                                  '--cleanall' not in sys.argv))
> +
> +    parser.add_argument('--toolchain', '-t', dest="toolchain",
> +                        help="using the Tool Chain Tagname to build \
> +                            the platform,overriding \
> +                            target.txt's TOOL_CHAIN_TAG definition")
> +
> +    parser.add_argument("--DEBUG", '-d', help="debug flag",
> +                        action='store_const', dest="target",
> +                        const="DEBUG", default="DEBUG")
> +
> +    parser.add_argument("--RELEASE", '-r', help="release flag",
> +                        action='store_const',
> +                        dest="target", const="RELEASE")
> +
> +    parser.add_argument("--TEST_RELEASE", '-tr', help="test Release flag",
> +                        action='store_const',
> +                        dest="target", const="TEST_RELEASE")
> +
> +    parser.add_argument("--RELEASE_PDB", '-rp', help="release flag",
> +                        action='store_const', dest="target",
> +                        const="RELEASE_PDB")
> +
> +    parser.add_argument('--list', '-l', action=PrintPlatforms,
> +                        help='lists available platforms', nargs=0)
> +
> +    parser.add_argument('--cleanall', dest='clean_all',
> +                        help='cleans all', action='store_true')
> +
> +    parser.add_argument('--clean', dest='clean',
> +                        help='cleans specific platform', action='store_true')
> +
> +    parser.add_argument("--capsule", help="capsule build enabled",
> +                        action='store_true', dest="capsule")
> +
> +    parser.add_argument("--silent", help="silent build enabled",
> +                        action='store_true', dest="silent")
> +
> +    parser.add_argument("--performance", help="performance build
> enabled",
> +                        action='store_true', dest="performance")
> +
> +    parser.add_argument("--fsp", help="fsp build enabled",
> +                        action='store_true', dest="fsp")
> +
> +    return parser.parse_args()
> +
> +
> +def keyboard_interruption(int_signal, int_frame):
> +    """ Catches a keyboard interruption handler
> +
> +        param int_signal: The signal this handler is called with
> +        :type int_signal: Signal
> +        param int_frame: The signal this handler is called with
> +        :type int_frame: frame
> +        :rtype: nothing
> +    """
> +    print("Signal #: {} Frame: {}".format(int_signal, int_frame))
> +    print("Quiting...")
> +    sys.exit(0)
> +
> +
> +def main():
> +    """ The main function of this module
> +        :rtype: nothing
> +    """
> +    # to quit the build
> +    signal.signal(signal.SIGINT, keyboard_interruption)
> +
> +    # get general build configurations
> +    build_config = get_config()
> +
> +    # get commandline parameters
> +    arguments = get_cmd_arguments(build_config)
> +
> +    if arguments.clean_all:
> +        clean(build_config.get("DEFAULT_CONFIG"))
> +
> +    # get platform specific config
> +    platform_config = get_platform_config(arguments.platform,
> build_config)
> +
> +    # update general build config with platform specific config
> +    config = build_config.get("DEFAULT_CONFIG")
> +    config.update(platform_config.get("CONFIG"))
> +
> +    # if user selected clean
> +    if arguments.clean:
> +        clean(config, board=True)
> +
> +    # Override config with cmd arguments
> +    cmd_config_args = get_cmd_config_arguments(arguments)
> +    config.update(cmd_config_args)
> +
> +    # get pre_build configurations
> +    config = pre_build(config,
> +                       build_type=arguments.target,
> +                       toolchain=arguments.toolchain,
> +                       silent=arguments.silent)
> +
> +    # build selected platform
> +    config = build(config)
> +
> +    # post build
> +    post_build(config)
> +
> +
> +if __name__ == "__main__":
> +    try:
> +        EXIT_CODE = 0
> +        main()
> +    except Exception as error:
> +        EXIT_CODE = 1
> +        traceback.print_exc()
> +    sys.exit(EXIT_CODE)
> --
> 2.19.1.windows.1
> 
> 
> 


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

* Re: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions
  2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions Agyeman, Prince
  2019-05-04  0:36   ` [edk2-devel] " Nate DeSimone
@ 2019-05-04  2:14   ` Kubacki, Michael A
  1 sibling, 0 replies; 9+ messages in thread
From: Kubacki, Michael A @ 2019-05-04  2:14 UTC (permalink / raw)
  To: devel@edk2.groups.io, Agyeman, Prince
  Cc: Kinney, Michael D, Desimone, Nathaniel L, Gao, Liming,
	Sinha, Ankit

Reviewed-by: Michael Kubacki <michael.a.kubacki@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Agyeman, Prince
> Sent: Friday, May 3, 2019 4:19 PM
> To: devel@edk2.groups.io
> Cc: Kubacki, Michael A <michael.a.kubacki@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2]
> Updated the build instructions to include the python script build instructions
> 
> Cc: Michael Kubacki <michael.a.kubacki@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Agyeman <prince.agyeman@intel.com>
> ---
>  ReadMe.md | 76
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
> 
> diff --git a/ReadMe.md b/ReadMe.md
> index 72e332a476..fbf735173f 100644
> --- a/ReadMe.md
> +++ b/ReadMe.md
> @@ -105,6 +105,82 @@ return back to the minimum platform caller.
> 
>  ### Build
> 
> +**Building with the python script**
> +
> +1. Open command window, go to the workspace directory, e.g.
> c:\Kabylake.
> +2. Type "cd edk2-platforms\Platform\Intel 3. Type "python build_bios.py
> +-p REPLACE_WITH_BOARD_NAME"
> +
> +* build_bios.py arguments:
> +
> +  | Argument              | Function                            |
> +  | ----------------------|-------------------------------------|
> +  | -h, --help            | show this help message and exit     |
> +  | --platform, -p        | the platform to build               |
> +  | --toolchain, -t       | tool Chain to use in build process  |
> +  | --DEBUG, -d           | debug flag                          |
> +  | --RELEASE, -r         | release flag                        |
> +  | --TEST_RELEASE, -tr   | test Release flag                   |
> +  | --RELEASE_PDB, -rp    | release flag                        |
> +  | --list, -l            | lists available platforms           |
> +  | --cleanall            | cleans all                          |
> +  | --clean               | cleans specified platform           |
> +  | --capsule             | capsule build enabled               |
> +  | --silent              | silent build enabled                |
> +  | --performance         | performance build enabled           |
> +  | --fsp                 | fsp build enabled                   |
> +  |                                                             |
> +
> +* For more information on build options
> +  * ``Type "python build_bios.py -h"``
> +
> +* Note
> +  * ``Python 2.7.16 and Python 3.7.3 compatible``
> +  * ``These python build scripts have been tested on Windows due to``
> +[cross-platform limitations](#Known-limitations)
> +
> +* Configuration Files
> +  * ``The edk2-platforms\Platform\Intel\build.cfg file contains the
> +default settings used by build_bios.py``
> +  * ``The default settings are under the DEFAULT_CONFIG section``
> +  * ``Each board can have a settings file that will override the
> +edk2-platforms\Platform\Intel\build.cfg settings``
> +  * ``An example of a board specific settings:``
> +    *
> +``edk2-
> platforms\Platform\Intel\KabylakeOpenBoardPkg\KabylakeRvp3\build
> +_config.cfg``
> +
> +* Workspace view of the build scripts
> +  * <pre>
> +    WORKSPACE
> +          |------edk2
> +          |------edk2-non-osi
> +          |------edk2-platforms
> +          |       |---Platform
> +          |       |    |--Intel
> +          |       |        |------build.cfg: Default build settings. These are overridden
> by
> +          |       |        |                 platform specific settings (build_config.cfg) and
> +          |       |        |                 then command-line settings.
> +          |       |        |
> +          |       |        |------build_bios.py: Main build script. Generic pre-build,
> build,
> +          |       |        |                     post-build, and clean functions.
> +          |       |        |
> +          |       |        |------ClevoOpenBoardPkg
> +          |       |        |        |------N1xxWU
> +          |       |        |                |---build_config.cfg: N1xxWU specific build
> +          |       |        |                                      settings environment variables.
> +          |       |        |
> +          |       |        |------KabylakeOpenBoardPkg
> +          |       |        |        |------KabylakeRvp3
> +          |       |        |                  |---build_config.cfg: KabylakeRvp3 specific
> +          |       |        |                  |                     build settings, environment
> variables.
> +          |       |        |                  |---build_board.py: Optional board-specific pre-
> build, build
> +          |       |        |                                      and clean post-build functions.
> +          |       |        |------PurleyOpenBoardPkg
> +          |       |        |       |------BoardMtOlympus
> +          |       |        |                |---build_config.cfg: BoardMtOlympus specific
> +          |       |        |                |                     build settings, environment variables.
> +          |       |        |                |---build_board.py: Optional board-specific pre-
> build,
> +          |       |        |                |                   build, post-build and clean functions.
> +          |------FSP
> +  </pre>
> +
> +**Building with the batch scripts**
>  For KabylakeOpenBoardPkg
>  1. Open command window, go to the workspace directory, e.g. c:\Kabylake.
>  2. Type "cd edk2-
> platforms\Platform\Intel\KabylakeOpenBoardPkg\KabylakeRvp3".
> --
> 2.19.1.windows.1
> 
> 
> 


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

end of thread, other threads:[~2019-05-04  2:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-03 23:19 [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Agyeman, Prince
2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added " Agyeman, Prince
2019-05-04  0:36   ` [edk2-devel] " Nate DeSimone
2019-05-04  2:14   ` Kubacki, Michael A
2019-05-03 23:19 ` [edk2-platforms/devel-MinPlatform] [PATCH v3 2/2] Updated the build instructions to include the python script build instructions Agyeman, Prince
2019-05-04  0:36   ` [edk2-devel] " Nate DeSimone
2019-05-04  2:14   ` Kubacki, Michael A
2019-05-04  0:36 ` [edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 0/2] Adding python build script Nate DeSimone
2019-05-04  2:14 ` Kubacki, Michael A

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