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.
pull/12691/head
Hugues Kamba 2020-03-20 14:54:35 +00:00
parent b090065dec
commit 0e5b71fdd7
6 changed files with 127 additions and 16 deletions

View File

@ -48,6 +48,7 @@ from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH, Target
from .libraries import Library
from .toolchains import TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
from .toolchains.arm import UARM_TOOLCHAIN_WARNING
from .toolchains.mbed_toolchain import should_replace_small_c_lib
from .config import Config
RELEASE_VERSIONS = ['2', '5']
@ -205,6 +206,7 @@ def get_toolchain_name(target, toolchain_name):
return toolchain_name
def find_valid_toolchain(target, toolchain):
"""Given a target and toolchain, get the names for the appropriate
toolchain to use. The environment is also checked to see if the corresponding
@ -250,6 +252,15 @@ def find_valid_toolchain(target, toolchain):
and "uARM" in {toolchain_name, target.default_toolchain}
):
end_warnings.append(UARM_TOOLCHAIN_WARNING)
if should_replace_small_c_lib(target, toolchain):
warning = (
"Warning: We noticed that target.c_lib is set to small.\n"
"As the {} target does not support a small C library for the {} toolchain,\n"
"we are using the standard C library instead. "
).format(target.name, toolchain)
end_warnings.append(warning)
return toolchain_name, internal_tc_name, end_warnings
else:
if last_error:

View File

@ -83,12 +83,12 @@ class TestArmToolchain(TestCase):
def test_arm_c_lib_small_exception(self):
"""Test that an exception is raised if the small C library is not supported for a target on the ARM toolchain."""
"""Test that an exception is raised if the small and std C library are not supported for a target on the ARM toolchain."""
mock_target = mock.MagicMock()
mock_target.core = "Cortex-M4"
mock_target.c_lib = "small"
del mock_target.default_lib
mock_target.supported_c_libs = {"arm": ["std"]}
mock_target.supported_c_libs = {"arm": [""]}
mock_target.default_toolchain = "ARM"
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
@ -97,6 +97,27 @@ class TestArmToolchain(TestCase):
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
ARMC6(mock_target)
def test_arm_small_c_lib_swap_std_lib(self):
"""Test that no exception is raised when small c lib is not supported but std lib is supported."""
mock_target = mock.MagicMock()
mock_target.core = "Cortex-M4"
mock_target.c_lib = "small"
del mock_target.default_lib
mock_target.supported_c_libs = {"arm": ["std"]}
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
mock_target.default_toolchain = "ARM"
try:
ARM_STD(mock_target)
except NotSupportedException:
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))
mock_target.default_toolchain = "ARMC6"
try:
ARMC6(mock_target)
except NotSupportedException:
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))
class TestGccToolchain(TestCase):
"""Test the GCC class."""
@ -147,25 +168,39 @@ class TestGccToolchain(TestCase):
"""Test that an exception is raised if the std C library is not supported for a target on the GCC_ARM toolchain."""
mock_target = mock.MagicMock()
mock_target.core = "Cortex-M4"
mock_target.default_toolchain = "ARM"
mock_target.default_toolchain = "GCC_ARM"
mock_target.c_lib = "std"
del mock_target.default_lib
mock_target.supported_c_libs = {"arm": ["small"]}
mock_target.supported_c_libs = {"gcc_arm": ["small"]}
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
GCC_ARM(mock_target)
def test_gcc_arm_c_lib_small_exception(self):
"""Test that an exception is raised if the small C library is not supported for a target on the GCC_ARM toolchain."""
"""Test that an exception is raised if the small and std C library are not supported for a target on the GCC_ARM toolchain."""
mock_target = mock.MagicMock()
mock_target.core = "Cortex-M4"
mock_target.c_lib = "small"
del mock_target.default_lib
mock_target.supported_c_libs = {"arm": ["std"]}
mock_target.default_toolchain = "ARM"
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
mock_target.supported_c_libs = {"gcc_arm": [""]}
mock_target.default_toolchain = "GCC_ARM"
mock_target.supported_toolchains = ["GCC_ARM"]
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
GCC_ARM(mock_target)
def test_gcc_arm_small_c_lib_swap_std_lib(self):
"""Test that no exception is raised when small c lib is not supported but std lib is supported."""
mock_target = mock.MagicMock()
mock_target.core = "Cortex-M4"
mock_target.supported_c_libs = {"gcc_arm": ["std"]}
mock_target.c_lib = "small"
del mock_target.default_lib
mock_target.supported_toolchains = ["GCC_ARM"]
mock_target.is_TrustZone_secure_target = False
mock_target.default_toolchain = "GCC_ARM"
try:
GCC_ARM(mock_target)
except NotSupportedException:
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))
class TestIarToolchain(TestCase):
"""Test the IAR class."""
@ -210,12 +245,26 @@ class TestIarToolchain(TestCase):
IAR(mock_target)
def test_iar_c_lib_small_exception(self):
"""Test that an exception is raised if the small C library is not supported for a target on the IAR toolchain."""
"""Test that an exception is raised if the small and std C library are not supported for a target on the IAR toolchain."""
mock_target = mock.MagicMock()
mock_target.core = "Cortex-M4"
mock_target.c_lib = "small"
del mock_target.default_lib
mock_target.supported_c_libs = {"iar": ["std"]}
mock_target.supported_c_libs = {"iar": [""]}
mock_target.supported_toolchains = ["IAR"]
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
IAR(mock_target)
def test_iar_small_c_lib_swap_std_lib(self):
"""Test that no exception is raised when small c lib is not supported but std lib is supported."""
mock_target = mock.MagicMock()
mock_target.core = "Cortex-M4"
mock_target.supported_c_libs = {"iar": ["std"]}
mock_target.c_lib = "small"
del mock_target.default_lib
mock_target.supported_toolchains = ["IAR"]
mock_target.is_TrustZone_secure_target = False
try:
IAR(mock_target)
except NotSupportedException:
self.fail(UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib))

View File

@ -26,7 +26,9 @@ from tempfile import mkstemp
from shutil import rmtree
from distutils.version import LooseVersion
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
from tools.toolchains.mbed_toolchain import (
mbedToolchain, TOOLCHAIN_PATHS, should_replace_small_c_lib
)
from tools.utils import mkdir, NotSupportedException, run_cmd
from tools.resources import FileRef
@ -70,7 +72,12 @@ class ARM(mbedToolchain):
raise NotSupportedException(
"this compiler does not support the core %s" % target.core)
self.check_c_lib_supported(target, "arm")
toolchain = "arm"
if should_replace_small_c_lib(target, toolchain):
target.c_lib = "std"
self.check_c_lib_supported(target, toolchain)
if (
getattr(target, "default_toolchain", "ARM") == "uARM"
@ -562,7 +569,12 @@ class ARMC6(ARM_STD):
"ARM/ARMC6 compiler support is required for ARMC6 build"
)
self.check_c_lib_supported(target, "arm")
toolchain = "arm"
if should_replace_small_c_lib(target, toolchain):
target.c_lib = "std"
self.check_c_lib_supported(target, toolchain)
if (
getattr(target, "default_toolchain", "ARMC6") == "uARM"

View File

@ -22,7 +22,9 @@ from os import getcwd, getenv
from distutils.spawn import find_executable
from distutils.version import LooseVersion
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
from tools.toolchains.mbed_toolchain import (
mbedToolchain, TOOLCHAIN_PATHS, should_replace_small_c_lib
)
from tools.utils import run_cmd
@ -54,7 +56,12 @@ class GCC(mbedToolchain):
# Add flags for current size setting
c_lib = "std"
if hasattr(target, "c_lib"):
self.check_c_lib_supported(target, "gcc_arm")
toolchain = "gcc_arm"
if should_replace_small_c_lib(target, toolchain):
target.c_lib = "std"
self.check_c_lib_supported(target, toolchain)
c_lib = target.c_lib
elif hasattr(target, "default_build"):
c_lib = target.default_build

View File

@ -20,7 +20,9 @@ from os import remove
from os.path import join, splitext, exists
from distutils.version import LooseVersion
from tools.toolchains.mbed_toolchain import mbedToolchain, TOOLCHAIN_PATHS
from tools.toolchains.mbed_toolchain import (
mbedToolchain, TOOLCHAIN_PATHS, should_replace_small_c_lib
)
from tools.utils import run_cmd
class IAR(mbedToolchain):
@ -54,6 +56,11 @@ class IAR(mbedToolchain):
build_profile=build_profile
)
toolchain = "iar"
if should_replace_small_c_lib(target, toolchain):
target.c_lib = "std"
self.check_c_lib_supported(target, "iar")
if target.is_TrustZone_secure_target:

View File

@ -1393,3 +1393,28 @@ class mbedToolchain(with_metaclass(ABCMeta, object)):
to_ret['linker'] = {'flags': copy(self.flags['ld'])}
to_ret.update(self.config.report)
return to_ret
def should_replace_small_c_lib(target, toolchain):
"""
Check if the small C lib should be replaced with the standard C lib.
Return True if the replacement occurs otherwise return False.
"""
return (
not is_library_supported("small", target, toolchain)
and is_library_supported("std", target, toolchain)
and target.c_lib == "small"
)
def is_library_supported(lib_type, target, toolchain):
"""
Check if a library type is supported by a toolchain for a given target.
Return True if the library type is supported, False if not supported or
the target does not have an supported_c_libs attribute.
"""
return (
hasattr(target, "supported_c_libs")
and toolchain.lower() in target.supported_c_libs
and lib_type in target.supported_c_libs[toolchain.lower()]
)