У меня возникли некоторые проблемы при компиляции и компоновке библиотеки, написанной на ассемблере, с моим программным кодом на C ++. В моем случае это микроконтроллер AVR, использующий пакет avr-gcc, но я думаю, что эта проблема в целом относится к GCC.
Я могу получить .o файлы, собранные из исходного кода и сборки C ++, но их соединение дает ошибку:
> avr-gcc -mmcu=attiny84 -lm -o obj\AvrTest.elf obj\Main.o obj\i2cmaster.o
obj\Main.o: In function `main':
Main.cpp:(.text+0x0): undefined reference to `i2c_init()'
Вот очень простой Main.cpp
код:
#include "i2cmaster.h"void main() {
i2c_init();
while ( true ) {
}
}
i2cmaster.h
определяет прототип функции следующим образом:
extern void i2c_init(void);
И в файле ассемблера, i2cmaster.S
эта функция:
.global i2c_init
.func i2c_init
i2c_init:
cbi SDA_DDR,SDA ;release SDA
cbi SCL_DDR,SCL ;release SCL
cbi SDA_OUT,SDA
cbi SCL_OUT,SCL
ret
.endfunc
Связывание может показаться легким делом — но я получаю эту ошибку ссылки. Я заметил код ассемблера, сгенерированный для Main.cpp
выходит так:
.global main
.type main, @function
main:
rcall _Z8i2c_initv
.L2:
rjmp .L2
.size main, .-main
Я подозреваю, что проблема в том, что i2c_init
это становится _Z8i2c_initv
через некоторый процесс искажения имени, я не понимаю, и что _Z8i2c_initv
больше не может быть сопоставлен с не искалеченным i2c_init
символ в i2cmaster.o
объектный файл.
Кто-нибудь понимает процесс искажения и как подавить его во время компиляции / сборки, чтобы эти модули могли общаться друг с другом? Или что-то еще я могу делать не так?
ОК, решил. Очевидно, искажение символов — это вещь C ++, а библиотека i2c не настроена для корректной работы с C ++. Был в состоянии исправить это с помощью следующего:
extern "C" {
#include "i2cmaster.h"};
void main() {
i2c_init();
while ( true ) {
}
}
Других решений пока нет …