There are 3 kinds of variables in tup. There is $, %, and @. For nethack fans, you will notice this corresponds to money, food, and the Wizard of Yendor. I don't need to tell you which is the most dangerous.
The $ variables work kind of like they do in make, only they are severely more limited. This is somewhat on purpose, so you can't make silly and unreadable Tupfiles. Also, I'm lazy. They are valid within a Tupfile, and aren't magically set from the environment. You would use these if you don't want to retype some long string in a Tupfile (like a list of source files, or something). For example:
srcs = foo.c srcs += bar.c ok.c cc = gcc : foreach $(srcs) |> $(cc) -c %f -o %o |> %F.o
Don't try to do anything crazy like:
If you do any of those things you will be considered crazy and met with frowny faces.
The % variables are similar to the special $^, $<, or $whatevs variables in make. They only make sense in the command (the stuff between the two |> markers), and, except for %o, in the output list (the part after the second |>). Break it down:
Flag | What it be |
%f | The filename |
%F | The filename without the extension (the last '.' and everything after it are removed) |
%b | The basename (only includes everything after the last '/') |
%B | The basename without the extension (err...yeah) |
%o | Copies whatever is in the output field. This is just for convenience in the command string. |
Let's play pretend! Say I want to compile two C files from a src/ directory and then link them. Here's how the % things would work out:
$ ls Tupfile src/ $ cat Tupfile : foreach src/*.c |> gcc -c %f -o %o |> %B.o : *.o |> gcc %f -o %o |> hello_world $ ls src/ foo.c bar.c
The first rule (the foreach one) would be parsed twice. The first time the flags would be set like so:
%f | src/foo.c |
%F | src/foo |
%b | foo.c |
%B | foo |
Then it would be parsed again for bar.c:
%f | src/bar.c |
%F | src/bar |
%b | bar.c |
%B | bar |
Then we can parse the second rule. Since it is not a foreach rule, the % variables contain the entire input list:
%f | src/foo.c src/bar.c |
%F | src/bar src/bar |
%b | foo.c bar.c |
%B | foo bar |
After you run update you would get this:
$ ls Tupfile foo.o bar.o hello_world src/
The @ variables are super special - they actually appear in the DAG. You use them by doing something like @FOO@. By appearing in the DAG, if you change the variable, any Tupfiles that use them will be re-parsed. Also, you can use a special sed rule to convert an input file that has @FOO@ references and replaces them with their values in the output file. You would want to use these for any global configuration options in your program. One way you could use them is to enable or disable rules based on their value:
ifeq (@NCURSES@,y) : foreach blah blah blah endif
If @NCURSES@ is set to y, then those rules take effect. If we later change @NCURSES@ to n, then this Tupfile will be parsed again during the update, and those rules will be deleted.
Using them in a sed rule is pretty easy too. You could make a file like so:
$ cat Tupfile , foo.h.in |> foo.h $ cat foo.h.in #define SPEED @SPEED@
Assuming there is a variable called @SPEED@ and it's set to "fast", then when we update you would get:
$ cat foo.h #define SPEED "fast"
If we then change @SPEED@ to "super fast", foo.h would be re-generated with the new value. Of course, since this is tup, the file would be re-generated at ludicrous speed, no matter what the variable @SPEED@ is set to.