реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Ошибки сборки при смешивании C и ASM, avr-gcc undefined reference
smalcom
сообщение Feb 8 2013, 14:05
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



Доброго дня.
Столкнулся с "невероятной" проблемой.
Есть файлы

main.c
Код
#include "asm_foo.h"

int main()
{
    asm_foo();
    return 0;;
}


asm_foo.h
Код
void asm_foo(void);


asm_foo.S
Код
#include <avr/io.h>
.section .text
.global asm_foo
asm__foo:
    ret


Сборка и результат
Цитата
asmc>avr-gcc -mmcu=atmega8 -o test_asm asm_foo.S main.c

C:\DOCUME~1\smalcom\LOCALS~1\Temp\cctCUv75.o: In function `main':
main.c:(.text+0x8): undefined reference to `asm_foo'
collect2.exe: error: ld returned 1 exit status


Буква S в расширении файла большая. ОС: WinXP 64

Компилятор
Цитата
asmc>avr-gcc -v
Using built-in specs.
COLLECT_GCC=G:\opt\avrgcc\bin\avr-gcc.EXE
COLLECT_LTO_WRAPPER=g:/opt/avrgcc/bin/../libexec/gcc/avr/4.7.2/lto-wrapper.exe
Target: avr
Configured with: ../gcc-4.7.2/configure --prefix=/g/opt/avrgcc --target=avr --with-dwarf2 --enable-languages=c,c++ --disable-libssp --disable-nls
Thread model: single
gcc version 4.7.2 (GCC)


На форуме искал, в интернете искал. У всех с такой ошибкой обычно была маленькая буква s в расширении.
Можно предположить, что проблема в неверном понимании этой буквы виндой или чем-то ещё, но тогда, по идее, была бы ошибка компиляции из-за использования #include в ассемблерном листинге.
---
Попробовал на другом ПК под линуксом и не авр-гцц, а обычный
Цитата
[smalcom@servelat asmc]$ gcc -o test_asm asm_foo.S main.c
/tmp/ccj533Bl.o: у функції «main»:
main.c:(.text+0x5): невизначене посилання «asm_foo»
collect2: error: ld returned 1 exit status

[smalcom@servelat asmc]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/src/gcc-4.7.2/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --enable-libstdcxx-time --enable-gnu-unique-object --enable-linker-build-id --with-ppl --enable-cloog-backend=isl --disable-ppl-version-check --disable-cloog-version-check --enable-lto --enable-gold --enable-ld=default --enable-plugin --with-plugin-ld=ld.gold --with-linker-hash-style=gnu --disable-multilib --disable-libssp --disable-build-with-cxx --disable-build-poststage1-with-cxx --enable-checking=release
Thread model: posix
gcc version 4.7.2 (GCC)

результат тот же. Значит есть какойто нюанс. Никак не могу понять какой.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 8 2013, 14:24
Сообщение #2


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(smalcom @ Feb 8 2013, 16:05) *
asm_foo.S
Код
#include <avr/io.h>
.section .text
.global asm_foo
asm__foo:
    ret
Это тут опечатка или и в коде два подчерка в метке asm__foo: ?


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
smalcom
сообщение Feb 8 2013, 15:00
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 292
Регистрация: 26-06-07
Пользователь №: 28 718



мдеееееее.
спасибо, мил человек.
проблема решена.

Наткнулся на новую проблему, опять по невнимательности. Вдруг ктото столкнётся.
Если у вас не main.c, а main.cpp, соответственно запустится "плюсовый" компилер - g++, то опять пойдут ошибки "undefined reference".
Чтобы этого не было, объявления ассемблерных функций - в данном примере это
Код
void asm_foo(void);


надо правильно экспортировать,

Код
extern "C"
{
void asm_foo(void);
}

Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 8 2013, 16:41
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Для одной функции можно и
Код
extern "C" void asm_foo(void);

Но лучше сразу так:
Код
#ifdef __cplusplus
extern "C" {
#endif
    // всё равно рано или поздно их будет много, пусть одним блоком
    void asm_foo(void);

#ifdef __cplusplus
}
#endif
и тогда .h можно будет включать хоть в .c, хоть в .cpp


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 12:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01392 секунд с 7
ELECTRONIX ©2004-2016