There are always cool new technologies being developed every day. I was introduced to the Tup build system from one of my colleagues at Sifteo. Mostly for giggles, I’ve decided to use it for my Raspberry Pi projects. But before we go any further I need to install it on my Raspberry Pi!
Why tup?
The idea behind Tup is basic but the implementation is far from trivial. Tup basically helps make your development cycles faster by creating a directed acyclic graph and then processes said graph to execute certain functions. The idea is that this system helps rebuilding files that otherwise don’t need to be touched. So as your code base increases you don’t waste time spinning in your desk chair waiting for everything to compile. Neat? I think so.
So lets get going. Instructions below:
Clone the tup repository
git clone https://github.com/gittup/tup.git
Note: Tup’s website suggests you use the below git address. It is outdated and not advisable.
git clone git://github.com/gittup/tup.git
Output:
Cloning into 'tup'...
remote: Reusing existing pack: 20129, done.
remote: Total 20129 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (20129/20129), 11.59 MiB | 89 KiB/s, done.
Resolving deltas: 100% (11180/11180), done.
Checking out files: 100% (1155/1155), done.
Just for your information the Git tag that I pulled down is the following:
pi@raspberrypi:~/tup$ git describe
v0.7.1-6-g4a55836
Install tup
First, set the permissions for the fuse system:
sudo usermod -aG fuse pi
reboot
Note: replace pi with your username. (Thanks to elfnet.org for that bit.)
Then run:
sudo ./bootstrap.sh
Note: the first time I ran the command I ran without sudo I got to the end and the following happened:
.tup repository initialized.
[ tup ] [0.072s] Scanning filesystem...
[ tup ] [1.364s] Reading in new environment variables...
[ tup ] [1.429s] Parsing Tupfiles...
fuse: failed to open /dev/fuse: Permission denied
tup error: Timed out waiting for the FUSE file-system to be ready.
tup error: Unable to mount FUSE on .tup/mnt
Once rebooted, run the ./bootstrap.sh script. Below is the successful output from the command:
pi@raspberrypi:~/tup$ ./bootstrap.sh
mkdir build
cd build
bootstrap CC -g ../src/lua/lapi.c
bootstrap CC -g ../src/lua/lauxlib.c
bootstrap CC -g ../src/lua/lbaselib.c
bootstrap CC -g ../src/lua/lbitlib.c
bootstrap CC -g ../src/lua/lcode.c
bootstrap CC -g ../src/lua/lcorolib.c
bootstrap CC -g ../src/lua/lctype.c
bootstrap CC -g ../src/lua/ldblib.c
bootstrap CC -g ../src/lua/ldebug.c
bootstrap CC -g ../src/lua/ldo.c
bootstrap CC -g ../src/lua/ldump.c
bootstrap CC -g ../src/lua/lfunc.c
bootstrap CC -g ../src/lua/lgc.c
bootstrap CC -g ../src/lua/linit.c
bootstrap CC -g ../src/lua/liolib.c
bootstrap CC -g ../src/lua/llex.c
bootstrap CC -g ../src/lua/lmathlib.c
bootstrap CC -g ../src/lua/lmem.c
bootstrap CC -g ../src/lua/loadlib.c
bootstrap CC -g ../src/lua/lobject.c
bootstrap CC -g ../src/lua/lopcodes.c
bootstrap CC -g ../src/lua/loslib.c
bootstrap CC -g ../src/lua/lparser.c
bootstrap CC -g ../src/lua/lstate.c
bootstrap CC -g ../src/lua/lstring.c
bootstrap CC -g ../src/lua/lstrlib.c
bootstrap CC -g ../src/lua/ltable.c
bootstrap CC -g ../src/lua/ltablib.c
bootstrap CC -g ../src/lua/ltm.c
bootstrap CC -g ../src/lua/lua.c
bootstrap CC -g ../src/lua/luac.c
bootstrap CC -g ../src/lua/lundump.c
bootstrap CC -g ../src/lua/lvm.c
bootstrap CC -g ../src/lua/lzio.c
link lua
bootstrap CC -g ../src/tup/bin.c
bootstrap CC -g ../src/tup/colors.c
bootstrap CC -g ../src/tup/config.c
bootstrap CC -g ../src/tup/create_name_file.c
bootstrap CC -g ../src/tup/db.c
bootstrap CC -g ../src/tup/debug.c
bootstrap CC -g ../src/tup/delete_name_file.c
bootstrap CC -g ../src/tup/dircache.c
bootstrap CC -g ../src/tup/entry.c
bootstrap CC -g ../src/tup/environ.c
bootstrap CC -g ../src/tup/estring.c
bootstrap CC -g ../src/tup/file.c
bootstrap CC -g ../src/tup/fslurp.c
bootstrap CC -g ../src/tup/graph.c
bootstrap CC -g ../src/tup/if_stmt.c
bootstrap CC -g ../src/tup/init.c
bootstrap CC -g ../src/tup/lock.c
bootstrap CC -g ../src/tup/luaparser.c
bootstrap CC -g ../src/tup/option.c
bootstrap CC -g ../src/tup/parser.c
bootstrap CC -g ../src/tup/path.c
bootstrap CC -g ../src/tup/pel_group.c
bootstrap CC -g ../src/tup/platform.c
bootstrap CC -g ../src/tup/privs.c
bootstrap CC -g ../src/tup/progress.c
bootstrap CC -g ../src/tup/send_event.c
bootstrap CC -g ../src/tup/string_tree.c
bootstrap CC -g ../src/tup/thread_tree.c
bootstrap CC -g ../src/tup/timespan.c
bootstrap CC -g ../src/tup/tupid_tree.c
bootstrap CC -g ../src/tup/updater.c
bootstrap CC -g ../src/tup/vardb.c
bootstrap CC -g ../src/tup/vardict.c
bootstrap CC -g ../src/tup/variant.c
bootstrap CC -g ../src/tup/varsed.c
bootstrap CC -g ../src/tup/tup/main.c
bootstrap CC -g ../src/tup/monitor/null.c
bootstrap CC -g ../src/tup/flock/fcntl.c
bootstrap CC -g ../src/tup/server/fuse_fs.c
bootstrap CC -g ../src/tup/server/fuse_server.c
bootstrap CC -g ../src/tup/server/master_fork.c
bootstrap CC -g ../src/inih/ini.c
bootstrap CC -g ../src/compat/dummy.c
bootstrap CC -g ../src/compat/utimensat_linux.c
bootstrap CC -g ../src/sqlite3/sqlite3.c
bootstrap LD tup -lm
.tup repository initialized.
[ tup ] [0.075s] Scanning filesystem...
[ tup ] [1.352s] Reading in new environment variables...
[ tup ] [1.426s] Parsing Tupfiles...
1) [0.171s] src/lua
2) [0.022s] src/luabuiltin
3) [0.191s] src/tup
4) [0.021s] src/tup/flock
5) [0.022s] src/tup/monitor
6) [0.030s] src/tup/server
7) [0.025s] src/sqlite3
8) [0.025s] src/inih
9) [0.025s] src/compat
10) [0.024s] src/tup/tup
11) [0.110s] .
12) [0.013s] build
13) [0.012s] build/luabuiltin
14) [0.008s] contrib
15) [0.010s] contrib/syntax
16) [0.011s] contrib/debian
17) [0.013s] contrib/debian/source
18) [0.010s] docs
19) [0.010s] docs/html
20) [0.020s] docs/html/pub
21) [0.014s] docs/html/pub/win32
22) [0.010s] src
23) [0.023s] src/compat/win32
24) [0.014s] src/compat/win32/sys
25) [0.018s] src/dllinject
26) [0.010s] src/bsd
27) [0.029s] test
28) [0.012s] test/make_v_tup
[ ETA~=<1s Remaining=0 ] 100%
[ tup ] [2.465s] No files to delete.
[ tup ] [2.475s] Generating .gitignore files...
[ tup ] [8.621s] Executing Commands...
1) [7.288s] src/lua: CC lapi.c
2) [5.075s] src/lua: CC lcode.c
3) [0.350s] src/lua: CC lctype.c
4) [7.476s] src/lua: CC ldebug.c
5) [3.730s] src/lua: CC ldo.c
6) [1.565s] src/lua: CC ldump.c
7) [2.087s] src/lua: CC lfunc.c
8) [6.880s] src/lua: CC lgc.c
9) [5.320s] src/lua: CC llex.c
10) [0.659s] src/lua: CC lmem.c
11) [2.324s] src/lua: CC lobject.c
12) [0.363s] src/lua: CC lopcodes.c
13) [8.912s] src/lua: CC lparser.c
14) [1.598s] src/lua: CC lstate.c
15) [4.863s] src/lua: CC lstring.c
16) [3.319s] src/lua: CC ltable.c
17) [0.672s] src/lua: CC ltm.c
18) [1.991s] src/lua: CC lundump.c
19) [8.877s] src/lua: CC lvm.c
20) [0.695s] src/lua: CC lzio.c
21) [5.280s] src/lua: CC lauxlib.c
22) [2.946s] src/lua: CC lbaselib.c
23) [1.275s] src/lua: CC lbitlib.c
24) [1.102s] src/lua: CC lcorolib.c
25) [2.793s] src/lua: CC ldblib.c
26) [8.493s] src/lua: CC liolib.c
27) [2.100s] src/lua: CC lmathlib.c
28) [1.917s] src/lua: CC loslib.c
29) [6.595s] src/lua: CC lstrlib.c
30) [2.650s] src/lua: CC ltablib.c
31) [5.049s] src/lua: CC loadlib.c
32) [0.461s] src/lua: CC linit.c
33) [0.250s] src/lua: AR liblua.a
34) [2.990s] src/lua: CC lua.c
35) [0.617s] src/lua: LINK lua
36) [0.334s] src/luabuiltin: ../lua/lua xxd.lua builtin.lua luabuiltin.h
37) [0.835s] src/tup: CC bin.c
38) [0.976s] src/tup: CC colors.c
39) [1.396s] src/tup: CC config.c
40) [3.632s] src/tup: CC create_name_file.c
41) [47.474s] src/tup: CC db.c
42) [1.289s] src/tup: CC debug.c
43) [1.642s] src/tup: CC delete_name_file.c
44) [0.748s] src/tup: CC dircache.c
45) [4.924s] src/tup: CC entry.c
46) [0.551s] src/tup: CC environ.c
47) [0.583s] src/tup: CC estring.c
48) [3.622s] src/tup: CC file.c
49) [0.798s] src/tup: CC fslurp.c
50) [6.469s] src/tup: CC graph.c
51) [0.580s] src/tup: CC if_stmt.c
52) [1.726s] src/tup: CC init.c
53) [0.812s] src/tup: CC lock.c
54) [7.856s] src/tup: CC luaparser.c
55) [3.027s] src/tup: CC option.c
56) [23.570s] src/tup: CC parser.c
57) [2.621s] src/tup: CC path.c
58) [1.887s] src/tup: CC pel_group.c
59) [0.187s] src/tup: CC platform.c
60) [0.667s] src/tup: CC privs.c
61) [2.832s] src/tup: CC progress.c
62) [0.419s] src/tup: CC send_event.c
63) [6.280s] src/tup: CC string_tree.c
64) [2.237s] src/tup: CC thread_tree.c
65) [0.541s] src/tup: CC timespan.c
66) [3.789s] src/tup: CC tupid_tree.c
67) [15.258s] src/tup: CC updater.c
68) [3.790s] src/tup: CC vardb.c
69) [0.923s] src/tup: CC vardict.c
70) [1.446s] src/tup: CC variant.c
71) [1.106s] src/tup: CC varsed.c
72) [0.934s] src/tup/flock: CC fcntl.c
73) [0.048s] AR libtup_client.a
74) [0.031s] CP src/tup/vardict.h -> tup_client.h
75) [8.259s] src/tup/monitor: CC inotify.c
76) [4.252s] src/tup/server: CC fuse_server.c
77) [6.485s] src/tup/server: CC fuse_fs.c
78) [3.836s] src/tup/server: CC master_fork.c
79) [319.050s] src/sqlite3: CC sqlite3.c
80) [1.764s] src/inih: CC ini.c
81) [0.545s] src/compat: CC utimensat_linux.c
82) [0.265s] src/compat: CC dummy.c
83) [0.402s] AR libtup.a
84) [7.570s] src/tup/tup: CC main.c
85) [1.451s] LINK tup
[ ETA~=<1s Remaining=0 Active=0 ] 100%
[ tup ] [641.945s] Updated.
Build complete. If ./tup works, you can remove the 'build' directory.
Note: It does take some time to get everything compiled. The Raspberry Pi is not known for its speed!
Once tup has been built successfully you can copy tup to /usr/local/bin/ as I did below:
sudo cp tup /usr/local/bin/
Congrats! Tup is ready to be used!
What’s next?
As I write this i’m trying to figure out the best way to build the source files and subsequently test those changes. I aim to have fast test cycles with the ability to run one simple command on my main machine to compile and test my changes on the Raspberry Pi.
Already have a fast and efficient C/C++ development cycle for the Raspberry Pi? Share in the comments below!
More Raspberry Pi posts
Want more Raspberry Pi Posts? Follow this link!
Last Modified: 2020.3.7