升级gcc-arm-none-eabi 11.3后出现系统调用未实现的链接警告
STM32裸机项目工具链升级后链接警告问题
我在Linux x64主机上开发STM32裸机项目,将工具链从gcc-arm-none-eabi-11.2-2022.02升级到arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi后,出现以下链接警告:
warning: _close is not implemented and will always fail warning: _fstat is not implemented and will always fail warning: _getpid is not implemented and will always fail warning: _isatty is not implemented and will always fail warning: _kill is not implemented and will always fail warning: _lseek is not implemented and will always fail warning: _open is not implemented and will always fail warning: _read is not implemented and will always fail warning: _write is not implemented and will always fail
完整警告信息如下:
~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-closer.o): in function `_close_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/closer.c:47: warning: _close is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-fstatr.o): in function `_fstat_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/fstatr.c:55: warning: _fstat is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-signalr.o): in function `_getpid_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/signalr.c:83: warning: _getpid is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-isattyr.o): in function `_isatty_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/isattyr.c:52: warning: _isatty is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-signalr.o): in function `_kill_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/signalr.c:53: warning: _kill is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-lseekr.o): in function `_lseek_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/lseekr.c:49: warning: _lseek is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(libc_a-openr.o): in function `_open_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/openr.c:50: warning: _open is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-readr.o): in function `_read_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/readr.c:49: warning: _read is not implemented and will always fail ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/bin/ld: ~/dev_tools/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/11.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libg.a(libc_a-writer.o): in function `_write_r': /data/jenkins/workspace/GNU-toolchain/arm-11/src/newlib-cygwin/newlib/libc/reent/writer.c:49: warning: _write is not implemented and will always fail
项目编译正常,但有三个疑问:
- 该问题由什么变更导致?
- 能否忽略这些警告?它们看起来是系统调用,我猜测可以忽略?
- 如果可以忽略,能否屏蔽这些警告?
问题解答
1. 变更原因
这是新版本工具链中的Newlib C库调整了链接警告策略导致的。旧版本中这些未实现的POSIX系统调用函数被静默处理,而11.3版本的Newlib新增了对这类未实现底层接口的警告输出。这些函数是Newlib为操作系统环境设计的依赖接口,裸机环境下没有对应实现,所以链接器会抛出警告。
2. 能否忽略这些警告
完全可以忽略。这些函数针对带操作系统的环境设计,STM32裸机项目中如果没有调用fopen、kill等依赖这些接口的标准库函数,或者已经自行实现了_write这类必要的底层接口(比如用于串口输出printf),那么这些未实现的函数根本不会被执行,不会影响程序功能。
如果项目用到了部分依赖这些函数的标准库功能,只需要实现用到的那几个函数即可,其余未用到的函数警告依然可以忽略。
3. 如何屏蔽警告
有两种常用方案:
- 方案一:链接时添加参数并实现空函数
在编译脚本中添加链接器参数,将未实现的函数映射到自定义包裹函数:
然后在代码中添加空实现的包裹函数:-Wl,--defsym=_close=__wrap__close -Wl,--defsym=_fstat=__wrap__fstat -Wl,--defsym=_getpid=__wrap__getpid -Wl,--defsym=_isatty=__wrap__isatty -Wl,--defsym=_kill=__wrap__kill -Wl,--defsym=_lseek=__wrap__lseek -Wl,--defsym=_open=__wrap__open -Wl,--defsym=_read=__wrap__read -Wl,--defsym=_write=__wrap__writeint __wrap__close(int fd) { return -1; } int __wrap__fstat(int fd, void* buf) { return -1; } int __wrap__getpid(void) { return 1; } int __wrap__isatty(int fd) { return 0; } int __wrap__kill(int pid, int sig) { return -1; } off_t __wrap__lseek(int fd, off_t offset, int whence) { return -1; } int __wrap__open(const char* path, int flags, int mode) { return -1; } ssize_t __wrap__read(int fd, void* buf, size_t count) { return -1; } ssize_t __wrap__write(int fd, const void* buf, size_t count) { return -1; } - 方案二:链接Newlib Nano库
如果项目不需要完整Newlib功能,可以添加编译参数链接轻量化的Newlib Nano库,它默认会减少这类警告,同时缩小代码体积:-specs=nano.specs
内容的提问来源于stack exchange,提问作者Nebular Noise
相关产品推荐
相关产品推荐

