123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976 |
- # @ 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)
|