[ci]:add armclang BSP build coverage (#11577)
* ci: add armclang BSP build coverage * components/libc: avoid armclang errno include recursion
This commit is contained in:
parent
937be2c97d
commit
ee43eeb685
|
|
@ -466,6 +466,13 @@
|
|||
"stm32/stm32l475-atk-pandora"
|
||||
]
|
||||
},
|
||||
{
|
||||
"RTT_BSP": "armclang-stm32",
|
||||
"RTT_TOOL_CHAIN": "armclang",
|
||||
"SUB_RTT_BSP": [
|
||||
"stm32/stm32f407-rt-spark"
|
||||
]
|
||||
},
|
||||
{
|
||||
"RTT_BSP": "simulator",
|
||||
"RTT_TOOL_CHAIN": "gcc",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"registries": [
|
||||
{
|
||||
"name": "arm",
|
||||
"kind": "artifact",
|
||||
"location": "https://artifacts.tools.arm.com/vcpkg-registry"
|
||||
}
|
||||
],
|
||||
"requires": {
|
||||
"arm:compilers/arm/armclang": "^6.24.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -161,6 +161,42 @@ jobs:
|
|||
echo "RTT_CC=llvm-arm" >> $GITHUB_ENV
|
||||
echo "RTT_EXEC_PATH=/opt/LLVMEmbeddedToolchainForArm-16.0.0-Linux-x86_64/bin" >> $GITHUB_ENV
|
||||
|
||||
- name: Install ArmClang ToolChains
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
|
||||
uses: ARM-software/cmsis-actions/setup-vcpkg@v1
|
||||
with:
|
||||
version: 2026.04.27
|
||||
|
||||
- name: Activate ArmClang ToolChains
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
|
||||
uses: ARM-software/cmsis-actions/vcpkg@v1
|
||||
with:
|
||||
config: .github/armclang-vcpkg-configuration.json
|
||||
cache: ${{ runner.os }}-armclang-6.24.0
|
||||
|
||||
- name: Activate ArmClang License
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
|
||||
uses: ARM-software/cmsis-actions/armlm@v1
|
||||
with:
|
||||
product: KEMDK-COM0
|
||||
|
||||
- name: Configure ArmClang ToolChains
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
|
||||
shell: bash
|
||||
run: |
|
||||
armclang --version
|
||||
command -v armlink
|
||||
command -v fromelf
|
||||
ARMCLANG_BIN="${AC6_TOOLCHAIN_6_24_0:-$(dirname "$(command -v armclang)")}"
|
||||
ARMCLANG_BIN="${ARMCLANG_BIN%/}"
|
||||
ARMCLANG_ROOT="$(dirname "$ARMCLANG_BIN")"
|
||||
test -d "$ARMCLANG_ROOT/include"
|
||||
test -d "$ARMCLANG_ROOT/lib"
|
||||
sudo mkdir -p /opt/Keil_v5/ARM
|
||||
sudo ln -sfn "$ARMCLANG_ROOT" /opt/Keil_v5/ARM/ARMCLANG
|
||||
echo "RTT_CC=keil" >> $GITHUB_ENV
|
||||
echo "RTT_EXEC_PATH=/opt/Keil_v5" >> $GITHUB_ENV
|
||||
|
||||
- name: Install AArch64 ToolChains
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-aarch64' && matrix.legs.RTT_SMART_TOOL_CHAIN != 'aarch64-linux-musleabi' && success() }}
|
||||
shell: bash
|
||||
|
|
@ -288,7 +324,7 @@ jobs:
|
|||
RTT_TOOL_CHAIN: ${{ matrix.legs.RTT_TOOL_CHAIN }}
|
||||
SRTT_BSP: ${{ join(matrix.legs.SUB_RTT_BSP, ',') }}
|
||||
ATTACHCONFIG_RTT_BSP: ${{ join(matrix.legs.ATTACHCONFIG_RTT_BSP || fromJSON('[]'), ',') }}
|
||||
RTT_CI_BUILD_DIST: "1"
|
||||
RTT_CI_BUILD_DIST: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && '0' || '1' }}
|
||||
run: |
|
||||
source ~/.env/env.sh
|
||||
python tools/ci/bsp_buildings.py
|
||||
|
|
|
|||
|
|
@ -38,8 +38,30 @@ defined in armcc/errno.h
|
|||
#define ERROR_BASE_NO 0
|
||||
#endif
|
||||
|
||||
#if defined(__ARMCC_VERSION) || defined(__IAR_SYSTEMS_ICC__)
|
||||
#if defined(__ARMCC_VERSION)
|
||||
#ifndef EDOM
|
||||
#define EDOM 1
|
||||
#endif
|
||||
#ifndef ERANGE
|
||||
#define ERANGE 2
|
||||
#endif
|
||||
#ifndef ESIGNUM
|
||||
#define ESIGNUM 3
|
||||
#endif
|
||||
#ifndef EILSEQ
|
||||
#define EILSEQ 4
|
||||
#endif
|
||||
#ifndef EINVAL
|
||||
#define EINVAL 5
|
||||
#endif
|
||||
#ifndef ENOMEM
|
||||
#define ENOMEM 6
|
||||
#endif
|
||||
#elif defined(__IAR_SYSTEMS_ICC__)
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#if defined(__ARMCC_VERSION) || defined(__IAR_SYSTEMS_ICC__)
|
||||
|
||||
#ifndef EPERM
|
||||
#define EPERM (ERROR_BASE_NO + 1)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,74 @@ Projects = []
|
|||
Rtt_Root = ''
|
||||
Env = None
|
||||
|
||||
if not hasattr(rtconfig, 'CXXFLAGS') and hasattr(rtconfig, 'CFLAGS'):
|
||||
rtconfig.CXXFLAGS = rtconfig.CFLAGS
|
||||
|
||||
def _path_variants(path):
|
||||
variants = set()
|
||||
if not path:
|
||||
return variants
|
||||
|
||||
normalized = path.replace('\\', '/').rstrip('/')
|
||||
variants.add(normalized)
|
||||
variants.add(normalized + '/')
|
||||
variants.add(normalized.replace('/', '\\'))
|
||||
variants.add((normalized + '/').replace('/', '\\'))
|
||||
|
||||
return variants
|
||||
|
||||
def _split_exec_path(exec_path):
|
||||
normalized = exec_path.replace('\\', '/').rstrip('/')
|
||||
lower = normalized.lower()
|
||||
for suffix in ('/arm/armclang/bin', '/arm/armcc/bin', '/arm/bin40', '/arm/bin', '/bin'):
|
||||
if lower.endswith(suffix):
|
||||
return normalized[:-len(suffix)], normalized[-len(suffix):]
|
||||
|
||||
return normalized, ''
|
||||
|
||||
def _replace_exec_path(value, old_path, new_path):
|
||||
if not isinstance(value, str):
|
||||
return value
|
||||
|
||||
result = value
|
||||
normalized_new_path = new_path.replace('\\', '/').rstrip('/')
|
||||
for old in sorted(_path_variants(old_path), key=len, reverse=True):
|
||||
replacement = normalized_new_path.replace('/', '\\') if '\\' in old else normalized_new_path
|
||||
if old.endswith(('/', '\\')):
|
||||
replacement += old[-1]
|
||||
result = result.replace(old, replacement)
|
||||
|
||||
return result
|
||||
|
||||
def _apply_exec_path_override(env, exec_path):
|
||||
old_exec_path = getattr(rtconfig, 'EXEC_PATH', '')
|
||||
old_root, suffix = _split_exec_path(old_exec_path)
|
||||
new_root, new_suffix = _split_exec_path(exec_path)
|
||||
new_exec_path = new_root + (new_suffix or suffix)
|
||||
|
||||
if old_root:
|
||||
for name in ('CFLAGS', 'CXXFLAGS', 'AFLAGS', 'LFLAGS',
|
||||
'M_CFLAGS', 'M_CXXFLAGS', 'M_LFLAGS'):
|
||||
if hasattr(rtconfig, name):
|
||||
setattr(rtconfig, name, _replace_exec_path(getattr(rtconfig, name), old_root, new_root))
|
||||
|
||||
rtconfig.EXEC_PATH = new_exec_path
|
||||
for key, name in (('CC', 'CC'), ('CXX', 'CXX'), ('AS', 'AS'), ('AR', 'AR'),
|
||||
('LINK', 'LINK'), ('CFLAGS', 'CFLAGS'),
|
||||
('CXXFLAGS', 'CXXFLAGS'), ('ASFLAGS', 'AFLAGS'),
|
||||
('LINKFLAGS', 'LFLAGS')):
|
||||
if hasattr(rtconfig, name):
|
||||
env[key] = getattr(rtconfig, name)
|
||||
|
||||
def _normalize_armclang_flags_for_host(env):
|
||||
if rtconfig.PLATFORM == 'armclang' and env['PLATFORM'] != 'win32':
|
||||
for name in ('LFLAGS', 'M_LFLAGS'):
|
||||
if hasattr(rtconfig, name):
|
||||
setattr(rtconfig, name, getattr(rtconfig, name).replace('\\', '/'))
|
||||
|
||||
if hasattr(rtconfig, 'LFLAGS'):
|
||||
env['LINKFLAGS'] = rtconfig.LFLAGS
|
||||
|
||||
def _as_unicode(value):
|
||||
try:
|
||||
unicode
|
||||
|
|
@ -208,6 +276,9 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
|
|||
os.environ['RTT_EXEC_PATH'] = exec_path
|
||||
|
||||
utils.ReloadModule(rtconfig) # update environment variables to rtconfig.py
|
||||
if exec_path:
|
||||
_apply_exec_path_override(env, exec_path)
|
||||
_normalize_armclang_flags_for_host(env)
|
||||
|
||||
# some env variables have loaded in Environment() of SConstruct before re-load rtconfig.py;
|
||||
# after update rtconfig.py's variables, those env variables need to synchronize
|
||||
|
|
@ -219,8 +290,6 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
|
|||
env['LINK'] = rtconfig.LINK
|
||||
if exec_path:
|
||||
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
|
||||
env['ASCOM']= env['ASPPCOM']
|
||||
|
||||
if GetOption('strict-compiling'):
|
||||
STRICT_FLAGS = ''
|
||||
if rtconfig.PLATFORM in ['gcc']:
|
||||
|
|
@ -241,8 +310,16 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
|
|||
env['LIBLINKPREFIX'] = ''
|
||||
env['LIBLINKSUFFIX'] = '.lib'
|
||||
env['LIBDIRPREFIX'] = '--userlibpath '
|
||||
if rtconfig.PLATFORM == 'armclang' and rtconfig.AS == 'armasm':
|
||||
env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES'
|
||||
env['ASPPCOM'] = env['ASCOM']
|
||||
else:
|
||||
env['ASCOM'] = env['ASPPCOM']
|
||||
|
||||
elif rtconfig.PLATFORM == 'iccarm':
|
||||
else:
|
||||
env['ASCOM'] = env['ASPPCOM']
|
||||
|
||||
if rtconfig.PLATFORM == 'iccarm':
|
||||
env['LIBPREFIX'] = ''
|
||||
env['LIBSUFFIX'] = '.a'
|
||||
env['LIBLINKPREFIX'] = ''
|
||||
|
|
|
|||
|
|
@ -115,10 +115,20 @@ def is_env_enabled(name, default=False):
|
|||
|
||||
return value.lower() not in ('', '0', 'false', 'no', 'off')
|
||||
|
||||
def get_ci_scons_args(scons_args=''):
|
||||
args = scons_args.strip()
|
||||
if os.getenv('RTT_TOOL_CHAIN') == 'armclang' and '--exec-path' not in args:
|
||||
exec_path = os.getenv('RTT_EXEC_PATH')
|
||||
if exec_path:
|
||||
args = f'{args} --exec-path="{exec_path}"'.strip()
|
||||
|
||||
return args
|
||||
|
||||
def run_dist_build_check(bsp, scons_args=''):
|
||||
"""
|
||||
build BSP distribution and verify that the generated project can compile.
|
||||
"""
|
||||
scons_args = get_ci_scons_args(scons_args)
|
||||
os.chdir(rtt_root)
|
||||
bsp_dir = os.path.join(rtt_root, 'bsp', bsp)
|
||||
if not check_bsp_build_scripts(bsp_dir):
|
||||
|
|
@ -144,13 +154,13 @@ def run_dist_build_check(bsp, scons_args=''):
|
|||
return False
|
||||
|
||||
old_rtt_root = os.environ.pop('RTT_ROOT', None)
|
||||
_, res = run_cmd(f'scons --pyconfig-silent -C {dist_project}', output_info=True)
|
||||
_, res = run_cmd(f'scons --pyconfig-silent -C {dist_project} {scons_args}', output_info=True)
|
||||
if res != 0:
|
||||
print(f"::error::dist project pyconfig failed for {bsp}")
|
||||
return False
|
||||
|
||||
nproc = multiprocessing.cpu_count()
|
||||
_, res = run_cmd(f'scons -C {dist_project} -j{nproc}', output_info=True)
|
||||
_, res = run_cmd(f'scons -C {dist_project} -j{nproc} {scons_args}', output_info=True)
|
||||
if res != 0:
|
||||
print(f"::error::dist project build failed for {bsp}")
|
||||
return False
|
||||
|
|
@ -193,6 +203,8 @@ def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_b
|
|||
if not check_bsp_build_scripts(bsp_dir):
|
||||
return False
|
||||
|
||||
scons_args = get_ci_scons_args(scons_args)
|
||||
|
||||
# 设置环境变量
|
||||
if bsp_build_env is not None:
|
||||
print("Setting environment variables:")
|
||||
|
|
@ -203,7 +215,7 @@ def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_b
|
|||
os.makedirs(f'{rtt_root}/output/bsp/{bsp}', exist_ok=True)
|
||||
if os.path.exists(f"{rtt_root}/bsp/{bsp}/Kconfig"):
|
||||
os.chdir(rtt_root)
|
||||
_, res = run_cmd(f'scons -C bsp/{bsp} --pyconfig-silent', output_info=True)
|
||||
_, res = run_cmd(f'scons -C bsp/{bsp} --pyconfig-silent {scons_args}', output_info=True)
|
||||
if res != 0:
|
||||
print(f"::error::pyconfig failed for {bsp}")
|
||||
success = False
|
||||
|
|
@ -250,6 +262,8 @@ def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_b
|
|||
for file_type in ['*.elf', '*.bin', '*.hex']:
|
||||
files = glob.glob(f'{rtt_root}/bsp/{bsp}/{file_type}')
|
||||
for file in files:
|
||||
if not os.path.isfile(file):
|
||||
continue
|
||||
shutil.copy(file, f'{rtt_root}/output/bsp/{bsp}/{name.replace("/", "_")}.{file_type[2:]}')
|
||||
if is_env_enabled('RTT_CI_BUILD_DIST'):
|
||||
print(f"::group::\tChecking dist project: {bsp} {name}")
|
||||
|
|
@ -270,7 +284,7 @@ def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_b
|
|||
print(f"Post-build command failed: {command}")
|
||||
print(output)
|
||||
success = False
|
||||
_, clean_res = run_cmd('scons -c', output_info=False)
|
||||
_, clean_res = run_cmd(f'scons -c {scons_args}', output_info=False)
|
||||
if clean_res != 0:
|
||||
print(f"::error::scons clean failed for {bsp}")
|
||||
success = False
|
||||
|
|
|
|||
Loading…
Reference in New Issue