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 > devkitARM template makefile issues

#58914 - wintermute - Thu Oct 27, 2005 5:42 am

(Split from here.)

Could you elaborate on "multiple levels of dependencies"?

The example makefiles and associated rules build everything in a separate build folder which makes dependency generation more reliable since a full path to the prerequsiites is created.

VPATH is simply a list of paths where prerequisites may be found, in most cases adding folders to the SOURCES variable will do what you need. The .P and .d files are autogenerated and you shouldn't need to do anything with them although enabling gbfs to generate it's own dependency list might be useful. Another handy feature might be to allow gbfs to parse an entire directory and add all the files it finds much like the way conv2AAS ( the Apex Audio converter) works.

The .d files are a simple format consisting of a standard dependency rule with no commands.

Code:

<output file>: <prerequiste file> \
 <prequisite file>
 ...


all prerequisites should be given as a full path spec.

#58916 - tepples - Thu Oct 27, 2005 6:43 am

wintermute wrote:
Could you elaborate on "multiple levels of dependencies"?

data.gbfs depends on skin2.lz, which depends on skin2.todbg, which depends on skin2.bmp, and the translator from .bmp to .todbg has a limitation that it must place the .todbg file in the same folder as the .bmp file and with the same base name (e.g. ../data/FooBar.bmp always becomes ../data/FooBar.todbg).

Or the build process depends on copying the whole thing to the CF writer's drive letter. I know how to express a lot of these things in raw Make language, but sometimes I draw a blank when it comes to getting it working within your template.

Quote:
The example makefiles and associated rules build everything in a separate build folder which makes dependency generation more reliable since a full path to the prerequsiites is created.

So should every program that performs translation output a .P file?

Quote:
VPATH is simply a list of paths where prerequisites may be found, in most cases adding folders to the SOURCES variable will do what you need.

Then what happens when two files in the project have the same name? Using VPATH looks to me like using the old 128K Mac's flat file system, where each file had to have a unique name even if the files were in different folders. Imagine two games in one cart, where both have a file called "skin02.lz".

And to exclude files that currently are unused from a build, do you have to move them out of the folder?

Quote:
The .P and .d files are autogenerated and you shouldn't need to do anything with them although enabling gbfs to generate it's own dependency list might be useful.

As well as all the other programs that write multiple files, such as the luminesweeper skin compiler. And I'm not so sure of myself as to how to write rules for simple "cmdname infile.ext outfile.sfx" type things that update the .d files.

Quote:
Another handy feature might be to allow gbfs to parse an entire directory and add all the files it finds much like the way conv2AAS ( the Apex Audio converter) works.

You're supposed to be able to do gbfs file.gbfs ..\data\* but for some reason the globber in the version of MinGW that I use doesn't work as advertised.

Quote:
all prerequisites should be given as a full path spec.

"full path" meaning drive letter and everything? Doesn't this eventually defeat the purpose of being able to compile a project on anyone's computer?

Another thing that surprised me was deciding whether or not to link a GBA project as cart or multiboot depending on the name of the folder that the project was in.

(Seems like I derailed this topic; I'll split it.)
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#58922 - wintermute - Thu Oct 27, 2005 9:08 am

tepples wrote:
wintermute wrote:
Could you elaborate on "multiple levels of dependencies"?

data.gbfs depends on skin2.lz, which depends on skin2.todbg, which depends on skin2.bmp, and the translator from .bmp to .todbg has a limitation that it must place the .todbg file in the same folder as the .bmp file and with the same base name (e.g. ../data/FooBar.bmp always becomes ../data/FooBar.todbg).


Being honest the best way to deal with data is really to have a separate Makefile for your data subdirectories, especially if you have tools which are incapable of writing files in another directory. To do this create a phoney target ( i.e. add the target to the Makefile's .PHONY list) which means the rule will always be executed.

Code:

.PHONY: data
#---------------------------------------------------------------------------------
data:
   @make -C <data dir>


or alternatively using the name of the folder as the target

Code:

.PHONY: data
#---------------------------------------------------------------------------------
data:
   @make -C $@


You can repeat a rule like this as many times as necessary for each data folder which contains a Makefile

One of the reasons that the devkitPro Makefiles have evolved to what you see today is that a *lot* of people are basically too lazy to bother with learning anything about make and want something that will just work for whatever project they're working on. There is a considerable amount of automation in there to allow for just that although I do use them a lot myself now since they've ended up being so convenient.

Quote:

Or the build process depends on copying the whole thing to the CF writer's drive letter. I know how to express a lot of these things in raw Make language, but sometimes I draw a blank when it comes to getting it working within your template.


Sometimes I draw a blank too :) It can be very hard to work some tools into the templates, especially when they don't allow for files to be output in a separate directory. Using the separate Makefile approach above should help quite a bit.

Quote:

So should every program that performs translation output a .P file?


No, the .P files are intermediate files used for adjusting the dependencies so that deleted files don't cause the build to fail, the Makefile only includes .d files. Unless the program in question requires more than one file then there's no need to write a .d file and even then it can be just as easy to write explicit dependencies or have the Makefile automate it in some way.

Quote:

Quote:
VPATH is simply a list of paths where prerequisites may be found, in most cases adding folders to the SOURCES variable will do what you need.

Then what happens when two files in the project have the same name? Using VPATH looks to me like using the old 128K Mac's flat file system, where each file had to have a unique name even if the files were in different folders. Imagine two games in one cart, where both have a file called "skin02.lz".


Yes, that's one limitation of this approach, far outweighed by the convenience of auto dependency generation imo. Again the best solution to this is probably the separate Makefile for data approach in conjunction with gbfs or some similar application.

Quote:

And to exclude files that currently are unused from a build, do you have to move them out of the folder?


If you want to retain the automation then yes. You can, of course, simply name the object files directly instead of having the functions to search the provided paths for potential source files. You can either list your source files in the CFILES/CPPFILES variables or the object files in the OFILES variable.

Quote:

Quote:
The .P and .d files are autogenerated and you shouldn't need to do anything with them although enabling gbfs to generate it's own dependency list might be useful.

As well as all the other programs that write multiple files, such as the luminesweeper skin compiler. And I'm not so sure of myself as to how to write rules for simple "cmdname infile.ext outfile.sfx" type things that update the .d files.


Unless the tools work with files that *contain* references to other files which should be treated as prerequisites you don't really need to worry about .d files. For tools which output more than one file then multiple target rules should suffice.

Code:

%.h %.c: %.bmp
   <tool to create .h & .c from bmp> $<


This also takes care of the dependencies since make now knows how to create both .h & .c from a .bmp file. Something to note, you can't always guarantee which target make will attempt to create with these rules, $* refers to the file without the extension.

Quote:

You're supposed to be able to do gbfs file.gbfs ..\data\* but for some reason the globber in the version of MinGW that I use doesn't work as advertised.


http://www.mingw.org/MinGWiki/index.php/TestForGlobbing?version=1 might help. I can't say I've made use of globbing recently so I haven't really looked at this. One other thing I've noticed a couple of times is that on some systems using * as a wildcard doesn't return files with extensions. You may also need to check if the argument refers to a directory.

Quote:

Quote:
all prerequisites should be given as a full path spec.

"full path" meaning drive letter and everything? Doesn't this eventually defeat the purpose of being able to compile a project on anyone's computer?


Why would you distribute generated dependency files? This comment was referring only to the generated .d files, not to prerequisites in general.

Quote:

Another thing that surprised me was deciding whether or not to link a GBA project as cart or multiboot depending on the name of the folder that the project was in.


Just name the target directly instead of using the default command that names the target from the folder. That's just another one of those attempts to stop lazy people moaning at me, not that it's worked very well - there are still people who think that I should provide rules to build from every extension known to man so they don't have to specify a rule for whatever bizarre extension they decide to dump in the data directory.

Something that might help a lot in understanding the devkitPro Makefiles is the documentation found here -> http://make.paulandlesley.org/ which was a large influence on them.

The rules given are very useful, I happen to agree with all of them.

http://make.paulandlesley.org/rules.html

The dependendency generation is based on http://make.paulandlesley.org/autodep.html

#58983 - tepples - Thu Oct 27, 2005 8:49 pm

wintermute wrote:
Being honest the best way to deal with data is really to have a separate Makefile for your data subdirectories

I have my doubts about that after having read things like Recursive Make Considered Harmful.

Quote:
One of the reasons that the devkitPro Makefiles have evolved to what you see today is that a *lot* of people are basically too lazy to bother with learning anything about make and want something that will just work for whatever project they're working on.

But when you get to the point where you need a separate makefile, then you're going to have to learn how to write a makefile anyway. And by that time, it becomes easier to rewrite than to work with/against all the automation, especially when none of it is documented anywhere. For example, how would I learn how to designate a .c file as to be compiled in ARM code and placed in IWRAM?

Quote:
Quote:
Quote:
The .P and .d files are autogenerated and you shouldn't need to do anything with them although enabling gbfs to generate it's own dependency list might be useful.

As well as all the other programs that write multiple files, such as the luminesweeper skin compiler. And I'm not so sure of myself as to how to write rules for simple "cmdname infile.ext outfile.sfx" type things that update the .d files.

Unless the tools work with files that *contain* references to other files which should be treated as prerequisites you don't really need to worry about .d files.

The luminesweeper skin compiler is exactly such a tool. It takes .Lspec files that look like this:
Code:
BG=skins/Shinin-bg.bmp
PF=skins/Shinin-pf.bmp
Music=Shinin.gsm
MusicBPM=133.000
MusicLoopStart=8
MusicLoopLen=2
MoveFreq=1761.99
RotateFreq=1174.66
BlawkFreq=73.41

In this case, skins/Shinin.Lskin depends on skins/Shinin.Lspec (the file listed above), skins/Shinin-bg.bmp, and skins/Shinin-pf.bmp. (Shinin.gsm is part of gsmsongs.gbfs, handled by its list of prerequisites.) Currently I'm using explicit lists of prerequisites for each .Lskin file for debug builds, and using a crude batch version of the separate makefile method for release builds (because my users don't all have GNU Make installed).

Quote:
Quote:
You're supposed to be able to do gbfs file.gbfs ..\data\* but for some reason the globber in the version of MinGW that I use doesn't work as advertised.

http://www.mingw.org/MinGWiki/index.php/TestForGlobbing?version=1 might help.

I'll look at that.

Quote:
One other thing I've noticed a couple of times is that on some systems using * as a wildcard doesn't return files with extensions.

Windows 2000 is not one of them.

Quote:
Just name the target directly instead of using the default command that names the target from the folder. That's just another one of those attempts to stop lazy people moaning at me

start > programs > devkitPro > documentation > (Empty)

Document, document, document, please. I tend to use what I can understand, and if I can't understand what is made available to me, I tend to write my own based on what I do understand.

Quote:
Something that might help a lot in understanding the devkitPro Makefiles is the documentation found here -> http://make.paulandlesley.org/ which was a large influence on them.

I could read that, but it would have been nice if that were documented.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.