#92581 - Spaceface - Fri Jul 14, 2006 12:04 am
At the moment I'm kinda having a problem getting FRAS to run on a devKitPro gba template.
Problem: I cannot seem to use lib files in my project. The makefiles in the templated don't seem to work for me.
Explanation:
Code: |
> "make"
linking cartridge
audio.o: In function `main':
c:/devkitPro/projects/gbarepos/Tests/audio/source/audio.c:25: undefined reference to `FrasInstall'
c:/devkitPro/projects/gbarepos/Tests/audio/source/audio.c:26: undefined reference to `FrasPlayMod'
collect2: ld returned 1 exit status
make[1]: *** [/c/devkitPro/projects/gbarepos/Tests/audio/audio.elf] Error 1
"make": *** [build] Error 2
> Process Exit Code: 2
> Time Taken: 00:00
|
This is what I get when I leave it at the default Makefile. Seems like a missing .lib file seeing there is no other file that refers to the function other than fras.lib.
Now when I look in the Makefile I see these lines (cutted out of file):
Code: |
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lgba
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBGBA)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
Now it seems that whatever I put behind LIBGBA := would be considdered a path to a dir which contains a /lib dir. In my case that would make LIBGBA blank since the /lib dir is in the root of my dir (along with 'source','build' and 'include'). So then it looks like this:
Code: |
TARGET := $(shell basename $(CURDIR))
BUILD := build
SOURCES := source
DATA :=
INCLUDES := include
LIBGBA :=
|
And I change the -lgba to -lfras, I get this errorcode:
Code: |
> "make"
linking cartridge
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: cannot find -lfras
collect2: ld returned 1 exit status
make[1]: *** [/c/devkitPro/projects/gbarepos/Tests/audio/audio.elf] Error 1
"make": *** [build] Error 2
> Process Exit Code: 2
> Time Taken: 00:00 |
I cannot seem to understand how this works since I'm not really familiar with Makefiles, though I have looked up stuff in many Makefiles. I hope someone.
The exact same goes for the MASO soundsystem, which uses a maso.a file instead of a .lib.
#93042 - Spaceface - Sun Jul 16, 2006 6:43 pm
bump.. anyone? :(
I thought it was a rather simple issue.. isn't it?
#93419 - wintermute - Wed Jul 19, 2006 1:30 am
the option -lfras expects to find a library calld libfras.a somewhere in the lib paths set with -L.
The devkitPro makefiles are set up to expect directories specified in LIBDIRS to be absolute paths which is why we use variables there.
Make a folder in the devkitPro directory called fras, create include and lib folders inside that, copy the fras header(s) to include, fras.lib to lib and rename it to libfras.a. In the LIBDIRS variable add $(DEVKITPRO)/fras and -lfras to lib then your project should link - maybe.
The latest devkitARM uses the new eabi so it will complain about libraries built with older toolchains. There's a tool to remark the files on the devkitpro site - http://www.devkitpro.org/index.php?action=fullnews&id=108
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#93546 - Spaceface - Wed Jul 19, 2006 8:42 pm
Yay! Finally I got a bit closer.. However, I do get the eabi version error. I downloaded the tool, but it expects the resulting .o files and I only have the .a file as of now, which I can't find to convert. The result is this:
Code: |
> "make"
Country.c
arm-eabi-gcc -MMD -MP -MF /c/devkitPro/projects/gbarepos/Tests/audio/build/Country.d -g -Wall -O3 -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer -ffast-math -mthumb -mthumb-interwork -I/c/devkitPro/projects/gbarepos/Tests/audio/include -I/c/devkitPro/fras/include -I/c/devkitPro/projects/gbarepos/Tests/audio/build -c /c/devkitPro/projects/gbarepos/Tests/audio/source/Country.c -o Country.o
audio.c
arm-eabi-gcc -MMD -MP -MF /c/devkitPro/projects/gbarepos/Tests/audio/build/audio.d -g -Wall -O3 -mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer -ffast-math -mthumb -mthumb-interwork -I/c/devkitPro/projects/gbarepos/Tests/audio/include -I/c/devkitPro/fras/include -I/c/devkitPro/projects/gbarepos/Tests/audio/build -c /c/devkitPro/projects/gbarepos/Tests/audio/source/audio.c -o audio.o
linking cartridge
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(PlayMod.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(PlayMod.o)
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(SoundVariables.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(SoundVariables.o)
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(UpdateMixer.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(UpdateMixer.o)
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(UpdateTick.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(UpdateTick.o)
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(UpdateEffectTick0.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(UpdateEffectTick0.o)
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(UpdateEffectBetweenTicks.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(UpdateEffectBetweenTicks.o)
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(Install.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(Install.o)
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: ERROR: Source object c:/devkitPro/fras/lib\libfras.a(StartSound.o) has EABI version 0, but target c:/devkitPro/projects/gbarepos/Tests/audio/audio.elf has EABI version 4
c:\devkitpro\devkitarm\arm-eabi\bin\ld.real.exe: failed to merge target specific data of file c:/devkitPro/fras/lib\libfras.a(StartSound.o)
collect2: ld returned 1 exit status
make[1]: *** [/c/devkitPro/projects/gbarepos/Tests/audio/audio.elf] Error 1
"make": *** [build] Error 2
> Process Exit Code: 2
> Time Taken: 00:01 |
Now I've looked in devKitPro/fras/lib and the /build dir of my project, but I can't seem to find any resulted .o files.
Where can I find these, or does devKit cleans them?
#93556 - wintermute - Wed Jul 19, 2006 9:53 pm
The .o files it's complaining about are found in libfras.a. The change-eabi.sh script included in the change-eabi zip converts archives.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#93599 - Spaceface - Thu Jul 20, 2006 1:04 am
Ah that did it. Now where does it expect my newly, created .o files to be? in /build in either my project or fras dir didn't work, and also not in de lib and include dir...
(good luck this is the beginners forum, sheesh ;))
#93602 - wintermute - Thu Jul 20, 2006 1:24 am
Spaceface wrote: |
Ah that did it. Now where does it expect my newly, created .o files to be? in /build in either my project or fras dir didn't work, and also not in de lib and include dir...
(good luck this is the beginners forum, sheesh ;)) |
I'm a bit lost, what isn't working now?
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#93638 - Spaceface - Thu Jul 20, 2006 9:10 am
Well I extracted several .o files from the .a file, so I think I can drop the .a file now (not sure though). But what should I do with the .o files? Where should they be place and how should I use them within my project(/makefile?) so that my project will pick up its functions?
#93641 - wintermute - Thu Jul 20, 2006 9:41 am
Well, that's what I was saying the change-eabi.sh script extracts the .o files from the archive, changes the eabi version and rebuilds the archive with the remarked object files. If you copy change-eabi.exe and change-eabi.sh somewhere in your path, open an msys shell, cd to the directory containing libfras.a and run change-eabi.sh there then the archive will be converted.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog
#93758 - Spaceface - Fri Jul 21, 2006 1:26 am
Yay! I got it working, finally! However it has some problems with .cpp files, whereas .c files don't have any problems. .cpp files can't seem to find the functions within the .a file. Any idea why this is?
Either way, finally! Would've NEVER figured this one out by myself...
#93760 - tepples - Fri Jul 21, 2006 1:54 am
Spaceface wrote: |
.cpp files can't seem to find the functions within the .a file. Any idea why this is? |
If it's a name-mangling issue in a C++ program that uses a C library, then try this with the library's header file:
Code: |
extern "C" {
#include "someFile.h"
} |
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#93791 - Spaceface - Fri Jul 21, 2006 8:17 am
Finally that did the job! Thank you guys so much! I know I asked much but I would've never figured these things out... Thanks again!
#93816 - tepples - Fri Jul 21, 2006 1:41 pm
Explanation of why it works:
C++ uses a different scheme for naming functions in object code files. This scheme, called "name mangling", allows for overloading of functions by argument number and type. Putting function prototypes in an extern "C" block disables name mangling for those prototypes.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#93834 - Spaceface - Fri Jul 21, 2006 4:10 pm
Ah, is that the same as how C and C++ differ in the way they define structs ?
#93849 - Cearn - Fri Jul 21, 2006 5:34 pm
Spaceface wrote: |
Ah, is that the same as how C and C++ differ in the way they define structs ? |
Nah, that's just C++ doing what everyone wanted C to do in the first place :P
Name mangling is what makes function overloading possible. For example, you might want func(int x) and and an overloaded version func(int x, int y). This would create problems in the object file because names have to be unique. C++ name mangling changes the names (internally) so that this problem is circumvented. For example, `void func(int x, int y)' will actually be called _Z7funcii. This works fine in C++ because when you call func(x,y), the compiler will know you mean _Z7funcii, based on the number and type of the arguments. This does not work fine when calling functions compiled in C, because those would still be called func in the object files. The `extern "C" ' tells the compiler that that particular function was defined in C, and won't apply the mangling when making the call.