<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matt Brennan</title>
    <description>The latest articles on DEV Community by Matt Brennan (@quarterto).</description>
    <link>https://dev.to/quarterto</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F50804%2F6d08699a-9f83-420a-b83b-a3c9b51bb814.jpeg</url>
      <title>DEV Community: Matt Brennan</title>
      <link>https://dev.to/quarterto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/quarterto"/>
    <language>en</language>
    <item>
      <title>Thinking in Make</title>
      <dc:creator>Matt Brennan</dc:creator>
      <pubDate>Sun, 23 Jul 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/quarterto/thinking-in-make-1826</link>
      <guid>https://dev.to/quarterto/thinking-in-make-1826</guid>
      <description>&lt;p&gt;Okay, but what &lt;em&gt;is&lt;/em&gt; a makefile. Actually what is it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make is for running tasks
&lt;/h2&gt;

&lt;p&gt;Here’s a simple makefile, as barebones as possible without it literally being an empty file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;do-a-thing&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; “did the thing”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save that as &lt;code&gt;makefile&lt;/code&gt;, and in the directory, run &lt;code&gt;make do-a-thing&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ make do-a-thing
echo “did the thing”
did the thing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tell Make what to run and it runs it. Each line like &lt;code&gt;do-a-thing:&lt;/code&gt; specifies a &lt;em&gt;target&lt;/em&gt;, and the indented lines (which need to be indented with actual tabs, sorry space-lovers) after the name are the shell commands to run for that target.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make is for generating files
&lt;/h2&gt;

&lt;p&gt;When the commands in a target create a file, you should let Make know about it. If the name of a target is the same as the name of the file it creates, Make can track that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;foo.txt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;echo &lt;/span&gt;lorem ipsum &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; foo.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ make foo.txt
echo lorem ipsum &amp;gt; foo.txt
⟩ make foo.txt
make: Nothing to be done for ‘foo.txt’
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait what? Nothing to be done? When the file exists, Make notices, and realises it doesn’t need to do anything. &lt;code&gt;foo.txt&lt;/code&gt; isn’t going to change if it runs the commands, so it doesn’t bother running them. Remove the file, and Make will create it again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;⟩ &lt;span class="nb"&gt;rm &lt;/span&gt;foo.txt
⟩ make foo.txt
&lt;span class="nb"&gt;echo &lt;/span&gt;lorem ipsum &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; foo.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Make is for generating files &lt;em&gt;from other files&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Say you’re generating a file and it depends on the content of another file. Maybe you’re just copying it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;foo.txt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;cp &lt;/span&gt;bar.txt foo.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;make&lt;/code&gt; doesn’t do anything when you update &lt;code&gt;bar.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ make foo.txt
cp bar.txt foo.txt
⟩ echo hello &amp;gt; bar.txt
⟩ make foo.txt
make: Nothing to be done for ‘foo.txt’
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the same as the last example: the file exists, so &lt;code&gt;make&lt;/code&gt; won’t create it again. If you want &lt;code&gt;foo.txt&lt;/code&gt; to update whenever &lt;code&gt;bar.txt&lt;/code&gt; does, you need to tell &lt;code&gt;make&lt;/code&gt; about it, by marking it as a &lt;em&gt;prerequisite&lt;/em&gt; of &lt;code&gt;foo.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;foo.txt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;bar.txt&lt;/span&gt;
    &lt;span class="nb"&gt;cp &lt;/span&gt;bar.txt foo.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything after the colon in a target’s name is a prerequisite of that target. It can be a file name, the name of another target, or even the name of another target that’s a file to generate. Prerequisites can also be chained: a target that’s a prerequisite can also have prerequisites, and so on.&lt;/p&gt;

&lt;p&gt;Running this example again does what you want: if you update &lt;code&gt;bar.txt&lt;/code&gt; and run &lt;code&gt;make foo.txt&lt;/code&gt; again, it’s updated. If &lt;code&gt;bar.txt&lt;/code&gt; hasn’t been updated, &lt;code&gt;make&lt;/code&gt; won’t do anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ make foo.txt
cp bar.txt foo.txt
⟩ echo hello &amp;gt; bar.txt
⟩ make foo.txt
cp bar.txt foo.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Make can work out filenames from patterns
&lt;/h2&gt;

&lt;p&gt;What if you’ve got a whole folder’s worth of targets and prerequisites? You don’t want to have to write a target for each one. I mean, that just sounds boring, and you’d have to remember to update it whenever you added or deleted a file.&lt;/p&gt;

&lt;p&gt;So if your file paths are predictable, e.g. if you want to express something like “here’s how to make any file in &lt;em&gt;this folder&lt;/em&gt; from the file with the same name in &lt;em&gt;that folder&lt;/em&gt;”, you use &lt;em&gt;file patterns&lt;/em&gt;. In the target and the prerequisite, write the bit that’s the hole to be filled in as &lt;code&gt;%&lt;/code&gt;, e.g. &lt;code&gt;target-files/%.txt: source-files/%.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then how do you refer to the actual filenames, if all we know is the pattern? &lt;code&gt;make&lt;/code&gt; defines a handful of &lt;em&gt;automatic variables&lt;/em&gt; to use with pattern rules, which it sets based on the pattern and the filename it’s matching. The two you need to know are &lt;code&gt;$@&lt;/code&gt;, which is the matched target filename, and &lt;code&gt;$&amp;lt;&lt;/code&gt;, which is the prerequisite filename it infers from the target pattern, the target filename and the prerequisite pattern, by working out what in the filename replaced &lt;code&gt;%&lt;/code&gt; in the pattern (the &lt;em&gt;stem&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Given our example above, when you run &lt;code&gt;make target-files/foo.txt&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt; matches it against &lt;code&gt;target-files/%.txt&lt;/code&gt; and runs that target. It sets &lt;code&gt;$@&lt;/code&gt; to &lt;code&gt;target-files/foo.txt&lt;/code&gt;, and because the stem is &lt;code&gt;foo&lt;/code&gt; (that’s what replaced &lt;code&gt;%&lt;/code&gt; in the pattern), it sets &lt;code&gt;$&amp;lt;&lt;/code&gt; to &lt;code&gt;source-files/foo.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;target-files/%.txt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;source-files/%.txt&lt;/span&gt;
    &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ make target-files/foo.txt
cp source-files/foo.txt target-files/foo.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Don’t tell Make what to do, let it find its own way
&lt;/h2&gt;

&lt;p&gt;Ok, what if you want to &lt;code&gt;make&lt;/code&gt; everything? All of the files? &lt;code&gt;make&lt;/code&gt; is actually a fully-fledged (if a little arcane, but hey, it’s 40 years old) programming language, with a handful of builtins useful for generating lists of files you want it to build.&lt;/p&gt;

&lt;p&gt;One of these is the &lt;code&gt;wildcard&lt;/code&gt; function. It takes a shell-like wildcard expression and expands it to a list of files that match. Let’s say your &lt;code&gt;source-files&lt;/code&gt; folder contains &lt;code&gt;foo.txt&lt;/code&gt;, &lt;code&gt;bar.txt&lt;/code&gt; and &lt;code&gt;baz.txt&lt;/code&gt;, then &lt;code&gt;$(wildcard source-files/*.txt)&lt;/code&gt; expands to &lt;code&gt;source-files/foo.txt source-files/bar.txt source-files/baz.txt&lt;/code&gt;. Why does this use &lt;code&gt;*&lt;/code&gt; when patterns use &lt;code&gt;%&lt;/code&gt;? Because reasons.&lt;/p&gt;

&lt;p&gt;Then there’s &lt;code&gt;patsubst&lt;/code&gt;. Give it two patterns and a list of files, and it matches and &lt;strong&gt;subst&lt;/strong&gt; itutes the &lt;strong&gt;pat&lt;/strong&gt; terns. So &lt;code&gt;$(patsubst source-files/%.txt, target-files/%.txt, source-files/foo.txt source-files/bar.txt)&lt;/code&gt; evaluates to &lt;code&gt;target-files/foo.txt target-files/bar.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I mentioned the automatic pattern variables above. You can define your own variables, and the syntax will look familiar: &lt;code&gt;source-files = $(wildcard source-files/*.txt)&lt;/code&gt;. Refer to variables using &lt;code&gt;$(variable-name)&lt;/code&gt;, e.g. &lt;code&gt;$(source-files)&lt;/code&gt;, and if the name is a single character you can drop the &lt;code&gt;()&lt;/code&gt;, like with &lt;code&gt;$&amp;lt;&lt;/code&gt; and &lt;code&gt;$@&lt;/code&gt; (which aren’t anything special; &lt;code&gt;make&lt;/code&gt; has &lt;em&gt;very&lt;/em&gt; lenient syntax for variables, and pretty much the only characters you &lt;em&gt;can’t&lt;/em&gt; use are &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;#&lt;/code&gt;, &lt;code&gt;:&lt;/code&gt; or whitespace).&lt;/p&gt;

&lt;p&gt;Variables can be used in prerequisites and commands. You’ll see them used in commands to pass long options to command-line programs. When used in prerequisites they can be used to make a bunch of files at once. A common use case is making every file in a folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;source-files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wildcard&lt;/span&gt; source-files/&lt;span class="k"&gt;*&lt;/span&gt;.txt&lt;span class="nf"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;target-files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;patsubst&lt;/span&gt; source-files/%.txt, target-files/%.txt, &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;source-files&lt;span class="nf"&gt;))&lt;/span&gt;

&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(target-files)&lt;/span&gt;

&lt;span class="nl"&gt;target-files/%.txt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;source-files/%.txt&lt;/span&gt;
    &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ make all
cp source-files/foo.txt target-files/foo.txt
cp source-files/bar.txt target-files/bar.txt
cp source-files/baz.txt target-files/baz.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking this down from the end, it’s the same target we saw before, which makes any &lt;code&gt;.txt&lt;/code&gt; file in &lt;code&gt;target-files/&lt;/code&gt;. The &lt;code&gt;all&lt;/code&gt; target has no commands, and the variable &lt;code&gt;$(target-files)&lt;/code&gt; as a prerequisite. When a target has no commands, it’s just there for the prerequisites. &lt;code&gt;make&lt;/code&gt; makes those in order to make &lt;code&gt;all&lt;/code&gt;, and then makes &lt;code&gt;all&lt;/code&gt; by doing nothing. Finally &lt;code&gt;$(target-files)&lt;/code&gt; is generated by using &lt;code&gt;wildcard&lt;/code&gt; to get a list of files in &lt;code&gt;source-files&lt;/code&gt; and &lt;code&gt;patsubst&lt;/code&gt; to turn that list into a list of files in &lt;code&gt;target-files&lt;/code&gt;. I’ll talk some more about this in a bit.&lt;/p&gt;

&lt;p&gt;Alright now check this out. I’ve gone over how &lt;code&gt;make&lt;/code&gt; only builds the things it needs to? This works &lt;em&gt;really well&lt;/em&gt; when building a bunch of files at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ make all
make: Nothing to be done for ‘all’
⟩ echo hello &amp;gt; source-files/baz.txt
⟩ make all
cp source-files/baz.txt target-files/baz.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update &lt;code&gt;baz.txt&lt;/code&gt;, leave the other two alone, and that’s the only one that &lt;code&gt;make&lt;/code&gt; decides to build. Internally, it’s looking at file modification times. When it discovers a target file depends on a prerequisite file, and both exist, it only makes the target if the prerequisite is newer.&lt;/p&gt;

&lt;p&gt;Oh, and if you run just &lt;code&gt;make&lt;/code&gt; on its own, it runs the first (non-pattern) target in the file. By convention, people call this &lt;code&gt;all&lt;/code&gt;. So you could run the last two examples with &lt;code&gt;make&lt;/code&gt; instead of &lt;code&gt;make all&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part where I actually talk about the title of the post
&lt;/h2&gt;

&lt;p&gt;What is the point of &lt;code&gt;make&lt;/code&gt;? By now, I hope you’ll see it’s more than a simple task runner. If you have a bunch of input files, and you want to transform them into a bunch of output files, the tool you should be reaching for is &lt;code&gt;make&lt;/code&gt;. If your input filenames look like your output filenames, see if you can write a pattern target.&lt;/p&gt;

&lt;p&gt;These are the steps I go through when writing a makefile:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a simple rule using concrete filenames&lt;/li&gt;
&lt;li&gt;Make the rule generic with patterns&lt;/li&gt;
&lt;li&gt;Work out how to generate a list of output files from your input filenames&lt;/li&gt;
&lt;li&gt;Make everything all at once&lt;/li&gt;
&lt;li&gt;Receive admiration from your friends and colleagues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’m still on step 4.&lt;/p&gt;

&lt;p&gt;I’ll go through a concrete example: building Javascript sources using Babel. To start with, it’s a single file, &lt;code&gt;src/index.js&lt;/code&gt; that I want to compile to &lt;code&gt;lib/index.js&lt;/code&gt;. To transform the file we run &lt;code&gt;babel src/index.js -o lib/index.js&lt;/code&gt;, so the whole rule would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;lib/index.js&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;src/index.js&lt;/span&gt;
    babel src/index.js &lt;span class="nt"&gt;-o&lt;/span&gt; lib/index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I’ve got more &lt;code&gt;.js&lt;/code&gt; files, I want to turn it into a pattern rule. The output and input files have a pretty clear pattern of &lt;code&gt;lib/%.js: src/%.js&lt;/code&gt;, so using that with automatic pattern variables, we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;lib/%.js&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;src/%.js&lt;/span&gt;
    babel &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To build all of the &lt;code&gt;.js&lt;/code&gt; files at once, we need a list of target files that our source files would generate. So get the list of source files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;source-files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wildcard&lt;/span&gt; src/&lt;span class="k"&gt;*&lt;/span&gt;js&lt;span class="nf"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And transform the output filenames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;output-files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;patsubst&lt;/span&gt; src/%.js, lib/%.js, &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;source-files&lt;span class="nf"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can use the list as a prerequisite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(output-files)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so our final makefile looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;source-files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wildcard&lt;/span&gt; src/&lt;span class="k"&gt;*&lt;/span&gt;js&lt;span class="nf"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;output-files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;patsubst&lt;/span&gt; src/%.js, lib/%.js, &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;source-files&lt;span class="nf"&gt;))&lt;/span&gt;

&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(output-files)&lt;/span&gt;

&lt;span class="nl"&gt;lib/%.js&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;src/%.js&lt;/span&gt;
    babel &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extra credit: automatically rebuilding files
&lt;/h2&gt;

&lt;p&gt;Because &lt;code&gt;make&lt;/code&gt; doesn’t do anything it doesn’t have to, a &lt;em&gt;really really&lt;/em&gt; basic way of remaking things as your change the input files is to run it in a Bash loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;make
    &lt;span class="nb"&gt;sleep &lt;/span&gt;1
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, if you’re not updating anything you’ll spam your terminal with &lt;code&gt;make: Nothing to be done for ‘all’&lt;/code&gt; forever. One alternative is a package called &lt;a href="https://github.com/quarterto/watch-make"&gt;&lt;code&gt;watch-make&lt;/code&gt;&lt;/a&gt; by (&lt;em&gt;coughs, looks bashful in a british-false-humility way&lt;/em&gt;) me. It wraps &lt;code&gt;make&lt;/code&gt;, gets the prerequisite files from it, and reruns &lt;code&gt;make&lt;/code&gt; when they change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⟩ wmake

  ⛭ running make
  │ babel src/index.js -o lib/index.js
  ✔︎ make
  ⚲ watching 2 files

  ✏︎ changed src/index.js
  ⛭ running make
  │ babel src/index.js -o lib/index.js
  ✔︎ make
  ⚲ watching 2 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Make can do a whole lot more
&lt;/h2&gt;

&lt;p&gt;I’ve just scratched the surface here, but this covers way more than most makefiles use in practice. If you’re burning to know more, the &lt;a href="https://www.gnu.org/software/make/manual/html_node/index.html"&gt;GNU Make documentation&lt;/a&gt; is exhaustive and very well written, but don’t blame me when you’re up to your elbows in static pattern rules and &lt;code&gt;SECONDEXPANSION&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before you know it you’ll be writing makefiles that make makefiles, and then no-one can save you.&lt;/p&gt;

&lt;p&gt;Iä iä make’file fhtagn.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about autotools/automake?
&lt;/h2&gt;

&lt;p&gt;No.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
