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)