Why does DevkitARM GBA linker detect multiple definitions?

202 Views Asked by At

Running make on this code to cross-compile for GBA with DevkitARM results in the following:

main.c
tilemap.c
linking cartridge
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/bin/ld: tilemap.o:/home/shuffles/repos/_gba_dev/catsvsrats/include/raw/images/gui/map/tiles25.h:14: multiple definition of `TILES25_IMAGE'; main.o:/home/shuffles/repos/_gba_dev/catsvsrats/include/raw/images/gui/map/tiles25.h:14: first defined here
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/bin/ld: tilemap.o:/home/shuffles/repos/_gba_dev/catsvsrats/include/raw/tilemap_data.h:11: multiple definition of `TILEMAP'; main.o:/home/shuffles/repos/_gba_dev/catsvsrats/include/raw/tilemap_data.h:11: first defined here
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/11.1.0/../../../../arm-none-eabi/bin/ld: tilemap.o:/home/shuffles/repos/_gba_dev/catsvsrats/include/raw/images/gui/map/tiles25.h:337: multiple definition of `TILES25_PALETTE'; main.o:/home/shuffles/repos/_gba_dev/catsvsrats/include/raw/images/gui/map/tiles25.h:337: first defined here
collect2: error: ld returned 1 exit status
make[1]: *** [/opt/devkitpro/devkitARM/gba_rules:25: /home/shuffles/repos/_gba_dev/catsvsrats/catsvsrats.elf] Error 1
make: *** [Makefile:121: build] Error 2

Although the linker complains of duplicate definitions, I have not found any in the code, and all header files have #include guards. Any info helps.

1

There are 1 best solutions below

0
On BEST ANSWER

Apparently you include the header in multiple sources. The header guard just prevents multiple definitions/declarations in the same translation unit. Each of the produced object file will contain the mentioned variable, and so the linker is correct by giving you the error.

Please do not define variables in header files. Define them in an associated source file, in your case "tiles25.c". Add that source to the list of sources to compile and link.

The header file should declare the variable, use the keyword extern for this.

/* tiles25.h */
/* ... */
extern const uint16_t TILES25_PALETTE[];
/* ... */
/* tiles25.c */
/* ... */
const uint16_t TILES25_PALETTE[] = {
};
/* ... */