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.

Beginners > OS X, GBASDK, and Linker errors...

#48333 - justinGBA - Tue Jul 19, 2005 8:41 am

Well, first off, i am new to mac and new to Xcode. I am wanting what GBASDK has to offer, but so far it seems like a dirty hack that could maybe be done better if i knew what i was doing...

So now the question? Here is the error i currently get...

source/helloworld.c:10: warning: implicit declaration of function `rand'
source/helloworld.c:10: warning: unused variable `myNumb'
Linking object files
/usr/local/gbasdk/arm-agb-elf/bin/ld: Dwarf Error: mangled line number section.
./build/helloworld.o: In function `AgbMain':
./build/helloworld.o(.text+0x28): undefined reference to `rand'


here is my make file...
Code:

# -----------------------------------------------------------------------------
# \file         makefile
# \brief      The SGADE template make file
# \date         August 23, 2002
#
# \author      Jaap Suter, Mark T. Price
#
# This file contains the make-instructions for a SGADE project. In
# order to use this make file you need to change
#   GCC_DIR,
#   PROJECT_DIR,
#   SOCRATES_LIB_DIR and
#   SOCRATES_INC_DIR and
# to the locations on your own computer.
#
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Project name definition;
# -----------------------------------------------------------------------------

PROJECT      = helloworld

# -----------------------------------------------------------------------------
# Base directory of the project. Replace this with wherever
# you have put the sample application on your computer
# -----------------------------------------------------------------------------

PROJECT_DIR   = .

# -----------------------------------------------------------------------------
# GCC Version you're using. If you're using the latest DevKitAdv this
# should be correct already.
# -----------------------------------------------------------------------------
GCC_VERSION   = 3.0.4

# -----------------------------------------------------------------------------
# Base directory for GCC Arm-Agb-Elf compiler. Replace with
# wherever you have put it.
# -----------------------------------------------------------------------------

GCC_DIR  = /usr/local/gbasdk/arm-agb-elf

# -----------------------------------------------------------------------------
# Socrates library and header directories. Replace this with wherever
# you have put the Socrates on your computer
# -----------------------------------------------------------------------------

SOCRATES_LIB_DIR   = /usr/local/gbasdk/lib
SOCRATES_INC_DIR   = /usr/local/gbasdk/include/sgade

# -----------------------------------------------------------------------------
# Socrates library itself;
# -----------------------------------------------------------------------------
SOCRATES_LIB      = $(SOCRATES_LIB_DIR)/libSocrates.a

# -----------------------------------------------------------------------------
# Compiler directories for includes and libs.
# Assuming you are using Devkit Advance there should be no need to change
# these, since they are derived from the above CMP_DIR directory definition.
# -----------------------------------------------------------------------------

STD_LIB_DIR0 = $(GCC_DIR)/lib/gcc-lib/arm-agb-elf/$(GCC_VERSION)/interwork
STD_LIB_DIR1 = $(GCC_DIR)/arm-agb-elf/lib/interwork

STD_INC_DIR0 = $(GCC_DIR)/lib/gcc-lib/arm-agb-elf/$(GCC_VERSION)/include
STD_INC_DIR1 = $(GCC_DIR)/arm-agb-elf/include

# -----------------------------------------------------------------------------
# Project directories.
# -----------------------------------------------------------------------------

INC_DIR      = $(PROJECT_DIR)/include
SRC_DIR      = $(PROJECT_DIR)/source
CRT0_S_DIR   = $(PROJECT_DIR)
LINK_SCRIPT_DIR = $(PROJECT_DIR)
OBJ_DIR      = $(PROJECT_DIR)/build
ELF_DIR      = $(PROJECT_DIR)/build
DAT_DIR      = $(PROJECT_DIR)/data

# -----------------------------------------------------------------------------
# Define the flags for the compiler, the assembler and the linker;
# -----------------------------------------------------------------------------
C_FLAGS  = -I$(DAT_DIR) -I$(INC_DIR) -I $(SOCRATES_INC_DIR) -I$(STD_INC_DIR0) -I$(STD_INC_DIR1) -I $(SGADE_SRC_DIR) -mthumb -mthumb-interwork -c -g -Wall -fverbose-asm
CPP_FLAGS  = -I$(DAT_DIR) -I$(INC_DIR) -I $(SOCRATES_INC_DIR) -I$(STD_INC_DIR0) -I$(STD_INC_DIR1) -I $(SGADE_SRC_DIR) -mthumb -mthumb-interwork -c -g -Wall -fverbose-asm
S_FLAGS  = -I$(DAT_DIR) -I$(INC_DIR) -I $(SOCRATES_INC_DIR) -I$(STD_INC_DIR0) -I$(STD_INC_DIR1) -mthumb-interwork

L_FLAGS = -lSocrates   -L $(SOCRATES_LIB_DIR) -L$(STD_LIB_DIR0) -L$(STD_LIB_DIR1) -T $(LINK_SCRIPT_DIR)/lnkscript -lgcc

# -----------------------------------------------------------------------------
# Define the list of object files
# -----------------------------------------------------------------------------

O_FILES_FROM_C      = $(PROJECT).o
O_FILES_FROM_CPP   =

O_FILES_FROM_C_FULL_PATH = $(addprefix $(OBJ_DIR)/, $(O_FILES_FROM_C))

O_FILES_FROM_CPP_FULL_PATH = $(addprefix $(OBJ_DIR)/, $(O_FILES_FROM_CPP))

CRT0_O         = $(OBJ_DIR)/crt0.o

#CRTBEGIN_O      = $(STD_LIB_DIR0)/crtbegin.o
#CRTEND_O      = $(STD_LIB_DIR0)/crtend.o

O_FILES_FULL_PATH   = $(CRT0_O) $(CRTBEGIN_O) $(CRTEND_O) $(O_FILES_FROM_C_FULL_PATH)  $(O_FILES_FROM_CPP_FULL_PATH)
                     
# -----------------------------------------------------------------------------
# Define the final dependecy;
# -----------------------------------------------------------------------------
all : $(PROJECT_DIR)/$(PROJECT).gba
   @echo Done

# -----------------------------------------------------------------------------
# Define the copy from .elf to .gba file
# -----------------------------------------------------------------------------
$(PROJECT_DIR)/$(PROJECT).gba : $(ELF_DIR)/$(PROJECT).elf
   @echo Object copying
   @$(GCC_DIR)/bin/objcopy -v -O binary $< $@
      
      
# -----------------------------------------------------------------------------
# Define the linker instruction;
# -----------------------------------------------------------------------------
$(ELF_DIR)/$(PROJECT).elf : $(O_FILES_FULL_PATH) $(SOCRATES_LIB)
   @echo Linking object files
   @$(GCC_DIR)/bin/ld  $(O_FILES_FULL_PATH) -o$@ $(L_FLAGS)    
   
# -----------------------------------------------------------------------------
# Define the C compiles;
# -----------------------------------------------------------------------------
$(O_FILES_FROM_C_FULL_PATH) : $(OBJ_DIR)/%.o : $(SRC_DIR)/%.c
   @echo Making $@
   @$(GCC_DIR)/bin/gcc  -c $< -o$@ $(C_FLAGS)
   
# -----------------------------------------------------------------------------
# Define the CPP compiles;
# -----------------------------------------------------------------------------
$(O_FILES_FROM_CPP_FULL_PATH) : $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
   @echo Making $@
   @$(GCC_DIR)/bin/gcc  -c $< -o$@ $(CPP_FLAGS)
   
$(O_FILES_FROM_CXX_FULL_PATH) : $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cxx
   @echo Making $@
   @$(GCC_DIR)/bin/gcc  -c $< -o$@ $(CPP_FLAGS)
   
$(O_FILES_FROM_CC_FULL_PATH) : $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cc
   @echo Making $@
   @$(GCC_DIR)/bin/gcc  -c $< -o$@ $(CPP_FLAGS)
   
# -----------------------------------------------------------------------------
# Define the assembly of the crt0 file;
# -----------------------------------------------------------------------------
$(CRT0_O) : $(OBJ_DIR)/%.o : $(CRT0_S_DIR)/%.S
   @echo Making $@
   @$(GCC_DIR)/bin/gcc -c $< -o$@ $(S_FLAGS)
      
# -----------------------------------------------------------------------------
# Clean definition;
# -----------------------------------------------------------------------------
.PHONY : clean
clean :
   @echo Cleaning object, .elf and .gba files.
   @/bin/rm -f $(OBJ_DIR)/*.o
   @/bin/rm -f $(ELF_DIR)/$(PROJECT).elf
   @/bin/rm -f $(PROJECT_DIR)/$(PROJECT).gba
   @echo Clean done...


# -----------------------------------------------------------------------------
# EOF;
# -----------------------------------------------------------------------------


here is my header...
Code:

#ifndef GBA_H
#define GBA_H

//Video Mode Defines
#define Mode3 0x3

//Backgrounds To Enable
#define Bg2 0x400

//Video Memory Pointer
#define VideoBufferPointer (unsigned short*)0x6000000

//Initialize Video Mode Macro
//Example:   InitVideo( Mode3 | Bg2 );
#define InitVideo(mode) *(unsigned long*)0x4000000 = (mode)

//RGB Macro
//Example:   RGB(30,30,30);
#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))

//Pixel plotting Macro
//Example:   DrawPixel3(20, 20, videoBuffer) = RGB(30, 30, 30);
#define DrawPixel3(x,y,buffer) (buffer)[(y) * 240 + (x)]

#endif


here is my c file...
Code:

#include <stdlib.h>
#include "gba.h"

int AgbMain(void)
{
   
   InitVideo( Mode3 | Bg2 );
   unsigned short* videoBuffer = VideoBufferPointer;
   
   int myNumb = rand();
   int x = 120;  int y = 80;
   DrawPixel3(x, y, videoBuffer) = RGB( 30, 0, 0 );
   
   while(1)  {
      
   }
   
   return 0;
}


And well the fun doesnt stop there. That is the first problem, second is that if i try to do the same thing in a cpp file, it just fails to compile.

SO thirdly and more advanced, does anyone have some help on just using devkitArm, and setting up Xcode to use with that? As well as makeing a project template? If we can make a comunity effort here, we could release a better xcode package, that isnt linked to SGADE.

#48381 - poslundc - Tue Jul 19, 2005 6:21 pm

rand() is not a native C operator but is a member of the ANSI standard library, which I suspect is not supported by Devkit Advance. I don't know if Devkit ARM supports it or not, but the standard libraries are ill-suited for GBA development (with some possible exceptions like the memory functions) and generally shouldn't be used anyway.

You can find many easy and effective random-number algorithms by searching the forum.

Dan.

#48394 - justinGBA - Tue Jul 19, 2005 7:52 pm

OK, well this same project works just fine in windows under Visual Ham, and i really would like to use sdtlib with my projects, so what do i need to do to use stdlib, or c++ on the gba?

#48395 - tepples - Tue Jul 19, 2005 7:55 pm

DevKit Advance and devkitARM come with Newlib, a permissively licensed implementation of the ANSI C standard library.
  • To get rid of "implicit declaration", use the right header file:
    #include <stdlib.h>
  • To get rid of "undefined reference", you'll need to link in the C standard library, framed on both sides with a -lgcc:
    L_FLAGS = -lSocrates -L $(SOCRATES_LIB_DIR) -L$(STD_LIB_DIR0) -L$(STD_LIB_DIR1) -T $(LINK_SCRIPT_DIR)/lnkscript -lgcc -lc -lgcc

If you still can't get rand() to work, here's a fast but decent linear congruential generator to replace it. It uses the "BCPL" parameters described here.
Code:
static unsigned int ayn_seed = 314159265;
void ayn_set_seed(unsigned int s)
{
  ayn_seed = s;
}
int ayn(void)
{
  ayn_seed = ayn_seed * 2147001325 + 715136305;
  return ayn_seed >> 17;
}

Then use ayn() instead of rand() (get it?) and ayn_set_seed() instead of srand().
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#48539 - justinGBA - Wed Jul 20, 2005 5:56 pm

WOOHOO! Thank you so much, i still get the implicit warning but it compiles and runs. is <stdlib.h> not the right include? Now i just have to stop using the GBASDK for OS X and make my own. off to learning makefiles.

#51000 - pizzach - Mon Aug 15, 2005 6:58 am

Not exactly what you were asking for, but I used a shell script when I build which should be easily convertible to a makefile.

It worked a lot better than the included GBASDK script because mode 3 graphics actually get a usable framerate on some of the demos out there like tankgba. Basically it's more compairable to the .bat make files the windows users tend to use.

Code:

/usr/local/gbasdk/arm-agb-elf/bin/gcc -c -O3 -mthumb -mthumb-interwork test.c
/usr/local/gbasdk/arm-agb-elf/bin/gcc -mthumb -mthumb-interwork -o test.elf test.o
/usr/local/gbasdk/arm-agb-elf/bin/objcopy -O binary test.elf test.gba


Hope this helps get you started if you didn't figure it out already.

#51029 - wintermute - Mon Aug 15, 2005 6:44 pm

pizzach wrote:


It worked a lot better than the included GBASDK script because mode 3 graphics actually get a usable framerate on some of the demos out there like tankgba. Basically it's more compairable to the .bat make files the windows users tend to use.



It got a better framerate because you increased the optimisation level, not because you used a shell script.

Makefiles *are* scripts and have special features for project building which standard shell scripts lack. Neither shell scripts or bat files should be used for building anything of any complexity (in practice anything more than 1 c/cpp file)

#51050 - pizzach - Mon Aug 15, 2005 10:04 pm

(-_-); Doesn't replace a makefile, but it IS a good place to start to figure out what is going on when you first start compiling stuffs in the terminal. makefiles can be a bit more difficult to parse in your brain the first time you look at it until you know where it is going.

The .bat that I had studied:
Code:

path=C:\devkitadv\bin

rem If you compile using this line and not the next three
rem it will run like 5 frames a second
rem gcc  -o tank.elf main.c gfx.c

gcc -c -O3 -mthumb -mthumb-interwork gfx.c
gcc -c -O3 -mthumb -mthumb-interwork main.c
gcc -mthumb -mthumb-interwork -o tank.elf main.o gfx.o

objcopy -O binary tank.elf tank.gba

pause


I hadn't tinkered or looked at the script in a long time. the -O3 seem to work for me, I just tried it. I would think that the author of tankgba must have had a reason though since he made the bat file....no one will ever know. The information is moot anyway, the thread starter appears to have changed compilers.

#51061 - wintermute - Tue Aug 16, 2005 12:22 am

pizzach wrote:
(-_-); Doesn't replace a makefile, but it IS a good place to start to figure out what is going on when you first start compiling stuffs in the terminal. makefiles can be a bit more difficult to parse in your brain the first time you look at it until you know where it is going.


It's not really. Using bat files is an extremely stupid way to compile a project, they're no different from sitting typing the commands.

Quote:

I hadn't tinkered or looked at the script in a long time. the -O3 seem to work for me, I just tried it. I would think that the author of tankgba must have had a reason though since he made the bat file....no one will ever know


He probably used a bat file because that's what the moronic tutorial he followed used.

#51063 - tepples - Tue Aug 16, 2005 12:35 am

wintermute wrote:
Using bat files is an extremely stupid way to compile a project, they're no different from sitting typing the commands.

Actually it is different. Unlike a .bat file or a shell script, a makefile can't be double-clicked in Windows Explorer, and a lot of the more generic programmers' text editors for Windows use similar code to launch programs that Explorer uses. Therefore, some people need a .bat file that does something like this:
Code:
@echo off
set PATH=C:\devkitARM\bin;C:\msys\1.0\bin;%PATH%
make %1 %2 %3

But if the .bat file is calling GCC directly in a larger project, I see your point.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.