I recently decided it was time to get a better understanding of how makefiles work, and after reading a few tutorials, I ended up just reading the manual. It’s long, but it’s very, very well written, to the point where just starting at the top and reading gives an almost tutorial-like effect. Just read the manual!

I realized you can use it for all sorts of things. Not just for compiling or making things. But as a shell-script replacement, I guess. Right now I’m building my website using Hugo dropping Wordpress into static CMS but that is a different story. In Hugo, you have to build or render your static files every time you have changed or creating posts.

Here comes exciting part building and deploying your site. With Makefiles you can just clean, build and deploy in a single make command.

The writing of rules/recipes mostly comes down to shell commands, which is the main reason Makefile are as portable as they are. The best part is that you can do pretty much anything in a terminal, and certainly handle all the workflow steps.

HUGOCMD=$(which) hugo
PUBLIC_FOLDER=public
SITEMAP_URL=https://example.com/sitemap.xml
PRODUCTION_SERVER=example.com
PRODUCTION_WEBROOT=/var/www/example_webroot

all: serve
check:
	$(HUGOCMD) --i18n-warnings
serve:
	$(HUGOCMD) serve
build:
	@echo "🍳 Generating site"
	$(HUGOCMD) --gc --minify
clean:
	@echo "🧹 Cleaning old build"
	find . -name "*~" -exec rm {} -v \;
	find . -name "*#" -exec rm {} -v \;
	$(HUGOCMD) --gc
	rm -fr public
deploy:
	ssh -C $(PRODUCTION_SERVER) "cd $(PRODUCTION_WEBROOT) && git pull && make clean && make build"
	curl --silent "http://www.google.com/ping?sitemap=$(SITEMAP_URL)"
	curl --silent "http://www.bing.com/webmaster/ping.aspx?siteMap=$(SITEMAP_URL)"
	@echo "🚀 Site is deployed!"
update-themes:
	git submodule update --remote --merge

The make should call serve:

$ make
hugo serve

                   | EN
-------------------+-----
  Pages            | 14
  Paginator pages  |  0
  Non-page files   |  0
  Static files     | 13
  Processed images |  0
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0

Built in 148 ms
Watching for changes in /Sites/shiftnull/{archetypes,assets,content,layouts,static,themes}
Watching for config changes in /Sites/shiftnull/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

It is a good practice not to call clean in all or put it as the first target. clean should be called manually when cleaning is needed as a first argument to make:

$ make clean
🧹 Cleaning old build
find . -name "*~" -exec rm {} -v \;
find . -name "*#" -exec rm {} -v \;
hugo --gc

                   | EN
-------------------+-----
  Pages            | 14
  Paginator pages  |  0
  Non-page files   |  0
  Static files     | 13
  Processed images |  0
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0

Total in 125 ms
rm -vfr public
public/index.html
public/posts/index.html
public/posts/index.xml
....

Using this Makefile is pretty straightforward and I’ll continue to refine this Makefile as I learn more, and readers are encouraged to hit me on Twitter with suggestions for improvement. I hope this information proves useful to others using static site generators.