2017-05-26 262 views
3

我有一堆arm组件,C和C++文件。 gcc正试图链接它们,但这些是针对嵌入式项目的。什么是__aeabi_unwind_cpp_pr1',我该如何避免它?

我没有使用任何外部库,所有正在使用的代码都是由我编写的。错误似乎发生,因为我有一个main.c中定义的名为int kernel_main(void)的函数,它试图调用在mailbox.cpp中定义的set_LED(int value),其中包含头文件mailbox.h(我确实在main.c文件中包含头文件)。

确切的错误是:

undefined reference to `__aeabi_unwind_cpp_pr1' 

:我将我的项目的方式是: -compile所有源文件(.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,我省略了它,并且在这两种情况下,错误仍然存​​在。我尽可能地尝试将文件扩展名更改为.cpp,并尽可能将它改为.cpp,但错误始终存在。

只有我有1个cpp文件,其余的文件都是C文件(这不再是真的,我试过)才得到修复。再次触发错误的是我重构了代码,我想将几​​个函数移动到新文件中。

换句话说,在不删除单个文件的情况下,在mailbox.cpp中声明一个名为wait(uint32_t time)的函数,将其声明在一个名为time.c(或cpp)的文件中,并带有相应的头声明并在邮箱中包含头文件。 cpp打破了一切。注意移动函数时,我不删除文件,只是删除每个文件中的函数声明。

添加这样的存根:

void __aeabi_unwind_cpp_pr1() 
{ 

} 

解决问题和代码工作。但我不喜欢这个解决方案。我不希望在我的代码中被称为神秘的无用存根。在当前的实现中,我不需要也不需要这个函数,我怎么能告诉编译器或者链接器他们会忽略他们正在做的需要这个函数的东西?

+3

只是一个猜测,但'unwind'部分听起来像是实现异常的一部分。 –

+0

我向编码之神发誓我没有使用例外explotetely虽然 – Makogan

+0

你读过这篇文章https://stackoverflow.com/questions/27831735/cross-compile-glibc-for-arm-got-undefined-reference-to - 某些展开功能? –

回答

1

该解决方案非常简单。事实证明,默认情况下启用了异常(这是生成调用__eabi_unwind_cpp_pr1的代码的原因)。要禁用它们,只需要传递: -fno-exceptions作为gcc/g ++编译器的参数,问题就解决了。

0

您对此函数的引用属于GCC的C++运行时。它是异常处理的一部分。无论你在做什么,听起来有点疯狂,但无论如何,如果你真的知道自己在做什么,就可以做到这一点。您必须链接到C++运行时库。而已。链接到“libstdC++”。

关于set_LED我也相信这只是关于C++的修改,就像Justin J在其他答案中提到的那样。

+0

这是“编译器定义”库还是实际库?问题是,这是针对嵌入式项目的,因此没有操作系统,如果这与异常处理有关,听起来像是需要OS – Makogan

+1

否,它不需要任何操作系统的异常处理。 ..你正在使用一些调用异常处理的代码。在'throw'后面的场景只不过是一个启动堆栈展开过程的函数。顾名思义,这个功能与放松过程有关。一旦GCC具体,很难说清楚。我建议你看看这个链接:https://monoinfinito.wordpress.com/series/exception-handling-in-c/ –

1

我在混合使用C和C++时看到了这个。由于名称变形,这些符号将在内部具有不同的名称,具体取决于源文件的类型。

如果'set_LED'的来源是c文件,请在原型的标题中使用以下内容,看看它是否有帮助。

#ifdef __cplusplus 
extern "C" { 
#endif 

// function prototypes here 

#ifdef __cplusplus 
} 
#endif 
+0

set_LED的源代码是一个cpp文件 – Makogan

-2

还请将不带引号的前缀“-shared”添加到-fno-exceptions。我正在使用ARM GCC版本

+0

它是做什么的,为什么它应该是添加? – user5226582

相关问题