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 > Makefile hassles...

#12563 - Burre - Mon Nov 17, 2003 10:51 pm

Hi there.

I've been fooling around in the HAM environment for some time now and are eager to move on to DevKit Advance. The mission: to move my project from HAM to DKA and thus construct a makefile/linkscript combo that produces the same result (or close to). After having my own fair share of escapades in the subject, I'm desperate for help and/or pointers.

What is included in my project:
* Some HAM macros (should be fairly easy to move or replace with wrappers)
* Krawall (the real deal, not the demo) help on link scripts and/or makefile flags wanted
* Note. HAMlib is NOT in use (wich should ease a lot)
* The rest should be close to C/C++-standards

I'm mainly interested in how the AS and GCC targets for krawall should be arranged and what to do with the linkscripts (krawall comes with one, as does DKA and HAM, wich one do I use?).

As you've might have guessed I'm quite unexperienced with makefiles, however I've done makefiles in the past but they hardly ever exeeded two or perhaps three targets (meaning, simple makefiles).

All and any help highly appreciated!

:)
_________________
"The best optimizer is between your ears..."

#12569 - Andy Friesen - Tue Nov 18, 2003 3:49 am

I'm not familiar with how Krawall works, but, assuming you can get a .a file, you can just link it in with -l

I usually wind up doing something like:

Code:

OBJS =\
    a.o \
    b.o \
    .....

blah.gba: blah.elf
    objcopy -O binary blah.elf blah.gba

blah.elf: $(OBJS)
    gcc -o blah.elf $(OBJS) -lgba -lkrawall -lwhateverelse


I'm not sure what you'd need a linkscript for; I've never needed to use one personally.

#12582 - johnny_north - Tue Nov 18, 2003 4:15 pm

-no expert-
The linkscript is used primarily to make sure certain types of code and variables are put into the correct sections (iwram, ewram, rom).

I've had very good luck using Jeff Frohwein's linkscript and crt0 in conjunction with devkitadv R3 http://www.devrs.com/gba/. DKA R4 is improved in some ways - although I won't explore it until my current project is finished. It's possible that the linkscripts that you memtion will work - however, I know that jeff's LS/CR combo works well in that:

1) it has a section for optionally targeting c or c++
2) you can select the interrupt scheme based on your needs and I like it's method of handling the interrupts via a function pointer table
3) you can fiddle with the where and size of the stack
4) krawall will work with this setup

You can mix and match this stuff in a number of ways as well. I.e. you can use the Ham compiler/tool chain without using the hamlib at all.

If I remember correctly, using Jeff's set up requires comiling in the following order:
crt0.o crtbegin.o crtend.o otherfiles.o ...

hope that helps.

#12583 - johnny_north - Tue Nov 18, 2003 4:18 pm

another caveat - make sure that your linker flags indicates the option:
-nostartfiles

This will prevent linking the default crt0 and lnkscript.

#12594 - Quirky - Tue Nov 18, 2003 11:28 pm

Krawall is easy to include.

For compiling, make sure you get the directory containing krawall.h in your (gcc -I) includes for compilation of the files that call krawall routines.

e.g. if the .h is in a directory "krawall" on the same level as your project then it would be...

gcc -I../krawall -c sound.c

And for linking, the krawall library file isn't called "libkrawall.a", which would be the standard thing to do, so you can't use -l as Andy mentioned. But! you can just stick the file "krawall.lib" (as it is called) on the end of the list of your object files. e.g.

gcc -o game.elf main.o gfx.o krawall.lib

#12664 - Burre - Fri Nov 21, 2003 4:32 pm

Thanks for all the help, but I might need some more. Compiling to object files now work (haven't included krawall yet because I need to make sure that the rest works properly first).

Here what I've done and what the result is. I figure I've placed some commands in wrong order or forgot some flags or so but I can't find the problem. However compiling seems to work (it successfully compiles into .o files), but linking produces a massive amount of errors.

makefile (this makefile is based on the one in HAM to make sure that the result/usage is as similar as possible):
Code:

# Program name (like PROGNAME.gba)
PROGNAME=meteor

# Directory for the env (edit if placed elsewhere)
DEVDIR = C:/devkitadv-r5-beta-3

# GCC base directory
GCCARM = $(DEVDIR)/arm-agb-elf

# GCC bin directory
GCCBIN = $(DEVDIR)/bin

# Object files (DO NOT EDIT)
OFILES = crt0.o

# Added object files (EDITABLE)
OFILES += main.o meteor.o collision.o sprite.o ship.o gameobject.o mapapi.o objapi.o irqapi.o dialogue.o game_menu.o

# Libraries to link with
LD_LIBS = -lm -lstdc++ -lsupc++ -lc

# "Inspired" by HAM makefile
#---------------------------------------------------
EXEC_PREFIX = arm-agb-elf-

INCDIR      = -I $(GCCARM)/include -I $(DEVDIR)/include/c++/3.2.2 -I $(DEVDIR)/lib/gcc-lib/arm-agb-elf/3.2.2/include
LIBDIR      = -L $(GCCARM)/lib -L $(DEVDIR)/lib/gcc-lib/arm-agb-elf/3.2.2
CFLAGS      = $(INCDIR) -marm -mthumb-interwork -mlong-calls -Wall -save-temps -fverbose-asm -nostartfiles -c
LDFLAGS     =
ASFLAGS     = -mthumb-interwork
PATH       +=;$(DEVDIR)
CC          = $(DEVDIR)/bin/$(EXEC_PREFIX)gcc.exe
GDB         = $(DEVDIR)/bin/$(EXEC_PREFIX)insight.exe
AS          = $(DEVDIR)/bin/$(EXEC_PREFIX)as.exe
LD          = $(DEVDIR)/bin/$(EXEC_PREFIX)ld.exe
OBJCOPY     = $(DEVDIR)/bin/$(EXEC_PREFIX)objcopy.exe
SHELL       = $(DEVDIR)/tools/sh.exe
PATH       := $(DEVDIR)/bin:$(PATH)
#---------------------------------------------------


###########################################
# Standard Makefile targets start here
###########################################
all : $(PROGNAME).gba clean

$(PROGNAME).gba : $(PROGNAME).elf
   $(OBJCOPY) -v -O binary $(PROGNAME).elf $(PROGNAME).gba


$(PROGNAME).elf : $(OFILES)
   $(LD) $(LDFLAGS) -o $(PROGNAME).elf $(OFILES)
   $(CC) $(CFLAGS) $(OFILES) $(LIBDIR)
   
#
# Compile Targets for C/C++
# (refined by Ulrich Hecht, thanks)
#
.s.o:
   $(AS) $(ASFLAGS) $< -o $@


crt0.o : e:/program/HAM271/system/crt0.s
   $(AS) $(ASFLAGS) e:/program/HAM271/system/crt0.s -ocrt0.o #This is the crt0.s file from the HAM-environment, using the DKA crt0.s only results in a lot of ASM errors.

#
# Other Targets
#
fixheader:
   $(DEVDIR)/tools/ham/gbafix.exe $(PROGNAME).gba 

clean:
   $(DEVDIR)/tools/rm -f *.o *.i *.ii


Output:
Code:

C:/devkitadv-r5-beta-3/bin/arm-agb-elf-as.exe -mthumb-interwork  e:/program/HAM2
71/system/crt0.s -ocrt0.o
g++    -c -o main.o main.cpp
g++    -c -o meteor.o meteor.cpp
g++    -c -o collision.o collision.cpp
g++    -c -o sprite.o sprite.cpp
g++    -c -o ship.o ship.cpp
g++    -c -o gameobject.o gameobject.cpp
g++    -c -o mapapi.o mapapi.cpp
g++    -c -o objapi.o objapi.cpp
g++    -c -o irqapi.o irqapi.cpp
g++    -c -o dialogue.o dialogue.cpp
g++    -c -o game_menu.o game_menu.cpp
C:/devkitadv-r5-beta-3/bin/arm-agb-elf-ld.exe  -o meteor.elf crt0.o main.o meteo
r.o collision.o sprite.o ship.o gameobject.o mapapi.o objapi.o irqapi.o dialogue
.o game_menu.o  -lm -lstdc++ -lsupc++ -lc
C:/devkitadv-r5-beta-3/bin/arm-agb-elf-ld.exe: Warning: main.o does not support
interworking, whereas meteor.elf does
C:/devkitadv-r5-beta-3/bin/arm-agb-elf-ld.exe: Warning: meteor.o does not suppor
t interworking, whereas meteor.elf does
C:/devkitadv-r5-beta-3/bin/arm-agb-elf-ld.exe: Warning: collision.o does not sup
port interworking, whereas meteor.elf does
C:/devkitadv-r5-beta-3/bin/arm-agb-elf-ld.exe: Warning: sprite.o does not suppor
t interworking, whereas meteor.elf does


<b>*Continuing like that for about 50 lines or so*</b>

C:/devkitadv-r5-beta-3/bin/arm-agb-elf-ld.exe: Warning: /devkitadv-r5-beta-3/arm
-agb-elf/lib\libc.a(impure.o) does not support interworking, whereas meteor.elf
does
C:/devkitadv-r5-beta-3/bin/arm-agb-elf-ld.exe: Warning: /devkitadv-r5-beta-3/arm
-agb-elf/lib\libc.a(reent.o) does not support interworking, whereas meteor.elf d
oes

crt0.o: In function `__FarProcedure':
crt0.o(.text+0x1b4): undefined reference to `__sp_irq'
crt0.o(.text+0x1b8): undefined reference to `__sp_usr'
crt0.o(.text+0x1bc): undefined reference to `__intr_vector_buf'
crt0.o(.text+0x1c4): undefined reference to `__text_start'
crt0.o(.text+0x1c8): undefined reference to `__sp_usr_offset'
crt0.o(.text+0x1d4): undefined reference to `__data_lma'
crt0.o(.text+0x1e0): undefined reference to `__iwram_lma'
crt0.o(.text+0x1f8): undefined reference to `__ewram_lma'
crt0.o: In function `IntrRet':
crt0.o(.iwram+0x10c): undefined reference to `IntrTable'
meteor.o: In function `METEOR::Game_Level_001_Init()':
meteor.o(.text+0xa20): undefined reference to `_Unwind_SjLj_Register'
meteor.o(.text+0xb08): undefined reference to `_Unwind_SjLj_Resume'
meteor.o(.text+0xbf0): undefined reference to `_Unwind_SjLj_Resume'

<b> *Continuing like that* </b>

dialogue.o(.text+0x204): undefined reference to `_Unwind_SjLj_Register'
dialogue.o(.text+0x320): undefined reference to `_Unwind_SjLj_Resume'
dialogue.o(.text+0x344): undefined reference to `_Unwind_SjLj_Unregister'
game_menu.o: In function `GameMenu::Show()':
game_menu.o(.text+0xe08): undefined reference to `_Unwind_SjLj_Register'
game_menu.o(.text+0xf10): undefined reference to `_Unwind_SjLj_Resume'
game_menu.o(.text+0x11c0): undefined reference to `_Unwind_SjLj_Resume'
game_menu.o(.text+0x1298): undefined reference to `_Unwind_SjLj_Unregister'
/devkitadv-r5-beta-3/arm-agb-elf/lib\libstdc++.a(eh_personality.o): In function
`base_of_encoded_value':
../../../../gcc-3.2.2/gcc/unwind-pe.h:106: undefined reference to `_Unwind_GetRe
gionStart'
/devkitadv-r5-beta-3/arm-agb-elf/lib\libstdc++.a(eh_personality.o): In function
`parse_lsda_header':
../../../../gcc-3.2.2/libstdc++-v3/libsupc++/eh_personality.cc:59: undefined ref
erence to `_Unwind_GetRegionStart'
/devkitadv-r5-beta-3/arm-agb-elf/lib\libstdc++.a(eh_personality.o): In function
`__gxx_personality_sj0':
../../../../gcc-3.2.2/libstdc++-v3/libsupc++/eh_personality.cc:418: undefined re
ference to `_Unwind_SetGR'
../../../../gcc-3.2.2/libstdc++-v3/libsupc++/eh_personality.cc:420: undefined re
ference to `_Unwind_SetGR'

<b>*Continuing like that*</b>

o `_Unwind_SjLj_Resume'
/devkitadv-r5-beta-3/arm-agb-elf/lib\libstdc++.a(eh_catch.o): In function `__cxa
_end_catch':
../../../../gcc-3.2.2/libstdc++-v3/libsupc++/eh_catch.cc:90: undefined reference
 to `_Unwind_DeleteException'
make: *** [meteor.elf] Error 1

_________________
"The best optimizer is between your ears..."

#12666 - johnny_north - Fri Nov 21, 2003 5:22 pm

You're using a couple of conventions that I'm not familiar with. I'd say that you might focus on two areas:

1) Make sure that you have selected the correct options in crt0.s for your project. These may include c++ support, interupt handling, and stack placement.
2) Make sure you've selected the appropriate link flags and that they are coming into play at the appropriate step in the process. It appears that some of your CFLAGS options actually belong to LDFLAGS

I can't say that either of these is the case, but probably. I'm not familiar with conventions like using '+=' in the make file. Also, the placement of tabs and spaces seems to be citical so stuff like:
Code:
-ocrt0.o

may cause problems not caused by
Code:
-o crt0.o


Here's a sample that works using no wild cards:

Code:
GCCARM = C:\WINDOWS\Desktop\devkit\devkitadv\bin
PRJDIR = c:\windows\Desktop\gamedir
LIBDIR  = C:\WINDOWS\Desktop\devkit\devkitadv\lib\gcc-lib\arm-agb-elf\3.0.2\interwork
LIBDIR2 = C:\WINDOWS\Desktop\devkit\devkitadv\arm-agb-elf\lib\interwork
INCDIR  = C:\WINDOWS\Desktop\devkit\devkitadv\lib\gcc-lib\arm-agb-elf\3.0.2\include
INCDIR2 = C:\WINDOWS\Desktop\devkit\devkitadv\arm-agb-elf\include

CFLAGS  = -I $(INCDIR2) -I $(INCDIR) -I $(PRJDIR) -mthumb-interwork -mthumb -c -g -Wall
SFLAGS  = -I $(INCDIR2) -I $(INCDIR) --warn -mthumb-interwork -marm7tdmi
LDFLAGS = -L $(LIBDIR) -L $(LIBDIR2) -L $(PRJDIR) -T lnkscript -lGbaPlayerGCC -lm -lg -lstdc++ -lgcc -nostartfiles -Wl,-Map,bin.map

GFXFILES =
MUSICFILES =
VOICEFILES =
OFILES = crt0.o crtbegin.o crtend.o main.o

all: game.bin

game.bin: game.elf
   objcopy -O binary game.elf game.bin

game.elf: $(OFILES) $(GFXFILES) $(MUSICFILES) $(VOICEFILES)
   gcc -o game.elf $(OFILES) $(GFXFILES) $(MUSICFILES) $(VOICEFILES) $(LDFLAGS)

main.o: main.cpp
   gcc $(CFLAGS) main.cpp
Crt0.o: Crt0.s
   as $(SFLAGS) -o Crt0.o Crt0.s


The code listing here will wrap certain long lines which won't work in an actual make file. If you need to break a line use the " \" at the end of the line. That's "(space)\". You may or may not want to include the -mthumb option. Also, certain measures need to be taken when using -O3. I've also include a mod playing lib other than karwall, but the idea is the same. I just renamed the lib replacing the .lib extension with .a so that it will cooperate with the gcc linking process.

#12679 - Burre - Sat Nov 22, 2003 2:30 pm

I think I'm getting close to solving this problem now. I've combined my makefile with yours, and it solved a lot of the error messages (I think I messed up with the linkscript and crt0.s).

However, some minor problems have occured:

Code:

# Program name (like PROGNAME.gba)
PROGNAME=meteor

# Directory for the env (edit if placed elsewhere)
DEVDIR = C:/devkitadv-r5-beta-3

#---------------------------------------------------
EXEC_PREFIX = arm-agb-elf-

CC          = $(DEVDIR)/bin/$(EXEC_PREFIX)gcc.exe
AS          = $(DEVDIR)/bin/$(EXEC_PREFIX)as.exe
OBJCOPY     = $(DEVDIR)/bin/$(EXEC_PREFIX)objcopy.exe
#---------------------------------------------------

PRJDIR = $(DEVDIR)/project
LIBDIR  = $(DEVDIR)/arm-agb-elf/lib/interwork
LIBDIR2 = $(DEVDIR)/lib/gcc-lib/arm-agb-elf/3.2.2/interwork
INCDIR  = $(DEVDIR)/lib/gcc-lib/arm-agb-elf/3.2.2/include
INCDIR2 = $(DEVDIR)/arm-agb-elf/include

CFLAGS  = -I $(INCDIR2) -I $(INCDIR) -I $(PRJDIR) -mthumb-interwork -mthumb -c -g -Wall
SFLAGS  = -I $(INCDIR2) -I $(INCDIR) --warn -mthumb-interwork -marm7tdmi
LDFLAGS = -L $(LIBDIR) -L $(LIBDIR2) -L $(PRJDIR) -T $(DEVDIR)/jeff/lnkscript -lm -lg -lstdc++ -lsupc++ -lgcc -lc -nostartfiles -Wl

GFXFILES =
MUSICFILES =
OFILES = crt0.o \
$(DEVDIR)/jeff/crtbegin.o \
$(DEVDIR)/jeff/crtend.o \
main.o meteor.o collision.o sprite.o ship.o gameobject.o mapapi.o objapi.o irqapi.o dialogue.o game_menu.o

#
# Targets start here
#

all: $(PROGNAME).gba fixheader clean

$(PROGNAME).gba: $(PROGNAME).elf
   $(OBJCOPY) -O binary $(PROGNAME).elf $(PROGNAME).gba

$(PROGNAME).elf: $(OFILES) $(GFXFILES) $(MUSICFILES)
   $(CC) -o game.elf $(OFILES) $(GFXFILES) $(MUSICFILES) $(LDFLAGS)
   
# Target for cpp files
.cpp.o:
   $(CC) $(CFLAGS) $< -o $@
   
# Handle the crt0.o file
crt0.o: $(DEVDIR)/jeff/crt0.s
   $(AS) $(SFLAGS) $(DEVDIR)/jeff/crt0.s -o crt0.o
   
# These two don't need any compilation since they're already o-files
crtbegin.o:
crtend.o:

# Make GBA-file ready for hardware
fixheader:
   $(DEVDIR)/tools/ham/gbafix.exe $(PROGNAME).gba 

# Clean up when done
clean:
   $(DEVDIR)/tools/rm -f *.o *.i *.ii


Output:
Code:


* Successful compilation and assemblation followed by:

C:/devkitadv-r5-beta-3/bin/arm-agb-elf-gcc.exe -o game.elf crt0.o C:/devkitadv-r5-beta-3/jeff/crtbegin.o C:/devkitadv-r5 -beta-3/jeff/crtend.o main.o meteor.o collision.o sprite.o ship.o gameobject.o mapapi.o objapi.o irqapi.o dialogue.o game_menu.o    -L C:/devkitadv-r5-beta-3/arm-agb-elf/lib/interwork -L C:/devkitadv-r5-beta-3/lib/gcc-lib/arm-agb-elf/3.2.2/interwork -L C:/devkitadv-r5-beta-3/project -T C:/devkitadv-r5-beta-3/jeff/lnkscript -lm -lg -lstdc++ -lsupc++ -lgcc -lc
 -nostartfiles -Wl

C:\devkitadv-r5-beta-3\bin\..\lib\gcc-lib\arm-agb-elf\3.2.2\..\..\..\..\arm-agb-elf\bin\ld.exe: section .data [082e8770-> 082e9143] overlaps section .gcc_except_table [082e86f4 -> 082e877b]

C:/devkitadv-r5-beta-3/arm-agb-elf/lib/interwork\libg.a(agbmain.o): In function `AgbMain':
../../../../../../../gcc-3.2.2/newlib/libc/sys/agb/agbmain.c:24: undefined reference to `_init'
../../../../../../../gcc-3.2.2/newlib/libc/sys/agb/agbmain.c:25: undefined reference to `_fini'
C:/devkitadv-r5-beta-3/arm-agb-elf/lib/interwork\libg.a(agb-sbrk.o): In function `_sbrk':
../../../../../../../gcc-3.2.2/newlib/libc/sys/agb/agb-sbrk.c:28: undefined reference to `__appended_end'
../../../../../../../gcc-3.2.2/newlib/libc/sys/agb/agb-sbrk.c:28: undefined reference to `__heap_limit'
../../../../../../../gcc-3.2.2/newlib/libc/sys/agb/agb-sbrk.c:28: undefined reference to `__appended_start'
collect2: ld returned 1 exit status
make: *** [game.elf] Error 1


It seems like it complains about libc, but that lib is already included (-lc in the makefile).

What could be wrong?

Note: I'm using Jeff Frohwein's crt0.s and linkscript (wich I found out is the same as included in HAM, so it shouldn't interfere with my code) and crtbegin.o and crtend.o from DKA.

Please help.
_________________
"The best optimizer is between your ears..."

#12715 - Miked0801 - Mon Nov 24, 2003 9:02 am

From what I can see, you've got 2 pieces of code requesting the same area on the cartridge for ROM - perhaps a funky __attribute(section...) in your code somewhere? Good luck on this one. I usually start punching things when I get section conflicts... :)

#12721 - johnny_north - Mon Nov 24, 2003 3:42 pm

Nothing like getting this far along and running up against a wall of link errors. The only thing I can think of this morining is to make sure that the crt0.s and the lnkscript are out of the same version. They are meant to go together and differing version might cause these problems. I'll think on this a while. Otherwise, take Mike D's feel-good approach.

Oh one more thing. I'm not personally using R5 yet. You may want to experiment with R4 and run the same make against it - just for an experiment. I know Jeff's file combo works with R4. The R4 includes a windows patch in one of the zip files. I think this one needs to be applied after the rest are unzipped into a directory to make sure the whole setup works.