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 > make file woe

#127802 - mrmarc772 - Sat May 05, 2007 3:08 am

...following a beginners tute

they wanted me to right:
Code:
set path=C:\devkitadv\bin;%path%
gcc -o hello.elf hello.c -lm
objcopy -O binary hello.elf hello.gba
pause

and i changed the set path line to the location that the exe is in my comp... C:\devkitPro\devkitARM\bin... i think
and this comes up when it's run
[Images not permitted - Click here to view it]

EDIT: im assuming that it must be because they made the tut on an older version of devkit

#127803 - tepples - Sat May 05, 2007 3:58 am

You don't use gcc to compile a GBA program. You use gcc to compile a Windows program, and you use arm-eabi-gcc to compile a GBA program. There are other differences between the older tools and the newer tools. As a beginner, you're better off grabbing wintermute's project template. Copy the devkitPro/examples/gba/template folder somewhere that you'll find it.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#127807 - mrmarc772 - Sat May 05, 2007 4:09 am

ugh... and i thought i was gettin a handle on this thingie... ok, thanks for the help, looks like it's back to the drawing board for me

#127811 - keldon - Sat May 05, 2007 8:33 am

Which beginners tutorial are you following?

#127821 - Cearn - Sat May 05, 2007 10:44 am

keldon wrote:
Which beginners tutorial are you following?

That's the Crash Course's batchfile. The '-lm' and 'pause' give it away. While it's an easy to understand tutorial, there is some seriously bad code in that thing, a few of which are covered here.

mrmarc772 wrote:
Code:
set path=C:\devkitadv\bin;%path%
gcc -o hello.elf hello.c -lm
objcopy -O binary hello.elf hello.gba
pause

This is not a makefile, this is a batchfile. Makefiles look more like this or this. Yes, they look more complicated than a batchfile, but that's only because the project is still very simple. For bigger projects with multiple files you need an easy way of managing all the files you have and makefiles allow you to do that. Batchfiles don't.

Use the devkitPro templates and the structure in the examples there. Use a programmer's editor or an IDE to run the makefiles for you. In PN2, you can open the makefile and Alt+1 build the project.

Lastly, do not use paths with spaces in them (like My Documents). Unix tools can't deal with them because the space indicates the separation between options.

#127822 - keldon - Sat May 05, 2007 11:00 am

In Unix you would use '\ ' to indicate a space in a path; does this also work in makefiles?

#127824 - Lick - Sat May 05, 2007 11:21 am

keldon wrote:
In Unix you would use '\ ' to indicate a space in a path; does this also work in makefiles?


I'm not really sure but I always just quote the whole path. And \ I use to indicate a not-new-line.

command \
param1 \
param2

Y'know.

#127838 - wintermute - Sat May 05, 2007 2:39 pm

Lick: that's just escaping the end of line sequence

Keldon: yes you can escape spaces in Makefiles too. The problem lies in maintaining the escaped spaces through all the tools. Some tools can cope with argv elements which contain spaces, others split them when passing them on to other tools.


The MinGW mailing list has similar questions on a regular basis and I'm pretty sure that most gcc ports being used on windows have had this question at some point. Many people have tried to make spaces in paths not break their toolchains, all of them failed.

Don't put spaces in paths.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#127839 - tepples - Sat May 05, 2007 2:59 pm

It's Microsoft's fault. Had underscore been treated as the uppercase version of space in FAT's case-preserving but -insensitive semantics, none of this would have happened.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#127842 - mrmarc772 - Sat May 05, 2007 3:28 pm

where do you run the makefile?

#127864 - Cearn - Sat May 05, 2007 10:55 pm

mrmarc772 wrote:
where do you run the makefile?

Inside the directory that the Makefile is in generally.

First though, take a step back and look at what's actually going on. Yes, it's (too) long, but read it anyway.

This is generally how building a program works; not just for C, but any compiled language. You have a number of source-files with code in them. There are tools (programs) that can convert that source into something that can actually execute. One such tool is arm-eabi-gcc, which is the compiler that comes with devkitPro, but there are many others as well.
The way it usually works is that you run the tool and give it a number of parameters to work with. One of these parameters is the source file's name; other parameters can be options that control the behavior of the tool. For example, this line:
Code:
arm-eabi-gcc -mthumb -c hello.c

calls the compiler and tells it to compile hello.c. It also tells it to compile to the Thumb instruction set (-mthumb) and to only compile hello.c into an object file named hello.o, but not to create an executable of it just yet (-c). Many other options exist as well, and different tools use different options.

Note that something very similar actually happens when you double-click on a file in Explorer or drag a file to an icon on the desktop. Windows looks up the extension and executes the associated program with the filename as a parameter. For example, if I double-click on file `c:/dir1/dir2/woot.doc', Windows will execute the command
Code:
`"c:/Program Files/more directories/winword.exe" "c:/dir1/dir2/woot.doc'
The principle is the same; it's just that Windows hides what's really going on when you double-click on something. Check the properties of the icons on your desktop and see how each of them has a 'target' with the program's path and sometimes some options as well.

In principle, you can make Windows compile a source-file when you double-click on a C file as well, but this is a bad idea because not all C files are to be executed with the same tool, and the options can differ as well. Also, bigger projects can easily get up to 100 files, and you really don't want to have to double-click each and every one of them. That why you use things like makefiles: to automate the process.

Now, notice that in the .doc example Windows uses the whole path of the tool and file, but in the compiler's case there's only the basename. The shell needs the whole path, but typing it all in manually is problematic in a number of ways, not in the least that different people have different directory structures and entering the whole path would break things. Enter the concept of PATH. The shell will look in the current directory first for a given file, and if it can't find it there it'll look in the directories specified in the PATH. The devkitPro installation adds the msys/bin directory to the path, and creates an environment variable DEVKITARM containing the path to the devkitARM directory. You can then use that variable to make the devkitARM/bin directory visible. by adding $(DEVKITARM)/bin to the path. This will work regardless of where the devkitARM directory actually is. That takes care of the tool's paths, now the source-file.

As said, while it's possible to tell Windows to compile a source-file by double-clicking, it's not a good idea. The standard procedure is to have a script call all the tools for you with the desired options. A batchfile is such a script. So is a makefile, only it has vastly superior options, although they are a little more complex at first.
The idea of makefiles is that you create rules for certain actions (say, turning a C file into an object file). You can then create a list of C files and the makefile will take care of the rest.
Okay, so it's a little more complicated than that, but you can write makefiles that act like that. In fact, the DKP Makefiles do just that and go one further: you only have to tell it the directories source files are in, and it will get collect all the source files in those directories automatically.

Now the question is how to run those makefiles (*sigh* finally!). The tool that can run makefiles is called 'make' and can be found in the msys/bin directory, which was added to the PATH by devkitPro. This means you can run it from anywhere. make is written in such a way that it'll try to execute the file called 'Makefile' in the current directory, which is why makefiles are generally called "Makefile".
Again, it's possible to tell Windows to run make by double-clicking on a makefile (just like you would a batchfile), but it's better to it from inside a programmer's editor like Programmer's Notepad 2 (PN2), which comes with the DKP installation.

Most editors can be customized to run shell commands on the currently active file. However, these usually have to be configured manually. That said, the editors also have a native 'project' file, with which you can manage the files of the project, and sometimes the tools to build the project as well. Because makefiles are fairly universal, these project files may already be set-up to run make.
This is the case for PN2. Its project files have the extension .pnproj, and when you've opened one of those, Alt+1 will run make in the directory of the project file. If you look in the DKP examples or tonc's projects, you'll see that all of them have .pnproj files and makefiles in their directories, so all you have to do is open the project file in PN2 and hit Alt+1.

This is essentially how and why things are done the way they are. You mentioned you used java and flash already. There are analogous items there as well. In java, for example, there's also a java compiler that needs to go over all the .java files to create the byte code. I assume it you've been working with an IDE for that. Those also have project files to manage the source files and build rules. It's just that the IDE takes care of all that stuff automatically. But for GBA/NDS homebrew, you have to get your hands dirty a little.

P.S.
cearn wrote:
Use the devkitPro templates and the structure in the examples there. Use a programmer's editor or an IDE to run the makefiles for you. In PN2, you can open the makefile and Alt+1 build the project.

Apparently this wasn't quite as true as I'd hoped. If you open the .pnproj file, you can use Alt+1 to run make in that directory. But just opening the makefile doesn't work. Sorry, my bad.

It is possible to make it work, though. In the Tools->Options dialog, there are 'Files' and 'Tools' settings with which you can create rules to run make when a file called Makefile is open.

#127910 - mrmarc772 - Sun May 06, 2007 2:42 pm

Well to start off, great post (worth the length imo) i think from reading that my iq went up a couple of point :), but other than that what you said pretty much makes sense... i guess ill go follow what tonic hasto say one more time and see how far i go...after reading atleast 5 gba tutes and one on makefiles stuff is finally making a little sense.



Quote:
You mentioned you used java and flash already. There are analogous items there as well. In java, for example, there's also a java compiler that needs to go over all the .java files to create the byte code. I assume it you've been working with an IDE for that. Those also have project files to manage the source files and build rules. It's just that the IDE takes care of all that stuff automatically. But for GBA/NDS homebrew, you have to get your hands dirty a little.


yeah, 1 year of vb, 2 of java, and 2 of flash... from what i see now, i don't know asmuch as i though i knew... that's why i find this all so fun i guess... this stuff feels much less fake than workin with any of those

thx for the help



EDIT: so i went to tonic and they explain and show this peice of code:

Code:
PROJ= first

CC= arm-eabi-gcc
OBJCOPY= arm-eabi-objcopy

.PHONY : build
build:
   $(CC) -mthumb-interwork -mthumb -c $(PROJ).c
   $(CC) -specs=gba_mb.specs -mthumb-interwork -mthumb $(PROJ).o -o $(PROJ).elf
   $(OBJCOPY) -v -O binary $(PROJ).elf $(PROJ).mb.gba
   -@gbafix $(PROJ).mb.gba

.PHONY : clean
clean:
   @rm -fv $(PROJ).o
   @rm -fv $(PROJ).mb.gba
   @rm -fv $(PROJ).elf


... so i understand it pretty well but 1) it's not compiling in pn2 and 2)shouldn't there be some full path names for the stuff not in the root folder?

#127914 - tepples - Sun May 06, 2007 3:00 pm

That is a batch file from the old days. At the time, it was common practice to put devkitARM in your shell's PATH, which explains the lack of full path names. Nowadays, people put devkitARM in the makefile's own PATH.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#127921 - kusma - Sun May 06, 2007 5:46 pm

tepples wrote:
It's Microsoft's fault.

Then how come visual studio has no issues with spaces in paths?

#127922 - mrmarc772 - Sun May 06, 2007 5:51 pm

tepples wrote:
That is a batch file from the old days. At the time, it was common practice to put devkitARM in your shell's PATH, which explains the lack of full path names. Nowadays, people put devkitARM in the makefile's own PATH.

huh?

#127925 - keldon - Sun May 06, 2007 6:12 pm

mrmarc772 wrote:
tepples wrote:
That is a batch file from the old days. At the time, it was common practice to put devkitARM in your shell's PATH, which explains the lack of full path names. Nowadays, people put devkitARM in the makefile's own PATH.

huh?

Basically he is saying that with the batch files you would add devkitARM to your own shell's PATH (which would explain the lack of full path names in your path).

#127936 - wintermute - Sun May 06, 2007 8:37 pm

Except it isn't recommended that you do that with the system path these days. Perhaps you've noticed me trying to avoid that issue completely? :P

Tepples is actually wrong, this isn't a batch file, it's an extremely basic Makefile for a single C file project.

The first thing to do is add the devkitARM tools to the path in the makefile.

Code:


export PATH := $(DEVKITARM)/bin:$(PATH)

PROJ= first

CC= arm-eabi-gcc
OBJCOPY= arm-eabi-objcopy

.PHONY : build
build:
   $(CC) -mthumb-interwork -mthumb -c $(PROJ).c
   $(CC) -specs=gba_mb.specs -mthumb-interwork -mthumb $(PROJ).o -o $(PROJ).elf
   $(OBJCOPY) -v -O binary $(PROJ).elf $(PROJ).mb.gba
   -@gbafix $(PROJ).mb.gba

.PHONY : clean
clean:
   @rm -fv $(PROJ).o
   @rm -fv $(PROJ).mb.gba
   @rm -fv $(PROJ).elf


cearn wrote:

It is possible to make it work, though. In the Tools->Options dialog, there are 'Files' and 'Tools' settings with which you can create rules to run make when a file called Makefile is open.


I'd prefer to avoid doing this, it adds an extra layer of complexity to an otherwise simple operation. The way I set up PN2 means that ALT 1 or Tools->make *always* builds the project regardless of what file you're looking at, provided you opened the .pnproj file or created a project in the first place.

The devkitPro .pnproj files are actually set up so that it finds the source files automatically using the magic folders too. This keeps everything as simple as possible so beginners aren't overwhelmed by the whole experience.

Well, that's the theory anyway. In practice I need to get all this documented and put on devkitpro.org for reference so people can point to it instead of using their own particular flavour of howto.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#127937 - keldon - Sun May 06, 2007 8:50 pm

I think Tepples may have been referring to the first post!

#127938 - wintermute - Sun May 06, 2007 8:53 pm

Oh, I see what happened there. It's the good old post edit confusion. Sorry Tepples.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#127977 - mrmarc772 - Mon May 07, 2007 4:08 am

i appreciate the help from everyone... unfortunately ive had so much hw this weekend my time spent trying to figure this all out has been minimal... ill have to try and understand what you guys are saying tommarow, but as a quick question: would devkit still work properly if i installed it onto my spare flash drive?

#128027 - tepples - Mon May 07, 2007 9:45 pm

mrmarc772 wrote:
tepples wrote:
That is a batch file from the old days. At the time, it was common practice to put devkitARM in your shell's PATH, which explains the lack of full path names. Nowadays, people put devkitARM in the makefile's own PATH.

huh?

One major religion (to remain nameless) teaches that misunderstandings of a passage stem from misunderstandings of each word in that passage. So which word of that passage was the first word you did not understand?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#128650 - mrmarc772 - Sun May 13, 2007 8:44 pm

tepples wrote:
mrmarc772 wrote:
tepples wrote:
That is a batch file from the old days. At the time, it was common practice to put devkitARM in your shell's PATH, which explains the lack of full path names. Nowadays, people put devkitARM in the makefile's own PATH.

huh?

One major religion (to remain nameless) teaches that misunderstandings of a passage stem from misunderstandings of each word in that passage. So which word of that passage was the first word you did not understand?

well schools been increasingly overbearing recently...
i barely finish all my hw as it is...
ill give this all another shot in 3 or 4 weeks when school ends...
btw i aced my comp. science ap test -go me!