Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
tup(1)				  tup manual				tup(1)

NAME
       tup - the updater

SYNOPSIS
	      tup [--debug-sql]	[--debug-fuse] [SECONDARY_COMMAND] [ARGS]

DESCRIPTION
       Tup is a	file-based build system. You should use	tup if you are
       developing software which needs to be translated	from input files
       (written	by you)	into a different output	format.	For example, if	you
       are writing a C program,	you could use tup to determine which files
       need to be recompiled, archived,	and linked based on a dependency
       graph.

       Tup has no domain specific knowledge. You must tell tup how to build
       your program, such as by	saying that all	.c files are converted to .o
       files by	using gcc. This	is done	by writing one or more Tupfiles.

PRIMARY	COMMAND: tup
       You can do all of your development with just 'tup', along with writing
       Tupfiles. See also the INI FILE,	OPTIONS	FILES and TUPFILES sections
       below.

       tup [<output_1> ... <output_n>]
	      Updates the set of outputs based on the dependency graph and the
	      current  state  of  the  filesystem. If no outputs are specified
	      then the whole project is	updated. This is what  you  run	 every
	      time  you	 make changes to your software to bring	it up-to-date.
	      You can run this anywhere	in the	tup  hierarchy,	 and  it  will
	      always  update  the  requested  output.  By default, the list of
	      files that are changed are determined by scanning	the filesystem
	      and checking modification	times. For very	 large	projects  this
	      may  be  slow, but you can skip the scanning time	by running the
	      file monitor (see	SECONDARY COMMANDS for a  description  of  the
	      monitor).

	      -jN    Temporarily  override the updater.num_jobs	option to 'N'.
		     This will run up to N jobs	in parallel,  subject  to  the
		     constraints  of the DAG. Eg: 'tup -j2' will run up	to two
		     jobs  in  parallel,  whereas  'tup'  will	 run   up   to
		     updater.num_jobs  in  parallel.  See the option secondary
		     command below.

	      --verbose
		     Causes tup	to display the full command string instead  of
		     just  the pretty-printed string for commands that use the
		     ^ TEXT^ prefix.

	      --quiet
		     Temporarily override the display.quiet option to '1'. See
		     the option	secondary command below.

	      -k
	      --keep-going
		     Temporarily override  the	updater.keep_going  option  to
		     '1'. See the option secondary command below.

	      --no-keep-going
		     Temporarily  override  the	 updater.keep_going  option to
		     '0'. See the option secondary command below.

	      --no-scan
		     Do	not scan the project for changed files.	 This  is  for
		     internal  tup testing only, and should not	be used	during
		     normal development.

	      --no-environ-check
		     Do	not check for updates  to  the	environment  variables
		     exported	to  sub-processes.  Instead,  the  environment
		     variables will be used from the database. This is used by
		     the monitor in autoupdate/autoparse mode so that the most
		     recent environment	variables are used,  rather  than  the
		     settings when the monitor was initialized.

	      -d     Output debug log to screen.

	      --debug-run
		     Output  the  :-rules  generated  by a run-script. See the
		     'run ./script args'  feature  in  the  TUPFILES  section.
		     --debug-logging  Save  some debug output and build	graphs
		     in	.tup/log. Graphs are rotated on	each  invocation  with
		     --debug-logging.

SECONDARY COMMANDS
       These  commands	are  used to modify the	behavior of tup	or look	at its
       internals. You probably won't need these	very often. Secondary commands
       are invoked as:

       tup	  [--debug-sql]	       [--debug-fuse]	     SECONDARY_COMMAND
       [SECONDARY_COMMAND_ARGS]

       init [directory]
	      Creates  a  '.tup'  directory  in	 the  specified	 directory and
	      initializes  the	tup  database.	If   a	 directory   name   is
	      unspecified,  it	defaults  to  creating	'.tup'	in the current
	      directory. This defines the top of your project,	as  viewed  by
	      tup.  Everything in the current directory	and its	subdirectories
	      are known	as the "tup hierarchy".

	      If you want to avoid having to run 'tup  init'  every  time  you
	      clone  your repository to	a new location,	you can	instead	create
	      an empty file called 'Tupfile.ini' in the	project	root. If 'tup'
	      is  run  without	the  '.tup'   directory	  present,   it	  will
	      automatically create one for you as a sibling of the Tupfile.ini
	      file,  as	if you had run 'tup init' in that directory.. If there
	      are multiple Tupfile.ini files in	parent paths, the one  highest
	      up the tree will be chosen.

	      --no-sync
		     Sets  the	'db.sync'  option  of  the  project to '0'. By
		     default the 'db.sync' option will be  set	to  '1'.  This
		     flag  is  mostly  used for	test cases, but	you could also
		     use this in any environment where you want	to script  tup
		     and use no	synchronization	by default.

       refactor
       ref    The refactor command can be used to help refactor	Tupfiles. This
	      will cause tup to	run through the	parsing	phase, but not execute
	      any  commands. If	any Tupfiles that are parsed result in changes
	      to the database, these are reported as errors. For  example,  we
	      may have the following simple Tupfile:

	      :	foreach	*.c |> gcc -c %f -o %o -Wall |>	%B.o

	      After an initial 'tup', we decide	that we	want to	move the -Wall
	      to a variable called CFLAGS. The Tupfile now looks like:

	      CFLAGS = -Wall
	      :	foreach	*.c |> gcc -c %f -o %o $(CFLAGS) |> %B.o

	      Running  'tup refactor' will cause tup to	parse the Tupfile, and
	      if we made any mistakes, an error	message	will be	displayed. The
	      Tupfiles can then	be modified to	fix  those  errors,  and  keep
	      running	'tup   refactor'   until   all	 Tupfiles  are	parsed
	      successfully.

	      Errors are reported for adding or	removing any of	the following:
	      commands,	 inputs	 that  are  generated  files,	outputs,   the
	      .gitignore  directive,  input  or	output <groups>, and directory
	      level dependencies. Otherwise, you are able to move any  strings
	      out  to $-variables, !-macros, and the like, so long as the end-
	      result of	the set	of :-rules is the same.

       monitor
	      *LINUX ONLY* Starts the inotify-based file monitor. The  monitor
	      must  scan  the  filesystem  once	and initialize watches on each
	      directory. Then when you make changes to the files, the  monitor
	      will  see	 them  and write them directly into the	database. With
	      the monitor running, 'tup' does not need to do the initial scan,
	      and can start constructing  the  build  graph  immediately.  The
	      "Scanning	 filesystem..."	time from 'tup'	is approximately equal
	      to the time you would save by  running  the  monitor.  When  the
	      monitor  is  running,  a	'tup' with no file changes should only
	      take a few milliseconds (on my machines I	get  about  2  or  3ms
	      when  everything	is  in	the  disk  cache). If you restart your
	      computer,	you will need to restart the  monitor.	The  following
	      arguments	 can  be  given	 on  the  command line.	Any additional
	      arguments	not handled by the monitor will	be passed along	to the
	      updater if either	monitor.autoupdate  or	monitor.autoparse  are
	      enabled.	For example, you could run the monitor as 'tup monitor
	      -f  -a  -j2'  to	run  the  monitor  in  the   foreground,   and
	      automatically  update with 2 jobs	when changes are detected. See
	      also the option secondary	command	below.

	      -d     Enable debugging of the monitor process.

	      -f
	      --foreground
		     Temporarily override the monitor.foreground option	to  1.
		     The monitor will run in the foreground (don't daemonize).

	      -b
	      --background
		     Temporarily  override the monitor.foreground option to 0.
		     The monitor will run in the background (daemonize).

	      -a
	      --autoupdate
		     Temporarily override the monitor.autoupdate option	to  1.
		     This  will	 automatically run an update when file changes
		     are detected.

	      -n
	      --no-autoupdate
		     Temporarily override the monitor.autoupdate option	to  0.
		     This  will	prevent	the monitor from automatically running
		     an	update when file changes are detected.

	      --autoparse
		     Temporarily override the monitor.autoparse	option	to  1.
		     This  will	automatically run the parser when file changes
		     are detected.

	      --no-autoparse
		     Temporarily override the monitor.autoparse	option	to  0.
		     This  will	prevent	the monitor from automatically running
		     the parser	when file changes are detected.

       stop   Kills the	monitor	if it is running. Basically it saves  you  the
	      trouble of looking up the	PID and	killing	it that	way.

       variant foo.config [bar.config] [...]
	      For each argument, this command creates a	variant	directory with
	      tup.config  symlinked to the specified config file. For example,
	      if a directory contained	several	 variant  configurations,  one
	      could easily create a variant for	each config file:

	      $	ls configs/
	      bar.config
	      foo.config
	      $	tup variant configs/*.config
	      tup: Added variant 'build-bar' using config file 'configs/bar.config'
	      tup: Added variant 'build-foo' using config file 'configs/foo.config'

	      This is equivalent to the	following:

	      $	mkdir build-bar
	      $	ln -s ../configs/bar.config build-bar/tup.config
	      $	mkdir build-foo
	      $	ln -s ../configs/foo.config build-foo/tup.config

	      For  projects  that  commonly use	several	variants, the files in
	      the configs/ directory could be checked in  to  source  control.
	      Each  developer  would  run  the	'tup variant' after 'tup init'
	      during the initial checkout of the software. Variants  can  also
	      be  created  manually by making a	build directory	and creating a
	      tup.config file in it (see the VARIANTS section).	 This  command
	      merely  helps  save  some	 steps,	so that	you don't have to make
	      each build directory and tup.config symlink manually.

       dbconfig
	      Displays the  current  tup  database  configuration.  These  are
	      internal values used by tup.

       options
	      Displays	all  of	the current tup	options, as well as where they
	      originated.

	      For details on all of the	available options and how to set them,
	      see the OPTIONS FILES section below.

       graph [--dirs] [--ghosts] [--env] [--combine] [--stickies] [<output_1>
       ... <output_n>]
	      Prints out a graphviz .dot format	graph of the tup  database  to
	      stdout.  By default it only displays the parts of	the graph that
	      have changes. If you  provide  additional	 arguments,  they  are
	      assumed  to  be  files  that  you	 want  to graph. This operates
	      directly on the tup database, so unless you are running the file
	      monitor you may want to run 'tup scan' first. This is  generally
	      used for debugging tup --	you may	or may not find	it helpful for
	      trying to	look at	the structure of your program.

	      --dirs Temporarily  override  the	graph.dirs option to '1'. This
		     will show the directory nodes and Tupfiles.

	      --ghosts
		     Temporarily override the graph.ghosts option to '1'. This
		     will show ghost nodes (files  that	 a  command  tried  to
		     access, but don't actually	exist).

	      --env  Temporarily override the graph.environment	option to '1'.
		     This will show the	environment variables, such as PATH.

       todo [<output_1>	... <output_n>]
	      Prints  out  the next steps in the tup process that will execute
	      when updating the	given outputs. If  no  outputs	are  specified
	      then  it	prints	the  steps needed to update the	whole project.
	      Similar to the 'upd' command, 'todo' will	automatically scan the
	      project for file changes if a file monitor is not	running.

	      --no-scan
		     Do	not scan the project for changed files.	 This  is  for
		     internal  tup testing only, and should not	be used	during
		     normal development.

	      --verbose
		     Causes tup	to display the full command string instead  of
		     just  the pretty-printed string for commands that use the
		     ^ TEXT^ prefix.

       generate	[--config config-file] script.sh (or script.bat	on Windows)
	      The generate command will	parse all Tupfiles and create a	 shell
	      script  that  can	 build	the  program  without running in a tup
	      environment. The expected	usage  is  in  continuous  integration
	      environments   that  aren't  compatible  with  tup's  dependency
	      checking (eg: if FUSE is not  supported).	 On  Windows,  if  the
	      script  filename has a ".bat" extension, then the	output will be
	      a	batch script instead of	a shell	script.	For example:

	      git clone	... myproj
	      cd myproj
	      tup generate build.sh
	      ./build.sh
	      #	Copy out build artifacts / logs	here
	      git clean	-f -x -d

	      The  shell  script  does	not  work  incrementally,  so  it   is
	      effectively  a  one-time use. You	will need to clean up the tree
	      before the next 'tup generate' and script	invocation. This  does
	      not  support  variants, however the top-level tup.config file is
	      used  to	define	the  configuration  variables.	Optionally,  a
	      separate	configuration  file can	be passed in with the --config
	      argument.

       varsed The varsed command is used as a subprogram  in  a	 Tupfile;  you
	      would  not  run  it  manually at the command-line. It is used to
	      read one file, and replace any variable references and write the
	      output to	a second file. Variable	references  are	 of  the  form
	      @VARIABLE@, and are replaced with	the corresponding value	of the
	      @-variable. For example, if foo.txt contains:

	      The architecture is set to @ARCH@

	      And you have a :-rule in a Tupfile like so:

	      :	foo.txt	|> tup varsed %f %o |> foo-out.txt

	      Then  on	an  update,  the  output file will be identical	to the
	      input file, except the  string  @ARCH@  will  be	replaced  with
	      whatever CONFIG_ARCH is set to in	tup.config. The	varsed command
	      automatically  adds  the	dependency  from  CONFIG_ARCH  to  the
	      particular command node that used	it (so if CONFIG_ARCH changes,
	      the output file will be updated with the new value).

       scan   You shouldn't ever need to run this, unless you want to make the
	      database reflect the filesystem before running 'tup graph'. Scan
	      is called	automatically by 'upd' if the monitor isn't running.

       upd    Legacy secondary command.	Calling	'tup  upd'  is	equivalent  to
	      simply calling 'tup'.

INI FILE
       The  tup	 command  can be run from anywhere in the source tree. It uses
       the information from all	Tupfiles (see the TUPFILES section) as well as
       it's own	dynamic	database, which	is maintained in  the  .tup  directory
       located	at  the	root of	the project. The .tup directory	can be created
       manually	 with  the  'tup  init'	 command,  or  you  can	 have  it  run
       automatically  by  adding  an empty Tupfile.ini file at the root	of the
       project's version control repository.

       The contents of the Tupfile.ini file are	ignored.

OPTIONS	FILES
       Tup allows for a	variety	of configuration files.	These files affect the
       behavior	of tup as a program, but not tup as a build system. That is to
       say, changing any of these options should not affect the	end result  of
       a  successful  build,  but may affect how tup gets there	(e.g. how many
       compile jobs to run in parallel).

       The options are read in the following precedence	order:

	 command-line overrides	(eg: -j	flag passed to 'tup')
	 .tup/options file
	 ~/.tupoptions file
	 /etc/tup/options file
	 tup's compiled	in defaults

       For Windows, the	options	files are read in as follows:

	 command-line overrides
	 .tup/options file
	 tup.ini in the	Application Data path (usually C:\ProgramData\tup\tup.ini)
	 tup's compiled	in defaults

       For an exact list of paths on your platform, type 'tup options'.

       All files use the same .ini-style syntax. A section header is  enclosed
       in square brackets, like	so:
       [updater]

       The  section header is followed by one or more variable definitions, of
       the form	'variable = value'.  Comments  start  with  a  semi-colon  and
       continue	 to  the  end of the line. The variable	definitions can	all be
       set to integers.	For boolean flags, "true"/"yes"	and  "false"/"no"  are
       synonyms	 for  1	 and  0,  respectively.	 For  example,	if  you	have a
       .tup/options file that contains:

       [updater]
	    num_jobs = 2
	    keep_going = true

       Then 'tup' will default to 2 jobs, and have the updater.keep_going flag
       set. The	options	listed below are of the	form 'section.variable', so to
       set 'db.sync' you would need a '[db]' section followed by 'sync	=  0',
       for example. The	defaults listed	here are the compiled-in defaults.

	      db.sync (default '1')
		     Set  to '1' if the	SQLite synchronous feature is enabled.
		     When enabled, the database	is  properly  synchronized  to
		     the  disk	in  a  way  that it is always consistent. When
		     disabled, it will run faster since	writes are left	in the
		     disk cache	for a time before being	written	out.  However,
		     if	 your  computer	 crashes  before everything is written
		     out,  the	tup  database  may   become   corrupted.   See
		     http://www.sqlite.org/pragma.html for more	information.

	      updater.num_jobs (defaults to the	number of processors on	the
	      system )
		     Set  to  the  maximum  number  of	commands  tup will run
		     simultaneously. The default is dynamically	determined  to
		     be	  the	number	 of   processors  on  the  system.  If
		     updater.num_jobs is greater than 1, commands will be  run
		     in	parallel only if they are independent. See also	the -j
		     option.

	      updater.keep_going (default '0')
		     Set  to  '1' to keep building as much as possible even if
		     errors are	encountered. Anything dependent	 on  a	failed
		     command  will  not	 be  executed,	but  other independent
		     commands will be. The default is '0',  which  will	 cause
		     tup  to stop after	the first failed command. See also the
		     -k	option.

	      updater.full_deps	(defaults to '0')
		     Set to '1'	to track dependencies on files outside of  the
		     tup  hierarchy.  The  default  is	'0', which only	tracks
		     dependencies within the tup hierarchy.  For  example,  if
		     you  want	all  C	files  to  be  re-compiled when	gcc is
		     updated on	your system, you should	set this  to  '1'.  In
		     Linux  and	OSX, using full	dependencies requires that the
		     tup binary	is suid	as  root  so  that  it	can  run  sub-
		     processes	in  a  chroot  environment.  Alternatively  on
		     Linux, if your kernel supports user namespaces, then  you
		     don't  need  to  make  the	binary suid. Note that if this
		     value is set to '1' from '0', tup will rebuild the	entire
		     project. Disabling	this option  when  it  was  previously
		     enabled  does  not	 require a full	rebuild, but does take
		     some time since the nodes representing external files are
		     cleared out. NOTE:	This  does  not	 currently  work  with
		     ccache or other programs that may write to	external files
		     due  to  issues  with  locking.  This may be fixed	in the
		     future.

	      updater.warnings (defaults to '1')
		     Set to '0'	to disable warnings about  writing  to	hidden
		     files. Tup	doesn't	track files that are hidden. If	a sub-
		     process writes to a hidden	file, then by default tup will
		     display   a  warning  that	 this  file  was  created.  By
		     disabling this option, those warnings are not  displayed.
		     Hidden  filenames	(or directories) include: ., .., .tup,
		     .git, .hg,	.bzr, .svn.

	      display.color (default 'auto')
		     Set to 'never' to disable ANSI escape codes  for  colored
		     output,  or  'always' to always use ANSI escape codes for
		     colored output. The default  is  'auto',  which  displays
		     uses  colored output if stdout is connected to a tty, and
		     uses no colors otherwise (ie: if stdout is	redirected  to
		     a file).

	      display.width (defaults to the terminal width)
		     Set to any	number 10 or larger to force a fixed width for
		     the  progress bar.	This is	assumed	to be the total	width,
		     some of which is used  for	 spacing,  brackets,  and  the
		     percentage	 complete.  If this value is less than 10, the
		     progress bar is disabled.

	      display.progress (defaults to '1'	if stdout is a TTY)
		     Set to '1'	to enable the progress bar, or '0' to turn  it
		     off.  By  default	it  is enabled if stdout is a TTY, and
		     disabled if stdout	is not a TTY.

	      display.job_numbers (default '1')
		     Set to '0'	to avoid displaying the	"N)  "	string	before
		     the  results  of  a  job.	The default is to display this
		     number.

	      display.job_time (default	'1')
		     Set to '0'	to avoid displaying the	runtime	of a job along
		     with the results. The default is to display the  runtime.
		     Note  that	 the  runtime displayed	includes the time that
		     tup takes	to  save  the  dependencies.  Therefore,  this
		     runtime  will  likely  be	larger	than  the runtime when
		     executing the same	job manually in	the shell.

	      display.quiet (default '0')
		     Set to '1'	to prevent tup from  displaying	 most  output.
		     Tup  will	still display a	banner and output from any job
		     that writes to stdout/stderr, or any job that  returns  a
		     non-zero  exit code. The progress bar is still displayed;
		     see also display.progress for really quiet	output.

	      monitor.autoupdate (default '0')
		     Set to '1'	to automatically rebuild if a file  change  is
		     detected.	This  only  has	 an  effect  if	the monitor is
		     running. The default is '0', which	means you have to type
		     'tup' when	you are	ready to update.

	      monitor.autoparse	(default '0')
		     Set to '1'	to automatically run  the  parser  if  a  file
		     change	is    detected.	   This	   is	 similar    to
		     monitor.autoupdate, except	the  update  stops  after  the
		     parser  stage  -  no  commands are	run until you manually
		     type 'tup'. This only has an effect  if  the  monitor  is
		     running.  Note  that if both autoupdate and autoparse are
		     set, then autoupdate takes	precedence.

	      monitor.foreground (default '0')
		     Set to '1'	to run	the  monitor  in  the  foreground,  so
		     control will not return to	the terminal until the monitor
		     is	stopped	(either	by ctrl-C in the controlling terminal,
		     or	 running  'tup stop' in	another	terminal). The default
		     is	 '0',  which  means  the  monitor  will	 run  in   the
		     background.

	      graph.dirs (default '0')
		     Set  to  '1'  and	the  'tup graph' command will show the
		     directory nodes and their ownership links.	 Tupfiles  are
		     also  displayed,  since they point	to directory nodes. By
		     default directories and Tupfiles are not shown since they
		     can clutter the graph in some cases, and are  not	always
		     useful.

	      graph.ghosts (default '0')
		     Set  to '1' to show ghost nodes. Some commands may	try to
		     read from many files  that	 don't	exist,	causing	 ghost
		     nodes  to be created. By default, ghosts are not shown to
		     make the graph easier to understand.

	      graph.environment	(default '0')
		     Set to '1'	to show	the environment	nodes (such  as	 PATH)
		     and   their  dependencies.	 By  default  the  environment
		     variables are not	shown  since  nearly  everything  will
		     depend on PATH.

	      graph.combine (default '0')
		     Set  to '1' to try	to combine similar nodes in the	graph.
		     For example, instead of showing 10	 separate  compilation
		     commands  that all	have one .c file input and one .o file
		     output, this will combine them into one command  to  more
		     easily  see  the whole structure of the graph. By default
		     all nodes are shown separately.

TUPFILES
       You must	create a file called "Tupfile" anywhere	in the	tup  hierarchy
       that  you  want	to create an output file based on the input files. The
       input files can be anywhere else	in the tup hierarchy, but  the	output
       file(s) must be written in the same directory as	the Tupfile.

       : [foreach] [inputs] [ |	order-only inputs] |> command |> [outputs] [ |
       extra outputs] [<group>]	[{bin}]
	      The  :-rules are the primary means of creating commands, and are
	      denoted by the fact that the ':' character appears in the	 first
	      column  of  the Tupfile. The syntax is supposed to look somewhat
	      like a pipeline, in that the input files on the left go into the
	      command in the middle, and the output  files  come  out  on  the
	      right.

	      foreach
		     This  is  either  the  actual  string "foreach", or it is
		     empty. The	 distinction  is  in  how  many	 commands  are
		     generated	 when  there  are  multiple  input  files.  If
		     "foreach" is specified, one command is created  for  each
		     file  in  the inputs section. If it is not	specified, one
		     command is	created	containing all of  the	files  in  the
		     inputs  section.  For example, the	following Tupfiles are
		     equivalent:

		     # Tupfile 1
		     : foo.c |>	gcc -c foo.c -o	foo.o |> foo.o
		     : bar.c |>	gcc -c bar.c -o	bar.o |> bar.o

		     # Tupfile 2
		     : foreach foo.c bar.c |> gcc -c %f	-o %o |> %B.o

		     Additionally, using "foreach" allows the use of the  "%e"
		     flag (see below).

	      inputs The  input	 files	for  the command. An input file	can be
		     anywhere in the tup hierarchy, and	is specified  relative
		     to	 the current directory.	Input files affect the %-flags
		     (see below). Wildcarding is supported within a  directory
		     by	 using	the  SQLite  glob  function.  The special glob
		     characters	are '*', '?', and  '[]'.  For  example,	 "*.c"
		     would   match  any	 .c  file,  "fo?.c"  would  match  any
		     3-character .c file that has 'f' and 'o' as the first two
		     characters, and "fo[xyz].c" would match fox.c, foy.c, and
		     foz.c. Globbing does not match directories, so  "src/*.c"
		     will work,	but "*/*.c" will not.

	      order-only inputs
		     These  are	 also used as inputs for the command, but will
		     not appear	in any of the %-flags. They are	separated from
		     regular inputs by use of the '|'  character.  In  effect,
		     these  can	 be  used  to  specify	additional inputs to a
		     command  that  shouldn't  appear  on  the	command	 line.
		     Globbing  is  supported  as  in  the  inputs section. For
		     example, one use for them is  to  specify	auto-generated
		     header dependencies:

		     : |> echo "#define	FOO 3" > %o |> foo.h
		     : foreach foo.c bar.c | foo.h |> gcc -c %f	-o %o |> %B.o

		     This  will	 add  the foo.h	dependency to the gcc commands
		     for foo.c and bar.c, so tup will  know  to	 generate  the
		     header before trying to compile. The foreach command will
		     iterate  over the regular inputs (here, foo.c and bar.c),
		     not the order-only	inputs (foo.h).	If you forget  to  add
		     such  a  dependency,  tup	will  report an	error when the
		     command is	executed. Note that the	 foo.h	dependency  is
		     only listed here because it is created by another command
		     --	normal headers do not need to be specified.

	      command
		     The  command  string that will be passed to the system(3)
		     call by tup. This command is allowed  to  read  from  any
		     file  specified  as an input or order-only	input, as well
		     as	any other file in the tup hierarchy that  is  not  the
		     output  of	 another  command.  In	other words, a command
		     cannot read from another command's	output	unless	it  is
		     specified	as  an	input. This restriction	is what	allows
		     tup to be parallel	safe. Additionally, the	 command  must
		     write  to	all  of	 the  output  files  specified	by the
		     "outputs" section,	if any.

		     When executed, the	command's file accesses	are  monitored
		     by	 tup  to  ensure that they conform to these rules. Any
		     files opened for reading that were	generated from another
		     command but not  specified	 as  inputs  are  reported  as
		     errors.  Similarly, any files opened for writing that are
		     not specified as outputs  are  reported  as  errors.  All
		     files  opened for reading are recorded as dependencies to
		     the command. If any of these files	change,	tup  will  re-
		     execute  the command during the next update. Note that if
		     an	input listed in	 the  Tupfile  changes,	 it  does  not
		     necessarily  cause	 the command to	re-execute, unless the
		     command actually read from	that input  during  the	 prior
		     execution.	 Inputs	 listed	 in  the  Tupfile only enforce
		     ordering among the	commands, while	file  accesses	during
		     execution determine when commands are re-executed.

		     A	command	 string	 can  begin  with the special sequence
		     ^ TEXT^, which will tell tup to only print	"TEXT" instead
		     of	the whole command string when  the  command  is	 being
		     executed.	This saves the effort of using echo to pretty-
		     print a long command. The short-display behavior  can  be
		     overridden	 by  passing  the --verbose flag to tup, which
		     will cause	tup  to	 display  the  actual  command	string
		     instead  of  "TEXT".  The	space  after  the first	'^' is
		     significant. Any characters immediately after  the	 first
		     '^'  are  treated as flags. See the ^-flags section below
		     for details. For example, this  command  will  print  "CC
		     foo.c" when executing system(gcc -c foo.c -o foo.o) :

		     : foo.c |>	^ CC %f^ gcc -c	%f -o %o |> foo.o

		     A	 command  string  can  also  begin  with  the  special
		     character '!', in which case the !-macro  specified  will
		     be	substituted in for the actual command. See the !-macro
		     definition	 later.	 Commands  can also be blank, which is
		     useful to put all the input files in a {bin} for a	 later
		     rule.

	      outputs
		     The  outputs  section  specifies  the  files that will be
		     written to	by the command.	Only one command can write  to
		     a specific	file, but a single command can output multiple
		     files  (such as how a bison command will output both a .c
		     and .h file). The output can use any %-flags  except  %o.
		     Once  a file is specified in an output section, it	is put
		     into the tup database. Any	following rules	can  use  that
		     file  as  an  input,  even	 if  it	 doesn't  exist	in the
		     filesystem	yet.

	      extra-outputs
		     The extra-outputs section is similar  to  the  order-only
		     inputs  section. It is separated from the regular outputs
		     by	the '|'	character. The extra-outputs behave exactly as
		     regular outputs, except they do  not  appear  in  the  %o
		     flag.  These  can	be  used  if a command generates files
		     whose names do not	actually appear	in the	command	 line.
		     If	there is exactly one output specified by the rule, the
		     extra-outputs  section  can  use the %O flag to represent
		     the basename of the output. This can be useful in	extra-
		     outputs for !-macros.

	      <group>
		     Output  files  can	 be  grouped  into  global  groups  by
		     specifying	a <group> after	the outputs but	before a  bin.
		     Groups allow for order-only dependencies between folders.
		     Note that groups are directory specific, however, so when
		     referring	to  a group you	must specify the path to where
		     it	is assigned. For example, if a main project depends on
		     the output	from several submodules	you can	structure  Tup
		     like  so to make sure the submodules are built before the
		     main project:

		     #./submodules/sm1/Tupfile
		     : foo.c |>	gcc -c %f -o %o	|> %B.o	../<submodgroup>

		     #./submodules/sm2/Tupfile
		     : bar.c |>	gcc -c %f -o %o	|> %B.o	../<submodgroup>

		     #./project/Tupfile
		     : baz.c | ../submodules/<submodgroup> |> gcc -c %f	-o %o |> %B.o

		     Notice how	groups are directory specific and the path  is
		     specified	 outside   of	the   <>.  By  specifying  the
		     <submodgroup> as an order-only input Tup will  build  the
		     submodules	before attempting to build the entire project.

	      {bin}  Outputs  can  be  grouped	into  a	 bin using the "{bin}"
		     syntax. A later rule can use "{bin}" as an	input  to  use
		     all  of  the  files in that bin. For example, the foreach
		     rule will put each	.o file	in the objs bin, which is used
		     as	an input in the	linker rule:

		     : foreach *.c |> gcc -c %f	-o %o |> %B.o {objs}
		     : {objs} |> gcc %f	-o %o |> program

		     In	this case one could use	*.o as the input instead,  but
		     sometimes	it  is	useful to separate outputs into	groups
		     even though they have the same extension (such as if  one
		     directory	creates	 multiple binaries, using *.o wouldn't
		     be	correct). If  a	 {bin}	is  specified  in  the	output
		     section  of  multiple rules, the bin will be the union of
		     all the outputs. You can't	remove things from a bin,  and
		     the bin disappears	after the current Tupfile is parsed.

       ^-flags
	      In  a  command  string  that  uses  the  ^ TEXT^	sequence, flag
	      characters can be	placed immediately after the ^ until the first
	      space character or closing caret.	For example:

	      :	foo.c |> ^c CC %f^ gcc --coverage %f -o	%o |> foo | foo.gcno
	      :	bar.c |> ^c^ gcc --coverage %f -o %o |>	bar | bar.gcno

	      In the foo.c case, the command requires namespaces (or suid) and
	      will display "CC foo.c". In the bar.c case, the command requires
	      namespaces (or suid) and	the  "gcc  --coverage  bar.c  -o  bar"
	      string is	displayed. These are the supported flag	characters:

	      b	     The   'b'	 flag	causes	the  command  to  be  run  via
		     "/usr/bin/env bash	-e -o pipefail -c  <command>"  instead
		     of	 the default "/bin/sh -e -c <command>".	In addition to
		     allowing bash extensions in  the  :-rule,	"-o  pipefail"
		     dictates  that  "the  return  value  of a pipeline	is the
		     value of the last (rightmost) command to exit with	a non-
		     zero status, or zero if all commands in the pipeline exit
		     successfully."

	      c	     The 'c' flag causes the command to	fail if	tup  does  not
		     support  user  namespaces (on Linux) or is	not suid root.
		     In	these cases, tup runs in a  degraded  mode  where  the
		     fake   working   directories  are	visible	 in  the  sub-
		     processes,	and some dependencies may be missed. If	 these
		     degraded  behaviors  will break your a particular command
		     in	your build, add	the 'c'	flag so	that users  know  they
		     need  to  add  the	suid bit or upgrade their kernel. This
		     flag is ignored on	Windows.

	      o	     The 'o' flag  causes  the	command	 to  compare  the  new
		     outputs  against  the  outputs from the previous run. Any
		     outputs that  are	the  same  will	 not  cause  dependent
		     commands  in  the DAG to be executed. For example,	adding
		     this flag to a compilation	command	will skip the  linking
		     step if the object	file is	the same from the last time it
		     ran. The 'o' flag is incompatible with the	't' flag.

	      t	     The   't'	 flag  causes  the  command's  outputs	to  be
		     transient.	The outputs may	be used	 as  inputs  to	 other
		     commands,	but after all dependent	commands are executed,
		     the  transient  outputs  will   be	  deleted   from   the
		     filesystem.  This	can be used to save space if there are
		     many  stages  of  processing  that	 each  produce	 large
		     outputs,  but only	the final output needs to be kept. The
		     't' flag is incompatible with the 'o' flag.

		     An	example	where the 't' flag can make sense in  a	 build
		     pipeline  is  if  there  are large	assets that go through
		     multiple stages of	processing. For	example, a large audio
		     or	video file that	has stages of effects applied, each as
		     a separate	step in	the Tupfile.

		     In	contrast, the 't'  flag	 does  *not*  make  sense  for
		     object  files  in	a  C  program, even though those could
		     theoretically be deleted after the	 final	executable  is
		     linked. If	the object files were marked transient in this
		     case,  a change to	any of the input C files would require
		     *all* object files	to be rebuilt in order to produce  the
		     executable,  instead  of  only  the  single file that was
		     changed.

       %-flags
	      Within a command string or output	string,	the following  %-flags
	      may  also	 be  used  to  substitute  values  from	 the inputs or
	      outputs.

	      %%     Expands to	a single "%" character in the command  string.
		     This  should  be used when	you want the percent character
		     to	be interpreted by the command itself  rather  than  by
		     tup's parser.

	      %f     The filename from the "inputs" section. This includes the
		     path  and	extension.  This  is most useful in a command,
		     since it  lists  each  input  file	 name  with  the  path
		     relative	to   the   current   directory.	 For  example,
		     "src/foo.c" would be copied exactly as "src/foo.c"

	      %b     Like %f, but is  just  the	 basename  of  the  file.  The
		     directory	part is	stripped off. For example, "src/foo.c"
		     would become "foo.c"

	      %B     Like %b, but strips the extension.	This is	most useful in
		     converting	an input file into an output file of the  same
		     name  but	with  a	 different extension, since the	output
		     file needs	to be in  the  same  directory.	 For  example,
		     "src/foo.c" would become "foo"

	      %e     The  file	extension  of  the current file	when used in a
		     foreach rule. This	can be used  for  variables  that  can
		     have  different  values  based on the suffix of the file.
		     For example, you could set	 certain  flags	 for  assembly
		     (.S) files	that are different from	.c files, and then use
		     a	construct  like	$(CFLAGS_%e) to	reference the CFLAGS_S
		     or	CFLAGS_c variable depending on what type  of  file  is
		     being  compiled.  For  example,  "src/foo.c" would	become
		     "c", while	"src/foo.S" would become "S"

	      %o     The name of the output file(s). It	is useful in a command
		     so	that the filename passed  to  a	 command  will	always
		     match  what  tup thinks the output	is. This only works in
		     the "command" section, not	in the "outputs" section.

	      %O     The name of the output file without the  extension.  This
		     only  works  in  the  extra-outputs  section  if there is
		     exactly one output	file specified.	A use-case for this is
		     if	you have a !-macro that	generates files	not  specified
		     on	the command line, but are based	off of the output that
		     is	 named.	For example, if	a linker creates a map file by
		     taking the	specified output "foo.so", removing the	 ".so"
		     and adding	".map",	then you may want a !-macro like so:

		     !ldmap = |> ld ...	-o %o |> | %O.map
		     : foo1.o foo2.o |>	!ldmap |> foo.so

	      %d     The  name	of  the	 lowest	 level	of  the	directory. For
		     example, in foo/bar/Tupfile, this	would  be  the	string
		     "bar".  One  case	where  this can	be useful is in	naming
		     libraries based on	the directory they  are	 in,  such  as
		     with the following	!-macro:

		     !ar = |> ar crs %o	%f |> lib%d.a

		     Using  this  macro	 in  foo/bar/Tupfile would then	create
		     foo/bar/libbar.a

	      %g     The string	that a glob operator matched. For example with
		     the files a_text.txt and b_text.txt, the rule:

		     : foreach *_text.txt |> foo %f |> %g_binary.bin

		     will output the filenames a_binary.bin and	 b_binary.bin.
		     Only  the	first glob expanded will be substituted	in for
		     %g. %g is only valid when there is	a single input file or
		     foreach is	used.

	      %<group>
		     All of the	files in "group". For example:

		     #./submodules/sm1/Tupfile
		     : foo.c |>	gcc -c %f -o %o	|> %B.o	../<submodgroup>

		     #./submodules/sm2/Tupfile
		     : bar.c |>	gcc -c %f -o %o	|> %B.o	../<submodgroup>

		     #./project/Tupfile
		     : ../submodules/<submodgroup> |> echo '%f'	> %o |>	submodules_f.txt
		     : ../submodules/<submodgroup> |> echo '%<submodgroup>' > %o |> submodules_group.txt

		     will     produce	  "../submodules/<submodgroup>"	    in
		     submodules_f.txt,	     but      "../submodules/sm1/foo.o
		     ../submodules/sm2/bar.o" in submodules_group.txt. If  the
		     input  contains  multiple	groups	with the same name but
		     different directories, %<group> will be expanded  to  all
		     of	the files in each listed group.

       var = value
       var := value
	      Set  the	$-variable  "var" to the value on the right-hand side.
	      Both forms are the same, and are allowed to more easily  support
	      converting  old  Makefiles.  The	$-variable  "var" can later be
	      referenced by using  "$(var)".  Variables	 referenced  here  are
	      always expanded immediately. As such, setting a variable to have
	      a	 %-flag	does not make sense, because a %-flag is only valid in
	      a	:-rule.	The syntax $(var_%e) is	allowed	in a :-rule.  Variable
	      references  do  not nest,	so something like $(var1_$(var2)) does
	      not make sense. You also cannot pass variable definitions	in the
	      command line or through the  environment.	 Any  reference	 to  a
	      variable that has	not had	its value set returns an empty string.

	      CFLAGS = -Dfoo
	      :	bar.c |> cc $(CFLAGS) $(other) -o %o -c	%f |> %B.o

	      will  generate  the  command  "cc	-Dfoo  -o bar.o	-c bar.c" when
	      run.

       Any $-variable that begins with the string "CONFIG_"  is	 automatically
       converted  to  the  @-variable  of  the	same  name minus the "CONFIG_"
       prefix. In other	words, $(CONFIG_FOO) and @(FOO)	 are  interchangeable.
       Attempting to assign a value to a CONFIG_ variable in a Tupfile results
       in an error, since these	can only be set	in the tup.config file.

       Note that you may see a syntax using back-ticks when setting variables,
       such as:

       CFLAGS += `pkg-config fuse3 --cflags`

       Tup  does  not  do  any	special	processing for back-ticks, so the pkg-
       config command is not actually executed when the	 variable  is  set  in
       this  example.  Instead,	this is	passed verbatim	to any place that uses
       it. Therefore if	a command later	references $(CFLAGS), it will  contain
       the  string  `pkg-config	 fuse3	--cflags`, so it will be parsed	by the
       shell.

       var += value
	      Append "value" to	the end	of the	current	 value	of  "var".  If
	      "var"  has  not  been  set,  this	is equivalent to a regular '='
	      statement. If "var" already has a	value, a space is appended  to
	      the $-variable before the	new value is appended.

       $(TUP_CWD)
	      The  special  $-variable	TUP_CWD	 is  always  set  to  the path
	      relative to the Tupfile currently	parsed.	It  can	 change	 value
	      when  including a	file in	a different directory. For example, if
	      you "include ../foo.tup",	then TUP_CWD will be set to ".."  when
	      parsing foo.tup. This lets foo.tup specify flags like "CFLAGS +=
	      -I$(TUP_CWD)",  and  CFLAGS  will	 always	 have the -I directory
	      where foo.tup is located,	 no  matter  if	 it  was  included  as
	      "../foo.tup"  or	"../../foo.tup"	 or  "subdir/foo.tup".	For an
	      alternative to $(TUP_CWD)	 when  referring  to  files,  see  the
	      section on &-variables below.

       No  other special $-variables exist yet,	but to be on the safe side you
       should assume that all variables	named TUP_* are	reserved.

       &var = file
       &var := file
       &var += file
	      p.PD 1 Set  the  &-variable  to  refer  to  the  given  file  or
	      directory.  The file must	be a normal file, not a	generated file
	      (an output from a	:-rule). &-variables  are  used	 to  refer  to
	      files  in	 a  similar  way as $(TUP_CWD),	except that instead of
	      storing the relative path	to the file, &-variables  store	 tup's
	      internal	ID  of	the file. This means that the relative path to
	      the file is determined when the &-variable is used, rather  than
	      when  the	 variable  is assigned as is the case with $(TUP_CWD).
	      &-variables can only be used in the following locations:	:-rule
	      inputs,  :-rule  order-only  inputs,  :-rule  commands,  include
	      lines, and run-script lines, and they are	later be referenced by
	      using "&(var)".

	      #	Tuprules.tup
	      &libdir =	src/lib
	      !cc = |> cc -I&(libdir) -c %f -o %o |> %B.o

	      #	src/lib/Tupfile
	      :	foreach	*.c |> !cc |>
	      :	*.o |> ar crs %o %f |> libstuff.a

	      #	src/lib/test/Tupfile
	      :	test_stuff.c |>	!cc |>
	      :	test_stuff.o &(libdir)/libstuff.a |> cc	-o %o %f |> test_stuff

	      #	src/Tupfile
	      :	main.c |> !cc |> main.o
	      :	main.o &(libdir)/libstuff.a |> cc -o %o	%f |> main_app

	      will generate the	following build.sh commands (via "tup generate
	      build.sh"):

	      cd src/lib
	      cc -I. -c	lib1.c -o lib1.o
	      cc -I. -c	lib2.c -o lib2.o
	      ar crs libstuff.a	lib1.o lib2.o
	      cd test
	      cc -I.. -c test_stuff.c -o test_stuff.o
	      cc -o test_stuff test_stuff.o ../libstuff.a
	      cd ../..
	      cc -Ilib -c main.c -o main.o
	      cc -o main_app main.o lib/libstuff.a

       ifeq (lval,rval)
	      Evaluates	the 'lval' and 'rval' parameters (ie: substitutes  all
	      $-variables  and	@-variables),  and does	a string comparison to
	      see if they match. If so,	 all  lines  between  the  'ifeq'  and
	      following	 'endif'  statement are	processed; otherwise, they are
	      ignored. Note that no whitespace is pruned for the values	-  all
	      text  between  the  '('  and  ','	 comprise 'lval', and all text
	      between the ',' and ')' comprise 'rval'. This  means  that  ifeq
	      (foo,  foo)  is false, while ifeq	(foo,foo) is true. This	is for
	      compatibility with Makefile if statements.

	      ifeq (@(FOO),y)
	      CFLAGS +=	-DFOO
	      else
	      CFLAGS +=	-g
	      endif

       ifneq (lval,rval)
	      Same as 'ifeq', but with the logic inverted.
       ifdef VARIABLE
	      Tests of the @-variable named VARIABLE  is  defined  at  all  in
	      tup.config.  If  so, all lines between the 'ifdef' and following
	      'endif' statement	are processed; otherwise,  they	 are  ignored.
	      For example, suppose tup.config contains:

	      CONFIG_FOO=n

	      Then  'ifdef  FOO'  will evaluate	to true. If tup.config doesn't
	      exist, or	does not set CONFIG_FOO	in any way, then  'ifdef  FOO'
	      will be false.
       ifndef VARIABLE
	      Same as 'ifdef', but with	the logic inverted.
       else   Toggles the true/false-ness of the previous if-statement.
       endif  Ends  the	previous ifeq/ifdef/ifndef. Note that only 8 levels of
	      nesting if-statements is supported.
       error [message]
	      Causes tup to stop parsing and fail,  printing  message  to  the
	      user as explanation.
       !macro =	[inputs] | [order-only inputs] |> command |> [outputs]
	      Set the !-macro to the given command string. This	syntax is very
	      similar  to the :-rule, since a !-macro is basically a macro for
	      those rules. The !-macro is not expanded until it	is used	in the
	      command string of	a :-rule. As such,  the	 primary  use  of  the
	      !-macro is to have a place to store command strings with %-flags
	      that may be re-used. For example,	we could have a	!cc macro in a
	      top-level	Tuprules.tup file like so:

	      !cc = |> ^ CC %f^	gcc -c %f -o %o	|>

	      A	Tupfile	could then do as follows:

	      include_rules
	      :	foreach	*.c |> !cc |> %B.o

	      You will only want to specify the	output parameter in either the
	      !-macro or the :-rule that uses it, but not both.	If you specify
	      any  inputs  in  the  !-macro,  they would usually be order-only
	      inputs. For example, if you have a !cc rule where	you are	 using
	      a	 compiler  that	 has  been  generated by tup, you can list the
	      compiler file  in	 the  order-only  list	of  the	 !-macro.  The
	      compiler	file  will  then  become  an  input dependency for any
	      :-rule that uses the macro.
       include file
	      Reads the	specified file and continues parsing almost as if that
	      file was pasted inline in	 the  current  Tupfile.	 Only  regular
	      files  are  allowed  to  be  included -- attempting to include a
	      generated	file is	an error. Any include statements that occur in
	      the included file	will be	parsed relative	to the included	file's
	      directory.
       include_rules
	      Reads in Tuprules.tup files up the directory  chain.  The	 first
	      Tuprules.tup  file  is  read  at	the  top of the	tup hierarchy,
	      followed by the next subdirectory, and  so  on  through  to  the
	      Tuprules.tup  file  in  the  current directory. In this way, the
	      top-level	 Tuprules.tup  file  can  specify   general   variable
	      settings,	 and  subsequent subdirectories	can override them with
	      more   specific	settings.   You	  would	  generally    specify
	      include_rules  as	 the  first line in the	Tupfile. The name is a
	      bit of a misnomer, since you would typically use Tuprules.tup to
	      define variables rather than :-rules.
       run ./script args
	      Runs an external script with the	given  arguments  to  generate
	      :-rules.	This  is an advanced feature that can be used when the
	      standard Tupfile syntax is too simplistic	for a complex program.
	      The script is expected to	write the :-rules to stdout. No	 other
	      Tupfile  commands	 are  allowed -	for example, the script	cannot
	      create $-variables or !-macros, but it can output	 :-rules  that
	      use  those  features. As a simple	example, consider if a command
	      must be executed 5 times,	but there are no input	files  to  use
	      tup's  foreach  keyword.	An  external  script called 'build.sh'
	      could be written as follows:

	      #! /bin/sh -e
	      for i in `seq 1 5`; do
		   echo	": |> echo $i >	%o |> $i.txt"
	      done

	      A	Tupfile	can then be used to get	these rules:

	      run ./build.sh

	      Tup will then treat this as if a	Tupfile	 was  written  with  5
	      lines like so:

	      :	|> echo	1 > %o |> 1.txt
	      :	|> echo	2 > %o |> 2.txt
	      :	|> echo	3 > %o |> 3.txt
	      :	|> echo	4 > %o |> 4.txt
	      :	|> echo	5 > %o |> 5.txt

	      Since the	Tupfile-parsing	stage is watched for dependencies, any
	      files  that  this	 script	accesses within	the tup	hierarchy will
	      cause the	Tupfile	to be re-parsed. There are  some  limitations,
	      however. First, the readdir() call is instrumented to return the
	      list  of	files  that  would be accessible at that time that the
	      run-script starts	executing. This	means the files	that  you  see
	      in 'ls' on the command-line may be different from	the files that
	      your  script  sees  when	it is parsed. Tup essentially pretends
	      that the generated files don't exist until it  parses  a	:-rule
	      that  lists  it  as an output. Note that any :-rules executed by
	      the run-script itself are	not parsed until the  script  executes
	      successfully. Second, due	to some	structural limitations in tup,
	      the  script  cannot  readdir()  on  any directory	other than the
	      directory	of the Tupfile.	In other words,	a script can do	'for i
	      in *.c', but not 'for i in sub/*.c'. The '--debug-run' flag  can
	      be passed	to 'tup' in order to show the list of :-rules that tup
	      receives	from the script. Due to	the readdir() instrumentation,
	      this may be different than the script's output when  it  is  run
	      manually from the	command-line.

       preload directory
	      By  default,  a  run-script  can only use	a readdir() (ie: use a
	      wild-card) on the	current	directory. To specify a	list of	 other
	      allowable	 wild-card  directories,  use the preload keyword. For
	      example, if a run	script needs to	look at	*.c and	 src/*.c,  the
	      src directory needs to be	preloaded:

	      preload src
	      run ./build.sh *.c src/*.c

       export VARIABLE
	      The  export  directive adds the environment variable VARIABLE to
	      the export list for future :-rules and  run-scripts.  The	 value
	      for  the	variable  comes	 from  tup's environment, not from the
	      Tupfile itself. Generally	this means you will need  to  set  the
	      variable	in  your shell if you want to change the value used by
	      commands and scripts. By default only PATH is exported.  Windows
	      additionally  exports  several  variables	 suitable for building
	      with the Visual  Studio  compiler	 suite.	 Tup  will  check  the
	      exported	environment  variables	to  see	 if  they have changed
	      values between updates, and re-execute any  commands  that  that
	      use those	environment variables. Note that this means if PATH is
	      changed, all commands will run again. For	example:

	      :	|> command1 ...	|>
	      export FOO
	      :	|> command2 ...	|>

	      Tup  will	 save  the  current  value  of	FOO and	pass it	to the
	      environment when executing command2.  If	FOO  has  a  different
	      value  during  the next update, then command2 will execute again
	      with the new value in the	environment. In	this example, command1
	      will not have FOO	in its environment  and	 will  not  re-execute
	      when its value changes.

	      Note  that the FOO above is passed to the	environment; it	is not
	      provided as an internal variable within  tup.  Thus,  given  the
	      following:

	      export FOO
	      :	|> echo	myFOO=$(FOO) envFOO=${FOO} > %o	|> foo.txt

	      when  run	 as  "$	FOO=silly tup" would result in the contents of
	      the foo.txt file being "myFOO=  envFOO=silly".  If  the  "export
	      FOO"  was	 removed  from	the  Tupfile, the contents of the file
	      would  be	 "myFOO=  envFOO="  because  tup  does	not  propagate
	      environment  variables unless they are explicitly	exported. This
	      helps preserve repeatable	and deterministic builds.

	      If you wish to export a variable to a specific value rather than
	      get the value from the environment, you  can  do	that  in  your
	      shell instead of through tup. For	example, in Linux you can do:

	      :	|> FOO=value command ... |>

	      This  usage  will	 not  create  a	 dependency on the environment
	      variable FOO, since it is	controlled through the Tupfile.

       .gitignore
	      Tells tup	to automatically generate a  .gitignore	 file  in  the
	      current directory	which contains a list of the output files that
	      are  generated  by tup. This can be useful if you	are using git,
	      since the	set of files generated by tup matches exactly the  set
	      of  files	 that  you  want  git  to  ignore.  If	you  are using
	      Tuprules.tup files, you may just want to specify	.gitignore  in
	      the  top-level  Tuprules.tup,  and then have every other Tupfile
	      use include_rules	to pick	up the .gitignore definition. In  this
	      way  you	never  have to maintain	the .gitignore files manually.
	      Note that	you may	wish to	ignore other files not created by tup,
	      such as temporary	files created by your  editor.	In  this  case
	      case  you	 will  want  to	 setup a global	gitignore file using a
	      command	like   'git    config	 --global    core.excludesfile
	      ~/.gitignore',  and  then	 setup ~/.gitignore with your personal
	      list. For	other cases, you can also simply add any custom	ignore
	      rules above the "##### TUP GITIGNORE #####" line.
       #      At the beginning of a line, a '#'	character signifies a comment.
	      A	comment	line is	ignored	by the parser. The  comment  can  have
	      leading  whitespaces  that is also ignored. If there is any non-
	      whitespace before	a '#'  character,  then	 the  line  is	not  a
	      comment.	It  also  means	that if	a previous line	ended with '\'
	      (line wrap) then '#' is interpreted as a regular symbol.

TUPFILE	NOTES
       Variable	expansion in  tup  is  immediate  in  every  case  except  for
       !-macros. That is, if you see a :-rule or variable declaration, you can
       substitute  the current values for the variables. The !-macros are only
       parsed when they	used in	a :-rule. In that case,	the actual :-rule is a
       sort of a union between the :-rule as written and the current value  of
       the !-macro.
       When  tup  parses  a  Tupfile, it makes a single	pass through the file,
       parsing a line at a time. At the	end  of	 the  Tupfile,	all  variable,
       !-macro,	 and  {bin}  definitions  are  discarded.  The	only lingering
       effects of parsing a Tupfile are	the  command  nodes  and  dependencies
       that now	exist in the tup database. Additionally, a .gitignore file may
       have been created if requested by the Tupfile.

@-VARIABLES
       @-variables   are   special   variables	 in  tup.  They	 are  used  as
       configuration variables,	and can	be read	by Tupfiles  or	 used  by  the
       varsed  command.	 Commands  are	able to	read them too, but the program
       executed	by the command has to have direct knowledge of the  variables.
       @-variables  are	specified in the tup.config file at the	top of the tup
       hierarchy or in	a  variant  directory.	For  example,  tup.config  may
       contain:

       CONFIG_FOO=y

       A Tupfile may then read the @-variable like so:

       srcs-@(FOO) += foo.c
       srcs-y += bar.c
       : foreach $(srcs-y) |> gcc -c %f	-o %o |> %B.o

       In  this	example, if CONFIG_FOO is set to 'y', then the foo.c file will
       be included in the input	list and therefore compiled. If	CONFIG_FOO  is
       unspecified or set to some other	value, foo.c will not be included.
       The  @-variables	can be used similar to $-variables, with the following
       distinctions:  1)  @-variables  are  read-only  in  Tupfiles,  and   2)
       @-variables  are	 in  the  DAG, which means reading from	them creates a
       dependency from the @-variable to the Tupfile.  Therefore  any  Tupfile
       that  reads @(FOO) like the above example will be reparsed if the value
       of CONFIG_FOO in	tup.config changes.
       The reason for prefixing	with "CONFIG_" in the tup.config  file	is  to
       maintain	compatibility with kconfig, which can be used to generate this
       file.
       Note  that  the syntax for tup.config is	fairly strict. For a statement
       like "CONFIG_FOO=y", tup	will create an	@-variable  using  the	string
       starting	 after	"CONFIG_",  and	 up  to	 the  '='  sign.  The value is
       everything immediately after the	'=' sign until	the  newline,  but  if
       there  is  a  surrounding  pair	of  quotes, they are stripped. In this
       example,	it would set "FOO" to "y". Note	that if	instead	the line  were
       "CONFIG_FOO = y", then the variable "FOO	" would	be set to " y".
       In  tup.config, comments	are determined by a '#'	character in the first
       column. These are ignored, unless the comment is	of the form:

       # CONFIG_FOO is not set

       In this case, the @-variable "FOO" is explicitly	set to "n".
       @(TUP_PLATFORM)
	      TUP_PLATFORM is a	special	@-variable. If CONFIG_TUP_PLATFORM  is
	      not set in the tup.config	file, it has a default value according
	      to  the  platform	that tup itself	was compiled in. Currently the
	      default value is one of "linux", "solaris",  "macosx",  "win32",
	      "freebsd"	or "netbsd".
       @(TUP_ARCH)
	      TUP_ARCH	is  another  special @-variable. If CONFIG_TUP_ARCH is
	      not set in the tup.config	file, it has a default value according
	      to the processor architecture that tup itself was	 compiled  in.
	      Currently	  the  default	value  is  one	of  "i386",  "x86_64",
	      "powerpc", "powerpc64", "ia64", "alpha",	"sparc",  "arm64",  or
	      "arm".

VARIANTS
       Tup  supports  variants,	which allow you	to build your project multiple
       times with different configurations. Perhaps the	most common case is to
       build a release and  a  debug  configuration  with  different  compiler
       flags,  though  any  number of variants can be used to support whatever
       configurations you like.	Each variant is	built  in  its	own  directory
       distinct	 from  each other and from the source tree. When building with
       variants, the in-tree build is disabled.	To create a  variant,  make  a
       new directory at	the top	of the tup hierarchy and create	a "tup.config"
       file there. For example:

       $ mkdir build-default
       $ touch build-default/tup.config
       $ tup

       Here  we	 created  a directory called "build-default" and made an empty
       tup.config inside. Note that the	build directory	must be	 at  the  same
       level as	the ".tup" directory. Upon updating, tup will parse all	of the
       Tupfiles	 using	the configuration file we created, and place all build
       products	within subdirectories of build-default that mirror the	source
       tree. We	could then create another variant like so:

       $ mkdir build-debug
       $ echo "CONFIG_MYPROJ_DEBUG=y" >	build-debug/tup.config
       $ tup

       This  time all Tupfiles will be parsed with @(MYPROJ_DEBUG) set to "y",
       and all build products will be placed  in  the  build-debug  directory.
       Note  that  setting @(MYPROJ_DEBUG) only	has any	effect if the variable
       is actually used	in a Tupfile (perhaps by adding	 debug	flags  to  the
       compiler	command-line).

       Running	"tup"  will  update  all variants. For example,	updating after
       modifying a C file that is used in all configurations will cause	it  to
       be  re-compiled for each	variant. As with any command that is executed,
       this is done in parallel	subject	to the constraints of the DAG and  the
       number  of  jobs	 specified.  To	 build	a single variant (or subset of
       variants), specify the build directory as the  target  to  "tup",  just
       like with any partial update. For example:

       $ tup build-default

       To delete a variant, just wipe out the build directory:

       $ rm -rf	build-debug

       If  you	build  with variants, it is recommended	that you always	have a
       default variant that contains an	 empty	tup.config  file.  This	 helps
       check  that your	software is always able	to be built by simply checking
       it out and  doing  'tup	init;  tup'  without  relying  on  a  specific
       configuration.

       When using in-tree builds, the resulting	build outputs may rely on run-
       time  files,  placed in the source tree and not being processed by tup.
       Tup allows such files to	 be  copied  verbatim  in  the	variant	 build
       directory by providing a	built-in macro "!tup_preserve":

       :foreach	*.png |> !tup_preserve |>

       Either  a  symbolic  link or a copy of the source file will be created,
       depending on the	OS and file system being used.

EXAMPLE
       Parsing a :-rule	may be a little	confusing at first. You	 may  find  it
       easy  to	 think	of  the	 Tupfile  as  a	 shell	script with additional
       input/output annotations	for the	commands. As an	example, consider this
       Tupfile:

       WARNINGS	+= -W
       WARNINGS	+= -Wall
       CFLAGS =	$(WARNINGS) -O2
       CFLAGS_foo.c = -DFOO
       : |> echo '#define BAR 3' > %o |> foo.h
       : foreach *.c | foo.h |>	gcc -c %f -o %o	$(CFLAGS) $(CFLAGS_%f) |> %B.o
       : *.o |>	gcc %f -o %o |>	program

       Tup begins parsing this Tupfile with an empty $-variable	set. The first
       "WARNINGS += -W"	line will set  the  WARNINGS  variable	to  "-W".  The
       second  line  will  append,  so WARNINGS	will be	set to "-W -Wall". The
       third line references this value, so CFLAGS will	now  equal  "-W	 -Wall
       -O2". The fourth	line sets a new	variable, called CFLAGS_foo.c, and set
       it  to  -DFOO".	The  first  rule will create a new node	"foo.h"	in the
       database, along with the	corresponding command to create	it. Note  this
       file  won't  exist  in  the  filesystem	until  the command is actually
       executed	after all Tupfiles are parsed.
       The foreach :-rule will generate	a command to compile each file.	 First
       tup  will  parse	 the  input section, and use the glob operation	on the
       database	since a	'*' is present.	This glob  matches  foo.c  and	bar.c.
       Since  it  is a foreach rule, tup will run through the rule first using
       the input "foo.c", and  again  using  the  input	 "bar.c".  The	output
       pattern is parsed on each pass, followed	by the command string.
       On  the	foo.c  pass,  the  output pattern "%B.o" is parsed, which will
       equal "foo.o". Now the command string is	parsed,	replacing "foo.c"  for
       "%f"  and  "foo.o"  for	"%o".  The  $-variables	 are then expanded, so
       $(CFLAGS) becomes "-W -Wall -O2", and $(CFLAGS_foo.c)" becomes "-DFOO".
       The final command string	written	to the database	is "gcc	 -c  foo.c  -o
       foo.o -W	-Wall -O2 -DFOO". An output link is written to the foo.o file,
       and  input  links  are  written	from  foo.c  and foo.h (the order-only
       input).
       On the second pass through the foreach rule,  the  only	difference  is
       "bar.c" is the input. Therefore the output pattern becomes "bar.o", and
       the  final command string becomes "gcc -c bar.c -o bar.o	-W -Wall -O2 "
       since $(CFLAGS_bar.c) was unspecified.
       For     more	examples     with     corresponding	DAGs,	   see
       http://gittup.org/tup/examples.html
OTHER BUILD SYSTEMS
       Tup is a	little bit different from other	build systems. It uses a well-
       defined	graph  structure  that is maintained in	a separate database. A
       set of algorithms to operate on this graph were developed in  order  to
       handle  cases  such as modifying	an existing file, creating or deleting
       files, changing command lines, etc. These algorithms are	very efficient
       - in particular,	for the	case where a project is	already	built and  one
       or  more	 existing  files are modified, tup is optimal among file-based
       build systems. For  other  cases,  tup  is  at  least  very  fast,  but
       optimality has not been proved.
       The  primary  reason  for the graph database is to allow	the tup	update
       algorithm to easily access the information it needs. As a  very	useful
       side-effect  of	the well-defined database structure, tup can determine
       when a generated	file is	no longer needed. What this means is there  is
       no clean	target.	Nor is there a need to do a "fresh checkout" and build
       your  software from scratch. Any	number of iterations of	updates	always
       produces	the same output	as it would  if	 everything  was  built	 anew.
       Should  you  find otherwise, you've likely found	a bug in tup (not your
       Tupfiles), in which case	 you  should  notify  the  mailing  list  (see
       CONTACT).
       For    more    information    on	   the	  theory   behind   tup,   see
       http://gittup.org/tup/build_system_rules_and_algorithms.pdf
SEE ALSO
       http://gittup.org/tup
CONTACT
       tup-users@googlegroups.com

http://gittup.org/tup		  2021/04/19				tup(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=tup&sektion=1&manpath=FreeBSD+Ports+15.0.quarterly>

home | help