multiple definition of `_start'

来源:互联网 发布:如何评价新东方 知乎 编辑:程序博客网 时间:2024/05/01 14:39

1.关于GCC编译问题:

huge.bin(.text+0x0): In function `_start':
: multiple definition of `_start'

 

 

2.这种问题,碰到很多次了, 因为是新手,这样就给我带来了很大的麻烦!

 

3.编译虽然成功了 但是 通过arm-linux-gcc -v huge.bin  来观察 就出现了这么多的错误提示! 真不知道该如何是好!

 

下面贴出全部的 编译信息:

book@book-desktop:~/TQ2440/huge/build/exes$
book@book-desktop:~/TQ2440/huge/build/exes$ arm-linux-gcc -v huge.bin


Reading specs from /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/specs
Configured with: /work/tools/create_crosstools/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6/gcc-3.4.5/configure --target=arm-linux --host=i686-host_pc-linux-gnu --prefix=/work/tools/gcc-3.4.5-glibc-2.3.6 --with-float=soft --with-headers=/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/include --with-local-prefix=/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long
Thread model: posix
gcc version 3.4.5
 /work/tools/gcc-3.4.5-glibc-2.3.6/libexec/gcc/arm-linux/3.4.5/collect2 --eh-frame-hdr -dynamic-linker /lib/ld-linux.so.2 -X -m armelf_linux -p /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crt1.o /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crti.o /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/crtbegin.o -L/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5 -L/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib huge.bin -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/crtend.o /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crtn.o
collect2: ld terminated with signal 11 [Segmentation fault]
huge.bin(.text+0x0): In function `_start':
: multiple definition of `_start'
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crt1.o(.text+0x0): first defined here
huge.bin(.fini+0x0):/work/tools/create_crosstools/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6/build-glibc/csu/crti.S:52: multiple definition of `_fini'
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crti.o(.fini+0x0):/work/tools/create_crosstools/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6/build-glibc/csu/crti.S:13: first defined here
huge.bin(.got+0x0): multiple definition of `_GLOBAL_OFFSET_TABLE_'
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crti.o(.got.plt+0x0): first defined here
huge.bin(.rodata+0x0): multiple definition of `_IO_stdin_used'
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crt1.o(.rodata+0x0): first defined here
huge.bin(.data+0x0): In function `__data_start':
: multiple definition of `__data_start'
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crt1.o(.data+0x0): first defined here
huge.bin(.data+0x4): In function `__data_start':
: multiple definition of `__dso_handle'
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/crtbegin.o(.data+0x0): first defined here
huge.bin(.init+0x0):/work/tools/create_crosstools/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6/build-glibc/csu/crti.S:37: multiple definition of `_init'
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crti.o(.init+0x0): first defined here
/work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5/../../../../arm-linux/lib/crti.o(.dynamic+0x0): multiple definition of `_DYNAMIC'
huge.bin(.dynamic+0x0): first defined here

 

 

3.只能求助论坛了:

 估计是动态链接的原因!

-l name 在连接时使用函数库libname.a,连接程序在-Ldir选项指定的目录下和/lib,/usr/lib目录下寻找该库文件。在没有使用-static选项时,如果发现共享函数库libname.so,则使用libname.so进行动态连接

-static 禁止与共享函数库连接。

-shared 尽量与共享函数库连接

date:2012-10-26


2013-4-22:来自StudyOS的链接不成功报错:

arm-linux-ld -Bstatic -T /home/book/TQ2440/StudyOS/startup/StudyOS.lds   -o StudyOS /home/book/TQ2440/StudyOS/startup/libstartup.a /home/book/TQ2440/StudyOS/major/libmain.a /home/book/TQ2440/StudyOS/drivers/strings/libstrings.a /home/book/TQ2440/StudyOS/drivers/interrupt/libinterrupt.a /home/book/TQ2440/StudyOS/drivers/hardware/libhardware.a /home/book/TQ2440/StudyOS/drivers/general/libgeneral.a /home/book/TQ2440/StudyOS/drivers/fontlibrary/libfontlibrary.a /home/book/TQ2440/StudyOS/memory/libmemory.a /home/book/TQ2440/StudyOS/application/libapp.a  \

                -L /work/tools/gcc-3.4.5-glibc-2.3.6/lib/gcc/arm-linux/3.4.5 -lgcc\

                -Map StudyOS.map -o StudyOS

/home/book/TQ2440/StudyOS/major/libmain.a(main.o)(.data+0x44): multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

/home/book/TQ2440/StudyOS/drivers/interrupt/libinterrupt.a(interrupt.o)(.data+0x84): multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

/home/book/TQ2440/StudyOS/drivers/hardware/libhardware.a(lcddriver.o)(.data+0x18):  multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

/home/book/TQ2440/StudyOS/drivers/hardware/libhardware.a(lcdappl.o)(.data+0x0):  multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

/home/book/TQ2440/StudyOS/drivers/hardware/libhardware.a(mouse.o)(.data+0x0):  multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

/home/book/TQ2440/StudyOS/drivers/hardware/libhardware.a(touch_screen.o)(.data+0x0):  multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

/home/book/TQ2440/StudyOS/drivers/hardware/libhardware.a(tc_correct.o)(.data+0x0):  multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

/home/book/TQ2440/StudyOS/drivers/hardware/libhardware.a(timer.o)(.data+0x0):  multiple definition of `BOOTINFO'

startup/nand.o(.data+0x0): first defined here

make: *** [StudyOS] Error 1



PS:这种在编译的时候能够成功,但链接不成功的例子,在我们 Linux 环境编译下,已经不是第一次了. 

下面我们来贴一下源代码中 BOOTINFO 的定义及引用文件 :

结构体原型:

struct BOOT

{

U8 cyls,leds,vmode,reserve;

U16 scrn_x,scrn_y;

U16 *vram;

}BOOTINFO = {0,0,0,0,480,272,NULL};

用到这个变量的文件夹:

Struct.h (include):typedef struct BOOT BOOT_INFO;

Lcdappl.c (drivers\hardware):static BOOT_INFO *bootinfo;

Lcddriver.c (drivers\hardware): static BOOT_INFO *bootinfo = (BOOT_INFO *)&BOOTINFO;

Mouse.c (drivers\hardware): static BOOT_INFO *bootinfo;

Tc_correct.c (drivers\hardware): static BOOT_INFO *bootinfo;

Touch_screen.c (drivers\hardware): static BOOT_INFO *bootinfo = (BOOT_INFO *)&BOOTINFO;



我们在Struct.h这个文件下定义了结构体,其中BOOT_INFO 结构体就是定义在其中,我们在很多.c文件中都包含了Struct.h这个文件 导致 这种报错,实属 耦合性 太高了,这是模块化编程中一个比较麻烦的事情.

当然我们有办法解决它:




解决方案:
date:2013-4-25

前言:
   今天我们这种错误,终于可以彻底解决了,一般伴随着 “重复定义(multiple definition of 'XXX')”的错误提示的还会携带 “未定义错误( undefined reference to ` XXX ')
这两个错误,在我们的"模块化编程中"是经常性的遇到的.实在太常见了,这里我需要来总结一下,避免以后初学者摸不着头脑
   
   ⑴先来说说我们上面那个错误导致的原因吧!  笔者在写StudyOS 的时候,采取的是“模块化编程”的思想,但是我们知道,C语言的灵活性比较高, 模块化的使用 也不是只有一种 方法! 来说说我熟悉的两种
   假设:如果在A.C函数中使用B.C中定义的函数
   ①:使用 extern 声明即可!笔者刚开始写的时候使用的是这种方法.也是为了避免 重复定义(multiple definition of 'XXX') 或者“ 未定义错误( undefined reference to ` XXX ') ”这样的错误提示. 后来笔者发现,如果 N(上百/千个)个 .C 文件中需要使用 B.C中定义的函数,那么你就必须使用 N次 extern 来进行声明. 当然还有更糟糕的. 这种方法对于工程比较小的项目还是可行的,但是如果代码量比较庞大,那你会累死,可读性也不高. 比如 Linux内核代码.  

   ②第二种方法:把B.C中定义的函数 全部声明 到B.H文件当中去,然后在B.C中包含. 如果A.C中需要调用 B.C中定义的函数,那么 在A.C中 包含B.H 。 也就是 #include"B.H"   就可以了吗? 当然不是,这样或许一两个文件包含 B.H没事,多了的话,不会出现“ 未定义错误( undefined reference to ` XXX ') ”只会出现重复定义(multiple definition of 'XXX') 
    其实你可能会觉得你只定义了一次,为什么会说" 重复定义(multiple definition of 'XXX') "呢? 原因就在这里:#include"B.H", B.H中声明的函数多次被包含进 XX.C文件中,编译器会认为你定义了多次.那么有解决的办法没? 当然是有的,其实很简单。
     使用下面的定义:
        #ifndef  __XXX_H 
       #define __XXX_H
       .................................(正文:你所需要声明的函数/变量)
       #endif      
注:条件指示符 #ifndef 的最主要目的是防止头文件重复包含编译


    这样就可以消除" 重复定义(multiple definition of 'XXX') "这样的错误提示了。

PS:综上,如果是比较大的项目,笔者建议采用第二种 方法, 一是便于“维护”,二是“可读性性”比较好.

由于笔者刚开始没有使用第二种方法,导致后来项目无法写下去了,而且很难修改,动不动就报错.




所以前面的错误也迎刃而解了。


转载:http://blog.sina.com.cn/s/blog_87c063060101bmtt.html



0 0