Hi Eddy,
It is quite weird to list wrong things, even more so when you use
negations in them. After looking a this whole list, It looks like random
rantings about issues with make. I have nonetheless tried to anwser all
of these. It appears that tup is a file-based build system, with a
minimal specification language, that it supports scripting to some
extent, and that it is designed to be correct and fast. What follows is
just twenty different ways to say that.
Also, I must say that there are several hundreds of different build
systems. There does not exist a single one to rule them all. All these
build systems come with features in their specification languages, and
some features in their dependency and execution engine. Tup has a
minimal fronted, with a simple text based specification language. It's
beauty resides in its design of the engine, and in its simplicity. If
you want bells and whistles, you either need to script it, or use
something else.
Anyway, here it comes:
* Build graphs are trees.
o Tup uses DAGs (Directed, Acyclic Graphs)
* Build graphs are acyclic.
o TL;DR: This is not a falsehood.
o Well, yes, they must be. Otherwise you sacrifice correctness.
o I am not aware of any build systems who supports cyclic graphs,
except for very dumb ones like make, which can be tricked to
somehow do it, while they do not *support* it per se.
o I have ideas on how to do that, and some examples on which it
may actually be useful, but this should not be needed in most cases.
o While the build graph *may* be cyclic, builds themselves are
*never* cyclic. Any output must be computed from previous
outputs. There is no way for a program to receive as input it's
own output as input in the same execution. Any loop must be
unrolled at execution.
* Every build step updates at most one file.
o Tup supports writing to multiple files. It does not yet support
writing to files whose name is unknown before executing the
command, nor writing directories.
* Every build step updates at least one file.
o It is possible with tup to have no output at all. It is not very
useful, except for tests (which have little support from tup)
o The underlying criticism is that most build systems are
file-based, which tup is, explicitly.
* Compilers will always modify the timestamps on every file they are
expected to output.
o Tup does not care about that. It tracks file much more precisely
than looking at the resulting timestamp.
o Tup will however not detect changes to files that were changed
outside of tup, if the timestamp has not changed and the file
monitor was not used. (it is always possible to trick a build
system anyway, but why would you want to shoot your own foot ?)
* It's possible to tell the compiler which file to write its output to.
o This is still an issue with tup. If the compiler writes to
outputs that are not know in advance, you need a wrapper script
around your command to rename the outputs. This is related to
the above, where I already mentioned files whose name is not
known beforehand.
* It's possible to tell the compiler which directory to write its
output to.
o Again, tup does not care, as long as the output directory is
known in advance, and contains a Tupfile.
* It's possible to predict in advance which files the compiler will
update.
o Tup requires a command to write to all its outputs. But you can
always write a small script that touches all the outputs.
o *Warning* This question assumes compilers that *update* files,
which is non-sense in acyclic build graphs. As long as you can
only produce files, there is little sense for a compiler to
sometimes generate a file, and sometimes not. Generating files
with unpredictable names is different, and covered above.
* It's possible to narrow down the set of possibly-updated files to a
small hand-enumerated set.
o Tup does not support this idea of "possibly updated", because it
does not support the idea of "possibly", nor this notion of
"update".
o Tup however can handle a large set of inputs/outputs files,
possibly with groups and bins. You can also generate rules with
scripts, which allows to describe a large set of file without
enumerating them.
* It's possible to determine the dependencies of a target without
building it.
o Tup allows you to specify a superset of the dependencies of a
rule. It will discover in this set the dependencies that are
really used.
* Targets do not depend on the rules used to build them.
o They do, of course. If a rule changes, tup rebuilds it. (In
fact, tup sees it as a new rule, but it is exactly the same.)
* Targets depend on every rule in the whole build system.
o Huh ?! Well, I do not understand this one. In tup, a target
depends on its build rule, which in turns depends on its inputs,
and so on. You can have completely separate build graphs with
tup, and a targets depends exactly on the files it requires to
be built.
* Detecting changes via file hashes is always the right thing.
o Well, tup depends on timestamps to detect changes in the
filesystem, then propagates changes (independently of the
generated timestamps. If you are using the file monitor, then
tup detects any update to the files, not only a timestamp change.
o But yes, detecting changes based on hashes seems quite right, so
how is this a fallacy ? In fact, I would like tup to do this
instaed of using timestamps.
* Detecting changes via file hashes is never the right thing.
o Huh ?! This guy rants about everything... See above anyway.
* Nobody will ever want to rebuild a subset of the available dirty
targets.
o Tup allows you to rebuild only a given target. This is called
"partial update".
* People will only want to build software on Linux.
o Tup supports Linux, MacOS and Windows.
* People will only want to build software on a Unix derivative.
o Ditto.
* Nobody will want to build software on Windows.
o Ditto, again.
* People will only want to build software on Windows.
(Thanks to David MacIver for spotting this omission.)
o Ditto. This looks like a way to increase this list length. And
he seriously needed someone else to find this one... This guy
seems to lack imagination ;-).
* Nobody will want to build on a system without |strace| or some
equivalent.
o Well, the less features you have on the system, the less
features you can implement in the build system. To work
properly, tup needs at leas a way to trace file accesses. This
is done using fuse file systems, and there is an implementation
usinf LD_PRELOAD. An implementation using strace exists but was
deemed too slow.
o But anyway, what is this rant about ?
* |stat| is slow on modern filesystems.
o Huh ?! Well, okay, if this is a fallacy it means that stat is
not slow on modern file systems. How does this relate to build
systems ?
o Tup uses an algorithm whose asymptotic complexity is much better
than make, who looks at all the files in the filesystem. Doing
so is simply more powerful than reading all the files. Tup may
need to stat all the files to detect changes when you are not
using the monitor. In that case, it does not distrust stat ;-).
I am using tup on firefox, and stat'ing all the files for
changes was never slow.
* Non-experts can reliably write portable shell script.
o Well, no, of-course not. But you need't use shell scripts.
Firefox uses python scripts that are called by the build system.
No build system can force you to use a given language.
o Some build systems provide rules for usual operations (like
bazel for example). In that case, the rules are portable and
often better implemented than any other bash script. Tup is
minimalist in that regard: there are no included rules.
* Your build tool is a great opportunity to invent a whole new language.
o Well, it is. Configuration languages are much different from
imperative programming languages.
o Tup does indeed define its own input language.
o Tup has a very simple input language, and supports automatic
rules generation from other scripts. It should therefore not get
too much in the way.
o Also, tup supports lua bindings, so you can program your rules
in lua, and possibly in a ny other language if you want to write
the required bindings.
o Bottom line is that the primitives that tup uses are so simple
that you can easily bridge it with anything.
* Said language does not need to be a full-featured programming language.
o Well, I really believe that the build system does not need a
full-featured programing language. Where it the case, there
would be really no point in inventing a new language. Reusing an
existing one would be much better.
* In particular, said language does not need a module system more
sophisticated than |#include
<https://www.livejournal.com/rsearch/?tags=%23include>|.
o Some want a simple language, and some want a very rich one. Tup
provides a simple one, and you can script whatever you want, and
generate your Tupfiles however you want. This allows for simple
usage at first, and more complexity later.
o There are very rich build systems with a large set of modules,
and turing complete languages, and there is tup, with a basic
and simple specification language. Pick whatever you prefer.
there are hundreds of build systems, no one size fits them all!
* Said language should be based on textual expansion.
o No recent build systems does that (okay, this was written in
2012, but still). Really, no-one does that.
o Well, tup has a text expansion system, but tup is minimalist. If
you want flexibility, you should not use tup directly. either
generate them, or generate the Tupfiles.
* Adding an Nth layer of textual expansion will fix the problems of
the preceding N-1 layers.
o Tup has only one layer. Variables in variables are not expanded,
or are expanded at variable definition. You will never risk
entering an expansion hell with that ;-)
* Single-character magic variables are a good idea in a language that
most programmers will rarely use.
o This targets make directly, not programming languages in general.
* System libraries and globally-installed tools never change.
o This is out of scope for a build system, this is handled by
package managers. Nix handles that very well. A build system
describes how to build. If this changes, then it needs to be
updated. There will always be system library changes that
require an update to the build description.
* Version numbers of system libraries and globally-installed tools
only ever increase.
o Well, again, this is out of scope for the build system. Package
managers (pypi, nix, cargo, npm) are the right tools to handle
dependencies and version detection.
* It's totally OK to spend over four hours calculating how much of a
25-minute build you should do.
o No, it is not. The core idea of tup is to make this as fast as
possible. See the paper from Mike Shal, and the benchmarks on
the website.
* All the code you will ever need to compile is written in precisely
one language.
o Tup does not care about what needs to be compiled. But it is
true that if you use multiple languages you will need to write
different rules for each of these.
* Everything lives in a single repository.
o Well, this one is tricky. I would argue that this is the
distinction between build systems and packages managers.
Anything that handles multiple repositories, and their
inter-dependencies would be called a package manager (or a
dependency manager, which is the same, but often for only one
language). Because code that depends on another repo sees that
dependency as an external dependency, out of scope for the build
system of that repo.
o Tup does not really care about that if you use git submodules.
It will look at all the files, and all the tupfiles, and build
the current checkout. It will however not manage these different
trees by itself.
* Files only ever get updated with timestamps by a single machine.
o Change detection based on timestamps is a bit outdated, and this
is one of the reasons why it does not work well.
o I think that tup does not support distributed compilation. It
was not written to let multiple tup processes access its
database at the same time from different machines (over NFS for
example).
o Tup is definitely a single-machine build system. Distributing
build jobs across machines is still under active development in
bazel, and seems to work correctly in gradle (not too sure about
this one). It is an advanced feature that requires a lot of
engineering.
* Version control systems will always update the timestamp on a file.
o Tup requires that indeed, unless the monitor is used.
* Version control systems will never update the timestamp on a file.
o Tup also requires to not update the timestamp of unchanged
files. It will rebuild anything that depends on files with a
modified timestamp, even if the file is the same. Depending on
your point of view, this may be exactly what you want.
* Version control systems will never change the time to one earlier
than the previous timestamp.
o Tup does not care in that case. It detect timestamp changes, it
does not compare timestamps between inputs and targets.
* Programmers don't want a system for writing build scripts; they want
a system for writing systems that write build scripts.
o Huh ?! Depending on what you want, you want a complex and rich
build system specification language, or not. See above.
o But tup *is* a system to write build scripts. If you want a
system for writing Tupfiles, you need to write your own, or use lua.
-- Layus.
On 01/11/17 16:40, Eddy Petrișor wrote:
How many of these are applicable to Tup?
http://pozorvlak.livejournal.com/174763.html
<http://pozorvlak.livejournal.com/174763.html>
Please take this as constructive criticism.
Eddy Petrișor
--
--
tup-users mailing list
email: [email protected]
unsubscribe: [email protected]
options: http://groups.google.com/group/tup-users?hl=en
---
You received this message because you are subscribed to the Google
Groups "tup-users" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.
--
--
tup-users mailing list
email: [email protected]
unsubscribe: [email protected]
options: http://groups.google.com/group/tup-users?hl=en
---
You received this message because you are subscribed to the Google Groups "tup-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.