User Tools

Site Tools


base:cross_development_using_makefile

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

base:cross_development_using_makefile [2015-04-17 04:31] (current)
Line 1: Line 1:
 +====== Cross Development using Makefile ======
 +by Burglar/SCS*TRC
 +===== Introduction =====
  
 +[[http://www.gnu.org/software/make/|GNU Make]] is a tool used to build executables, libraries and whole applications.
 +You can use it to script all commands you are using to compile your code.
 +Once properly set up, it will automatically resolve dependencies and
 +only rebuild what has changed.
 +
 +This will drastically speed up your development process for any project,
 +small or large.
 +
 +Once automated you will never have to do conversions of graphics and sids
 +by hand anymore.
 +
 +It will also help you think structured about your code and data.
 +===== How Makefile works =====
 +
 +A basic Makefile is a plaintext file in your working directory consisting
 +of one or more rules to satisfy all dependencies required to build the
 +requested target. A dependency can be another file or another target.
 +
 +<code make>target: dependencies
 +[tab]command</code>
 +**WARNING**: The single tab is important, make sure your editor doesn't change them.
 +
 +The target is what we want, the dependencies what we need and
 +the command is to build the required target.
 +
 +Let's say we're coding an intro in kickass and to compile it we type:
 +<code make>java -jar /usr/share/java/KickAss.jar intro.s -o intro.prg</code>
 +
 +To do that with a Makefile:
 +<code make>intro.prg: intro.s
 + java -jar /usr/share/java/KickAss.jar intro.s -o intro.prg</code>
 +
 +Now you can run "make" or "make intro.prg" to compile.
 +
 +===== Implicit Rules =====
 +
 +The command to build your sources is probably always the same, so you
 +can use wildcards to make implicit rules.
 +
 +The automatic variables $< and $@ are used as dependency and target respectively.
 +
 +<code make># % is a wildcard
 +# $< is the first dependency
 +# $@ is the target
 +# $^ is all dependencies
 +
 +%.prg: %.s
 + java -jar /usr/share/java/KickAss.jar $< -o $@</code>
 +
 +This enables you to compile any ".s" source file with "make anything.prg".
 +
 +===== Setting up dependencies =====
 +
 +We are still working on the intro, and now we're going to add music and a bitmap
 +logo. We add the necessary imports and a LoadSid in our source-file intro.s.
 +Time to add the dependencies in our Makefile:
 +
 +<code make># our implicit build rule
 +%.prg: %.s
 + java -jar /usr/share/java/KickAss.jar $< -o $@
 +
 +# default build target
 +all: intro.prg
 +
 +# dependencies for our intro, which files do we need to compile intro.s into intro.prg
 +# the implicit rule will take care of depending on intro.s itself
 +intro.prg: tune.sid logo.prg</code>
 +
 +Now type "make" twice, it builds, but the second time it won't waste
 +your time like a .bat.
 +If you modify any of the files "intro.s", "tune.sid" or "logo.prg", make
 +will rebuild the intro.
 +
 +===== Automatic Crunching =====
 +
 +To add another rule to our build chain, we need to think of a new file extension
 +for the new target. We'll use exomizer, so ".prg.exo" sounds about right.
 +
 +<code make>exomizer sfx basic -n intro.prg -o intro.prg.exo</code>
 +
 +Let Makefile handle the thing:
 +
 +<code make>%.prg: %.s
 + java -jar /usr/share/java/KickAss.jar $< -o $@
 +
 +%.prg.exo: %.prg
 + exomizer sfx basic -n $< -o $@
 +
 +all: intro.prg.exo
 +
 +intro.prg: tune.sid logo.prg</code>
 +
 +This same technique can be used for many other things, see the full example
 +below.
 +
 +===== Variables/Macros =====
 +
 +You can use variables to define some defaults and locations. It will also clean up 
 +your Makefile and make it more readable.
 +It is best explained by example:
 +
 +<code make>JAVA=java
 +KICKASS=$(JAVA) -jar /usr/share/java/KickAss.jar
 +EXOMIZER=exomizer
 +EXOMIZERFLAGS=sfx basic -n
 +SOURCEFILES=intro.s part1.s part2.s
 +OBJECTS=intro.prg part1.prg part2.prg
 +PACKEDOBJECTS=intro.prg.exo part1.prg.exo part2.prg.exo
 +
 +%.prg: %.s
 + $(KICKASS) $< -o $@
 +
 +%.prg.exo: %.prg
 + $(EXOMIZER) $(EXOMIZERFLAGS) $< -o $@
 +
 +all: $(PACKEDOBJECTS)
 +
 +$(OBJECTS): tune.sid logo.prg</code>
 +
 +Btw, this demo sucks, same tune and logo in every part ;)
 +===== Cleaning up your working directory =====
 +
 +Sometimes you may want to get rid of every object to be able to explicately
 +rebuild everything. Or you want to give your source to someone else, you'll only
 +want to give the source, not pre-built objects.
 +
 +The common way to do that is to add a "make clean" target:
 +
 +<code make>clean:
 + rm -f *.exo
 + rm -f intro.prg
 + rm -f part?.prg</code>
 +
 +===== Building in Parallel =====
 +
 +Most people have a cpu with more than 1 core. Makefile can transparently
 +utilize them to speed up your compiles even more.
 +It is important you have all your dependencies correctly mapped out or
 +strange things might happen.
 +
 +<code make># build using up to 4 cores in parallel
 +make -j4 all</code>
 +
 +===== Full Example =====
 +
 +Combining the things we learned, we can now write a Makefile capable of:
 +
 +  * compiling kickass source code
 +
 +  * compiling 64tass source code
 +
 +  * packing with exomizer
 +
 +  * bitmap to sprite conversion
 +
 +  * building a d64 with all files
 +
 +  * autostarting vice with "make vice" (6581, press f7 at start to avoid cartridge).
 +
 +We already have java, kickassembler, 64tass, exomizer, cc1541, bitmap2spr.py and vice installed and in our path.
 +
 +=== Source Files ===
 +
 +<code make>
 +Makefile
 +intro.s             # uses LoadSid to include the .sid
 +lib.s               # contains macros and stuff
 +part1.s             # uses LoadSid and .import c64 "gfx/picture.prg"
 +part2.s             # uses LoadSid and .import c64 "gfx/spritelogo.spr"
 +part3.asm           # has no dependencies
 +gfx/picture.s       # calls a macro to convert the .png to .prg
 +gfx/picture.png
 +gfx/spritelogo.bmp
 +sid/introtune.sid
 +sid/part1.sid
 +sid/part2.sid
 +</code>
 +
 +=== Makefile ===
 +
 +<code make>JAVA=java
 +KICKASS=$(JAVA) -jar /usr/share/java/KickAss.jar
 +TASS64=64tass
 +EXOMIZER=exomizer
 +EXOMIZERFLAGS=sfx basic -n
 +CC1541=cc1541
 +BITMAP2SPR=bitmap2spr.py
 +VICE=x64
 +VICEFLAGS=-sidenginemodel 1803 -keybuf "\88"
 +SOURCEFILES=intro.s part1.s part2.s part3.asm gfx/picture.s
 +OBJECTS=intro.prg.exo part1.prg.exo part2.prg.exo part3.prg.exo
 +
 +%.prg: %.s
 + $(KICKASS) $< -o $@
 +
 +%.prg: %.asm
 + $(TASS64) $< -o $@
 +
 +%.spr: %.bmp
 + $(BITMAP2SPR) $< $@
 +
 +%.prg.exo: %.prg
 + $(EXOMIZER) $(EXOMIZERFLAGS) $< -o $@
 +
 +all: demo.d64
 +
 +vice: demo.d64
 + $(X64) $(X64FLAGS) $<
 +
 +intro.prg: lib.s sid/introtune.sid gfx/spritelogo.spr
 +
 +part1.prg: lib.s sid/part1.sid gfx/picture.prg
 +
 +gfx/picture.prg: lib.s gfx/picture.png
 +
 +part2.prg: lib.s sid/part2.sid gfx/spritelogo.spr
 +
 +demo.d64: $(OBJECTS)
 + $(CC1541) -f "DEMO" -w intro.prg.exo \
 + -f "PART1" -w part1.prg.exo \
 + -f "PART2" -w part2.prg.exo \
 + -f "PART3" -w part3.prg.exo \
 + $@
 +
 +clean:
 + rm -f demo.d64
 + rm -f *.prg
 + rm -f *.exo
 + rm -f gfx/*.spr
 + rm -f gfx/*.prg
 + rm -f gfx/*.exo
 +</code>
 +
 +===== Questions and Comments =====
 +
 +Please refer to the [[http://csdb.dk/forums/?roomid=11&topicid=95684|thread on CSDb]].
 +
 +You can also check the official [[http://www.gnu.org/software/make/manual/|GNU Make Manual]].
base/cross_development_using_makefile.txt ยท Last modified: 2015-04-17 04:31 (external edit)