[HN Gopher] Using Landlock to Sandbox GNU Make
___________________________________________________________________
Using Landlock to Sandbox GNU Make
Author : jart
Score : 174 points
Date : 2022-08-07 13:30 UTC (9 hours ago)
(HTM) web link (justine.lol)
(TXT) w3m dump (justine.lol)
| skybrian wrote:
| One of the downsides of Blaze/Bazel is that the symlink tree adds
| indirection that makes debugging broken builds that much harder.
| This approach, while not very portable, seems like a win from an
| ease of use standpoint.
|
| (Also, at least internally, Blaze pretty much required Linux for
| the longest time anyway.)
| [deleted]
| djhaskin987 wrote:
| I wonder why there was no mention of simply contributing these
| 200 lines to GNU make proper instead of forking. Super cool
| though.
| jart wrote:
| That 200 lines doesn't include our pledge() implementation,
| which Make assumes is provided by the C library. Right now only
| Cosmopolitan Libc and OpenBSD have an unveil() implementation.
| It would take some thought to decide what the best approach
| would be for incorporating something like that into GNU Make.
| So I'm waiting on more feedback from the community and the GNU
| developers. Because upstreaming is totally something I'm open
| to considering.
|
| Also please consider that GNU Make supports so many ancient
| platforms, like DOS, QDOS, Amiga, Windows 3.1. When I forked
| GNU Make, the first thing I did was delete all that support for
| ancient defunct platforms to give me enough room to think about
| how to approach implementing this feature. I don't think I
| could have done this if I had to wade through all that code
| from the start. I'm doing this work just for fun and to help
| out, and coding is only fun when the code is clean.
| jonahx wrote:
| > and coding is only fun when the code is clean.
|
| I wish I could upvote this more than one time.
| dwheeler wrote:
| I'd like to see this upstream. It's okay if the functionality
| only works on some platforms... it would force fixing of
| makefiles, and all platforms would benefit from that result.
| brabel wrote:
| Very nice, this is almost exactly the kind of thing I wanted to
| have to create a higher level build tool (make files are IMO
| pretty terrible as a declarative language for building, but
| perhaps a good low level primitive to use to build systems like
| Bazel on top of). The only problem is the dependency on a fresh
| Linux feature (ported from OpenBSD if I understand correctly)...
| my ultimate goal was to have a Landlock thing that works on all
| OSs, but that may be really hard as not many languages abstract
| the file system away so that this can be implemented in the
| application-level (Dart has support for abstracting away the file
| system, and I was trying to use that, but it doesn't seem to
| support that kind of thing when running processes).
|
| I suspect this should also make things like Nix and Guix
| easier... or maybe lighter-version of them easier as you don't
| need to implement the build sandox anymore when building software
| if you use Landlock Make.
| ghoward wrote:
| Good work, but I'm afraid that this will not really catch on
| because it's not that portable. I also think that Bazel has the
| same problem; most of the sandboxing works only on Linux.
|
| Until something like this works on Windows, it won't get wide
| adoption. And it _is_ possible to do something like this on
| Windows.
|
| And personally, I would want to avoid the use of GNU make.
|
| Nevertheless, this is a step forward for those who _have_ to use
| GNU make.
| 3836293648 wrote:
| It _is_ portable. That 's the whole point of cosmopolitan
| binaries. Sure, there's probably a bunch of ugly hacks in
| cosmopolitan libc, but it works.
| ghoward wrote:
| Does Cosmopolitan's Landlocking work on anything besides
| Linux? By definition, that cannot be the case because
| Landlock is a Linux thing.
|
| Cosmopolitan is portable, yes, but this sandboxing is not.
| jart wrote:
| The Landlock Make binary runs on OpenBSD too, where it also
| supports sandboxing. But those are the only two platforms
| right now where it's fully-featured. As I mentioned in the
| article, the next logical step is to add FreeBSD support
| using jails. The other platforms, I'm not so sure about.
| Might have to do something like run the binary in a
| blinkenlights emulator to intercept the system calls of
| programs we didn't build ourselves. But it's kind of a moot
| point, since every platform supports spinning up a Linux
| thing that lets you build code. On Windows you have WSL. On
| Mac you have Docker. So I don't know why people are egging
| on with the portability angle. I mean, just having unveil()
| on Linux in addition to OpenBSD is HUGE! We've been waiting
| decades for this, and now it's finally here, thanks to
| Landlock!
| ghoward wrote:
| After having used unveil() in OpenBSD, I don't really
| agree that it's huge. Not until it's everywhere. In fact,
| that's the reason I'm egging on portability: until it's
| everywhere, it doesn't really matter, and all the world
| is not a Linux or an OpenBSD.
|
| And while WSL and Docker might exist on those platforms,
| they are still hobbled. They're both VM's, not native.
|
| Oh, and the other reason that unveil() is not huge is
| because it's _voluntary_ for programs that use them. That
| 's why using pledge() and unveil() for regular programs
| is not huge and never was.
|
| Sure, it can help you identify missing dependencies.
| That's great, sure. Your work here is good because any
| GNU Makefile can be sandboxed. That's good. That is
| actually _not_ voluntary for build scripts because they
| won 't usually unveil() things. That is a step forward,
| which is why I said that in my first comment.
|
| But the _real_ problem in build systems is making sure
| that build scripts and the software they build cannot do
| anything bad to machines. Look at all the protest malware
| with the Russia situation, as well as other instances of
| supply chain attacks. Using pledge() and unveil() can
| help with the build scripts problem, but not the actual
| software. Unless you patch yourself, which you can do,
| but that 's manual, and people aren't going to bother.
|
| And then there are the limits: on OpenBSD, they tell you
| not to unveil() just the paths passed on the command-
| line, at least last I checked. That's kind of dumb. I
| hope Cosmopolitan on Linux does not have that issue
| because that's a big limitation. It means, for example,
| that my `bc` cannot use unveil() until _after_ it
| processes the files given to it by the user, i.e., only
| when it starts reading from stdin. If that were not the
| case, I could have called unveil() as soon as all
| command-line arguments were processed.
|
| Anyway, the point is that yes, this is a step forward,
| for Linux, but we need an automated way of checking for
| supply chain attacks in software, not just builds.
| yjftsjthsd-h wrote:
| From a comment upthread:
|
| > Also please consider that GNU Make supports so many ancient
| platforms, like DOS, QDOS, Amiga, Windows 3.1. When I forked
| GNU Make, the first thing I did was delete all that support
| for ancient defunct platforms to give me enough room to think
| about how to approach implementing this feature.
|
| - https://news.ycombinator.com/item?id=32376870
|
| From https://github.com/jart/cosmopolitan#support-vector ,
| supported platforms are Windows, Linux, Mac OS X, FreeBSD,
| OpenBSD, and NetBSD, on AMD and Intel x86 processors. That's
| a large list, maybe large enough to become widely accepted,
| but GNU Make supports ... pretty much everything, ever.
| Darwin on ARM (probably the most important), NetBSD on MIPS,
| Solaris on SPARC, FreeBSD on POWER, Haiku, FreeDOS, HURD.
|
| Cosmopolitan is probably portable _enough_ and Landlock is
| probably portable _enough_ to catch on, but compared to
| make(1), it 's not _that_ portable.
| __float wrote:
| Bazel uses "sandbox-exec" on macOS, and has a more generic
| POSIX compatible sandbox if you can't use the Linux sandboxing
| tool too.
|
| > And it _is_ possible to do something like this on Windows.
|
| Are you able to point to any open source examples of this?
| Bazel supports Windows, and I'm sure they'd love to be able to
| support sandboxing on Windows as well.
| ghoward wrote:
| It can be done on Windows, but not how Bazel would want to do
| it.
|
| Basically, the sandbox has to be in the interpreter. And I
| guess I should be clear that it still won't be be as good as
| on Linux.
|
| By the way, what's this "POSIX compatible sandbox"? chroot?
| That's not POSIX compatible.
| __float wrote:
| What interpreter? Why do you assert that it's "not how
| Bazel would want to do it"?
|
| No, it's not chroot -- it uses a tree of symlinks, created
| specifically for each process being run, that assumes the
| process isn't trying to escape the 'sandbox' too much.
|
| At the end of the day, a _strong_ sandbox is going to
| require some OS-specific support, and this could be seen as
| a kind of graceful degradation when there's not a better
| OS-provided sandboxing tool.
|
| (As an aside, your comments seem rather combative and I
| don't really understand why; we can discuss the merits of
| this tool without declaring it'll never catch on and won't
| _do enough_ for your standards.)
| ghoward wrote:
| Why do my comments seem combative? All I said was
| basically good job, but it will unfortunately not be used
| much. Why is that combative?
|
| With regards to chroot, I stand corrected. I knew it was
| a tree of symlinks, but I thought it was also more than
| that because symlinks alone don't seem like a sandbox.
| Honestly, Cosmopolitan's system appears to be more of a
| sandbox than that.
|
| I agree that a strong sandbox is going to require OS-
| specific support as of right now. I do have ideas for
| implementing sandboxes without it, but it requires
| putting the sandbox into the interpreter. And I could be
| completely wrong that the interpreter would do a good
| enough job.
|
| And this is what I mean by interpreter: Bazel has a
| language. I think it's called Starlark. To make that
| language useful, it needs some interpreter. That
| intepreter might just be reading the language and
| building a dependency tree, but my point is that it could
| do more, including checks.
|
| Perhaps my assertion that Bazel would not want to do it
| that way is not fair, but I said that because Bazel's
| method of sandboxing is different, and I suspect that
| they would not want to refactor their Starlark
| interpreter. That's all. They certainly could, and I
| would encourage them to. So I could be wrong, and I would
| eat my words in that case.
| mastax wrote:
| > but my point is that it could do more, including
| checks.
|
| Could you explain more how you see this working?
|
| For example: the build system is running a build step. It
| has determined the inputs and the outputs for that build
| step. It is going to execute a subprocess for that build
| step (say, GCC). It wants to ensure that GCC doesn't
| accidentally depend on files other than thaie that the
| build system knows about. How can that functionality be
| implemented with checks in the build system interpreter?
|
| I suppose it could run the process with something strace-
| like and monitor which files it accesses but isn't that
| just a way of implementing a sandbox? I'm not sure what
| you mean exactly.
| ghoward wrote:
| The best way to do this is best described in the thesis
| that Eelco Dolstra wrote describing Nix. I suggest you
| read that.
|
| tl;dr: Clear the environment, know where all of the
| system headers are, control the build environment of the
| dependencies. Basically, knowing dependencies means
| controlling them.
|
| But to expand on that, an interpreter could do some basic
| checking like:
|
| * Does the command reference a path that the build system
| doesn't know about?
|
| * Does the build system know where the executable is for
| the command, and is it well-known?
|
| Things like that.
|
| It won't be perfect, but it would be better. And it can
| get better with time.
| gray_-_wolf wrote:
| This is definitely interesting and cool, however:
|
| > Landlock Make can build code five times faster than Bazel,
| while offering the same advantages in terms of safety. In other
| words, you get all the benefits of a big corporation build
| system, in a tiny lightweight binary that any indie developer can
| love.
|
| In terms of safety, maybe almost (bazel can check if the source
| files changed during the build, this (afaict) can not). But bazel
| also provides a lot more (caching, remote builds, ...). So, while
| cool, read more on it and evaluate it in depth before deciding to
| replace bazel with this.
| jart wrote:
| One of the nice things about Bazel that the article didn't get
| a chance to go into is it uses SHA hashes of files, rather than
| file timestamps, to determine when an artifact has changed and
| therefore needs to be updated. It's slightly more costly to
| compute hashes, but it's necessary if you want to have
| something like a global cache of build artifacts, since
| synchronizing time across machines is hard.
|
| What I'd recommend for anyone really, is to just do what Google
| did. For the first six years of Google's lifecycle, they got
| along just fine with GNU Make. Then they switched to the huge
| scalable thing once they actually reached that inflection
| point. I'm obviously not there since I'm just a scrappy open
| source coder. So for me I'm quite happy to be working with GNU
| Make and I can foresee myself getting many additional years of
| use out of it.
| gravypod wrote:
| > What I'd recommend for anyone really, is to just do what
| Google did. For the first decade and a half of Google's
| company lifecycle, they got along just fine with GNU Make.
| Then they switched to the huge scalable thing once they
| actually reached that inflection point.
|
| Hopefully as a community we can build things that are
| scalable and as-simple-as Make. I think please.build is a
| step in the right direction but still too complicated.
| chubot wrote:
| Eh Make is not good for most problems -- see experiences
| here by dwheeler, me, frankohn:
|
| https://news.ycombinator.com/item?id=32301606
|
| And this other thread I linked there, with feedback from
| FreeBSD engineers:
|
| https://lobste.rs/s/7svvkz/using_bsd_make#c_bfwcyc
|
| ---
|
| Ninja basically gives you the parts of GNU make that are
| good, without the cruft and slowness. And you can learn it
| in 20 minutes, unlike GNU make
| [deleted]
| gravypod wrote:
| (Opinions are my own)
|
| > Eh Make is not good for most problems
|
| Agreed. I spend a lot of time advocating for Bazel for
| this reason.
|
| > Ninja basically gives you the parts of GNU make that
| are good, without the cruft and slowness. And you can
| learn it in 20 minutes, unlike GNU make
|
| Ninja seems more like a side-grade than a wholesale
| improvement. It does not fix all the problems that need
| to be addressed. Compare the two:
|
| * https://ninja-
| build.org/manual.html#_philosophical_overview
|
| * https://bazel.build/start/bazel-intro
|
| Right now Bazel's biggest issues are:
|
| 1. Getting started is difficult: There is a lot of
| impedance mismatch across various language toolchains.
| This can be fixed over time by improving the
| tooling/libraries/docs. If JetBrains had a "New Bazel
| Project" and had a way to 1-click-add
| Java/Python/Ruby/golang/Rust/etc source into
| //third_party with BUILD files and a version of
| build_cleaner Bazel would win. Just making it easy to
| vendor libraries and build software from the IDE is I
| think all it would take to get popular.
|
| 2. The JVM: I am a huge fan of Java (I've build multiple
| company's backends in it) but it is not a great choice
| for CLI tooling (even with a daemon). A no-dependency,
| small, build system executable would go a long way to
| making it easy to get people started.
|
| 3. The cruft: A lot of things in Bazel are the way they
| are because someone had to get a feature out ASAP to
| support $BIG_USER to do $BIG_THING and it would be too
| difficult to migrate away/to something at Google. If we
| drop the cruft and redesign things from the ground up we
| can get a nice abstraction for the world. For example,
| please.build's proto_library is VERY easy to use (way
| easier than even the Google internal versions imo).
|
| 4. The tooling: You can get massive CI improvements, free
| mutation testing, frameworks for build (integration
| tests, e2e tests, etc), and much more by building things
| against the Bazel API. Unfortunately not much outside of
| Google supports this API. Example of things you can do
| with this API: https://kythe.io/examples/#extracting-
| compilations-using-baz...
|
| We could live in a world where people can build langauge-
| agnostic tooling that automatically works so long as you
| pass it a `*_binary` target that transparently builds for
| all major platforms (zig's or APE's as crosstool) which
| would allow platform vendors to define macros to
| completely automate deployment and development for their
| systems. For example we could have:
|
| ``` from aws import lambda
|
| lambda.package( name = "my_api", deps = [":api_handler"],
| ) ```
|
| And just by running `build :my_api` you could have a zip
| file which packages your code (from any language) into a
| lambda.
| tux1968 wrote:
| > Ninja basically gives you the parts of GNU make that
| are good, without the cruft and slowness. And you can
| learn it in 20 minutes, unlike GNU make
|
| Are you suggesting it's easy to learn how to hand code
| Ninja files, or do you have a different easy-to-learn
| tool to generate them, in mind?
| dwheeler wrote:
| GNU make is great for many things, used correctly. The
| problem is that POSIX make is extremely impoverished, so
| sticking to just the POSIX subset is often a bad idea. In
| many cases using "make" should really mean using "GNU
| make" so you can use conditionals, automated
| dependendency generation (via reloads of dependency
| info), etc.
| zvr wrote:
| (GNU) Make _by default_ uses the file change timestamp to
| trigger actions. But this is definitely not the only way, and
| you can code your Makefile so that rebuilds happen when a
| file 's checksum changes. IIRC, the GNU Make Book has the
| code ready for you to study...
|
| Or, you might get more clever and say "when only a comment is
| changed, I don't want to rebuild"; file checksums are not the
| correct solution for this, so you can code another trigger.
| jeffreygoesto wrote:
| SCons [0] uses something similar (MD5 instead of SHA) since
| the end of the 90es, so at least that aspect is not a Google
| invention. The cache there is local though. We never had
| flaky builds with it and could extend it very nicely,
| unfortunately it was not very fast.
|
| [0] https://en.m.wikipedia.org/wiki/SCons
| chubot wrote:
| _For the first decade and a half of Google 's company
| lifecycle, they got along just fine with GNU Make_
|
| ??? Google was started in 1998, and Bazel was created ~2006
| as a replacement for Python + GNU Make ("gconfig"). I was on
| that team, though I only worked on Blaze a tiny bit. The
| "google3" build migration was sometime around 2003 or 2004.
|
| So at most there were 6 years of using Make only, i.e.
| "google2".
|
| Importantly, pre-Blaze google3 wasn't just GNU make -- Python
| was a huge part of it, which is why the Bazel build language
| Starlark looks like Python. It used to literally be Python,
| and now it's a Python-like language with parallel evaluation.
|
| ---
|
| If you want to do what "scrappy Google" did these days, then
| you should use Python + Ninja. Ninja is meant to be
| generated, just like GNU Make was generated by Python. (A big
| difference is that GNU make has a big database of built-in
| rules that basically do nothing but slow down incremental
| rebuilds.)
|
| I described that strategy a bit a few days ago:
| https://news.ycombinator.com/item?id=32307188
|
| ---
|
| This work with Landlock looks very cool, and it would make a
| lot of sense for Ninja to have optional support for it. Some
| of the caveats are a bit scary but hopefully that can be
| worked out over time.
|
| The way I was thinking of doing it was just to have a
| ./NINJA_config.py --slow-sandbox mode. So you can use any
| sandbox to warn you about missing dependencies, including
| something container-based like bubblewrap, symlink farms, or
| Landlock. I think that would work, though I haven't tried it.
| The shared library issue is tricky, etc.
|
| It's very useful to have the build config / generator split
| for this reason, and many others (e.g. build variants go only
| in the first stage, not the second).
|
| I wrote 3 substantial GNU makefiles from scratch and
| regretted it largely because it lacks this split -- it has a
| very tortured way of doing build "metaprogramming". IIRC one
| dimension of variants was OK, but 2 got you into the "write a
| Lisp in Make" territory. Might as well use Python (or Lua,
| etc.)
| jart wrote:
| I wouldn't say it's scary. There's always been full
| transparency with the caveats and they're being lifted
| incrementally.
| https://twitter.com/l0kod/status/1556378406983458818 The
| workarounds are perfectly reasonable. Also take into
| consideration that Landlock is so simple as a security
| tool, that it really opens itself up to people like us
| being able to focus in on the opportunities for
| improvement. A lot of security stuff, like containers, is
| so byzantine that no one would enjoy having open
| discussions about their design. Landlock has felt different
| to me, simply because we are having these conversations,
| and it's been so engaging that it really makes me want to
| believe in Torvald's whole mythology about the many
| eyeballs.
|
| Email me if there's anything I can do to help Ninja adopt
| Landlock. The Cosmopolitan Libc pledge() and unveil()
| implementations are written to be relatively easy to
| transplant into other codebases. I'd love to see a broader
| audience benefiting from our work.
| dima55 wrote:
| I don't disagree with anything you said, but I think it's
| important to point out that your experience is unique in
| that you're talking about build infrastructure for a
| massive codebase: most of Google's internal stuff, right?
|
| In my experience plain GNU Make works great until you start
| working with massive projects. Similarly, the ninja speed
| improvement: you just don't see it unless you have a truly
| massive project, or you're using low-quality Makefiles,
| like what CMake produces. I've measured; I can't see it. I
| have many medium-sized projects, all with simple Makefiles,
| and it works really really well. I'm pretty convinced at
| this point that this should be the way to go for most
| projects out there.
| ErikCorry wrote:
| I like the speed of Ninja, and the flexibility of having a
| stage that generates the ninja (or make) files. But it's a
| bit unclear to me what the best practice is for when to
| generate the ninja files. It feels like the programmer is
| expected to do this stage manually and there's no great
| automatic way to generate the ninja files when they need to
| be generated. How do good build systems solve this?
| avar wrote:
| I wrote 3 substantial GNU makefiles from scratch
| and regretted it largely because it lacks this
| split -- it has a very tortured way of doing build
| "metaprogramming".
|
| GNU make definitely still has a lot of rough edges, but
| parts of your comment seems as though you're making claims
| about it that haven't been true in a decade or more.
|
| For one, you don't need to "write a Lisp in Make", it has
| Guile built-in now (but probably didn't when you were
| actively using it):
| https://www.gnu.org/software/make/manual/html_node/Guile-
| Exa...
|
| There's quite a few small things about modern GNU make that
| make it easier to use for meta-programming than it was even
| just a decade ago. It still has a lot of rough edges that I
| wish it didn't have though.
| jchw wrote:
| I will chime in in agreement with you, since the replies
| here are mostly to the contrary. Writing Makefiles by hand
| sucks eggs.
|
| It's really worse than this because this probably assumed a
| specific Linux setup at least, but everything goes out the
| window once Windows is in the mix. If having to deal with
| potentially multiple shells was a problem with Make, having
| to deal with multiple shells on Windows (where it could be
| CMD, PowerShell, or a UNIX like shell under MSys or
| Cygwin...) is untenable.
|
| Today the only obviously valid reason to use Make is
| because you have to or already are. Most Linux distros ship
| Ninja. Hell, MSVC ships Ninja.
|
| There are many examples of Makefiles for open source
| projects that validate how ugly things can get without
| needing to be Google scale. One of the most elegant
| Makefile setups I can think of is Near's setup for
| bsnes/higan,and honest to goodness, it's still a pretty
| horrific mess.
|
| I don't want to be hyperbolic, but also it's irresponsible
| for people to suggest you should just use Make. You
| shouldn't just use Make. Not even as a beginner. If you
| wanted a nice turnkey solution for a beginner, I'd suggest
| CMake or Meson, both of which happily generate Ninja files
| and also have the bonus of supporting Windows well. CMake
| has broad ecosystem support, despite it's many
| shortcomings. It's far from elegant, but definitely
| practical.
| jart wrote:
| That's Windows' problem and it's not even a real problem
| anymore because make runs fine in WSL. Microsoft has
| pretty much gotten their act together in the last four
| years in supporting open developer tools. They've got
| bash and ANSI support. It's great. Give them credit where
| credit is due. It's time to say goodbye to shoehorning
| unix devops into win32. Doing that gets sillier each
| year. Especially since, as Microsoft has been generous in
| supporting tools, they've certainly been boiling the frog
| with their win32 environment. The last time I extracted a
| zip file containing dev work on Windows, it extracted at
| 64 kilobytes per second to the local hard drive, because
| their virus technology was scanning and uploading
| everything I was doing. How can you build software in
| that kind of environment? And why is it that it's always
| the voices coming from our own community who insist that
| we should. People shouldn't fall that far in love with an
| operating system because even with perfect support,
| builds are still going to go slow on Windows. Use WSL.
| BiteCode_dev wrote:
| This comment is a plug.
|
| I've tried many alternative to make over the years, and
| eventually, doit (pydoit.org/) was the one I sticked with.
|
| It's declarative yet dynamic, it's simple yet powerful, you get
| to use shell command or a custom function, and it deals with all
| the things you need like deps and targets, creating a dag,
| caching, etc.
|
| It's the sweat spot for me.
| spockz wrote:
| The only thing I'm really missing for my usecase with make is the
| ability to specify goals/targets other than files. E.g., I want a
| docker image to be present in the daemon. Basically, calling out
| to a function. (Probably somebody is going to correct me and say
| there is something there in the form of conditionals or
| something..)
| Toaster-King wrote:
| Wow. Strange seeing something I helped with on the front page of
| HN[1]. Thanks for the shoutout Justine!
|
| [1] https://github.com/jart/cosmopolitan/pull/490
| ezekiel68 wrote:
| I want to like this (and I do). It just feels like yet another
| perfectly wonderful tool that only 1000 other people in the world
| (besides me) will use.
|
| Not really sure why that even bothers me.
| now wrote:
| Could you please explain the `o//` "convention"?
| mtlmtlmtlmtl wrote:
| Justine is one of my fav contemporary hackers. Whenever I see her
| stuff posted on here, not only am I amazed that anyone did what
| was done, but even more amazed that one person did it all on
| their own.
|
| Justine, if you're reading this, keep up the amazing work!
| [deleted]
| marcodiego wrote:
| I hope landlock brings a simple unveil and pledge.
| elteto wrote:
| Very interesting and impressive technically but the post took a
| dive towards the end with the anti-Java rant.
|
| We can celebrate our work without having to stand on a platform
| made by bashing the work of others.
| sneak wrote:
| That was no rant or bashing, it was short, accurate, and
| directly relevant to the primary topic of the article.
| sophacles wrote:
| This is pretty cool! I have a habit of using Makefiles to
| automate a lot of things that aren't really build systems (it
| just maps nicely to how i think of a lot of problems - the whole
| target + dependency graph concept is powerful). While I'm
| positive that this work is great for build system stuff too, this
| will certainly also help solve some problems I've created for
| myself in the past - namely accidentally acting on files I didn't
| intent to.
| ndriiu- wrote:
___________________________________________________________________
(page generated 2022-08-07 23:00 UTC)