base:cross_development_using_makefile
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:cross_development_using_makefile [2015-04-17 04:31] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Cross Development using Makefile ====== | ||
+ | by Burglar/ | ||
+ | ===== Introduction ===== | ||
+ | [[http:// | ||
+ | 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> | ||
+ | [tab]command</ | ||
+ | **WARNING**: | ||
+ | |||
+ | 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> | ||
+ | |||
+ | To do that with a Makefile: | ||
+ | <code make> | ||
+ | java -jar / | ||
+ | |||
+ | Now you can run " | ||
+ | |||
+ | ===== 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 / | ||
+ | |||
+ | This enables you to compile any " | ||
+ | |||
+ | ===== 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 / | ||
+ | |||
+ | # 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</ | ||
+ | |||
+ | Now type " | ||
+ | your time like a .bat. | ||
+ | If you modify any of the files " | ||
+ | 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 " | ||
+ | |||
+ | <code make> | ||
+ | |||
+ | Let Makefile handle the thing: | ||
+ | |||
+ | <code make> | ||
+ | java -jar / | ||
+ | |||
+ | %.prg.exo: %.prg | ||
+ | exomizer sfx basic -n $< -o $@ | ||
+ | |||
+ | all: intro.prg.exo | ||
+ | |||
+ | intro.prg: tune.sid logo.prg</ | ||
+ | |||
+ | This same technique can be used for many other things, see the full example | ||
+ | below. | ||
+ | |||
+ | ===== Variables/ | ||
+ | |||
+ | 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> | ||
+ | KICKASS=$(JAVA) -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</ | ||
+ | |||
+ | 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> | ||
+ | rm -f *.exo | ||
+ | rm -f intro.prg | ||
+ | rm -f part? | ||
+ | |||
+ | ===== 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</ | ||
+ | |||
+ | ===== 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, | ||
+ | |||
+ | === Source Files === | ||
+ | |||
+ | <code make> | ||
+ | Makefile | ||
+ | intro.s | ||
+ | lib.s # contains macros and stuff | ||
+ | part1.s | ||
+ | part2.s | ||
+ | part3.asm | ||
+ | gfx/ | ||
+ | gfx/ | ||
+ | gfx/ | ||
+ | sid/ | ||
+ | sid/ | ||
+ | sid/ | ||
+ | </ | ||
+ | |||
+ | === Makefile === | ||
+ | |||
+ | <code make> | ||
+ | KICKASS=$(JAVA) -jar / | ||
+ | TASS64=64tass | ||
+ | EXOMIZER=exomizer | ||
+ | EXOMIZERFLAGS=sfx basic -n | ||
+ | CC1541=cc1541 | ||
+ | BITMAP2SPR=bitmap2spr.py | ||
+ | VICE=x64 | ||
+ | VICEFLAGS=-sidenginemodel 1803 -keybuf " | ||
+ | SOURCEFILES=intro.s part1.s part2.s part3.asm gfx/ | ||
+ | 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/ | ||
+ | |||
+ | part1.prg: lib.s sid/ | ||
+ | |||
+ | gfx/ | ||
+ | |||
+ | part2.prg: lib.s sid/ | ||
+ | |||
+ | demo.d64: $(OBJECTS) | ||
+ | $(CC1541) -f " | ||
+ | -f " | ||
+ | -f " | ||
+ | -f " | ||
+ | $@ | ||
+ | |||
+ | clean: | ||
+ | rm -f demo.d64 | ||
+ | rm -f *.prg | ||
+ | rm -f *.exo | ||
+ | rm -f gfx/*.spr | ||
+ | rm -f gfx/*.prg | ||
+ | rm -f gfx/*.exo | ||
+ | </ | ||
+ | |||
+ | ===== Questions and Comments ===== | ||
+ | |||
+ | Please refer to the [[http:// | ||
+ | |||
+ | You can also check the official [[http:// |
base/cross_development_using_makefile.txt · Last modified: 2015-04-17 04:31 by 127.0.0.1