""" core.build.rules - Vhex build shell command abstraction """ import os import subprocess from core.logger import log from core.build.cmake import ( cmake_configure, cmake_build, cmake_install, cmake_uninstall ) __all__ = [ 'rules_project_exec' ] #--- # Internals #--- def _exec_default_rules(pkg_info, rules, verbose, env): """ Execute default rules if no one found @args > pkg_info (obj) - package information > rules (list) - list of rules > verbose (bool) - enable verbose or not > env (dict) - can contain VXSDK_HOOK_* information @return > 0 if success, negative value otherwise """ default_rules = { 'configure' : cmake_configure, 'build' : cmake_build, 'install' : cmake_install, 'uninstall' : cmake_uninstall } for rule in rules: if rule not in default_rules: log.warn(f"rule '{rule}' not recognized, skipped") continue log.debug(f"default rule '{rule}' : with env = {env}") if (ret := default_rules[rule](pkg_info, verbose, env)) != 0: return ret return 0 #--- # Public #--- def rules_project_exec(pkg_meta, rule_list, env_config, verbose): """ Walk through project rules 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 > pkg_meta (obj) - package information > rule_list (list,str) - list of wanted operations to performs > env_config (dict) - "extra" env configuration > 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) # update ENV os.environ.update(env_config) # fetch build rules project_rules = pkg_meta.get_build_rules() if not project_rules: return _exec_default_rules(pkg_meta, rule_list, verbose, env_config) # 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] log.debug( f"[{pkg_meta.name}] rule : {rule} -> cmd : ${cmd}$ " f"(with env = {env_config})" ) ret = subprocess.run( cmd.split(), capture_output=False, 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