2017-05-26 261 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

相關問題