c - 未定义的 _write 引用,在库中实现
问题描述
在我的嵌入式项目中,我得到了 printf 语句所需的对 _write 的未定义引用。使用 arm-none-eabi-gcc 9.3.1。
uart.c实现_write,如下图:
int _write(int file, char* ptr, int len) __atribute__ ((used));
int _write(int file, char* ptr, int len)
{
...
}
void foo()
{
nop();
}
uart.c 被编译成一个静态库,该库在编译可执行文件时被链接。
这是main.c:
int main()
{
//foo();
printf("Hello world!");
}
foo();
注释掉,我得到undefined reference to '_write'
. 取消注释后,项目按预期foo();
构建。如何在不包含虚拟功能的情况下构建它?
构建步骤:
arm-none-eabi-gcc -c uart.c
ar rvs uart.a uart.o
arm-none-eabi-gcc main.c uart.a
解决方案
问题是标准库是在您的库之后链接的:
arm-none-eabi-gcc -v main.c uart.a
...
/usr/lib/gcc/arm-none-eabi/11.1.0/collect2 ....
uart.a
--start-group -lgcc -lc --end-group
/usr/lib/gcc/arm-none-eabi/11.1.0/crtend.o /usr/lib/gcc/arm-none-eabi/11.1.0/crtn.o
这是有道理的,但随后-lc
无法从uart.a
. 你可以:
- 先包括
-lc
自己uart.a
- 或使用
--whole-archive
并包含uart.a
.
经测试:
// main.c
#include <stdio.h>
int main() {
printf("Hello wolrd\n");
}
// uart.c
#define nop() __asm__("nop")
void _exit(int a) { for(;;); }
int _sbrk() { return -1; }
int _close() { return -1; }
int _read() { return -1; }
int _fstat() { return -1; }
int _isatty() { return -1; }
int _lseek() { return -1; }
int _write(int file, char* ptr, int len)
{
nop();
}
void foo()
{
nop();
}
// Makefile
all:
arm-none-eabi-gcc -c uart.c
ar rvs uart.a uart.o
arm-none-eabi-gcc main.c -lc uart.a
arm-none-eabi-gcc main.c -Wl,--whole-archive uart.a -Wl,--no-whole-archive
推荐阅读
- c# - Ajax POST 请求未命中控制器方法
- java - 形式的 Java 泛型
> 和 Eclipse 编译器 - node.js - 如何在将在后端使用 nodejs/mongodb 的 No-CPanel VPS 上部署 react js 应用程序?
- c# - DataTable select 方法已将字符串更改为 DBNull
- python - 想要使用正则表达式从给定文本中查找特定字符串
- javascript - 使用 Npm 作为不同配置的构建工具
- angular - 如何使用 Angular 7 标准翻译从 .ts 文件中翻译文本
- javascript - 如何从 RadListView 中的标签更改属性
- c# - .Net 4.5 程序集注册由 2.0
- c# - 如何在循环之前定义mysql参数min(date)和max(date)