#121416 - HyperHacker - Mon Mar 12, 2007 8:05 am
I'd like to know how to make .a library files with DevkitPro like libFAT and libCartReset. All Google is telling me is how to make .so files which are apparently dynamic link libraries for Linux. Anyone?
_________________
I'm a PSP hacker now, but I still <3 DS.
#121423 - Diddl - Mon Mar 12, 2007 10:06 am
a library is only a collection of object files. after compiling a c source file (.c) you get an object file. if same object file is included in many projects you should collect them to a library (.a) file.
look at the Makefile of libfat and you see the building of library file as last operation.
#121425 - keldon - Mon Mar 12, 2007 10:48 am
There is also an example in the tonc library.
#121513 - Puyo - Mon Mar 12, 2007 9:33 pm
There is a template in devkitPro examples.
#121524 - Ant6n - Mon Mar 12, 2007 10:20 pm
i use something like this. i basicly say some files are part of some library and they get 'ar rcs'ed.
Code: |
#
# creation of a gba library
# and testing
#
# --- Project details ---
PROJ := lib
EXT := gba
LIBRARY := lib_simple_gba.a
LCFILES := lib_palette.c lib_time.c lib_frame.c lib_math.c lib_interrupt.c lib_memory.c lib_sprite.c lib_texture.c
LSFILES := lib_asmirqhandler.S lib_asmagbprint.S
CFILES := main.c rock.c ship.c shipdata.c
COBJS := $(CFILES:.c=.o)
LSOBJS := $(LSFILES:.S=.o)
LCOBJS := $(LCFILES:.c=.o)
LOBJS := $(LCOBJS) $(LSOBJS)
#--- Tool settings ---
PREFIX := arm-eabi-
AS := $(PREFIX)gcc
CC := $(PREFIX)gcc
AR := $(PREFIX)ar
LD := $(PREFIX)gcc
OBJCOPY := $(PREFIX)objcopy
MODEL := -mthumb-interwork
SPECS := -specs=gba.specs # comment out for DKA
ASFLAGS := -mthumb-interwork -Wall
CFLAGS := -I./ $(MODEL) -O0 -mthumb -Wall
LDFLAGS := $(SPECS) $(MODEL)
#--- Build steps ---
build : $(PROJ).$(EXT)
$(PROJ).$(EXT) : $(PROJ).elf
@$(OBJCOPY) -v -O binary $< $@
-@gbafix $@
$(PROJ).elf : $(COBJS) $(LIBRARY)
@$(LD) $(COBJS) $(LIBRARY) $(LDFLAGS) -o $@
$(LIBRARY) : $(LOBJS)
$(AR) rcs $(LIBRARY) $(LOBJS)
$(LCOBJS) : %.o : %.c
$(CC) $(CFLAGS) -g -c $< -o $@
$(COBJS) : %.o : %.c
$(CC) $(CFLAGS) -g -c $< -o $@
$(LSOBJS) : %.o : %.S
$(CC) $(ASFLAGS) -g -c $< -o $@
# --- Clean ---
.PHONY : clean
clean :
@rm -fv $(COBJS)
@rm -fv $(LOBJS)
@rm -fv $(LIBRARY)
@rm -fv $(PROJ).$(EXT)
@rm -fv $(PROJ).elf
|
#123801 - HyperHacker - Sat Mar 31, 2007 6:53 am
Diddl wrote: |
look at the Makefile of libfat and you see the building of library file as last operation. |
Where is the libfat source?
keldon wrote: |
There is also an example in the tonc library. |
I see info about makefiles, but not about making libraries.
Puyo wrote: |
There is a template in devkitPro examples. |
Where?
Ant6n wrote: |
i use something like this. i basicly say some files are part of some library and they get 'ar rcs'ed. |
Wow, that code means absolutely nothing to me. I got the part about using ar, but that's about it. I've simply been including the source files into each program, and that works fine. How do I compile them on their own? They don't have a main() or anything. :-S I haven't been this lost since I wandered into the woods as a young child and couldn't find my way out again.
_________________
I'm a PSP hacker now, but I still <3 DS.
#123805 - Ant6n - Sat Mar 31, 2007 8:05 am
this was a makefile. I just posted to show the notion of having some library related files and some testing project that are compiled separately and then linked. The essential command here is
$(LIBRARY) : $(LOBJS)
$(AR) rcs $(LIBRARY) $(LOBJS)
which would probably expand into something like
arm-eabi-ar rcs mylib.a file1.o file2.o
that's it. I dont remember what rcs stand for, but i've been using that option like that since forever and it works for me. If you supply the mylib.a with the header files, then the library should be usable.
#123811 - keldon - Sat Mar 31, 2007 10:25 am
The tonc library comes with the makefiles; unless Cearn has changed the library not to include the makefiles.
#123815 - Cearn - Sat Mar 31, 2007 1:21 pm
HyperHacker wrote: |
keldon wrote: | There is also an example in the tonc library. | I see info about makefiles, but not about making libraries. |
It'shere I admit it's well hidden ^_^;; But the tonclib and libgba's makefiles also contain the relevant stuff. It's like Ant6n says:
Code: |
$(LIBRARY) : $(LOBJS)
$(AR) rcs $(LIBRARY) $(LOBJS)
|
HyperHacker wrote: |
Ant6n wrote: | i use something like this. i basicly say some files are part of some library and they get 'ar rcs'ed. | Wow, that code means absolutely nothing to me. I got the part about using ar, but that's about it. |
When in doubt, RTFM. Or just consider them the standard options.
HyperHacker wrote: |
I've simply been including the source files into each program, and that works fine. How do I compile them on their own? They don't have a main() or anything. :-S I haven't been this lost since I wandered into the woods as a young child and couldn't find my way out again. |
Roughly put, building a project happens in two stages: compilation and linking. Compilation (and assembling too, I guess) converts a C source file into an ELF binary file called an object file (.o). This contains the machine code for the functions, data for the global variables, and other items that tells you where these items go and what their names are.
Linking is the stage where all these items are brought together into an executable. The linker looks at all the object files and places them into the right sections and links function/data calls to the addresses that those functions/data now have.
The object files themselves are just collections of functions and data in a format that makes more sense to a computer. However, each of these items is still loose: they don't have their addresses yet. Only at the linking stages are the addresses fixed, and it's only at that point that one can actually run the executable*. It's only at that point that a main() needs to exist. There was a nice tutorial about how it all works here, but it seems unavailable now.
Libraries are little more than collections of object files. Because the hard work (compilation) is already done, they can be build into an executable faster than if you had to compile them as well.
* GBA/NDS games also need stripping of excess data with objcopy.
#123816 - kusma - Sat Mar 31, 2007 1:29 pm
HyperHacker wrote: |
I've simply been including the source files into each program, and that works fine. How do I compile them on their own? They don't have a main() or anything. |
compile with the gcc-flag -c to output an object file instead of directly compiling and linking all sources. remember to specify an output filename (-o option). use ar to archive these objects together as an .a-file.
A typical makefile-rule to build object files from c-sources looks like this:
Code: |
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
And a typical makefile-rule to build an .a file from a set of object files looks like this:
Code: |
%.a:
$(AR) $(ARFLAGS) $@ $?
mylib.a: souce1.o source2.o source3.o
|
#123898 - HyperHacker - Sun Apr 01, 2007 9:05 am
Yeah, I know about as much about Unix makefiles as Homer Simpson knows about calculus. I can make out some of it, but $< $@ $what? It looks like someone fell on the keyboard.
I do know how to compile to a .o file, and I managed to compile just a header file which includes stdio.h, does a few #defines and function prototypes, defines a few bytes worth of globals, and references a 2KB font file (extern u8 etc...). The .o file is 1.23MB, and so is the .a file created with arm-eabi-ar rcs! How did that happen? The entire test program is only 36KB.
I tried including that .o file along with the others when creating the .elf file, rather than including the header file itself in the source, but then it won't even get that far because none of the stuff in that file is defined anymore. >_<
_________________
I'm a PSP hacker now, but I still <3 DS.
Last edited by HyperHacker on Sun Apr 01, 2007 9:09 am; edited 1 time in total
#123899 - Piratero - Sun Apr 01, 2007 9:09 am
HyperHacker wrote: |
Yeah, I know about as much about Unix makefiles as Homer Simpson knows about calculus. I can make out some of it, but $< $@ $what? It looks like someone fell on the keyboard.
I do know how to compile to a .o file, and I managed to compile just a header file which includes stdio.h, does a few #defines and function prototypes, defines a few bytes worth of globals, and references a 2KB font file (extern u8 etc...). The .o file is 1.23MB, and so is the .a file created with arm-eabi-ar rcs! How did that happen? The entire test program is only 36KB. |
Try this:
Code: |
%.o: %.c
<tab>@echo $? $@ $*
|
_________________
http://mrkotfw.ribrdb.com/
#123901 - HyperHacker - Sun Apr 01, 2007 9:21 am
Well I'd like to get this working with batch scripts before I go off learning another whole language. I'd appreciate a link to some sort of documentation but for now let's just leave that alone if possible. I've almost got it working, but I'm getting compiler errors that make no sense. I figured leave the header file and compile the source itself (which includes the header), and in the test program, link to the .o file (which is now only 25K, which still seems pretty bloated) instead of including the source. But these errors...
Code: |
F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `_NumConsoles'
..\general\console.o:(.bss+0x0): first defined here
|
"_NumConsoles" doesn't appear in system.h at all! Line 135 is just:
void powerON(int on) { POWER_CR |= on;}
wtf?
Code: |
F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `_CurrentConsole'
..\general\console.o:(.bss+0x1): first defined here
F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `Console'
..\general\console.o:(.bss+0x4): first defined here |
More of this. This makes no sense at all.
Code: |
f:/dos/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.1.1/../../../../arm-eabi/bin/ld.exe: Warning: size of symbol `Console' changed from 84 in ..\general\console.o to 112 in F:\DOS\DevKitPro\devkitARM\bin\arm9.o
collect2: ld returned 1 exit status |
What?
_________________
I'm a PSP hacker now, but I still <3 DS.
#123908 - kusma - Sun Apr 01, 2007 10:59 am
#123912 - keldon - Sun Apr 01, 2007 12:47 pm
#123920 - kusma - Sun Apr 01, 2007 2:59 pm
Uhm, yeah. A tutorial that places preprocessor-flags in the CFLAGS variable... no thanks. Besides it barely scratches the surface of make, and i spot lots of minor error there.
#123923 - keldon - Sun Apr 01, 2007 4:03 pm
It's a great gateway into using makefiles though, showing the reasoning behind it and the basics in under 10 minutes.
#123976 - HyperHacker - Mon Apr 02, 2007 7:15 am
OK, thanks. :-) But I still don't understand where in the world these errors are coming from. @_@
_________________
I'm a PSP hacker now, but I still <3 DS.
#124006 - gmiller - Mon Apr 02, 2007 1:28 pm
HyperHacker wrote: |
Well I'd like to get this working with batch scripts before I go off learning another whole language. I'd appreciate a link to some sort of documentation but for now let's just leave that alone if possible. I've almost got it working, but I'm getting compiler errors that make no sense. I figured leave the header file and compile the source itself (which includes the header), and in the test program, link to the .o file (which is now only 25K, which still seems pretty bloated) instead of including the source. But these errors...
Code: | F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `_NumConsoles'
..\general\console.o:(.bss+0x0): first defined here
|
"_NumConsoles" doesn't appear in system.h at all! Line 135 is just:
void powerON(int on) { POWER_CR |= on;}
wtf?
Code: | F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `_CurrentConsole'
..\general\console.o:(.bss+0x1): first defined here
F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `Console'
..\general\console.o:(.bss+0x4): first defined here |
More of this. This makes no sense at all.
Code: | f:/dos/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.1.1/../../../../arm-eabi/bin/ld.exe: Warning: size of symbol `Console' changed from 84 in ..\general\console.o to 112 in F:\DOS\DevKitPro\devkitARM\bin\arm9.o
collect2: ld returned 1 exit status |
What? |
The complaint about _NumConsoles and _CurrentConsole (based on the "name mangling rules" this is the variable "NumConsoles" / "CurrentConsole" and the linker has found two definitions of the variables which is not allowed (you can only have one definition but you can have multiple references). It is giving the location of the two definitions.
The definition could be hidden in a macro so you would need to search further. The linker is saying that the variable is first defined in console.o so look there to see if it needs to be defined there if that is your code.
You could also be linking in two mutually exclusive object files or libraries. The problems here could be the way you are linking or what you are linking and there is little I could add without more information.
#124011 - Puyo - Mon Apr 02, 2007 1:41 pm
HyperHacker wrote: |
Puyo wrote: | There is a template in devkitPro examples. | Where? |
Here. Or the same path in your local installation.
#124057 - HyperHacker - Mon Apr 02, 2007 9:29 pm
Puyo, was DKP updated recently? I don't have any "arm9lib" there.
gmiller, the variables do in fact begin with an underscore. I understand the problem with multiple definitions and what might cause it, I just don't get why it's complaining about those particular lines. I'll look around to see if I can find any redefinitions.
_________________
I'm a PSP hacker now, but I still <3 DS.
#124064 - Ant6n - Mon Apr 02, 2007 11:20 pm
Another thing I would like to ask, directly connected to 'how to make a library', is the question of what else one has to supply in order to give out some library that people might actually use. checklist:
- *.a
- *.h-files
- documentation??
#124104 - kusma - Tue Apr 03, 2007 3:03 am
Ant6n wrote: |
- *.a
- *.h-files
- documentation?? |
- source code
- example code
#124112 - Ant6n - Tue Apr 03, 2007 5:44 am
source code? awww....
and make public under which license? LGPL?
#124125 - kusma - Tue Apr 03, 2007 9:46 am
Ant6n wrote: |
source code? awww....
and make public under which license? LGPL? |
I prefer less restrictive open source licenses like BSD or Zlib License (or even public domain). This is simply because everything I release isn't open source software (in fact very little of what I release are), but I strongly prefer using open source libraries over closed source ones. This is because I don't want to depend on something I can't be sure is available in the future and for future compiler tool-chains.
#128971 - Karatorian - Thu May 17, 2007 7:37 am
HyperHacker wrote: |
Well I'd like to get this working with batch scripts before I go off learning another whole language. I'd appreciate a link to some sort of documentation but for now let's just leave that alone if possible. I've almost got it working, but I'm getting compiler errors that make no sense. I figured leave the header file and compile the source itself (which includes the header), and in the test program, link to the .o file (which is now only 25K, which still seems pretty bloated) instead of including the source. |
Well, it proably includes debugging information, so after you strip it, it should be smaller. It also includes the ELF header, which is pretty heavyweight as well. Once you convert from the ELF file to a GB ROM, that gets stripped also, so the end result will be smaller.
Quote: |
But these errors...
Code: | F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `_NumConsoles'
..\general\console.o:(.bss+0x0): first defined here
|
"_NumConsoles" doesn't appear in system.h at all! Line 135 is just:
void powerON(int on) { POWER_CR |= on;}
wtf?
|
Without seeing your code (and libnds, I only have a GBA), I can't be sure exactly where the problem is. However, I will point out that GCC is sometimes a bit off when quoting line numbers. It does seem that _NumConsoles is being defined twice. Do you define _NumConsoles in a header of your own? Or is it defined in a system header? In either case, you should chech if the header where it's defined has an #ifndef to ensure that even if it's included by multiple source files in an object that it's defines are only executed once. Such code usually looks something like this:
Code: |
#ifndef _foo_h_
#define _foo_h_
// content of header here
#endif // _gba_video_h_
|
Quote: |
Code: | F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `_CurrentConsole'
..\general\console.o:(.bss+0x1): first defined here
F:\DOS\DevKitPro\devkitARM\bin\arm9.o: In function `powerON':
F:\DOS\DevKitPro\libnds\include/nds/system.h:135: multiple definition of `Console'
..\general\console.o:(.bss+0x4): first defined here |
More of this. This makes no sense at all. |
This is the same sort of problem as the first one as is likely caused by a similar issue.
Quote: |
Code: | f:/dos/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.1.1/../../../../arm-eabi/bin/ld.exe: Warning: size of symbol `Console' changed from 84 in ..\general\console.o to 112 in F:\DOS\DevKitPro\devkitARM\bin\arm9.o
collect2: ld returned 1 exit status |
What? |
In this case, there is a variable named Console that is defined to be one size in console.o's source code, but is defined as a different size in arm9.o. To find out how this happened, you'll have to look into the source code, including included source, to see where the conflict arises.
It might be helpful to see your build system and and a list of what's included by what.