gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > multiple source file, linking err (GCC)

#74619 - aik6980 - Mon Mar 06, 2006 1:08 pm

Here is my problem, I want to separate the src file for functions, and they are linking to the same header that contained some global variable.

here is my error message;
Code:

mygba.o(.data+0x0): multiple definition of `OAM'
main.o(.data+0x0): first defined here
mygba.o(.data+0x4): multiple definition of `OBJPalMem'
main.o(.data+0x4): first defined here
mygba.o(.data+0x8): multiple definition of `FrontBuffer'
main.o(.data+0x8): first defined here
mygba.o(.data+0xc): multiple definition of `OAMData'
main.o(.data+0xc): first defined here
mygba.o(.data+0x10): multiple definition of `sprites'
main.o(.data+0x10): first defined here
collect2: ld returned 1 exit status
make: *** [main.elf] Error 1


and here is my header code
Code:

#ifndef MYGBA_H
#define MYGBA_H

//include file

...
//***TYPE_COMMON***
...
//***GLOBAL***
extern u16* OAM =      (u16*)0x7000000;
extern u16* OBJPalMem =   (u16*)0x5000200;
extern u16* FrontBuffer =    (u16*)0x6000000;
extern u16* OAMData =      (u16*)0x6010000;
//create array of sprites
extern OAMEntry sprites[128]={0};

..
#ifndef MYGBA_C

//***FUNCTION***
//function to copy our Sprite --> OAMMemory
void CopyOAM(void);
//Set sprites off screen
void InitSprites(void);
//Update during VBlank
void WaitForVSync(){
   while(REG_VCOUNT != 160);
}
#endif
#endif


my functions, struct and #define work, but not for the global var
anyidea??
Code:

#define MYGBA_C
//include
#include "mygba.h"

//function
//function to copy our Sprite --> OAMMemory
void CopyOAM(void){
   u16 loop=0;
   u16* temp=(u16*)sprites; //point to sprites
   for(loop=0;loop<128*4;loop++)
      OAM[loop] = temp[loop];   //need to use temp, because we want to pack each
   //data to 16 bits first before write down to OAMMemory
}
//Set sprites off screen
void InitSprites(){
   u16 loop=0;
   for(loop=0;loop<128;loop++){
      sprites[loop].attribute[0]=SCRWIDTH; //y >159
      sprites[loop].attribute[1]=SCRHEIGHT; //x >239
   }
}


please help

thank a lot

#74622 - gauauu - Mon Mar 06, 2006 2:10 pm

Don't assign the value to the global variables in the .h file. Move the assignment to one of the .c files.

like:

header:
Code:

extern u16* OAM ;
extern u16* OBJPalMem;
extern u16* FrontBuffer;
extern u16* OAMData;
//create array of sprites
extern OAMEntry sprites[];


and in ONE of the source files:
Code:

//***GLOBAL***
u16* OAM =      (u16*)0x7000000;
u16* OBJPalMem =   (u16*)0x5000200;
u16* FrontBuffer =    (u16*)0x6000000;
u16* OAMData =      (u16*)0x6010000;
//create array of sprites
OAMEntry sprites[128]={0};

#74631 - aik6980 - Mon Mar 06, 2006 5:21 pm

I try that also. However, do you have another way?

my Global variables are used in both of them. If they define in any src file, the rest cannot compile.

:<

#74633 - poslundc - Mon Mar 06, 2006 5:54 pm

aik6980 wrote:
I try that also. However, do you have another way?

my Global variables are used in both of them. If they define in any src file, the rest cannot compile.


Do it the way gauauu showed you.

Header file contains "extern" declarations. Then #include the header file in any .c file that needs to access the global variables.

Then define the actual instance of each global variable in one .c file, and one .c file only.

This is how global variables work. You declare a single instance of them, and then use "extern" to tell the compiler that it exists in some other .c module, and to let the linker sort it out.

If you don't use the "extern" keyword, the compiler generates an instance in every .c module, and when it comes time to link you get the multiple instance error you've been having.

If you don't put a single instance into one of your .c files, the code will compile using the "extern" keyword but when it comes time to link, the linker won't be able to find any modules that contain the actual instance.

Dan.

#74643 - aik6980 - Mon Mar 06, 2006 7:00 pm

sorry gauauu, i miss reading the extern declaration.

and it work now.

thank you you guys very much

:)