[HN Gopher] Mk: A Successor to Make (1987) [pdf]
___________________________________________________________________
Mk: A Successor to Make (1987) [pdf]
Author : SllX
Score : 62 points
Date : 2023-07-16 09:03 UTC (13 hours ago)
(HTM) web link (doc.cat-v.org)
(TXT) w3m dump (doc.cat-v.org)
| vmsp wrote:
| For those curious, Mk is available in Plan 9 from User Space
|
| https://9fans.github.io/plan9port/
| jacobvosmaer wrote:
| I tried plan9port's mk for a moment out of curiosity. I quickly
| ran into an annoying usability problem: it compares file mtimes
| with second accuracy.
|
| https://github.com/9fans/plan9port/blob/cc4571fec67407652b03...
|
| With sub-second build times for individual targets, this causes
| mk to needlessly recompile files because the target may have
| the same mtime as the prerequisites.
| raddan wrote:
| 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)
| imran-iq wrote:
| There's also tup: https://gittup.org/tup/
| nmz wrote:
| 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.
| vimax wrote:
| I agree with you about that statement, but why don't you
| commit to an unstable branch? Why risk losing something or
| pass up having a better development history?
| nemetroid wrote:
| The way the warning is worded suggests that any
| invocation of tup has a risk of deleting your files,
| implying that to be entirely safe you should commit
| _before every single build_ , which would be ludicrous.
| [deleted]
| jylam wrote:
| Funny how building tools are reinvented again and again, with all
| the same culprits. I'm a programmer since the mid-90's, there are
| countless tools to do the job, and they are just as cumbersome
| and complicated the more they evolve. I'm personally sticking to
| the good old configure/make for my own C projects, but I
| understand that's a matter of taste and habits. I've written some
| CMakeLists.txt from time to time, anything you want to do
| requires some digging in some sort of stackoverflow answers
| (thanks to those who answer) for "not so common but yet I need
| them" weird features.
|
| I'm not criticizing anyone or any tool, just that we can't seem
| to find some good way to tool the compilation of both trivial and
| very complex projects, without taking an hour or two off.
|
| I also understand that I do _not_ want to work on such an
| endeavor, that seems boring AF and kudos for people that like
| that. You are not enough it seem :)
| mananaysiempre wrote:
| 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 inherits from rc the principle of having the
| list of strings as the fundamental datatype (also used by Jam).
| That works, but it's noticeably more limiting than Tcl's route
| of having everything be strings but with robust quoting and
| unquoting procedures for putting lists inside them--at which
| point Tcl starts to look like a Lisp-2 with a slight propensity
| for stringiness and a mildly unusual syntax.
| mort96 wrote:
| 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.
| throwawaaarrgh wrote:
| 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?
| mananaysiempre wrote:
| 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.
| gigatexal wrote:
| I like the simplified syntax of this mk, anyone know why it
| didn't catch on?
| adamgordonbell wrote:
| Here is my silly alternative. You just write bash, with
| preconditions and annotations to describe what can run in
| parallel.
|
| https://github.com/adamgordonbell/job-runner/blob/main/tests...
| throwawaaarrgh wrote:
| 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.
| duped wrote:
| Programs are just DAGS with syntactic sugar
| kdmccormick wrote:
| Not sure I follow. 0001 GOTO 0002 0002
| GOTO 0001
|
| How would that be a DAG?
| mananaysiempre wrote:
| > It seems to me that all build systems are just DAGs with
| syntactic sugar and functions.
|
| True in the broadest sense, but there are choices to be done
| regarding the possibility of discovering what the graph is or
| has become on the fly and the propagation directions. See
| "Build systems a la carte"[1,2] for a systematic exploration.
|
| (See also a neighbouring comment[3] re how the discourse
| structure[4] of the build script might be important in a way
| orthogonal to these execution-engine issues. The boundary
| between the build system and the build tool proper can be drawn
| in very different places here.)
|
| [1] https://dx.doi.org/10.1145/3236774
|
| [2] https://youtu.be/BQVT6wiwCxM
|
| [3] https://news.ycombinator.com/item?id=36749885
|
| [4] https://brenocon.com/blog/2009/09/dont-mawk-awk-the-
| fastest-...
| wahern wrote:
| > if there were some Unix commands that manage an arbitrary DAG
|
| There is: tsort. It's a POSIX utility, even, not just a GNU or
| BSD utility.
| chriswarbo wrote:
| 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 ;)
| klysm wrote:
| I didn't realize that content addressing girls like that
| prevented circular deps by construction (with very high
| probability). That's a super cool property to get as a bonus
| ur-whale wrote:
| > 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.
| mike_hock wrote:
| - 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.
| ripe wrote:
| I like simple Makefiles. Keeping them POSIX compliant makes them
| portable, including on cygwin-type environments on Windows.
|
| I used this tutorial:
|
| https://nullprogram.com/blog/2017/08/20/
| TheLocehiliosan wrote:
| An alternative I quite like is "just".
|
| https://github.com/casey/just
| dimator wrote:
| 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'
| DanHulton wrote:
| Was going to mention this. I've recently started converting my
| Makefiles to justfiles, and it's just nicer. Even being able to
| inline scripts to clean up "loose" files is a big win.
| packetlost wrote:
| 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.
| zokier wrote:
| Of course that is the whole point of just, to be simpler and
| more focused tool because a task runner is what people
| commonly want and the bloat/complexity of make is more of
| hindrance. This is clearly mentioned in the readme too
|
| > just has a ton of useful features, and many improvements
| over make:
|
| > * just is a command runner, not a build system, so it
| avoids much of make's complexity and idiosyncrasies. No need
| for .PHONY recipes!
___________________________________________________________________
(page generated 2023-07-16 23:00 UTC)