From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: prince.agyeman@intel.com) Received: from mga06.intel.com (mga06.intel.com []) by groups.io with SMTP; Fri, 03 May 2019 16:19:20 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 May 2019 16:19:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,427,1549958400"; d="scan'208";a="148017019" Received: from paagyema-desk2.amr.corp.intel.com ([10.7.159.148]) by orsmga003.jf.intel.com with ESMTP; 03 May 2019 16:19:19 -0700 From: "Agyeman, Prince" To: devel@edk2.groups.io Cc: Michael Kubacki , Nate DeSimone , Ankit Sinha , Michael D Kinney , Isaac W Oram , Liming Gao , Bowen Zhou , Shifei A Lu Subject: [edk2-platforms/devel-MinPlatform] [PATCH v3 1/2] Platform/Intel: Added python build script. Date: Fri, 3 May 2019 16:19:18 -0700 Message-Id: X-Mailer: git-send-email 2.19.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 Cc: Nate DeSimone Cc: Ankit Sinha Cc: Michael D Kinney Cc: Isaac W Oram Cc: Liming Gao Cc: Bowen Zhou Cc: Shifei A Lu Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Agyeman --- .../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.
+# 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.
+# 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.
+# 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.
+# 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.
+# 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.
+# 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.
+# 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