Skip to content

Commit ee43eeb

Browse files
authored
[ci]:add armclang BSP build coverage (#11577)
* ci: add armclang BSP build coverage * components/libc: avoid armclang errno include recursion
1 parent 937be2c commit ee43eeb

6 files changed

Lines changed: 177 additions & 9 deletions

File tree

.github/ALL_BSP_COMPILE.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,13 @@
466466
"stm32/stm32l475-atk-pandora"
467467
]
468468
},
469+
{
470+
"RTT_BSP": "armclang-stm32",
471+
"RTT_TOOL_CHAIN": "armclang",
472+
"SUB_RTT_BSP": [
473+
"stm32/stm32f407-rt-spark"
474+
]
475+
},
469476
{
470477
"RTT_BSP": "simulator",
471478
"RTT_TOOL_CHAIN": "gcc",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"registries": [
3+
{
4+
"name": "arm",
5+
"kind": "artifact",
6+
"location": "https://artifacts.tools.arm.com/vcpkg-registry"
7+
}
8+
],
9+
"requires": {
10+
"arm:compilers/arm/armclang": "^6.24.0"
11+
}
12+
}

.github/workflows/bsp_buildings.yml

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,42 @@ jobs:
161161
echo "RTT_CC=llvm-arm" >> $GITHUB_ENV
162162
echo "RTT_EXEC_PATH=/opt/LLVMEmbeddedToolchainForArm-16.0.0-Linux-x86_64/bin" >> $GITHUB_ENV
163163
164+
- name: Install ArmClang ToolChains
165+
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
166+
uses: ARM-software/cmsis-actions/setup-vcpkg@v1
167+
with:
168+
version: 2026.04.27
169+
170+
- name: Activate ArmClang ToolChains
171+
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
172+
uses: ARM-software/cmsis-actions/vcpkg@v1
173+
with:
174+
config: .github/armclang-vcpkg-configuration.json
175+
cache: ${{ runner.os }}-armclang-6.24.0
176+
177+
- name: Activate ArmClang License
178+
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
179+
uses: ARM-software/cmsis-actions/armlm@v1
180+
with:
181+
product: KEMDK-COM0
182+
183+
- name: Configure ArmClang ToolChains
184+
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && success() }}
185+
shell: bash
186+
run: |
187+
armclang --version
188+
command -v armlink
189+
command -v fromelf
190+
ARMCLANG_BIN="${AC6_TOOLCHAIN_6_24_0:-$(dirname "$(command -v armclang)")}"
191+
ARMCLANG_BIN="${ARMCLANG_BIN%/}"
192+
ARMCLANG_ROOT="$(dirname "$ARMCLANG_BIN")"
193+
test -d "$ARMCLANG_ROOT/include"
194+
test -d "$ARMCLANG_ROOT/lib"
195+
sudo mkdir -p /opt/Keil_v5/ARM
196+
sudo ln -sfn "$ARMCLANG_ROOT" /opt/Keil_v5/ARM/ARMCLANG
197+
echo "RTT_CC=keil" >> $GITHUB_ENV
198+
echo "RTT_EXEC_PATH=/opt/Keil_v5" >> $GITHUB_ENV
199+
164200
- name: Install AArch64 ToolChains
165201
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-aarch64' && matrix.legs.RTT_SMART_TOOL_CHAIN != 'aarch64-linux-musleabi' && success() }}
166202
shell: bash
@@ -288,7 +324,7 @@ jobs:
288324
RTT_TOOL_CHAIN: ${{ matrix.legs.RTT_TOOL_CHAIN }}
289325
SRTT_BSP: ${{ join(matrix.legs.SUB_RTT_BSP, ',') }}
290326
ATTACHCONFIG_RTT_BSP: ${{ join(matrix.legs.ATTACHCONFIG_RTT_BSP || fromJSON('[]'), ',') }}
291-
RTT_CI_BUILD_DIST: "1"
327+
RTT_CI_BUILD_DIST: ${{ matrix.legs.RTT_TOOL_CHAIN == 'armclang' && '0' || '1' }}
292328
run: |
293329
source ~/.env/env.sh
294330
python tools/ci/bsp_buildings.py

components/libc/compilers/common/extension/sys/errno.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,30 @@ defined in armcc/errno.h
3838
#define ERROR_BASE_NO 0
3939
#endif
4040

41-
#if defined(__ARMCC_VERSION) || defined(__IAR_SYSTEMS_ICC__)
41+
#if defined(__ARMCC_VERSION)
42+
#ifndef EDOM
43+
#define EDOM 1
44+
#endif
45+
#ifndef ERANGE
46+
#define ERANGE 2
47+
#endif
48+
#ifndef ESIGNUM
49+
#define ESIGNUM 3
50+
#endif
51+
#ifndef EILSEQ
52+
#define EILSEQ 4
53+
#endif
54+
#ifndef EINVAL
55+
#define EINVAL 5
56+
#endif
57+
#ifndef ENOMEM
58+
#define ENOMEM 6
59+
#endif
60+
#elif defined(__IAR_SYSTEMS_ICC__)
4261
#include <errno.h>
62+
#endif
63+
64+
#if defined(__ARMCC_VERSION) || defined(__IAR_SYSTEMS_ICC__)
4365

4466
#ifndef EPERM
4567
#define EPERM (ERROR_BASE_NO + 1)

tools/building.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,74 @@
4848
Rtt_Root = ''
4949
Env = None
5050

51+
if not hasattr(rtconfig, 'CXXFLAGS') and hasattr(rtconfig, 'CFLAGS'):
52+
rtconfig.CXXFLAGS = rtconfig.CFLAGS
53+
54+
def _path_variants(path):
55+
variants = set()
56+
if not path:
57+
return variants
58+
59+
normalized = path.replace('\\', '/').rstrip('/')
60+
variants.add(normalized)
61+
variants.add(normalized + '/')
62+
variants.add(normalized.replace('/', '\\'))
63+
variants.add((normalized + '/').replace('/', '\\'))
64+
65+
return variants
66+
67+
def _split_exec_path(exec_path):
68+
normalized = exec_path.replace('\\', '/').rstrip('/')
69+
lower = normalized.lower()
70+
for suffix in ('/arm/armclang/bin', '/arm/armcc/bin', '/arm/bin40', '/arm/bin', '/bin'):
71+
if lower.endswith(suffix):
72+
return normalized[:-len(suffix)], normalized[-len(suffix):]
73+
74+
return normalized, ''
75+
76+
def _replace_exec_path(value, old_path, new_path):
77+
if not isinstance(value, str):
78+
return value
79+
80+
result = value
81+
normalized_new_path = new_path.replace('\\', '/').rstrip('/')
82+
for old in sorted(_path_variants(old_path), key=len, reverse=True):
83+
replacement = normalized_new_path.replace('/', '\\') if '\\' in old else normalized_new_path
84+
if old.endswith(('/', '\\')):
85+
replacement += old[-1]
86+
result = result.replace(old, replacement)
87+
88+
return result
89+
90+
def _apply_exec_path_override(env, exec_path):
91+
old_exec_path = getattr(rtconfig, 'EXEC_PATH', '')
92+
old_root, suffix = _split_exec_path(old_exec_path)
93+
new_root, new_suffix = _split_exec_path(exec_path)
94+
new_exec_path = new_root + (new_suffix or suffix)
95+
96+
if old_root:
97+
for name in ('CFLAGS', 'CXXFLAGS', 'AFLAGS', 'LFLAGS',
98+
'M_CFLAGS', 'M_CXXFLAGS', 'M_LFLAGS'):
99+
if hasattr(rtconfig, name):
100+
setattr(rtconfig, name, _replace_exec_path(getattr(rtconfig, name), old_root, new_root))
101+
102+
rtconfig.EXEC_PATH = new_exec_path
103+
for key, name in (('CC', 'CC'), ('CXX', 'CXX'), ('AS', 'AS'), ('AR', 'AR'),
104+
('LINK', 'LINK'), ('CFLAGS', 'CFLAGS'),
105+
('CXXFLAGS', 'CXXFLAGS'), ('ASFLAGS', 'AFLAGS'),
106+
('LINKFLAGS', 'LFLAGS')):
107+
if hasattr(rtconfig, name):
108+
env[key] = getattr(rtconfig, name)
109+
110+
def _normalize_armclang_flags_for_host(env):
111+
if rtconfig.PLATFORM == 'armclang' and env['PLATFORM'] != 'win32':
112+
for name in ('LFLAGS', 'M_LFLAGS'):
113+
if hasattr(rtconfig, name):
114+
setattr(rtconfig, name, getattr(rtconfig, name).replace('\\', '/'))
115+
116+
if hasattr(rtconfig, 'LFLAGS'):
117+
env['LINKFLAGS'] = rtconfig.LFLAGS
118+
51119
def _as_unicode(value):
52120
try:
53121
unicode
@@ -208,6 +276,9 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
208276
os.environ['RTT_EXEC_PATH'] = exec_path
209277

210278
utils.ReloadModule(rtconfig) # update environment variables to rtconfig.py
279+
if exec_path:
280+
_apply_exec_path_override(env, exec_path)
281+
_normalize_armclang_flags_for_host(env)
211282

212283
# some env variables have loaded in Environment() of SConstruct before re-load rtconfig.py;
213284
# 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 = [
219290
env['LINK'] = rtconfig.LINK
220291
if exec_path:
221292
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
222-
env['ASCOM']= env['ASPPCOM']
223-
224293
if GetOption('strict-compiling'):
225294
STRICT_FLAGS = ''
226295
if rtconfig.PLATFORM in ['gcc']:
@@ -241,8 +310,16 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
241310
env['LIBLINKPREFIX'] = ''
242311
env['LIBLINKSUFFIX'] = '.lib'
243312
env['LIBDIRPREFIX'] = '--userlibpath '
313+
if rtconfig.PLATFORM == 'armclang' and rtconfig.AS == 'armasm':
314+
env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES'
315+
env['ASPPCOM'] = env['ASCOM']
316+
else:
317+
env['ASCOM'] = env['ASPPCOM']
318+
319+
else:
320+
env['ASCOM'] = env['ASPPCOM']
244321

245-
elif rtconfig.PLATFORM == 'iccarm':
322+
if rtconfig.PLATFORM == 'iccarm':
246323
env['LIBPREFIX'] = ''
247324
env['LIBSUFFIX'] = '.a'
248325
env['LIBLINKPREFIX'] = ''

tools/ci/bsp_buildings.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,20 @@ def is_env_enabled(name, default=False):
115115

116116
return value.lower() not in ('', '0', 'false', 'no', 'off')
117117

118+
def get_ci_scons_args(scons_args=''):
119+
args = scons_args.strip()
120+
if os.getenv('RTT_TOOL_CHAIN') == 'armclang' and '--exec-path' not in args:
121+
exec_path = os.getenv('RTT_EXEC_PATH')
122+
if exec_path:
123+
args = f'{args} --exec-path="{exec_path}"'.strip()
124+
125+
return args
126+
118127
def run_dist_build_check(bsp, scons_args=''):
119128
"""
120129
build BSP distribution and verify that the generated project can compile.
121130
"""
131+
scons_args = get_ci_scons_args(scons_args)
122132
os.chdir(rtt_root)
123133
bsp_dir = os.path.join(rtt_root, 'bsp', bsp)
124134
if not check_bsp_build_scripts(bsp_dir):
@@ -144,13 +154,13 @@ def run_dist_build_check(bsp, scons_args=''):
144154
return False
145155

146156
old_rtt_root = os.environ.pop('RTT_ROOT', None)
147-
_, res = run_cmd(f'scons --pyconfig-silent -C {dist_project}', output_info=True)
157+
_, res = run_cmd(f'scons --pyconfig-silent -C {dist_project} {scons_args}', output_info=True)
148158
if res != 0:
149159
print(f"::error::dist project pyconfig failed for {bsp}")
150160
return False
151161

152162
nproc = multiprocessing.cpu_count()
153-
_, res = run_cmd(f'scons -C {dist_project} -j{nproc}', output_info=True)
163+
_, res = run_cmd(f'scons -C {dist_project} -j{nproc} {scons_args}', output_info=True)
154164
if res != 0:
155165
print(f"::error::dist project build failed for {bsp}")
156166
return False
@@ -193,6 +203,8 @@ def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_b
193203
if not check_bsp_build_scripts(bsp_dir):
194204
return False
195205

206+
scons_args = get_ci_scons_args(scons_args)
207+
196208
# 设置环境变量
197209
if bsp_build_env is not None:
198210
print("Setting environment variables:")
@@ -203,7 +215,7 @@ def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_b
203215
os.makedirs(f'{rtt_root}/output/bsp/{bsp}', exist_ok=True)
204216
if os.path.exists(f"{rtt_root}/bsp/{bsp}/Kconfig"):
205217
os.chdir(rtt_root)
206-
_, res = run_cmd(f'scons -C bsp/{bsp} --pyconfig-silent', output_info=True)
218+
_, res = run_cmd(f'scons -C bsp/{bsp} --pyconfig-silent {scons_args}', output_info=True)
207219
if res != 0:
208220
print(f"::error::pyconfig failed for {bsp}")
209221
success = False
@@ -250,6 +262,8 @@ def build_bsp(bsp, scons_args='',name='default', pre_build_commands=None, post_b
250262
for file_type in ['*.elf', '*.bin', '*.hex']:
251263
files = glob.glob(f'{rtt_root}/bsp/{bsp}/{file_type}')
252264
for file in files:
265+
if not os.path.isfile(file):
266+
continue
253267
shutil.copy(file, f'{rtt_root}/output/bsp/{bsp}/{name.replace("/", "_")}.{file_type[2:]}')
254268
if is_env_enabled('RTT_CI_BUILD_DIST'):
255269
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
270284
print(f"Post-build command failed: {command}")
271285
print(output)
272286
success = False
273-
_, clean_res = run_cmd('scons -c', output_info=False)
287+
_, clean_res = run_cmd(f'scons -c {scons_args}', output_info=False)
274288
if clean_res != 0:
275289
print(f"::error::scons clean failed for {bsp}")
276290
success = False

0 commit comments

Comments
 (0)