1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

build system: Fix linker feature test with newlib 4.3.0

Before the build system used something like

    echo "int main(){} void _exit(int n) {(void)n;while(1);}" | LC_ALL=C $(LINK) -xc - -o /dev/null -lc -Wall -Wextra -pedantic <FLAGS_TO_TEST>

to check for flags supported by the compiler (used as linker frontend).
This however no longer works with newlib 4.3.0, which requires the
symbols `_sbrk_r`, `_close_r`, `_lseek_r`, `_read_r`, and `_write_r` to
be present. Instead, now a new file `minimal_linkable.c` was added that
adds all the missing symbols and is used in the linker feature tests
instead.
This commit is contained in:
Marian Buschsieweke 2023-02-01 15:57:45 +01:00
parent cf2d66ede8
commit 2b2506c052
No known key found for this signature in database
GPG Key ID: CB8E3238CE715A94
5 changed files with 74 additions and 4 deletions

15
dist/tools/testprogs/README.md vendored Normal file
View File

@ -0,0 +1,15 @@
Test Programs
=============
This folder contains a collection of test programs for use by the build system,
e.g. to check for compiler features.
`minimal_linkable.c`
--------------------
This is a minimal C program that is expected to compile and link with all
supported versions of GCC and newlib.
Note: We currently even link with GCC when compilation is done with LLVM. It is
expected to compile and link fine with LLVM as well, but may require more some
additional flags to find the embedded C lib to link against.

55
dist/tools/testprogs/minimal_linkable.c vendored Normal file
View File

@ -0,0 +1,55 @@
#include <reent.h>
int main(void)
{
return 0;
}
void _exit(int n)
{
(void)n;
while(1);
}
void *_sbrk_r(struct _reent *r, ptrdiff_t incr)
{
(void)r;
(void)incr;
return NULL;
}
int _close_r(struct _reent *r, int fd)
{
(void)r;
(void)fd;
return 0;
}
_off_t _lseek_r(struct _reent *r, int fd, _off_t off, int whence)
{
(void)r;
(void)fd;
(void)off;
(void)whence;
return 0;
}
_ssize_t _read_r(struct _reent *r, int fd, void *buffer, size_t count)
{
(void)r;
(void)fd;
(void)buffer;
(void)count;
return 0;
}
_ssize_t _write_r(struct _reent *r, int fd, const void *data, size_t count)
{
(void)r;
(void)fd;
(void)data;
(void)count;
return 0;
}

View File

@ -67,7 +67,7 @@ endif
# Check if linker supports `-z noexecstack`. Handle BUILD_IN_DOCKER separately,
# as this is run in the host environment rather than inside the container. We
# just hardcode this in the BUILD_IN_DOCKER case for now.
LINKER_SUPPORTS_NOEXECSTACK ?= $(shell echo "int main(){} void _exit(int n) {(void)n;while(1);}" | LC_ALL=C $(LINK) -xc - -o /dev/null -lc -Wall -Wextra -pedantic -z noexecstack 2> /dev/null && echo 1 || echo 0)
LINKER_SUPPORTS_NOEXECSTACK ?= $(shell LC_ALL=C $(LINK) $(RIOTTOOLS)/testprogs/minimal_linkable.c -o /dev/null -lc -Wall -Wextra -pedantic -z noexecstack 2> /dev/null && echo 1 || echo 0)
# As we do not use nested functions or other stuff requiring trampoline code,
# we can safely mark the stack as not executable. This avoids warnings on newer

View File

@ -2,7 +2,7 @@ ifneq (,$(filter newlib_nano,$(USEMODULE)))
# Test if nano.specs is available
ifeq ($(shell $(LINK) -specs=nano.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
USE_NEWLIB_NANO = 1
ifeq ($(shell echo "int main(){} void _exit(int n) {(void)n;while(1);}" | LC_ALL=C $(LINK) -xc - -o /dev/null -lc -specs=nano.specs -Wall -Wextra -pedantic 2>&1 | grep -q "use of wchar_t values across objects may fail" ; echo $$?),0)
ifeq ($(shell LC_ALL=C $(LINK) $(RIOTTOOLS)/testprogs/minimal_linkable.c -o /dev/null -lc -specs=nano.specs -Wall -Wextra -pedantic 2>&1 | grep -q "use of wchar_t values across objects may fail" ; echo $$?),0)
CFLAGS += -fshort-wchar
LINKFLAGS += -Wl,--no-wchar-size-warning
endif

View File

@ -2,7 +2,7 @@ ifneq (,$(filter picolibc,$(USEMODULE)))
# Test if picolibc.specs is available
ifeq ($(shell $(LINK) -specs=picolibc.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
USE_PICOLIBC = 1
ifeq ($(shell echo "int main(){} void _exit(int n) {(void)n;while(1);}" | LC_ALL=C $(LINK) -xc - -o /dev/null -lc -specs=picolibc.specs -Wall -Wextra -pedantic 2>&1 | grep -q "use of wchar_t values across objects may fail" ; echo $$?),0)
ifeq (LC_ALL=C $(LINK) $(RIOTTOOLS)/testprogs/minimal_linkable.c -o /dev/null -lc -specs=picolibc.specs -Wall -Wextra -pedantic 2>&1 | grep -q "use of wchar_t values across objects may fail" ; echo $$?),0)
CFLAGS += -fshort-wchar
LINKFLAGS += -Wl,--no-wchar-size-warning
endif
@ -31,7 +31,7 @@ ifeq (1,$(USE_PICOLIBC))
# picolibc. But since (as of now) RIOT only supports disabling the execute of
# all RAM via the `mpu_noexec_ram` module, permissions of the segments are
# ignored anyway. So for now, we just simply disable the warning.
LINKER_SUPPORTS_NOWARNRWX ?= $(shell echo "int main(){} void _exit(int n) {(void)n;while(1);}" | LC_ALL=C $(LINK) -xc - -o /dev/null -lc -Wall -Wextra -pedantic -Wl,--no-warn-rwx-segments 2> /dev/null && echo 1 || echo 0)
LINKER_SUPPORTS_NOWARNRWX ?= $(shell LC_ALL=C $(LINK) $(RIOTTOOLS)/testprogs/minimal_linkable.c -o /dev/null -lc -Wall -Wextra -pedantic -Wl,--no-warn-rwx-segments 2> /dev/null && echo 1 || echo 0)
ifeq (1,$(LINKER_SUPPORTS_NOWARNRWX))
LINKFLAGS += -Wl,--no-warn-rwx-segments
endif