Error del enlazador en un proyecto de C usando Eclipse


Quiero crear un proyecto para el microcontrolador STM32F217IG.

Luego instalé Eclipse y el compilador cruzado de GNU para ARM embebido en GCC. No creo que sea el Código Fuente uno. Lo usé, porque soporta coma flotante y Code Sourcery no.

Una vez que lo hice intenté crear un proyecto realmente pequeño con solo dos archivos de origen: test.c y main.c con solo escrito en ambos:

#include <stdlib.h>
#include <stdio.h>

int main (void)
{
    printf("Hello, World!");
    return 0;
}

Cambié el comando line en la propiedad project para reemplazar GCC por arm-none-eabi-gcc y luego trató de compilar el proyecto.

No creé ningún archivo make yo mismo; usé la creación automática en Eclipse.

El edificio parece estar bien, pero cuando se trata del enlazador tengo los siguientes errores en la consola:

make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status

make: *** [test3] Erreur 1

Busqué en Internet, y descubrí que puede ser un problema de syscall. Pero no se como puedo agregar esta librería a mi proyecto en Linux.

¿Es realmente eso? En caso afirmativo, ¿cómo lo arreglo? Y si no, ¿de dónde viene eso?

Como alguien sugirió, intenté "vincular" la biblioteca de tiempo de ejecución de C. En Eclipse parece que tengo dos soluciones para hacerlo:

En Primer lugar, en las propiedades del proyecto → C/C++ConstruirConfiguraciónCruz vinculadorlas bibliotecas. Solo añado la letra c y luego el error no cambia, pero hay -lc al final de la línea de comandos:

 make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -lc

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1

Pero no se si es realmente significa añadir la C runtime library.

Segundo, agregué el libc.una biblioteca en las propiedades del proyecto → C / C++ generalRuta y símbolosBibliotecas , y esto es lo que obtengo (completamente diferente):

make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -l"C:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a"

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/bin/ld.exe: cannot find -lC:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1

Entonces todavía no funciona, pero ¿es la buena manera de buscar?

Oh y un hecho muy interesante:

Tengo los errores solo en el modo de depuración. Si estoy en modo release todo está bien, y no tengo ningún error (excepto si agrego el libc.un entonces creo que esto no es lo bueno que hay que hacer). ¿Eso significa que el problema es el .creación de archivos elf?

Author: Peter Mortensen, 2012-11-05

5 answers

He mirado el kit de herramientas que vinculó, solo para leer lo siguiente en el readme.txt:

Esta cadena de herramientas está construida y optimizada para el desarrollo de Cortex-R/M bare metal.

En otras palabras, esta cadena de herramientas está configurada específicamente para sistemas embebidos, tal vez sin ningún sistema operativo en ejecución. En tal caso, no hay un sistema que proporcione, por ejemplo, una salida estándar donde printf() se supone que debe escribir, no hay un sistema de archivos, etc. - tienes que enlazar contra algunos biblioteca que proporciona estos servicios básicos, si desea utilizarlos.

Dicho esto, su kit de herramientas proporciona librdimon.a biblioteca que proporciona todos esos servicios básicos. Esta biblioteca es en realidad una parte de la compilación libgloss . Si quieres enlazar contra ella, prueba el siguiente comando:

arm-none-eabi-gcc --specs=rdimon.specs   -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group -o test test.c

Esto enlaza bien en mi PC, pero si es lo que realmente quieres es otra historia (¿dónde esperas ver la salida printf(), de todos modos?).

Para usted chip que probablemente debería buscar para una biblioteca que redirige la salida estándar al puerto serie o proporciona salida de depuración a través de JTAG. Alternativamente, puede usar su función personalizada, por ejemplo, enviar la salida de depuración a la consola serie en lugar de printf() - depende de usted. Si decide usar printf() le sugiero que lea la documentación de libgloss.

También, sugiero buscar una cadena de herramientas que esté específicamente incluida para la familia STM32. Configurar correctamente todas estas cosas básicas(biblioteca C, script enlazador, etc.) requiere un poco de experiencia.

Edit: Muchos sistemas embebidos realmente no usan la biblioteca estándar de C, comenzando prácticamente desde cero. Si quieres ir por este camino, debes pasar -nostdlib a tu invocación gcc. Por supuesto, ya no tendrás cosas como printf() disponibles.

Edit 2: Otra forma es usar la biblioteca estándar (newlib, quiero decir) sin libgloss y proporcionar los stubs apropiados para las cosas que no necesita. Es posible que desee seguir este tutorial, donde _read y _write se implementa sobre el puerto serie, y todo lo demás se stubbed. Esto es probablemente lo que realmente quieres.

 26
Author: Code Painters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-07 10:01:42

Sé que esta es una vieja pregunta, pero me encontré con esto hoy al tratar de construir para una placa STM32. El proyecto que tengo tiene algunos scripts enlazadores (específicamente libs.ld). Añadiendo una entrada para libnosys.a en esto satisfecho el enlazador y pude continuar.

Libs.ld:

 GROUP(
   libgcc.a
   libg.a
   libc.a
   libm.a
   libnosys.a
 )
 7
Author: Shane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-15 06:32:08

Guardar su programa C como "myprint.c", lo compilo como sigue:

Brazo-ninguno-eabi-gcc myprint.c-lc-specs = nosys.especificaciones

No hay errores y la salida está bien.

 6
Author: Peter Teoh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-12 02:42:23

También hubo un problema con las llamadas a funciones malloc() y free() en el proyecto Eclipse. He escrito firmware para un microcontrolador STM32 usando Eclipse + GNU para el compilador cruzado ARM embedded GCC + STM32CubeMX para la inicialización de la periferia del microcontrolador y la creación de scripts de enlazador.

Cuando he añadido cadenas faltantes libg.a ( * ) y libnosys.a ( * ) en la sección DESCARTE del script .ld, mi proyecto se ha compilado correctamente.

 3
Author: Sergey Starovoitov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-11 21:13:32

Había creado un proyecto RTOS usando CubeMX y añadido un printf y tenía el mismo problema en la vinculación, mientras que la depuración utilizando OpenOCD.

Reemplazé el printf ("Hello ARM World!") con trace_puts ("Hello ARM World!"); y tenía los mensajes aparecen en la consola de depuración.

 0
Author: Laguna Thangarajah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-11 21:14:20