Jump to content
IGNORED

Makefile breakdown for the Hello World! exercise


JagChris

Recommended Posts

Here is what the makefile looks like for Boz's Hello World!

 

OFILES = \
startup.o \
jag.o

jag : $(OFILES)
    aln -c jag.lnk 

GAS2OBJ = mac -i/jaguar/include -fb -g $?
C2OBJ = gccjag -b m68k -B/jaguar/bin/ -V2.6 -Wall -DJAGUAR -O2 -c -o $@ $?

#
# 68k jaguar specific asm files
#

startup.o : startup.s
    $(GAS2OBJ)

#
# 68k jaguar specific C files
#    
jag.o : jag.c
    $(C2OBJ)

clean :
    rm *.o
    rm *.abs

Link to comment
Share on other sites

Belboz breaks down his Hello World! makefile.

 

OFILES = \
startup.o \
jag.o

 

OFILES is a definition that is a list of all the object files needed for this project. The \ is used to denote that the definition isn't finished (normally the carriage return would mark the end of it). You can see we don't have a \ after jag.o

 

So basically we have two object files in our project. statup.o and jag.o

 


jag : $(OFILES)
    aln -c jag.lnk 

 

This tells us in order to build jag we need all the object files defined above. If they all exist then the linker (aln) is called as noted.

 

GAS2OBJ = mac -i/jaguar/include -fb -g $?
C2OBJ = gccjag -b m68k -B/jaguar/bin/ -V2.6 -Wall -DJAGUAR -O2 -c -o $@ $?

 

These two lines define command line parameters for generating object files from c and assembly source.

 

GAS2OBJ tell how to use the assembler "mac" to assemble and assembly source code into and object file.

 

C2OBJ tells how to compile a C file into an object file.

 

startup.o : startup.s
    $(GAS2OBJ)

 

These two lines show how to build startup.o

 

If the make utility doesn't see a startup.o file in the project (or the source code file is newer than the .o file denoting changes were made) it assembles the file into an object file.

 

So if startup.o is missing the makefile executes the GAS2OBJ command with startup.s as the source file. This will generate the startup.o if the assembly is ok (i.e. no errors in the code). This is what the make utility would do if it needed to generate the startup.o file

 

mac -i/jaguar/include -fb -g startup.s

 

jag.o : jag.c
    $(C2OBJ)

 

This is the same as the above example but tells the make utility how to build jag.o . If jag.o doesn't exist the C2OBJ command line is executed with jag.c as a parameter.

 

clean :
    rm *.o
    rm *.abs

 

this is what happens if you type "make clean" from the command line.

 

It removes all the *.o and *.abs files. This will probably fail on DOS systems since the rm command doesn't exist. So you should edit and change the rm to del.

 

That is a quick run through. Please ask if you have more questions.

 

A makefile greatly simplifies building a project. Especially with large numbers of files.

 

You can see it basically tells how to build the program in stages. I.E.

 

In order to build jag I need object files I will link with aln

 

In order to build object files I need to either assemble or compile the .s and .c files into object files

 

It is also nice because the make utility looks at whatever it is building (and object file, the abs file) and it compares the file date of the two items.

 

So if the jag.abs is older than the object files, it knows it has to re-link.

 

If an assembly file is newer than its object file, it knows it has to re-assemble that file

 

So if you have a large project with lots of C and assembly files and you make a change to one file it will only recompile or assemble that file, and relink the project. It wont recompile and re-assemble all the other source files.

Edited by JagChris
  • Like 1
Link to comment
Share on other sites

Boz's new tools use smac and vlink.

 

The command prompt commands to manually compile and link the projects:

 

smac assemble command line for startup.s:

 

smac -i/jaguar/include -fb startup.s

 

VBCC command line for hello world:

 

vc -DJAGUAR -O2 -c -o jag.o jag.c

 

To link them together using vlink:

 

vlink -brawbin1 -Ttext 0x4000 startup.o jag.o -L/jaguar/lib -lvbcc -o jag.bin

 

However of course, the purpose of the makefile is to automate this process for you. But this was posted for the curious. Otherwise go to the directory you are working in and simply type 'make' and all this will be done automatically.

Edited by JagChris
  • Like 1
Link to comment
Share on other sites

#
# 68k jaguar specific asm files
#

startup.o : startup.s
    $(GAS2OBJ)

#
# 68k jaguar specific C files
#    
jag.o : jag.c
    $(C2OBJ)

 

These can be replaced with the somewhat more generic version below

 


#
# 68k jaguar specific asm files
#

%.o : %.s
    $(GAS2OBJ)

#
# 68k jaguar specific C files
#    
%.o : %.c
    $(C2OBJ)

 

The difference is that the former rule told make how to make startup.o from startup.s, and jag.o out of jag.c, respectively. The new rules tell make how to make any .o file out of a correspondingly named .s or .c file.

 

 

For comparison, the makefile format I normally use looks like this:

 

#====================================================================
#       Macro & Assembler flags
#====================================================================

STADDR = 4000
MACFLAGS = -fb -g
ALNFLAGS = -v -v -e -g -l -rd -a $(STADDR) x x

#====================================================================
#       Default Rules
#====================================================================

%.o : %.s
mac $(MACFLAGS) $*

%.s : %.tga
tga2cry -header -f rgb -o $*.s $*.tga

#====================================================================
#       EXECUTABLES
#====================================================================

OBJ = startup.o main.o objlist.o logo.o background.o

demo.cof: $(OBJ)
aln $(ALNFLAGS) -o demo.cof $(OBJ)

#====================================================================
#       EXTRA DEPENDANCY INFO
#====================================================================

main.o: objlist.inc
objlist.o: objlist.inc

#====================================================================
#       CLEANUP
#====================================================================

.PHONY: clean
clean:
del *.o
del *.cof
del *.bak

 

The first section sets up macros for the flags past to mac and aln, as well as the address where the code should be linked to, in this case 4000 hex, which is the start of "user ram" I've never worked out what's below that address on retail consoles, or if it's usable, but it's used by the official dev kit for storing code and data related to the link with the debugging pc and other stuff, so the Atari docs suggest linking to there. Of course they suggest code and data should be at 802000 hex, which is the start of cart space (after the encryption header, which goes from 800000 to 801FFFF).

 

The second section contains rules for building .o files out of .s files, and for converting images into .s files out of .tga files by running tga2cry. I have taken to using the -header option, as well as outputting to source code, which provides a global label as well as a header with the image dimensions, and a set of blitter flags. One cute thing about make is that it can do these intermediate transformations. If it finds it needs to make background.o, and has a rule for making *.o out of *.s, but doesn't have a background.s, it will look and see if it can make it, find the rule for making a *.s out of *.tga, execute it, making background.s, then compile that into background.o, and then finally delete the intermediate file background.s. It is then smart enough to still do this even when checking for modifications, so if I change background.tga, background.o will automagically be updated too.

 

Next comes the section where we define the files to be included in the final output. OBJ defines a list of files equivalent to OFILES in the original example, and the next line is the main rule that tells make how to call aln to link all the objects together into a coff format executable.

 

The 4th section tells make about any extra dependancies that it needs to know about. For example, if I were ever to change objlist.inc (a file containing definitions of constants and static variables for my object list building code), then the files which included it would need to be updated. Make can't determine that on it's own, so these lines teach it about those dependancies.

 

Finally the last section declares a phony target called clean, which (when invoked with "make clean") will delete the executable (*.cof), any object files (*.o) and also backup files made my text editor (*.bak).

  • Like 2
Link to comment
Share on other sites

I generally don't like the global rule for all C or all assembly. I generally specify it for each source file since I like to have any include files for that particular source file on the line also. That way I don't have to add those dependencies down below, and can keep them all together.

 

Plus sometimes I use different compiler/assembler options for particular files. That way I can turn a debugging define on for a particular source file instead of group wide. Or I may turn off optimization on a certain file (sometimes I have found the optimization with the old gcc with the original dev tools can cause problems).

 

But the beauty of makefiles are they can be tailored to each programmers use and tastes.

Link to comment
Share on other sites

As a sidenote, I dont really want to derail this thread, but Tyrant you do not use the new linker or assembler?

Nope, I started playing with the Jag back before they were written. It took me a while to set up my dev tools, and I'm happy with what I've got. I code on an alpine so I have to use wdb (well I could use rdbjag but wdb is so very useful), and that means I have to use win98 in order to get the parallel port to work. Plus I sort of dropped out of the Jag scene a few years back due to real life taking over for a bit, and when I came back, there are all these shiney new tools. I kinda missed most of the announcements, and thus didn't even know about the skunkboard until after it was too late to get one. As for the new assembler and linker... well, the old ones do the job perfectly well, and I don't really know what's different about the new ones or why I should switch.

 

But the beauty of makefiles are they can be tailored to each programmers use and tastes.

Indeed. Each unto their own. Just so long as that doesn't go so far as gnu automake :x

 

But yeah, lets not derail this thread, makefiles are awesome powerful tools, and really need not be complicated or hard to understand. I think people get scared off by them when they don't need to be. Make does one thing and does it well: it compares the modification date of the compiled program with the modification dates of all the files that created it, and all the files that created them, and it rebuilds anything that has been changed since last time you ran it. That's all, but it's very helpful.

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...