An alternative I quite like is “just”. https://github.com/casey/just
Mk: A Successor to Make (1987) [pdf]
11–20 of 54 posts
Re: Mk: A Successor to Make (1987) [pdf]
#12Here’s another make alternative. You do not need to specify dependencies at all. https://www.usenix.org/conference/atc22/presentation/curtsin... (full disclosure: I am one of the authors)
Re: Mk: A Successor to Make (1987) [pdf]
#13Earlier quoted context omitted.
Plan 9’s mk isn’t really a radical departure from Make, it is more of an adaptation of it to the (decidedly non-POSIX) Plan 9 shell, rc, with modest extensions. One design mistake in make that mk fixes is variables in recipes: those are now passed as environment variables, with no prior substitution, so no more writing $$$$ to get the current PID in a recipe (and it’s written $pid in rc anyway). Unfortunately, mk inh…
Ohhh, passing variables as env vars is a good idea. That means things like "$foo" in a recipe just works even if 'foo' contains quotes.
Re: Mk: A Successor to Make (1987) [pdf]
#14Re: Mk: A Successor to Make (1987) [pdf]
#15Here’s another make alternative. You do not need to specify dependencies at all. https://www.usenix.org/conference/atc22/presentation/curtsin... (full disclosure: I am one of the authors)
There's also tup: https://gittup.org/tup/
> Make sure your source files are backed up, like in source control, or something. Tup is able to delete old files automatically, though it tries to prevent you from doing silly things like overwrite your hand-written C files. Still, it would suck if you got boned because tup has a bug or something. Hey, your hard disk can go at anytime, too.
This is unacceptable, no thanks, I build first (test) and then commit, not the other way around.
Re: Mk: A Successor to Make (1987) [pdf]
#16It seems to me that all build systems are just DAGs with syntactic sugar and functions. You could do away with build systems entirely if there were some Unix commands that manage an arbitrary DAG, where the state is kept out of band (in a file, in a database, etc) so you can operate on the DAG from any process. That way the shell (or any program, really) becomes your build system and you can compose any kind of logic…
Note that Nix doesn't use a shell to execute things, it uses raw `exec` calls (each .drv file specifies the absolute path to an executable, a list of argument strings, and a set of environment variable strings). Though in practice, most .drv files specify a bash executable ;)
Re: Mk: A Successor to Make (1987) [pdf]
#17It seems to me that all build systems are just DAGs with syntactic sugar and functions. You could do away with build systems entirely if there were some Unix commands that manage an arbitrary DAG, where the state is kept out of band (in a file, in a database, etc) so you can operate on the DAG from any process. That way the shell (or any program, really) becomes your build system and you can compose any kind of logic…
Yeah, well, it's a little bit more than that.
Two things come to mind that don't neatly fit the DAG mental framework:
- dynamically generated dependencies (e.g. when you compile a C++ file only to discover that it #includes something and therefore has a dependency on that thing, and therefore the DAG has to be updated on the fly). Creating them by hand is horribly tedious, and/or borderline impossible (#includes that #include other #include ad infinitum)
- reproducible builds, where a build system is capable of rebuilding a binary from scratch down to having not a single different bit in the final output assuming the leaves of the DAG haven't changed. A desirable feature that is darn near impossible to do unless you pair the DAG with something else.Re: Mk: A Successor to Make (1987) [pdf]
#18It seems to me that all build systems are just DAGs with syntactic sugar and functions. You could do away with build systems entirely if there were some Unix commands that manage an arbitrary DAG, where the state is kept out of band (in a file, in a database, etc) so you can operate on the DAG from any process. That way the shell (or any program, really) becomes your build system and you can compose any kind of logic…
> It seems to me that all build systems are just DAGs Yeah, well, it's a little bit more than that. Two things come to mind that don't neatly fit the DAG mental framework: - dynamically generated dependencies (e.g. when you compile a C++ file only to discover that it #includes something and therefore has a dependency on that thing, and therefore the DAG has to be updated on the fly). Creating them by hand is horribly…
- defining different build types (debug/release)
- optionally building and running tests
- incremental builds (detecting what has changed)
That doesn't necessarily run counter to the concept of a DAG, but the organizational structures to manage this is what makes the build system. Topologically sorting the dependencies isn't the hard part. That's why make isn't a build system. It is the generic DAG runner, but that's not sufficient.
Re: Mk: A Successor to Make (1987) [pdf]
#19Earlier quoted context omitted.
Ohhh, passing variables as env vars is a good idea. That means things like "$foo" in a recipe just works even if 'foo' contains quotes.
Actually it doesn't really solve the $$foo problem. If your make target has an inline shell script with a variable reference, is it referring to a make variable or a shell variable? Is it set in make? If not, what will make do with that variable reference in the inline shell - nothing? Make it an empty string? Keep the literal '$foo' string? And what if both make and inline script have the variable set but they need…
Re: Mk: A Successor to Make (1987) [pdf]
#20An alternative I quite like is “just”. https://github.com/casey/just
It makes it easier to come back to a project after a few weeks, because you don't have to remember the N commands you were using to iterate/test, you only have to remember the 'just' invocation.
For some reason, it feels like a more natural fit for this than 'make'