Using makefiles to package addons

Ahh final­ly putting your addon in a zip file and post­ing it, the most relax­ing part of devel­op­ment. Except when you have to do it often!

Generating the doc­u­men­ta­tion and includ­ing it as well as icons, py files, extra assets, etc. all while mak­ing sure I don’t include __pycache__ by mis­take is a chore on the lev­el of doing dish­es after christ­mas. It’s also very error prone, spe­cial­ly when you’re rush­ing embar­rass­ing bug­fix updates. Not that I ever had to do that **cough**

The solu­tion, of course, is automat­ing it.

There’s a tool devel­op­ers know well and is includ­ed with Linux and OS X: Make.
Make is a com­mand line util­i­ty used to sim­pli­fy the com­pil­ing process, how­ev­er it can be used like a shell script to auto­mate oth­er things (for instance, zip­ping files). Make uses a spe­cial for­mat file to set up the com­mands it has to run, these are files are called Makefiles.

A Makefile con­sists of one or more tar­gets. A tar­get is a group of com­mands iden­ti­fied by a name. You can be make indi­vid­ual tar­gets by run­ning make [target name].

Knowing this, we can now fig­ure out what com­mands to use and write a Makefile to take care of them for us.
Ok so now that we know how it works, how can we use make to get addons packaged?

Meet the addon Makefile

You can see the actu­al file below. Simply save it in your addon fold­er as “Makefile” (no exten­sion). To build (or “deploy”) open a ter­mi­nal in your addon direc­to­ry (where the make­file is) and sim­ply run make. A file brows­er will show you the fold­er con­tain­ing the zip file when it’s done.

Let’s look at the set­tings avail­able. You can change the FILE_BROWSER set­ting to what­ev­er you use to man­age files (find­er, ranger, thu­nar, etc.), or com­ment the last line if you don’t care about see­ing the zip file.

The FILES vari­able is passed as it is to the zip com­mand. Each file or direc­to­ry is sep­a­rat­ed by a space, and you can use wild­cards like I did in the exam­ple below.

BUILD_DIR refers to the direc­to­ry to put the zip file, it can be either a rel­a­tive or absolute path. The rest of the vari­ables are self-explanatory.

After the set­tings, I have set the tar­gets. You can adapt the make­file to any project by tweak­ing the vari­ables, but you can also adapt tar­gets and com­mands to your needs.

I’ve writ­ten three tar­gets in the file:

docsregen­er­ate the documentation
cleanDelete the zip
buildRun docs tar­get and cre­ate zip

The default tar­get is build. If you sim­ply run make with no argu­ments, it will use that target.

Also as you can read below, this Makefile requires Sphinx to build the docs (since that’s what I use) and the zip com­mand. If you’re not using Sphinx you can com­ment out that line, or replace it with a com­mand of your own.

# ---------------------------------------------------------------
# Makefile for My_addon
# Diego Gangl - <diego@sinestesia.co>
# ---------------------------------------------------------------


# /./././././././././././././././././././././././././././././././
# SETTINGS
# /./././././././././././././././././././././././././././././././

NAME            = My_addon
VERSION         = 1_0
BUILD_DIR       = ../release/
BUILD_FILE      = $(BUILD_DIR)/$(NAME)_$(VERSION).zip
FILES           = *.py icons/* docs/*
FILE_BROWSER    = nautilus

.DEFAULT_GOAL 	:= build


# /./././././././././././././././././././././././././././././././
# TARGETS
# /./././././././././././././././././././././././././././././././

.PHONY: docs
docs:
	sphinx-build -b html docs_src docs


clean:
	rm -rf $(BUILD_FILE)
	@echo "Release zip deleted - " $(BUILD_FILE)


build: 	docs

	mkdir -p $(BUILD_DIR)

	zip -r9T $(BUILD_FILE) $(FILES)

	@echo
	@echo $(NAME)" "$(VERSION) " is ready"
	$(FILE_BROWSER) $(BUILD_DIR) & 

Hope this you found this use­ful. Feel free to use this code for any­thing, tweak it or even change the ASCII art.

All the posts you can read
TutorialsAddon, Blender03.09.2018