【发布时间】:2017-05-26 22:16:29
【问题描述】:
我有一堆 arm 程序集、C 和 C++ 文件。 gcc 正在尝试链接它们,但这些是针对嵌入式项目的。
我没有使用任何外部库,所有正在使用的代码都是由我编写的。似乎发生了错误,因为我在main.c 中定义了一个名为int kernel_main(void) 的函数,它试图调用mailbox.cpp 中定义的set_LED(int value),其中包括标题mailbox.h(我确实在main.c 中包含了标题文件)。
确切的错误是:
undefined reference to `__aeabi_unwind_cpp_pr1'
我制作项目的方式是: - 将所有源文件(.s、.c、.cpp)编译为目标文件(.o)而不使用链接(-c),然后使用自定义链接器脚本将它们链接在一起。
编辑:我将添加一些信息以使事情更清楚。
首先更改所有文件,使它们都是 C 文件(无 cpp 扩展名):
undefined reference to `set_LED'
问题本身不太可能是名称混淆,它可能与 CPP 和 C 的差异无关。
问题很可能是链接器问题
这是构建过程:
编译c文件,示例:
arm-none-eabi-g++ -O0 -march=armv8-a source/MainFiles/mailbox.cpp -nostartfiles -c -o objects/MainFiles/mailbox.o
(编译一个 C++ 文件将是相同的,除了使用 g++ 而不是 gcc)
链接一切:
arm-none-eabi-ld object1 object2... -o build/kernel.elf -T ./source/kernel.ld -I include_directory_1 -I include_directory_2 -L include_directory_1 -L indlude_directory_2
包含目录是当前目录下的所有目录
编辑: 错误又回来了。忽略此问题中与名称修改相关的部分。我需要修复的错误是:
./objects/Hardware/mailbox.o:(.ARM.exidx+0x18): undefined reference to `__aeabi_unwind_cpp_pr1'
到目前为止,我所知道的是,这与展开堆栈和异常有关。似乎该函数是在 libgcc 中定义的。但是我使用了-nostdlib,我省略了它,并且在这两种情况下错误仍然存在。我已尝试尽可能将文件扩展名更改为 .c 并尽可能更改为 .cpp,可惜错误始终存在。
只要我有 1 个 cpp 文件并且我的其余文件是 C 文件,它就得到了修复(这不再是真的,我试过了)。再次触发错误的是我正在重构代码,并且我想将几个函数移动到新文件中。
换句话说,在不删除单个文件的情况下,在mailbox.cpp 中声明一个名为wait(uint32_t time) 的函数可以工作,在名为time.c(或cpp)的文件中声明它,并使用其各自的标头声明并在邮箱中包含标头.cpp 打破了一切。注意我在移动函数时不会删除文件我只是删除每个文件中的函数声明。
像这样添加存根:
void __aeabi_unwind_cpp_pr1()
{
}
解决了问题并且代码有效。但我不喜欢这个解决方案。我不希望在我的代码中神秘地调用无用的存根。我在当前的实现中不需要也不想要这个函数,我怎么能告诉编译器或链接器他们要忽略他们正在做的任何需要这个函数的事情?
【问题讨论】:
-
只是猜测,但
unwind部分听起来像是异常实现的一部分。 -
我向编码之神发誓我并没有明确地使用异常
-
你看过这篇stackoverflow.com/questions/27831735/…的帖子了吗?
-
是的,并添加 -lgcc_eh。似乎对我没有任何作用
-
我不知道 gcc 是否仍然支持
-fno-exceptions,但如果支持,您可以尝试使用它进行编译,这样它就不会放入展开代码以防万一。构造函数抛出异常。