tup(1) tup manual tup(1) (NAME) tup - (SYNOPSIS) tup [--debug-sql] [--debug-fuse] [SECONDARY_COMMAND] [ARGS] (DESCRIPTION) tup (build system) . ( ) tup . C tup (dependency graph) (link) . tup . tup .c gcc .o . Tupfile . : tup (PRIMARY COMMAND: tup) 'tup' Tupfile . INI FILE OPTIONS FILES TUPFILES . tup [ ... ] . . . tup . . (file monitor) ( SECONDARY COMMANDS ). -jN updater.num_jobs 'N' . (DAG) N . : 'tup -j2' 'tup' updater.num_jobs . option . --verbose tup ^ TEXT^ . --quiet display.quiet '1' . option . -k --keep-going updater.keep_going '1' . option . --no-keep-going updater.keep_going '0' . option . --no-scan . tup . --no-environ-check . autoupdate/autoparse . -d . --debug-run :- run-script . 'run ./script args' TUPFILES . --debug-logging .tup/log . --debug- logging (rotate) . (SECONDARY COMMANDS) tup . . : tup [--debug-sql] [--debug-fuse] SECONDARY_COMMAND [SECONDARY_COMMAND_ARGS] init [directory] '.tup' tup . '.tup' . tup . " tup" . 'tup init' clone 'Tupfile.ini' . 'tup' '.tup' Tupfile.ini 'tup init' . Tupfile.ini . --no-sync 'db.sync' '0' . 'db.sync' '1' . tup . refactor ref refactor (refactor) Tupfile . tup (parsing) . Tupfile . Tupfile : : foreach *.c |> gcc -c %f -o %o -Wall |> %B.o 'tup' -Wall CFLAGS . Tupfile : CFLAGS = -Wall : foreach *.c |> gcc -c %f -o %o $(CFLAGS) |> %B.o 'tup refactor' tup Tupfile . Tupfile 'tup refactor' Tupfile . : .gitignore . :- -$ -! . monitor * * inotify . (watches) . . 'tup' . 'tup' . 'tup' ( ). . . monitor.autoupdate monitor.autoparse . 'tup monitor -f -a -j2' . option . -d . -f --foreground monitor.foreground 1 . ( ). -b --background monitor.foreground 0 . ( ). -a --autoupdate monitor.autoupdate 1 . . -n --no-autoupdate monitor.autoupdate 0 . . --autoparse --autoparse monitor.autoparse 1 . . --no-autoparse monitor.autoparse 0 . . stop . (PID) . variant foo.config [bar.config] [...] variant (symlink) tup.config . variant : $ 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' : $ mkdir build-bar $ ln -s ../configs/bar.config build-bar/tup.config $ mkdir build-foo $ ln -s ../configs/foo.config build-foo/tup.config variant configs/ . checkout 'tup init' 'tup variant' . (variants) tup.config ( VARIANTS ). tup.config . dbconfig tup . tup . options tup . OPTIONS FILES . graph [--dirs] [--ghosts] [--env] [--combine] [--stickies] [ ... ] tup .dot graphviz . . . tup 'tup scan' . tup -- . --dirs graph.dirs '1' . Tupfile . --ghosts graph.ghosts '1' . ( ) . --env graph.environment '1' . PATH . todo [ ... ] tup . . 'upd' 'todo' . --no-scan . tup . --verbose tup ^ TEXT^ . generate [--config config-file] [--builddir directory] script.sh (or script.bat on Windows) [ ... ] generate Tupfile tup . (CI) tup ( FUSE ). ".bat" batch script . : git clone ... myproj cd myproj tup generate build.sh ./build.sh # Copy out build artifacts / logs here git clean -f -x -d (incremental) . 'tup generate' . tup.config . --config . --builddir variant . . . . . . compiledb compiledb compile_commands.json . tup variant variant compile_commands.json . (export) ^j . ^j : : foreach *.c |> ^j^ gcc -c %f -o %o |> %B.o tup Tupfile ( 'tup parse') . compile_commands.json Tupfile **. 'tup compiledb' . compile_commands.json 'commandline' . : https://clang.llvm.org/docs/JSONCompilationDatabase.html commandline [ ... ] commandline . JSON compile_commands.json 'tup compiledb' (stdout) . compiledb 'tup commandline' Tupfile . .ycm_extra_conf.py git tup : https://github.com/gittup/tup varsed varsed Tupfile . . @VARIABLE@ @-variable . foo.txt : The architecture is set to @ARCH@ :- Tupfile : : foo.txt |> tup varsed %f %o |> foo-out.txt @ARCH@ CONFIG_ARCH tup.config . varsed CONFIG_ARCH ( CONFIG_ARCH ). scan 'tup graph' . (monitor) scan 'upd' . upd (Legacy). 'tup upd' 'tup' . INI (INI FILE) tup . Tupfile ( TUPFILES ) .tup . .tup 'tup init' Tupfile.ini . Tupfile.ini . (OPTIONS FILES) tup . tup tup . tup ( ). : command-line overrides (eg: -j flag passed to 'tup') .tup/options file ~/.tupoptions file /etc/tup/options file tup's compiled in defaults Windows : command-line overrides .tup/options file tup.ini in the Application Data path (usually C:\ProgramData\tup\tup.ini) tup's compiled in defaults 'tup options' . .ini . () : [updater] 'variable = value' . - (;) . . "true"/"yes" "false"/"no" 1 0 . .tup/options : [updater] num_jobs = 2 keep_going = true 'tup' (job) updater.keep_going . 'section.variable' 'db.sync' '[db]' 'sync = 0' . () . db.sync ( '1') synchronous SQLite '1' . . . tup . http://www.sqlite.org/pragma.html . updater.num_jobs ( ) tup . . updater.num_jobs 1 . -j . updater.keep_going ( '0') '1' . . '0' tup . -k . updater.full_deps ( '0') '1' tup . '0' tup . gcc C '1' . Linux OSX tup suid root chroot . Linux user namespaces suid . '0' '1' tup . . : ccache . . updater.warnings ( '1') '0' . tup . tup . . ( ) : . .. .tup .git .hg .bzr .svn. display.color ( 'auto') 'never' ANSI 'always' ANSI . 'auto' (stdout) tty ( ). display.width ( ) . . . display.progress ( '1' stdout TTY ) '1' '0' . TTY TTY . display.job_numbers ( '1') '0' "N) " . . display.job_time ( '1') '0' . . tup . . display.quiet ( '0') '1' tup . tup stdout/stderr . display.progress . monitor.autoupdate ( '0') '1' . (monitor) . '0' 'tup' . monitor.autoparse ( '0') '1' . monitor.autoupdate 'tup' . monitor . autoupdate autoparse autoupdate . monitor.foreground ( '0') '1' ( ctrl-C 'tup stop' ). '0' . graph.dirs ( '0') '1' 'tup graph' . Tupfile . Tupfile . graph.ghosts ( '0') '1' (ghost nodes) . . . graph.environment ( '0') '1' ( PATH) . PATH . graph.combine ( '0') '1' . .c .o . . tup <> . tup () Tupfile . : [foreach] [inputs] [ | order-only inputs] |> command |> [outputs] [ | extra outputs] [] [{bin}] : ( :-rules) <<:>> Tupfile . (pipeline) . foreach <> . . <> inputs . inputs . Tupfile : # 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 <> <<%e>> ( ). inputs . tup . % ( ) . (wildcarding) glob SQLite . glob <<*>> <> <<[]>>. <<*.c>> .c <> .c <> <> <> fox.c foy.c foz.c . glob <> <<*/*.c>> . <<^>> glob . *.c main.c : : foreach *.c ^main.c |> ... |> (parser time) (outputs) . order-only inputs % %i . <<|>> . . glob inputs . : : |> echo "#define FOO 3" > %o |> foo.h : foreach foo.c bar.c | foo.h |> gcc -c %f -o %o |> %B.o foo.h gcc foo.c bar.c tup . foreach ( foo.c bar.c) - (order-only inputs foo.h). tup . foo.h -- . command tup system(3) . - tup . . (parallel safe) tup . <> ( ) . tup . . . . tup . Tupfile . Tupfile . ^ TEXT^ tup <> . echo . --verbose tup tup <> . <<^>> . <<^>> . ^ . system(gcc -c foo.c -o foo.o) <> : : foo.c |> ^ CC %f^ gcc -c %f -o %o |> foo.o <> ! . ! . {bin} . outputs (outputs) . ( bison .c .h ). % %o . tup . . <<^>> . . tup . <> tup : : foreach *.c |> ... |> %B.o ^license_file.txt tup . glob <<^>> inputs . ( ) . <> . . tup . extra-outputs extra-outputs - (order-only inputs) . <<|>> . extra-outputs %o . . extra-outputs %O (basename) . extra-outputs ! . bin . - . . Tup : #./submodules/sm1/Tupfile : foo.c |> gcc -c %f -o %o |> %B.o ../ #./submodules/sm2/Tupfile : bar.c |> gcc -c %f -o %o |> %B.o ../ #./project/Tupfile : baz.c | ../submodules/ |> gcc -c %f -o %o |> %B.o <> . - Tup . {bin} <<{bin}>> (bin) . <<{bin}>> . foreach .o objs (linker) : : foreach *.c |> gcc -c %f -o %o |> %B.o {objs} : {objs} |> gcc %f -o %o |> program *.o ( *.o ). {bin} bin . bin bin Tupfile . ^-flags ^ TEXT^ ^ . : : foo.c |> ^c CC %f^ gcc --coverage %f -o %o |> foo | foo.gcno : bar.c |> ^c^ gcc --coverage %f -o %o |> bar | bar.gcno foo.c (namespaces) ( suid) <> . bar.c ( suid) <> . : b <> <>> <>> . bash : <<-o pipefail>> << () >>. c <> tup ( ) suid root . tup (degraded mode) . <> suid . . j <> <> . compile_commands.json ^j <> . compiledb . o <> . (DAG) . (object file) (linking) . <> <> . s <> stdout/stderr << >> (streaming mode) . stdout/stderr tup . 's' tup tup . . tup ( ) . . t <> (transient) . . . <> <> . <> Tupfile . <> C ** . C ** . %-flags % . % . %o . %1o %2o ( ) . %% <<%>> . tup. %f <>. . . <> <> . %1f %2f . %i <>. . - %i . %1i %2i . %b %f (basename) . . <> <> . %1b %2b . %B %b . . <> <> . %1B %2B . %e foreach. . (.S) .c $(CFLAGS_%e) CFLAGS_S CFLAGS_c . <> <> <> <> . %o () . tup . <> <>. %1o %2o . %O . extra-outputs . ! . <> <<.so>> <<.map>> (map file) ! : !ldmap = |> ld ... -o %o |> | %O.map : foo1.o foo2.o |> !ldmap |> foo.so %d . foo/bar/Tupfile <> . ! : !ar = |> ar crs %o %f |> lib%d.a foo/bar/Tupfile foo/bar/libbar.a . %g glob . a_text.txt b_text.txt : : foreach *_text.txt |> foo %f |> %g_binary.bin a_binary.bin b_binary.bin . glob %g . %g foreach . % <>. : #./submodules/sm1/Tupfile : foo.c |> gcc -c %f -o %o |> %B.o ../ #./submodules/sm2/Tupfile : bar.c |> gcc -c %f -o %o |> %B.o ../ #./project/Tupfile : ../submodules/ |> echo '%f' > %o |> submodules_f.txt : ../submodules/ |> echo '%' > %o |> submodules_group.txt <<../submodules/>> submodules_f.txt submodules_group.txt <<../submodules/sm1/foo.o ../submodules/sm2/bar.o>> . % . var = value var := value -$ "var" . Makefile . "$(var)" -$ "var" . . -% -% -: . $(var_%e) -: . $(var1_$(var2)) . . . CFLAGS = -Dfoo : bar.c |> cc $(CFLAGS) $(other) -o %o -c %f |> %B.o "cc -Dfoo -o bar.o -c bar.c" . -$ "CONFIG_" -@ "CONFIG_" . $(CONFIG_FOO) @(FOO) . CONFIG_ Tupfile tup.config . : CFLAGS += `pkg-config fuse3 --cflags` tup pkg-config . . $(CFLAGS) `pkg- config fuse3 --cflags` (shell) . var += value "value" "var" . "var" '=' . "var" -$ . $(TUP_CWD) [lua] tup.getcwd() -$ TUP_CWD Tupfile . include . "include ../foo.tup" TUP_CWD foo.tup ".." . foo.tup "CFLAGS += -I$(TUP_CWD)" CFLAGS "../foo.tup" "../../foo.tup" "subdir/foo.tup" -I foo.tup . $(TUP_CWD) -& . $(TUP_VARIANTDIR) [lua] tup.getvariantdir() $(TUP_CWD) $(TUP_VARIANTDIR) Tupfile variant . "include/" . Tuprules.tup -I$(TUP_VARIANTDIR) . variant "../build/path/to/include" "build" variant . variant TUP_VARIANTDIR TUP_CWD . $(TUP_VARIANT_OUTPUTDIR) [lua] tup.getvariantoutputdir() $(TUP_VARIANT_OUTPUTDIR) variant . $(TUP_VARIANTDIR) Tuprules.tup *.tup . variant "." . -$ *TUP_ . &var = file &var := file &var += file -& . ( -:). -& $(TUP_CWD) -& tup . -& $(TUP_CWD) . -& : -: - (order-only) -: -: include run-script "&(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 build.sh ( "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) 'lval' 'rval' (: -$ -@ ) . 'ifeq' 'endif' . (whitespace) - '(' ',' 'lval' ',' ')' 'rval' . ifeq (foo, foo) (false) ifeq (foo,foo) (true) . if Makefile . ifeq (@(FOO),y) CFLAGS += -DFOO else CFLAGS += -g endif ifneq (lval,rval) 'ifeq' . ifdef VARIABLE -@ VARIABLE tup.config . 'ifdef' 'endif' . tup.config : CONFIG_FOO=n 'ifdef FOO' (true) . tup.config CONFIG_FOO 'ifdef FOO' (false) . ifndef VARIABLE 'ifdef' . else / (true/false) if . endif ifeq/ifdef/ifndef . if . error [message] tup message . !macro = [inputs] | [order-only inputs] |> command |> [outputs] -! . -: -! . -! -: . -! -% . !cc Tuprules.tup : !cc = |> ^ CC %f^ gcc -c %f -o %o |> Tupfile : include_rules : foreach *.c |> !cc |> %B.o -! -: . -! - (order-only) . !cc tup order-only -! . -: . include file Tupfile . -- include . include . include_rules Tuprules.tup . Tuprules.tup tup Tuprules.tup . Tuprules.tup (override) . include_rules Tupfile . Tuprules.tup -:. run ./script args -: . Tupfile . -: (stdout) . Tupfile - -$ -! -: . foreach tup . 'build.sh' : #! /bin/sh -e for i in `seq 1 5`; do echo ": |> echo $i > %o |> $i.txt" done Tupfile : run ./build.sh tup Tupfile : : |> 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 Tupfile tup Tupfile . . ()readdir run . 'ls' . tup -: . -: run . tup Tupfile ()readdir . 'for i in *.c' 'for i in sub/*.c' . '--debug-run' 'tup' -: tup . ()readdir . preload directory run ()readdir (: / wildcard) . preload . run *.c src/*.c src (preload) : preload src run ./build.sh *.c src/*.c export VARIABLE export VARIABLE (export) -: run . tup Tupfile. (shell) . PATH . Visual Studio . tup . PATH . : : |> command1 ... |> export FOO : |> command2 ... |> tup FOO command2 . FOO command2 . command1 FOO . FOO tup . : export FOO : |> echo myFOO=$(FOO) envFOO=${FOO} > %o |> foo.txt "$ FOO=silly tup" foo.txt "myFOO= envFOO=silly" . "export FOO" Tupfile "myFOO= envFOO=" tup (export) . (deterministic) . tup . Linux : : |> FOO=value command ... |> FOO Tupfile ..TP import VARIABLE[=default] import Tupfile . . Tupfile Tupfile . : import CC=gcc : foreach *.c |> $(CC) -c %f -o %o |> %B.o .c CC . CC gcc . 'CC=clang tup' Tupfile .c clang ( ). 'export' import . CC 'export CC' Tupfile . .gitignore tup .gitignore tup . git tup git . Tuprules.tup .gitignore Tuprules.tup Tupfile include_rules .gitignore . .gitignore . tup . 'git config --global core.excludesfile ~/.gitignore' gitignore ~/.gitignore . "##### TUP GITIGNORE #####" . # '#' () . . . '#' . '\' ( ) '#' . TUPFILE (TUPFILE NOTES) tup ! : . ! : . : : ! . tup Tupfile . Tupfile ! {bin} . Tupfile tup . Tupfile .gitignore . @ (@-VARIABLES) @ tup . Tupfile varsed . . @ tup.config tup (variant directory) . tup.config : CONFIG_FOO=y Tupfile @ : srcs-@(FOO) += foo.c srcs-y += bar.c : foreach $(srcs-y) |> gcc -c %f -o %o |> %B.o CONFIG_FOO 'y' foo.c . CONFIG_FOO foo.c . @ $ : ) @ Tupfile ) @ DAG @ Tupfile . Tupfile @(FOO) CONFIG_FOO tup.config . "CONFIG_" tup.config kconfig . tup.config . "CONFIG_FOO=y" tup @ "CONFIG_" '=' . '=' . "FOO" "y" . "CONFIG_FOO = y" "FOO " " y" . tup.config '#' . : # CONFIG_FOO is not set @ "FOO" "n" . @(TUP_PLATFORM) @ . CONFIG_TUP_PLATFORM tup.config () tup . "linux" "solaris" "macosx" "win32" "freebsd" "netbsd" . @(TUP_ARCH) @ . CONFIG_TUP_ARCH tup.config tup . "i386" "x86_64" "powerpc" "powerpc64" "ia64" "alpha" "sparc" "riscv32" "riscv64" "arm64" "arm" "s390x" . (VARIANTS) tup (variants) . release debug . . (in-tree) . tup "tup.config" . : $ mkdir build-default $ touch build-default/tup.config $ tup "build-default" tup.config . ".tup" . tup Tupfile build- default . : $ mkdir build-debug $ echo "CONFIG_MYPROJ_DEBUG=y" > build-debug/tup.config $ tup Tupfile "y" @(MYPROJ_DEBUG) build-debug . @(MYPROJ_DEBUG) Tupfile ( ). "tup" . C . DAG (jobs) . ( ) "tup" . : $ tup build-default : $ rm -rf build-debug tup.config . 'tup init; tup' . tup . tup "!tup_preserve" : :foreach *.png |> !tup_preserve |> (symbolic link) . (EXAMPLE) : . Tupfile / . 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 Tupfile $ . "WARNINGS += -W" WARNINGS "-W" . WARNINGS "-W -Wall" . CFLAGS "-W -Wall -O2" . CFLAGS_foo.c "-DFOO" . "foo.h" . Tupfile . : foreach . tup '*' (glob) . foo.c bar.c . foreach tup "foo.c" "bar.c" . . foo.c "%B.o" "foo.o" . "foo.c" "%f" "foo.o" "%o" . $ $(CFLAGS) "-W -Wall -O2" $(CFLAGS_foo.c) "-DFOO" . "gcc -c foo.c -o foo.o -W -Wall -O2 -DFOO". foo.o foo.c foo.h ( order-only) . foreach "bar.c" . "bar.o" $(CFLAGS_bar.c) "gcc -c bar.c -o bar.o -W -Wall -O2 " . DAG http://gittup.org/tup/examples.html ..SH " (OTHER BUILD SYSTEMS)" tup . . . tup . tup . tup . tup . clean ("fresh checkout") . . tup ( Tupfile ) ( (CONTACT) ). tup 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 2023/10/14 tup(1)