[edk2-devel] [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added python build script.

Kubacki, Michael A michael.a.kubacki at intel.com
Sat May 4 02:14:43 UTC 2019


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

> -----Original Message-----
> From: devel at edk2.groups.io [mailto:devel at edk2.groups.io] On Behalf Of
> Agyeman, Prince
> Sent: Friday, May 3, 2019 4:19 PM
> To: devel at edk2.groups.io
> Cc: Kubacki, Michael A <michael.a.kubacki at intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone at intel.com>; Sinha, Ankit
> <ankit.sinha at intel.com>; Kinney, Michael D <michael.d.kinney at intel.com>;
> Oram, Isaac W <isaac.w.oram at intel.com>; Gao, Liming
> <liming.gao at intel.com>; Zhou, Bowen <bowen.zhou at intel.com>; Lu, Shifei
> A <shifei.a.lu at 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 at intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
> Cc: Ankit Sinha <ankit.sinha at intel.com>
> Cc: Michael D Kinney <michael.d.kinney at intel.com>
> Cc: Isaac W Oram <isaac.w.oram at intel.com>
> Cc: Liming Gao <liming.gao at intel.com>
> Cc: Bowen Zhou<bowen.zhou at intel.com>
> Cc: Shifei A Lu <shifei.a.lu at intel.com>
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Agyeman <prince.agyeman at 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
> 
> 
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#39975): https://edk2.groups.io/g/devel/message/39975
Mute This Topic: https://groups.io/mt/31489355/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list