vxSDK/vxsdk/core/build/rules.py

161 lines
5.4 KiB
Python

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