Any good tutorials or resources for learning that show a broader applicability for makefiles?
Any good tutorials or resources for learning that show a broader applicability for makefiles?
A good detailed example; Using GNU Make to Manage the Workflow of Data Analysis Projects (pdf) here : https://www.jstatsoft.org/article/download/v094c01/1368
More generally, also take a look at how to use Unix Tools effectively, see; Unix : Concepts and Applications by Sumitabha Das and The Unix Programming Environment by Kernighan & Pike.
Here's a simple example to get you started. Create a file named "Makefile" with the following text and an empty file alongside it named foo.txt.
bar.txt: foo.txt
cp foo.txt bar.txt
When you run the "make" command in your shell it will check if the "bar.txt" file exists. If it does not exist OR if "foo.txt" has a newer timestamp, then it will rebuild "bar.txt" by executing the tab indented shell commands underneath. In this case, the only shell command used is the 'cp' command. In the linked article the author invokes npm, bundler, and netlify.When people use Make to compile their C code they are simply invoking the C compiler just like they would any other shell command. You might have seen something in a Makefile that looks like this:
foobar.o: foobar.c
gcc -c foobar.c
This is just saying: "The output file 'foobar.o' depends on the input file 'foobar.c' and to build 'foobar.o' run the shell command 'gcc -c foobar.c'" which is conceptually the same as my previous example were we built "bar.txt". Since explicitly listing every .o and .c file in a Makefile is tedious, many authors opt for wildcards.I hope this helped!
I got to this point and ran into an error: Makefile:2: *** missing separator. Stop.
Ok I'm just giving you a hard time, and you mention right after the existence of "tab indented" so whatever. Still it's one of the things I detest on an aesthetic level about make, even if my editor has special syntax support for makefiles to handle this archaic requirement of actual tabs without me ever having to worry about it in practice.
There's a little-known variable called .RECIPEPREFIX that lets you switch from tabs to anything else. Probably a bad idea to use it in anything shared with anyone else.
[1] https://pubs.opengroup.org/onlinepubs/9799919799/utilities/m...
Nah, who am I kidding ... no one loves yaml, it's just better than most of the alternatives.
the philosophical "c" centredness is true, but doesn't get in the way of using other languages. (there's things like indirect rules for compiling .c files auromatically for instance, but even this can be turned off)
Well that's kind of wrong (it's used for that but that's an extremely limited viewpoint). Here's a short introduction to get started:
foo: bar
baz
This means "whenever bar has been updated, create or recreate foo by running baz". You run it with "make foo", and make will run "baz" by default in "sh".Here's an example in a totally different context:
.PHONY: build
build: node_modules
node_modules: package.json yarn.lock
yarn install
touch node_modules
With this, when you run "make build", it'll only do "yarn install" if node_modules's last-modified timestamp is older than both package.json and yarn.lock. The touch is there to mark it updated for the next time you run "make build", so it knows it doesn't have to do anything. Normally you wouldn't have to do that but make assumes the commands given will update the file, and "yarn install" won't necessarily update the directory's last-modified time.This example isn't terribly useful because "yarn install" is fast and doesn't do anything itself when it's up-to-date, but it should give ideas about how flexible make actually is.
One of the big criticisms of how people use "make", and why people recommend things like "just" instead, is they don't bother to use that functionality (or any of the piles of stuff built on top of it like pattern matching) and would have just done:
build:
yarn install
...which appears to be how OP uses it.