mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
b090065dec
commit
0e5b71fdd7
|
@ -48,6 +48,7 @@ from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH, Target
|
||||||
from .libraries import Library
|
from .libraries import Library
|
||||||
from .toolchains import TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
|
from .toolchains import TOOLCHAIN_CLASSES, TOOLCHAIN_PATHS
|
||||||
from .toolchains.arm import UARM_TOOLCHAIN_WARNING
|
from .toolchains.arm import UARM_TOOLCHAIN_WARNING
|
||||||
|
from .toolchains.mbed_toolchain import should_replace_small_c_lib
|
||||||
from .config import Config
|
from .config import Config
|
||||||
|
|
||||||
RELEASE_VERSIONS = ['2', '5']
|
RELEASE_VERSIONS = ['2', '5']
|
||||||
|
@ -205,6 +206,7 @@ def get_toolchain_name(target, toolchain_name):
|
||||||
|
|
||||||
return toolchain_name
|
return toolchain_name
|
||||||
|
|
||||||
|
|
||||||
def find_valid_toolchain(target, toolchain):
|
def find_valid_toolchain(target, toolchain):
|
||||||
"""Given a target and toolchain, get the names for the appropriate
|
"""Given a target and toolchain, get the names for the appropriate
|
||||||
toolchain to use. The environment is also checked to see if the corresponding
|
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}
|
and "uARM" in {toolchain_name, target.default_toolchain}
|
||||||
):
|
):
|
||||||
end_warnings.append(UARM_TOOLCHAIN_WARNING)
|
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
|
return toolchain_name, internal_tc_name, end_warnings
|
||||||
else:
|
else:
|
||||||
if last_error:
|
if last_error:
|
||||||
|
|
|
@ -83,12 +83,12 @@ class TestArmToolchain(TestCase):
|
||||||
|
|
||||||
|
|
||||||
def test_arm_c_lib_small_exception(self):
|
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 = mock.MagicMock()
|
||||||
mock_target.core = "Cortex-M4"
|
mock_target.core = "Cortex-M4"
|
||||||
mock_target.c_lib = "small"
|
mock_target.c_lib = "small"
|
||||||
del mock_target.default_lib
|
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.default_toolchain = "ARM"
|
||||||
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
|
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
|
||||||
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
|
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)):
|
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
|
||||||
ARMC6(mock_target)
|
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):
|
class TestGccToolchain(TestCase):
|
||||||
"""Test the GCC class."""
|
"""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."""
|
"""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 = mock.MagicMock()
|
||||||
mock_target.core = "Cortex-M4"
|
mock_target.core = "Cortex-M4"
|
||||||
mock_target.default_toolchain = "ARM"
|
mock_target.default_toolchain = "GCC_ARM"
|
||||||
mock_target.c_lib = "std"
|
mock_target.c_lib = "std"
|
||||||
del mock_target.default_lib
|
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)):
|
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
|
||||||
GCC_ARM(mock_target)
|
GCC_ARM(mock_target)
|
||||||
|
|
||||||
def test_gcc_arm_c_lib_small_exception(self):
|
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 = mock.MagicMock()
|
||||||
mock_target.core = "Cortex-M4"
|
mock_target.core = "Cortex-M4"
|
||||||
mock_target.c_lib = "small"
|
mock_target.c_lib = "small"
|
||||||
del mock_target.default_lib
|
del mock_target.default_lib
|
||||||
mock_target.supported_c_libs = {"arm": ["std"]}
|
mock_target.supported_c_libs = {"gcc_arm": [""]}
|
||||||
mock_target.default_toolchain = "ARM"
|
mock_target.default_toolchain = "GCC_ARM"
|
||||||
mock_target.supported_toolchains = ["ARM", "uARM", "ARMC5"]
|
mock_target.supported_toolchains = ["GCC_ARM"]
|
||||||
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
|
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
|
||||||
GCC_ARM(mock_target)
|
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):
|
class TestIarToolchain(TestCase):
|
||||||
"""Test the IAR class."""
|
"""Test the IAR class."""
|
||||||
|
|
||||||
|
@ -210,12 +245,26 @@ class TestIarToolchain(TestCase):
|
||||||
IAR(mock_target)
|
IAR(mock_target)
|
||||||
|
|
||||||
def test_iar_c_lib_small_exception(self):
|
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 = mock.MagicMock()
|
||||||
mock_target.core = "Cortex-M4"
|
mock_target.core = "Cortex-M4"
|
||||||
mock_target.c_lib = "small"
|
mock_target.c_lib = "small"
|
||||||
del mock_target.default_lib
|
del mock_target.default_lib
|
||||||
mock_target.supported_c_libs = {"iar": ["std"]}
|
mock_target.supported_c_libs = {"iar": [""]}
|
||||||
mock_target.supported_toolchains = ["IAR"]
|
mock_target.supported_toolchains = ["IAR"]
|
||||||
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
|
with self.assertRaisesRegexp(NotSupportedException, UNSUPPORTED_C_LIB_EXCEPTION_STRING.format(mock_target.c_lib)):
|
||||||
IAR(mock_target)
|
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))
|
||||||
|
|
|
@ -26,7 +26,9 @@ from tempfile import mkstemp
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from distutils.version import LooseVersion
|
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.utils import mkdir, NotSupportedException, run_cmd
|
||||||
from tools.resources import FileRef
|
from tools.resources import FileRef
|
||||||
|
|
||||||
|
@ -70,7 +72,12 @@ class ARM(mbedToolchain):
|
||||||
raise NotSupportedException(
|
raise NotSupportedException(
|
||||||
"this compiler does not support the core %s" % target.core)
|
"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 (
|
if (
|
||||||
getattr(target, "default_toolchain", "ARM") == "uARM"
|
getattr(target, "default_toolchain", "ARM") == "uARM"
|
||||||
|
@ -562,7 +569,12 @@ class ARMC6(ARM_STD):
|
||||||
"ARM/ARMC6 compiler support is required for ARMC6 build"
|
"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 (
|
if (
|
||||||
getattr(target, "default_toolchain", "ARMC6") == "uARM"
|
getattr(target, "default_toolchain", "ARMC6") == "uARM"
|
||||||
|
|
|
@ -22,7 +22,9 @@ from os import getcwd, getenv
|
||||||
from distutils.spawn import find_executable
|
from distutils.spawn import find_executable
|
||||||
from distutils.version import LooseVersion
|
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
|
from tools.utils import run_cmd
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +56,12 @@ class GCC(mbedToolchain):
|
||||||
# Add flags for current size setting
|
# Add flags for current size setting
|
||||||
c_lib = "std"
|
c_lib = "std"
|
||||||
if hasattr(target, "c_lib"):
|
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
|
c_lib = target.c_lib
|
||||||
elif hasattr(target, "default_build"):
|
elif hasattr(target, "default_build"):
|
||||||
c_lib = target.default_build
|
c_lib = target.default_build
|
||||||
|
|
|
@ -20,7 +20,9 @@ from os import remove
|
||||||
from os.path import join, splitext, exists
|
from os.path import join, splitext, exists
|
||||||
from distutils.version import LooseVersion
|
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
|
from tools.utils import run_cmd
|
||||||
|
|
||||||
class IAR(mbedToolchain):
|
class IAR(mbedToolchain):
|
||||||
|
@ -54,6 +56,11 @@ class IAR(mbedToolchain):
|
||||||
build_profile=build_profile
|
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")
|
self.check_c_lib_supported(target, "iar")
|
||||||
|
|
||||||
if target.is_TrustZone_secure_target:
|
if target.is_TrustZone_secure_target:
|
||||||
|
|
|
@ -1393,3 +1393,28 @@ class mbedToolchain(with_metaclass(ABCMeta, object)):
|
||||||
to_ret['linker'] = {'flags': copy(self.flags['ld'])}
|
to_ret['linker'] = {'flags': copy(self.flags['ld'])}
|
||||||
to_ret.update(self.config.report)
|
to_ret.update(self.config.report)
|
||||||
return to_ret
|
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()]
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue