""" Vhex build shell command abstraction """ import os import subprocess from core.logger import log from core.config import config_get __all__ = [ 'project_rules_exec' ] #--- # Internals #--- def __project_generate_env(env_extra, pkg_meta, target): r""" Generate environment variables ================================ ======================================= Type Description ================================ ======================================= VXSDK_PKG_NAME project name VXSDK_PKG_VERSION project version VXSDK_PKG_IS_ORIGINAL 'true' if the package is the original VXSDK_PREFIX_BUILD project build prefix (for object files) VXSDK_PREFIX_INSTALL project installation prefix VXSDK_PREFIX_LIB prefix for all stored library VXSDK_GCC_CFLAGS include flags for GCC VXSDK_ASSETS_SRC assets sources file directory VXSDK_ASSETS_BUILD assets build directory VXSDK_PATH_SYSROOT_LIB sysroot library path VXSDK_PATH_SYSROOT_INCLUDE sysroot include path ================================ ======================================= @arg > board_target (str) - targeted board """ prefix = f"{pkg_meta.parent_path}/.vxsdk" # generate VXSDK_PREFIX_BUILD information pkg_prefix_build = f'{prefix}/build/{pkg_meta.name}' if not os.path.exists(pkg_prefix_build): os.makedirs(pkg_prefix_build) # generate VXSDK_PREFIX_INSTALL information pkg_prefix_install = f'{prefix}/lib' if pkg_meta.type == 'app': pkg_prefix_install = os.path.expanduser(config_get('path.bin')) if not os.path.exists(pkg_prefix_install): os.makedirs(pkg_prefix_install) # generate VXSDK_PREFIX_LIB information pkg_prefix_lib = f'{prefix}/lib' if not os.path.exists(pkg_prefix_lib): os.makedirs(pkg_prefix_lib) # generate VXSDK_GCC_CFLAGS information #@todo : compiler specific ! #pkg_gcc_cflags = f'-L. -Llib/ -L{prefix}/lib/' #pkg_gcc_cflags += f' -I. -Iinclude/ -I{prefix}/lib/include/' # generate VXSDK_ASSETS_* information pkg_assets_src = f'{prefix}/converter/{pkg_meta.name}/src' pkg_assets_obj = f'{prefix}/converter/{pkg_meta.name}/obj' # generate VXSDK_PKG_* information pkg_name = pkg_meta.name pkg_is_original = str(pkg_meta.is_original) pkg_version = pkg_meta.version pkg_target = target # generate "dependence-specific" env envp = { 'VXSDK_PKG_NAME' : pkg_name, 'VXSDK_PKG_TARGET' : pkg_target, 'VXSDK_PKG_VERSION' : pkg_version, 'VXSDK_PKG_IS_ORIGINAL' : pkg_is_original, 'VXSDK_PREFIX_BUILD' : pkg_prefix_build, 'VXSDK_PREFIX_INSTALL' : pkg_prefix_install, 'VXSDK_PREFIX_LIB' : pkg_prefix_lib, 'VXSDK_ASSETS_SRC' : pkg_assets_src, 'VXSDK_ASSETS_BUILD' : pkg_assets_obj, 'VXSDK_CURRENT_SOURCE_DIR' : pkg_meta.path } # merge extra env configuration for key in env_extra: if key in envp: log.warn(f"[{pkg_name}] extra env key '{key}' already exist") envp[key] += f' {env_extra[key]}' # update env log.debug(f"{envp}") os.environ.update(envp) #--- # Public #--- def project_rules_exec(pkg_meta, target, rule_list, env_extra, verbose): """ Walk through project rules and performs target operation if needed This method will build the project source using the custom build information set by the author in the TOML description. Sometimes, we need to pass extra flags information in some steps. You can pass this information using the 'rules_extra' property of this class (see more information at 'VxProject.extra') @args > board_target (str) : targeted board for operation (fxcg50, SDL, ...) > rules (array,str) : list of wanted operations to performs > extra (dict,str) : user extra information about operations > verbose (bool) : capture (verbose=False) or not the operation print @return > 0 if success, negative value otherwise """ # save env information saved_pwd = os.getcwd() saved_env = os.environ.copy() # move to the project path os.chdir(pkg_meta.path) # fetch target specific rules project_rules = pkg_meta.get_build_rules(target) # main loop. Fetch operation, check if available, generate env # information, and perform said operation ret = 0 verbose = not verbose for rule in rule_list: if rule not in project_rules: continue cmd = project_rules[rule].strip() if pkg_meta.extra_conf and rule in pkg_meta.extra_conf: cmd += ' ' + pkg_meta.extra_conf[rule] __project_generate_env(env_extra, pkg_meta, target) log.debug(f"[{pkg_meta.name}] rule : {rule} -> cmd : ${cmd}$") ret = subprocess.run( cmd.split(), capture_output=verbose, check=False ) if ret.returncode != 0: if ret.stdout: log.error(ret.stdout.decode('utf8')) if ret.stderr: log.error(ret.stderr.decode('utf8')) ret = ret.returncode break ret = 0 # restore env information os.environ.update(saved_env) os.chdir(saved_pwd) return ret