Live data from Hacker News

Mk: A Successor to Make (1987) [pdf]

doc.cat-v.org

11–20 of 54 posts

Re: Mk: A Successor to Make (1987) [pdf]

#11

An alternative I quite like is “just”. https://github.com/casey/just

Just isn't really a replacement for make outside of the "simple command/task runner". Make is really a lot more powerful and has things like files system driven dependency handling.

Re: Mk: A Successor to Make (1987) [pdf]

#13
post #5

Earlier 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.

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 to be different?

Re: Mk: A Successor to Make (1987) [pdf]

#14
It 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 that requires walking or manipulating a tree of dependencies. This could apply to anything where you need to execute arbitrary jobs with a DAG, not just builds.

Re: Mk: A Successor to Make (1987) [pdf]

#15
post #8

Here’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/

From https://gittup.org/tup/getting_started.html

> 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]

#16

It 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…

Nix represents its builds in a way that's similar: each "derivation" is a text file like /nix/store/XXXXXXX-foo.drv, where XXXXXX is a hash of that file's content. This way each file can reference any others by their path, and there can never be cycles (unless we brute-forced SHA256 to find a pair of files which contain each others hashes!). This uses of hashing requires the files to be immutable, but that's good for caching/validation/reuse/etc. anyway.

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]

#17

It 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 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]

#18

It 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…

- detection/management of external dependencies

- 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]

#19
post #5

Earlier 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…

It does solve the $$foo problem in that mk just doesn’t do any variable substitution in recipes, at all. For each invocation of a recipe, it adds the values of mk variables it has computed to the parent environment, then execs a shell and passes it the entire recipe verbatim.

Re: Mk: A Successor to Make (1987) [pdf]

#20

An alternative I quite like is “just”. https://github.com/casey/just

I've been using 'just' for running a set of commands that I can't be bothered to remember.

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'

Post reply on HN