diff --git a/tests/libc_newlib/Makefile b/tests/libc_newlib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1cb5ca7a49b5859d1e1d2f3929f76d8753de9c5b --- /dev/null +++ b/tests/libc_newlib/Makefile @@ -0,0 +1,47 @@ +include ../Makefile.tests_common + +TEST_ON_CI_WHITELIST += all +USEMODULE += embunit + +include $(RIOTBASE)/Makefile.include + +# Compile time tests +.PHONY: compile-test test-newlib-nano +all: compile-test + +ifneq (,$(filter newlib,$(USEMODULE))) + COMPILE_TESTS += test-newlib + ifneq (,$(filter newlib_nano,$(USEMODULE))) + CMP_OP = = + else + CMP_OP = != + endif +endif + +# Newlib-nano removed the integer only 'iprintf' functions which are now mapped +# to printf. +# +# `main.c` uses both functions to be sure they are included. +# It also duplicates the same test in C to verify it at runtime. +# +# Source: +# +# https://github.com/32bitmicro/newlib-nano-1.0/blob/f157c994b9a2c4bd8d0cfe9fe8fdd9cd54f8c63b/newlib/README.nano#L32 + +test-newlib: $(ELFFILE) + $(Q)\ + PRINTF_ADDR=$$($(NM) $^ | sed -n '/ printf$$/ s/ .*//p');\ + IPRINTF_ADDR=$$($(NM) $^ | sed -n '/ iprintf$$/ s/ .*//p');\ + echo "Test: comparing addresses of 'printf' and 'iprintf' symbols";\ + if test "$${PRINTF_ADDR}" $(CMP_OP) "$${IPRINTF_ADDR}" ; then \ + echo "[SUCCESS] '$${PRINTF_ADDR}' $(CMP_OP) '$${IPRINTF_ADDR}' is True"; \ + else \ + echo "[FAILED] '$${PRINTF_ADDR}' $(CMP_OP) '$${IPRINTF_ADDR}' is False"; \ + exit 1; \ + fi + +compile-test: $(COMPILE_TESTS) + + +test: + tests/01-run.py diff --git a/tests/libc_newlib/README.md b/tests/libc_newlib/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d4a72d53aa09b45d2aae4052151f351e5b605a25 --- /dev/null +++ b/tests/libc_newlib/README.md @@ -0,0 +1,20 @@ +About +===== + +Terifies if newlib/newlib-nano is correctly included by the build system + +At compile time, it checks that: + +* newlib-nano header is used when 'newlib-nano' module is included + * It defines `_NANO_FORMATTED_IO` macro + https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/newlib.hin;h=eadafc8a6a51ef7674c004a14777f6a4619115ee;hb=d34336767e45ee801ebb107e40abe4b1acbd3d14#l83 +* newlib or newlib-nano is properly linked + * `iprintf` is the same as `printf` or not as mentionned in: + https://github.com/32bitmicro/newlib-nano-1.0/blob/f157c994b9a2c4bd8d0cfe9fe8fdd9cd54f8c63b/newlib/README.nano#L32 + +At runtime, it checks that: + +* the same `iprintf` and `printf` test as at compile time + + +Without newlib, the test does nothing. diff --git a/tests/libc_newlib/main.c b/tests/libc_newlib/main.c new file mode 100644 index 0000000000000000000000000000000000000000..11b1bb1327a8bfdf40326b238623b1b03be8ecd9 --- /dev/null +++ b/tests/libc_newlib/main.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2018 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Test application for newlib/newlib-nano inclusion + * + * @author Gaëtan Harter <gaetan.harter@fu-berlin.de> + * + * @} + */ + +/* + * Make some different functions visible between newlib and newlib-nano + */ +#define _DEFAULT_SOURCE 1 + +#include <stdio.h> +#include "embUnit.h" + + +#ifdef MODULE_NEWLIB +#include <newlib.h> + +/* Newlib-nano defines the _NANO_FORMATTED_IO macro + * + * Source: + * + * https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/newlib.hin;h=eadafc8a6a51ef7674c004a14777f6a4619115ee;hb=d34336767e45ee801ebb107e40abe4b1acbd3d14#l83 + */ +#ifdef MODULE_NEWLIB_NANO +#ifndef _NANO_FORMATTED_IO +#error newlib-nano is enabled but the header is not visible by the build system +#endif /* _NANO_FORMATTED_IO */ +#endif /* MODULE_NEWLIB_NANO */ + +#endif /* MODULE_NEWLIB */ + + +/* Newlib-nano removed the integer only 'iprintf' functions which are now mapped + * to printf. + * + * Source: + * + * https://github.com/32bitmicro/newlib-nano-1.0/blob/f157c994b9a2c4bd8d0cfe9fe8fdd9cd54f8c63b/newlib/README.nano#L32 + * + */ +static void test_newlib(void) +{ + /* + * Be sure `iprintf` and `printf` are used when `newlib` is included as + * they should be visible in the final elf file for compile time tests + */ + +#ifdef MODULE_NEWLIB +#ifdef MODULE_NEWLIB_NANO + /* Nano maps iprintf to printf */ + TEST_ASSERT(iprintf == printf); +#else + /* Normal newlib does not */ + TEST_ASSERT(iprintf != printf); +#endif +#endif +} + + +static Test *tests_newlib(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_newlib), + }; + + EMB_UNIT_TESTCALLER(tests, NULL, NULL, fixtures); + return (Test *)&tests; +} + +int main(void) +{ + puts("Newlib/nano test"); + TESTS_START(); + TESTS_RUN(tests_newlib()); + TESTS_END(); + + return 0; +} diff --git a/tests/libc_newlib/tests/01-run.py b/tests/libc_newlib/tests/01-run.py new file mode 100755 index 0000000000000000000000000000000000000000..eeaa7d2c1f391be53c9e1484bd1dd96ff3448615 --- /dev/null +++ b/tests/libc_newlib/tests/01-run.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2018 Freie Universität Berlin +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +import os +import sys + + +def testfunc(child): + child.expect(r"OK \([0-9]+ tests\)") + + +if __name__ == "__main__": + sys.path.append(os.path.join(os.environ['RIOTTOOLS'], 'testrunner')) + from testrunner import run + sys.exit(run(testfunc))