vxSDK/vxsdk/core/build/rules.py

120 lines
3.3 KiB
Python

"""
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