Skip to content

Commit 0e5b71f

Browse files
committed
Replace small with std C lib if not supported by a target's toolchain
Display a post-build warning indicating to the user that the standard C library was used instead of the small C library if the former is not supported.
1 parent b090065 commit 0e5b71f

File tree

6 files changed

+127
-16
lines changed

6 files changed

+127
-16
lines changed

tools/build_api.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from .libraries import Library
4949
from .toolchains import TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
5050
from .toolchains.arm import UARM_TOOLCHAIN_WARNING
51+
from .toolchains.mbed_toolchain import should_replace_small_c_lib
5152
from .config import Config
5253

5354
RELEASE_VERSIONS = ['2', '5']
@@ -205,6 +206,7 @@ def get_toolchain_name(target, toolchain_name):
205206

206207
return toolchain_name
207208

209+
208210
def find_valid_toolchain(target, toolchain):
209211
"""Given a target and toolchain, get the names for the appropriate
210212
toolchain to use. The environment is also checked to see if the corresponding
@@ -250,6 +252,15 @@ def find_valid_toolchain(target, toolchain):
250252
and "uARM" in {toolchain_name, target.default_toolchain}
251253
):
252254
end_warnings.append(UARM_TOOLCHAIN_WARNING)
255+
256+
if should_replace_small_c_lib(target, toolchain):
257+
warning = (
258+
"Warning: We noticed that target.c_lib is set to small.\n"
259+
"As the {} target does not support a small C library for the {} toolchain,\n"
260+
"we are using the standard C library instead. "
261+
).format(target.name, toolchain)
262+
end_warnings.append(warning)
263+
253264
return toolchain_name, internal_tc_name, end_warnings
254265
else:
255266
if last_error:

tools/test/toolchains/test_toolchains.py

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ def test_arm_c_lib_std_exception(self):
8383

8484

8585
def test_arm_c_lib_small_exception(self):
86-
"""Test that an exception is raised if the small C library is not supported for a target on the ARM toolchain."""
86+
"""Test that an exception is raised if the small and std C library are not supported for a target on the ARM toolchain."""
8787
mock_target = mock.MagicMock()
8888
mock_target.core = "Cortex-M4"
8989
mock_target.c_lib = "small"
9090
del mock_target.default_lib
91-
mock_target.supported_c_libs = {"arm": ["std"]}
91+
mock_target.supported_c_libs = {"arm": [""]}
9292
mock_target.default_toolchain = "ARM"
9393
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
9494
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
@@ -97,6 +97,27 @@ def test_arm_c_lib_small_exception(self):
9797
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
9898
ARMC6(mock_target)
9999

100+
def test_arm_small_c_lib_swap_std_lib(self):
101+
"""Test that no exception is raised when small c lib is not supported but std lib is supported."""
102+
mock_target = mock.MagicMock()
103+
mock_target.core = "Cortex-M4"
104+
mock_target.c_lib = "small"
105+
del mock_target.default_lib
106+
mock_target.supported_c_libs = {"arm": ["std"]}
107+
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
108+
109+
mock_target.default_toolchain = "ARM"
110+
try:
111+
ARM_STD(mock_target)
112+
except NotSupportedException:
113+
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))
114+
115+
mock_target.default_toolchain = "ARMC6"
116+
try:
117+
ARMC6(mock_target)
118+
except NotSupportedException:
119+
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))
120+
100121
class TestGccToolchain(TestCase):
101122
"""Test the GCC class."""
102123

@@ -147,25 +168,39 @@ def test_gcc_arm_c_lib_std_exception(self):
147168
"""Test that an exception is raised if the std C library is not supported for a target on the GCC_ARM toolchain."""
148169
mock_target = mock.MagicMock()
149170
mock_target.core = "Cortex-M4"
150-
mock_target.default_toolchain = "ARM"
171+
mock_target.default_toolchain = "GCC_ARM"
151172
mock_target.c_lib = "std"
152173
del mock_target.default_lib
153-
mock_target.supported_c_libs = {"arm": ["small"]}
174+
mock_target.supported_c_libs = {"gcc_arm": ["small"]}
154175
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
155176
GCC_ARM(mock_target)
156177

157178
def test_gcc_arm_c_lib_small_exception(self):
158-
"""Test that an exception is raised if the small C library is not supported for a target on the GCC_ARM toolchain."""
179+
"""Test that an exception is raised if the small and std C library are not supported for a target on the GCC_ARM toolchain."""
159180
mock_target = mock.MagicMock()
160181
mock_target.core = "Cortex-M4"
161182
mock_target.c_lib = "small"
162183
del mock_target.default_lib
163-
mock_target.supported_c_libs = {"arm": ["std"]}
164-
mock_target.default_toolchain = "ARM"
165-
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
184+
mock_target.supported_c_libs = {"gcc_arm": [""]}
185+
mock_target.default_toolchain = "GCC_ARM"
186+
mock_target.supported_toolchains = ["GCC_ARM"]
166187
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
167188
GCC_ARM(mock_target)
168189

190+
def test_gcc_arm_small_c_lib_swap_std_lib(self):
191+
"""Test that no exception is raised when small c lib is not supported but std lib is supported."""
192+
mock_target = mock.MagicMock()
193+
mock_target.core = "Cortex-M4"
194+
mock_target.supported_c_libs = {"gcc_arm": ["std"]}
195+
mock_target.c_lib = "small"
196+
del mock_target.default_lib
197+
mock_target.supported_toolchains = ["GCC_ARM"]
198+
mock_target.is_TrustZone_secure_target = False
199+
mock_target.default_toolchain = "GCC_ARM"
200+
try:
201+
GCC_ARM(mock_target)
202+
except NotSupportedException:
203+
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))
169204
class TestIarToolchain(TestCase):
170205
"""Test the IAR class."""
171206

@@ -210,12 +245,26 @@ def test_iar_c_lib_std_exception(self):
210245
IAR(mock_target)
211246

212247
def test_iar_c_lib_small_exception(self):
213-
"""Test that an exception is raised if the small C library is not supported for a target on the IAR toolchain."""
248+
"""Test that an exception is raised if the small and std C library are not supported for a target on the IAR toolchain."""
214249
mock_target = mock.MagicMock()
215250
mock_target.core = "Cortex-M4"
216251
mock_target.c_lib = "small"
217252
del mock_target.default_lib
218-
mock_target.supported_c_libs = {"iar": ["std"]}
253+
mock_target.supported_c_libs = {"iar": [""]}
219254
mock_target.supported_toolchains = ["IAR"]
220255
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
221256
IAR(mock_target)
257+
258+
def test_iar_small_c_lib_swap_std_lib(self):
259+
"""Test that no exception is raised when small c lib is not supported but std lib is supported."""
260+
mock_target = mock.MagicMock()
261+
mock_target.core = "Cortex-M4"
262+
mock_target.supported_c_libs = {"iar": ["std"]}
263+
mock_target.c_lib = "small"
264+
del mock_target.default_lib
265+
mock_target.supported_toolchains = ["IAR"]
266+
mock_target.is_TrustZone_secure_target = False
267+
try:
268+
IAR(mock_target)
269+
except NotSupportedException:
270+
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))

tools/toolchains/arm.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
from shutil import rmtree
2727
from distutils.version import LooseVersion
2828

29-
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
29+
from tools.toolchains.mbed_toolchain import (
30+
mbedToolchain, TOOLCHAIN_PATHS, should_replace_small_c_lib
31+
)
3032
from tools.utils import mkdir, NotSupportedException, run_cmd
3133
from tools.resources import FileRef
3234

@@ -70,7 +72,12 @@ def __init__(self, target, notify=None, macros=None,
7072
raise NotSupportedException(
7173
"this compiler does not support the core %s" % target.core)
7274

73-
self.check_c_lib_supported(target, "arm")
75+
toolchain = "arm"
76+
77+
if should_replace_small_c_lib(target, toolchain):
78+
target.c_lib = "std"
79+
80+
self.check_c_lib_supported(target, toolchain)
7481

7582
if (
7683
getattr(target, "default_toolchain", "ARM") == "uARM"
@@ -562,7 +569,12 @@ def __init__(self, target, *args, **kwargs):
562569
"ARM/ARMC6 compiler support is required for ARMC6 build"
563570
)
564571

565-
self.check_c_lib_supported(target, "arm")
572+
toolchain = "arm"
573+
574+
if should_replace_small_c_lib(target, toolchain):
575+
target.c_lib = "std"
576+
577+
self.check_c_lib_supported(target, toolchain)
566578

567579
if (
568580
getattr(target, "default_toolchain", "ARMC6") == "uARM"

tools/toolchains/gcc.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
from distutils.spawn import find_executable
2323
from distutils.version import LooseVersion
2424

25-
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
25+
from tools.toolchains.mbed_toolchain import (
26+
mbedToolchain, TOOLCHAIN_PATHS, should_replace_small_c_lib
27+
)
2628
from tools.utils import run_cmd
2729

2830

@@ -54,7 +56,12 @@ def __init__(self, target, notify=None, macros=None, build_profile=None,
5456
# Add flags for current size setting
5557
c_lib = "std"
5658
if hasattr(target, "c_lib"):
57-
self.check_c_lib_supported(target, "gcc_arm")
59+
toolchain = "gcc_arm"
60+
61+
if should_replace_small_c_lib(target, toolchain):
62+
target.c_lib = "std"
63+
64+
self.check_c_lib_supported(target, toolchain)
5865
c_lib = target.c_lib
5966
elif hasattr(target, "default_build"):
6067
c_lib = target.default_build

tools/toolchains/iar.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
from os.path import join, splitext, exists
2121
from distutils.version import LooseVersion
2222

23-
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
23+
from tools.toolchains.mbed_toolchain import (
24+
mbedToolchain, TOOLCHAIN_PATHS, should_replace_small_c_lib
25+
)
2426
from tools.utils import run_cmd
2527

2628
class IAR(mbedToolchain):
@@ -54,6 +56,11 @@ def __init__(self, target, notify=None, macros=None, build_profile=None,
5456
build_profile=build_profile
5557
)
5658

59+
toolchain = "iar"
60+
61+
if should_replace_small_c_lib(target, toolchain):
62+
target.c_lib = "std"
63+
5764
self.check_c_lib_supported(target, "iar")
5865

5966
if target.is_TrustZone_secure_target:

tools/toolchains/mbed_toolchain.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,3 +1393,28 @@ def report(self):
13931393
to_ret['linker'] = {'flags': copy(self.flags['ld'])}
13941394
to_ret.update(self.config.report)
13951395
return to_ret
1396+
1397+
def should_replace_small_c_lib(target, toolchain):
1398+
"""
1399+
Check if the small C lib should be replaced with the standard C lib.
1400+
Return True if the replacement occurs otherwise return False.
1401+
"""
1402+
return (
1403+
not is_library_supported("small", target, toolchain)
1404+
and is_library_supported("std", target, toolchain)
1405+
and target.c_lib == "small"
1406+
)
1407+
1408+
1409+
def is_library_supported(lib_type, target, toolchain):
1410+
"""
1411+
Check if a library type is supported by a toolchain for a given target.
1412+
1413+
Return True if the library type is supported, False if not supported or
1414+
the target does not have an supported_c_libs attribute.
1415+
"""
1416+
return (
1417+
hasattr(target, "supported_c_libs")
1418+
and toolchain.lower() in target.supported_c_libs
1419+
and lib_type in target.supported_c_libs[toolchain.lower()]
1420+
)

0 commit comments

Comments
 (0)