Go Ahead ‘make’ My Day (Part III)
This is the last in a 3 part series on . You can catch up by reading our introduction and dissection of Scriptlets.
- Part I — An introduction to scriptlets
- Part II — The anatomy of a scriptlet
In this final part, we talk about restraint — the discipline that keeps a clever trick from turning into a maintenance hazard.
That uneasy feeling…
So you are starting to write a few scriptlets and it seems pretty cool. But something doesn’t feel quite right…
You’re editing a Makefile and suddenly you feel anxious. Ah, you expected syntax highlighting, linting, proper indentation, and maybe that warm blanket of static analysis. So when we drop a 20 - line chunk of Perl or Python into our Makefile, our inner OCD alarms go off. No highlighting. No linting. Just raw text.
The discomfort isn’t a flaw — it’s feedback. It tells you when you’ve added too much salt to the soup.
A scriptlet is not a script!
A scriptlet is a small, focused snippet of code embedded inside a Makefile that performs one job quickly and deterministically. The "-let" suffix matters. It's not a standalone program. It's a helper function, a convenience, a single brushstroke that belongs in the same canvas as the build logic it supports.
If you ever feel the urge to bite your nails, pick at your skin, or start counting the spaces in your indentation — stop. You’ve crossed the line. What you’ve written is no longer a scriptlet; it’s a script. Give it a real file, a shebang, and a test harness. Keep the build clean.
Why we use them
Scriptlets shine where proximity and simplicity matter more than reuse (not that we can’t throw it in a separate file and include it in our Makefile).
- Cleanliness: prevents a recipe from looking like a shell script.
- Locality: live where they’re used. No path lookups, no installs.
- Determinism: transform well-defined input into output. Nothing more.
- Portability (of the idea): every CI/CD system that can run
makecan run a one-liner.
A Makefile that can generate its own dependency file, extract version numbers, or rewrite a cpanfile doesn't need a constellation of helper scripts. It just needs a few lines of inline glue.
Why they’re sometimes painful
We lose the comforts that make us feel like professional developers:
- No syntax highlighting.
- No linting or type hints.
- No indentation guides.
- No “Format on Save.”
The trick is to accept that pain as a necessary check on the limits of the scriptlet. If you’re constantly wishing for linting and editor help, it’s your subconscious telling you: this doesn’t belong inline anymore. You’ve outgrown the -let.
When to promote your scriptlet to a script…
Promote a scriptlet to a full-blown script when:
- It exceeds 30–50 lines.
- It gains conditionals or error handling.
- You need to test it independently.
- It uses more than 1 or 2 non-core features.
- It’s used by more than one target or project.
- You’re debugging quoting more than logic.
- You’re spending more time fixing indentation, than working on the build
At that point, you’re writing software, not glue. Give it a name, a shebang, and a home in your tools/ directory.
When to keep it inside your Makefile...
Keep it inline when:
- It’s short, pure, and single-use.
- It depends primarily on the environment already assumed by your build (Perl, Python, awk, etc.).
- It’s faster to read than to reference.
A good scriptlet reads like a make recipe: do this transformation right here, right now.
define create_cpanfile =
while (<STDIN>) {
s/[#].*//; s/^\s+|\s+$//g;
next if $_ eq q{};
my ($mod,$v) = split /\s+/, $_, 2;
print qq{requires "$mod", "$v";\n}; }
endef
export s_create_cpanfile = $(value create_cpanfile)That’s a perfect scriptlet: small, readable, deterministic, and local.
Rule of Thumb: If it fits on one screen, keep it inline. If it scrolls, promote it.
Tools for the OCD developer
If you must relieve the OCD symptoms without promotion of your scriptlet to a script …
- Add a
lint-scriptletstarget:perl -c -e '$(s_create_requires)'checks syntax without running it. - Some editors (Emacs
mmm-mode, Vimpolyglot) can treat marked sections as sub-languages to enable localized language specific editing features. - Use
includeto include a scriptlet into yourMakefile
…however try to resist the urge to over-optimize the tooling. Feeling the uneasiness grow helps identify the boundary between scriptlets and scripts.
You’ve been warned!
Because scriptlets are powerful, flexible, and fast, it’s easy to reach for them too often or make them the focus of your project. They start as a cure for friction — a way to express a small transformation inline — but left unchecked, they can sometimes grow arms and legs. Before long, your Makefile turns into a Frankenstein monster.
The great philosopher Basho (or at least I think it was him) once said:
A single aspirin tablet eases pain. A whole bottle sends you to the hospital.
Thanks for reading.
Learn More
Originally published at https://blog.tbcdevelopmentgroup.com.
