wiki:make:basics
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| wiki:make:basics [2014/08/17 15:35] – Add first make example jensv | wiki:make:basics [2022/07/21 06:59] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ===Basics=== | ||
| + | To illustrate how Make works, here's the an example from our shell lecture: | ||
| + | To analyse some molecule data we wrote two scripts: '' | ||
| + | '' | ||
| + | We have a little analysis pipeline here. We want to write a makefile we can run each time we collect new molecule data. | ||
| + | |||
| + | Let's start by creating a makefile: | ||
| + | |||
| + | #This is a makefile for analyzing molecule data | ||
| + | result.dat: sorted_lengths.txt | ||
| + | ./middle.sh sorted_lengths.txt -5 -3 | ||
| + | | ||
| + | sorted_lengths.txt: | ||
| + | ./ | ||
| + | |||
| + | A configuration file for Make like this one is called a '' | ||
| + | |||
| + | |||
| + | The filename on the left of the colon in the first line is the **target** of the rule. The rule tells Make how to update or re-create this file. The target' | ||
| + | |||
| + | The second line of the rule is its **action**. This tells Make what shell command or commands to run to bring the target up to date if it is older than any of its prerequisites. This rule only has one command, but a rule can contain any number. Make will run these commands in a sub shell. The sub shell should run the default bash shell. | ||
| + | |||
| + | One thing to note is that the actions in rules must be indented with a single **tab** character. Make will not accept spaces, or mixes of spaces and tabs. (As we said in the introduction, | ||
| + | |||
| + | |||
| + | Now that we've created our Makefile, we can tell Make to obey its instructions by running make from the command line. First we run a test: | ||
| + | |||
| + | $ make -n | ||
| + | |||
| + | ./ | ||
| + | ./middle.sh sorted_lengths.txt -5 -3 | ||
| + | |||
| + | When we type the command '' | ||
| + | |||
| + | Let's run make without the '' | ||
| + | |||
| + | $ make | ||
| + | |||
| + | ./ | ||
| + | ./middle.sh sorted_lengths.txt -5 -3 | ||
| + | |||
| + | Make's output shows us that it has run the command we wanted it to. It did this because at least one prerequisite for '' | ||
| + | |||
| + | Let's run Make again: | ||
| + | |||
| + | $ make | ||
| + | |||
| + | make: ' | ||
| + | |||
| + | This time, it doesn' | ||
| + | |||
| + | That's change the timestamp on the '' | ||
| + | |||
| + | $ touch sorted_lengths.txt | ||
| + | $ make | ||
| + | |||
| + | /.middle.sh sorted_lengths.txt -5 -3 | ||
| + | |||
| + | Make only executed the first rule since it is only rule that has a dependency which has a newer timestamp then the target. | ||
| + | |||
| + | One thing to note is that the order in which make executes rules that are not constrained by dependencies is arbitrary. | ||
| + | |||
| + | Something else this example shows us is that a single thing can be a target in one rule, and a prerequisite in others. The dependencies between the files mentioned in the Makefile make up a directed graph. In order for Make to run, this graph must not contain any cycles. For example, if X depends on Y, Y depends on Z, and Z depends on X, everything depends on something else, so there is nothing Make can build first. If it detects a cycle in a Makefile, Make will print an error message and stop. Unfortunately, | ||