make
Anyone that has seen any of my projects on
GitHub knows that I love me some
Makefile
. I’ve been using make
since the days I started
programming and I doubt I’m going to give it up any time soon.
I know the kids today are haters, but make
, in all its wonky glory is a
true wonder and the
Leatherman
of GNU tools. I continually find new tricks that extend my love and
adoration for this ubiquitous tool.
My latest find is what I’ll term scriptlets. Many times
I’ll find myself creating a Makefile
that requires some
non-trivial manipulation or transformation of data. In those cases
I’ll usually try a Perl one-liner and pipe some data through a Perl
command.
Let’s suppose file foo.txt
depends on bar.txt
and we need to replace all
instances of xyz
with abc
(yes, sed
my be a better choice, but
let’s go with this for now…). Your make
recipe might look like this:
foo.txt: bar.txt
perl -npe 's/xyz/abc/g;' $< > $@
But what happens when things get a little more complicated and the
Perl one-liner is insufficient for the task? Well, maybe it’s time to
write a little Perl script. Of course, if I do that, I’ll then need to include
that script in my project, make it executable and reference it from my
Makefile
. Hmmm…is there a better way than cluttering the project
with scripts? Enter scriptlets…
Here’s a short example that removes all members of a hash where the
keys do not represent a file with an extension of .pm
.
define create_json =
use JSON::PP;
my $file_list = JSON::PP->new->decode(<>);
my @pm_files = grep { /[.]pm$/ } keys %{$file_list};
my %new_file_list = map { $_ => $file_list->{$_} } @pm_files;
print JSON::PP->new->pretty->encode(\%new_file_list);
endef
export s_create_json = $(value create_json)
foo.json: bar.json
perl -0 -e "$$s_create_json" $< > $@
…and then:
make
You can read more about the GNU make
features used above by
following these links.
Hope you find make
as useful as I do…drop me a line if you have a
favorite make
trick or tip.
Thanks for reading.