HowTo: Using makefiles in Blender

When you start a large project in Blender, especially if you are doing compositing, you wind up in a very familiar situation in computerdom: - You have a large, complex project with many disparate parts. - You need to be able to re-generate the project to a known, fully reproducible state, anytime and without conscious thought or supervision. - This process consumes a lot of time, and needs to be done in such a way that, while every changed piece (and those pieces which depend on them) must be regenerated, you need for only those pieces to be re-done. - You have a socio-biological need to sleep and/or drink beer :wink: while this is being done.
… A perfect application for a programmer’s utility called make. (nmake on many MS-DOS systems.)

make allows you to build (amazingly enough…) Makefiles which specify which files depend on which other files, and how to rebuild them. Makefiles can invoke other makefiles. On some systems and in some circumstances, more than one make-step can be active at the same time.

In my project, I have one Makefile in the project directory, which builds all of the Scenes and then assembles them into the Finished movie. In the Scenes directory, I have a subdirectory for each scene and a Makefile in each. Here is the Makefile for scene #1:

# Makefile for sc01_establishing

BLEND = nice blender -b
OPTS  = -a

LAYERFILES += touched/bkgnd touched/roof touched/anim touched/pedro touched/river touched/smoke

.PHONY: all clean avi layers

all     : avi

avi     : touched/avi

layers  : $(LAYERFILES)

touched/avi         : sc01A_avi.blend layers
	-rm avi/*
	$(BLEND) sc01A_avi.blend $(OPTS)
	touch touched/avi

# ===

touched/bkgnd       : sc01A_bkgnd.blend
	-rm output_bkgnd/*kg*
	$(BLEND) sc01A_bkgnd.blend $(OPTS)
	touch touched/bkgnd

touched/roof       : sc01A_roof.blend
	-rm output_bkgnd/*ro*
	$(BLEND) sc01A_roof.blend $(OPTS)
	touch touched/roof

touched/anim       : sc01A_anim.blend
	-rm output_anim/*
	$(BLEND) sc01A_anim.blend $(OPTS)
	touch touched/anim

touched/pedro       : sc01A_pedro.blend
	-rm output_pedro/*
	$(BLEND) sc01A_pedro.blend $(OPTS)
	touch touched/pedro

touched/river       : sc01A_river.blend
	-rm output_river/*
	$(BLEND) sc01A_river.blend $(OPTS)
	touch touched/river

touched/smoke       : sc01A_smoke.blend
	-rm output_smoke/*
	$(BLEND) sc01A_smoke.blend $(OPTS)
	touch touched/smoke

clean   :
	-rm touched/*
	-rm output_bkgnd/* output_anim/* output_pedro/* output_river/* output_smoke/* avi/*

The makefile starts with a few command-definitions, namely the correct Blender command to render the animation. Then it contains rules which specify the dependent-file on the left of the “:” and the files upon which it depends on the right. The makefile plays a few games with “touch,” creating sentinal files that simply indicate the latest date/time a particular output step was run.

The command make all, or simply make, will re-generate all of the files that need to be re-made, if any. The command make clean will remove (“rm”) all of the files generated in this step so that you can “start clean” in preparation for forcing a re-make of everything. Notice how each step also removes any prior output before starting a new render, since the number of output files (.tga’s) may be lesser or greater in any given run.

The scene-level Makefile looks like this:

 # Makefile for all the scenes

.PHONY: all clean

all:
	cd sc01_establishing && $(MAKE) || exit 1
	cd sc02_med          && $(MAKE) || exit 1
        <i>...etc...</i>

clean:
	cd sc01_establishing && $(MAKE) clean || exit 1
	cd sc02_med          && $(MAKE) clean || exit 1
        <i>...etc..</i>

And the overall make-it-all Makefile looks like this:

# Makefile for the movie .. the whole shebang

.PHONY: all clean


all:
	cd scenes   && $(MAKE) || exit 1
	cd finished && $(MAKE) || exit 1

clean:
	cd scenes   && $(MAKE) clean || exit 1
	cd finished && $(MAKE) clean || exit 1

(The Makefile for the “finished” step is not shown but is like the first one shown above.)

So, even though you have to put a little effort into maintaining the Makefiles, if you do this you can easily bring the project up-to-date … guaranteed … just by issuing one command. You can run it overnight or at any time, and the entire project will always be brought reliably, automatically, up-to-date, always using the least number of Blender steps required.

That’s a totally funny way to use make, but I agree it could be useful. Sadly, most people here don’t even know what a command line is, much less an ASCII editor, or even make :wink:

Well, the good news is that this computer-graphics stuff is genuinely Art :smiley: … and the bad news is that it still involves a computer. :o … :wink:

“The art of making art … is putting it together.”

It didn’t take me too long in even a three-minute movie project to start scrambling for tools and techniques that would help me avoid multi-hour renders (and re-renders).

A couple of clarifications have been requested.

===

(1) The essential idea behind a Makefile is that it consists of rules of the form Dependent_File : Depends_On_Files… . When a dependent-file is found to be older than any of the files it depends on (or if it doesn’t exist at all), the dependent file must be remade. The indented lines following the rule tell how. (But first, all of those dependent files must be remade, ad infinitum. All rules and dependencies required to do so must exist somewhere in the Makefile.)

(2) I’m using the touched/filename files as “sentinals” to indicate the date-and-time when the corresponding output was produced. “The output” of a render might consist of hundreds of files; sentinal-files are easier. The touch command creates a file, or changes its modification-date to the current date/time, basically by opening the file and closing it again. The files thus created are empty.

(3) Yes, the rules are funny, with these “sentinal” files being listed as the dependent-files to be remade. This is simply done just to satisfy Make.

(4) Why is the blender command in two parts, with the second-part nothing but “-a”? Because Blender doesn’t recognize the “-b” parameter if the “-a” parameter comes before it! %| Don’t ask me why.

(5) Make is a programmer’s utility. Linux systems usually come with it; MS-DOS systems usually don’t. But copies can be downloaded from the Internet.