by ducaale on 3/14/22, 12:26 PM with 177 comments
by Steltek on 3/14/22, 1:51 PM
But I've lost track of the number of languages and environments that I've worked in. Make ties it together by being the Good Enough anchor point that documents and launches all the other tools and compilers.
- Compile this Rust app with Cargo then flash it to the esp32? Make.
- Build this page with JS using Tool Of The Week and push it to a test container? Make.
- Compile ancient C app and build a .deb? Make.
And so on.
Why not use shell scripts you may ask? Because shell scripts are way too free form and your tastes will change over time. Make forces just enough structure that you won't get carried away with yourself. Not for the basic task running stuff anyway.
by kall on 3/14/22, 4:34 PM
When I see a makefile, I expect they will be making more assumptions about my system and expect a little more work.
I do appreciate the "has worked fine for decades" aspect of makefiles, and I guess docker solves some of this, but I still prefer a fully self contained javascript project.
by nicoburns on 3/14/22, 1:24 PM
by gjvc on 3/14/22, 12:41 PM
An alternative approach for the "batches of files to process" situation is to generate the commands and feed them to GNU parallel for execution.
[1] no pun intended
by devn0ll on 3/14/22, 1:20 PM
https://www.thapaliya.com/en/writings/well-documented-makefi...
by k__ on 3/14/22, 2:58 PM
by btbuildem on 3/14/22, 2:55 PM
by BeefWellington on 3/14/22, 1:17 PM
I thought it was insane at first but actually I've come around to it; Make hits that sweet spot of being ubiquitous, simple, and flexible. There's a little bit of a learning curve but once you're over that initial hurdle it's pretty straightforward, especially for one-way operations, e.g. install without uninstall, build without clean, etc.
by Cthulhu_ on 3/14/22, 12:49 PM
The most complicated command I have is something that removes a folder or set of files, invokes the swagger generator with a list of options, copies it to a target folder, and passes it through a formatter/processor. But it's very straightforward, and it's "just" shell script, not shell script wrapped in a JSON document, or some Java tool invoked indirectly through an XML configuration file like back in the day with Maven.
by jgrahamc on 3/14/22, 12:31 PM
by WesolyKubeczek on 3/14/22, 1:26 PM
Use make for dependency graph, but also use "npm run" or "yarn run" to make sure you're running with the correct Node and correct paths to all your tools.
I know you can specify those in your Makefile too, but the plus of running via npm/yarn is that they know where your binaries live, where your mode_nodules are, and that sort of thing.
by boondaburrah on 3/14/22, 1:17 PM
Also, it's very strict about declaring dependencies properly, and will actually fail the build if you've set things up in a way that depends on something not tracked (by watching filesystem access as the compiler runs). That gives me warm fuzzies that my builds are reproducible.
Also I can get a neat dependency graph as a PNG if I want.
by rbongers on 3/14/22, 3:05 PM
On some projects I've worked on, it's been used as basically a command alias system that only a few people can maintain. None of its caching or dependency chain capabilities were utilized.
In these cases, shell scripts would have been a better option, and in some cases were later introduced with success.
by synergy20 on 3/14/22, 2:17 PM
cmake can help portability across OSes but it has a layer of its own complexity, I mostly work on linux alone, makefile seems more than enough.
google etc produces new tools to build its huge code base but I don't have that large scale source code, makefile so far worked well for my scale.
unless you have specific needs I feel makefile will do just fine. it's simple, readable, manageable, and get the job done fast.
by mark_l_watson on 3/14/22, 1:40 PM
by spion on 3/14/22, 6:44 PM
- turborepo (https://turborepo.org/) can describe dependency pipelines and provide automatic caching. Makefiles aren't designed for multi-input, multi-output scenarios - its really awkward: https://www.gnu.org/software/automake/manual/html_node/Multi... and https://stackoverflow.com/questions/39237306/makefile-compil...
- turborepo can also run never-ending targets in parallel (e.g. API server and static file server in development mode). Not sure how well make supports that
- turborepo can depend on env var values. Makefiles can to, but like everything with makefiles, its an awkward workaround: https://stackoverflow.com/questions/14840474/make-target-whi...
- makefiles do not work on Windows (They are portable, just not to platforms most node devs care about)
- Its unclear whether `make` will ever add features to remove the awkwardness for supporting the various scenarios above. It doesn't seem likely to happen.
by the-alchemist on 3/14/22, 3:13 PM
* parallelism
* hooks (before/after each task, etc.)
* command-line arg parsing
* --help equivalent
* bash/zsh/fish autocompletion
* you can also just spawn a shell with bb/shell
* yes, dependencies
* regular programming language (Clojure), with commonly used shell functions like glob()
* import code from locations (don't need to copy/paste between Makefiles)
* built-in JSON and CSV support, so you can use your app's JSON files right in your build file
by andrew_ on 3/14/22, 1:41 PM
I like that the author isn't being authoritative, but there could be some additional due diligence. I ran the make-is-faster loose benchmark via PNPM and runtime was 0m0.022s for make and 0m0.012s for PNPM. If I care about those 10ms, PNPM is my horse. Yarn is a glacier compared to PNPM.
Another thing I would've liked to see comment on is the automatic pre and post paradigm that package.json "scripts" affords. The big three package managers all support pre and post, and it makes arranging "scripts" a breeze, it breaks down dependent steps into separate console output, and is generally easy to organize imho.
All in all a nice write up for folks who might not really like package.json "scripts" to begin with, or for those who'd rather not gain more granular insight into how "scripts" works, but I don't see this being the nail in the coffin case against them.
by mc4ndr3 on 3/14/22, 7:59 PM
Unfortunately, the shell commands that are typically setup in a Makefile, are rather unportable. They waste a touch of time and space. They can break in surprising ways.
For this reason, I try to write my build tasks in terms of the same programming language as the application language. For example, Grunt for JavaScript projects, Shake for Haskell projects, Gradle for Groovy projects, Rez for C/C++ projects, Dale for D projects, TinyRick for Rust projects, and Mage for Go projects. Leiningen for Clojure projects, SBT for Scala projects. Vast for shell projects.
Make, like Python, suffers from the appearance of simplicity, at the cost of long term maintainability. Ideally both the build system and the main application are compiled. That doesn't have to be a cumbersome process, but rather a guide to identify potential bugs sooner during development.
Make is my first choice for random projects, but only when better build systems are unavailable.
by Mister_Snuggles on 3/14/22, 3:58 PM
It's clearly an abuse of a build tool, but it's also a testament to make's incredible flexibility.
I've also heard of someone who replaced their Linux startup scripts (in the pre-systemd days) with make to speed up boot time. That's actually what inspired my batch schedule work.
by jitl on 3/14/22, 12:58 PM
What I learned from supporting Make and shell among a few different audiences is that most developers have no interest in how to write or maintain shell-like tooling. They forget or mess up quoting rules constantly, and eschew learning things and good design in these tools to a much greater degree than in their “normal” work in Java/Python/Ruby/Typescript/Golang.
For every POSIXly Correct HN Commenter (of which I count myself a member), there’s 100 regular software engineers who won’t read a `man` page on what $@ or $< mean in Make. I know that if I start writing a Makefile for $JOB, it’s gonna be me and that one guy who uses tcsh who are gonna maintain it and answer questions.
(Although for what it’s worth we don’t use package.json scripts either thank goodness. All our complicated build steps are typescript commands, and our glue is CI system YAML files.)
by ThePhysicist on 3/14/22, 4:19 PM
by SkyPuncher on 3/14/22, 2:49 PM
by aitchnyu on 3/14/22, 2:26 PM
by andreineculau on 3/14/22, 7:01 PM
As others have mentioned on this thread, the problem is not just "use Makefiles instead of package.json scripts", but quickly ending up with duplicate Makefile content and then supporting more than just one language. It's inevitable.
PS
for those that don’t know, npm’s “scripts” functionality as we know it today was not “designed”, but it was simply a byproduct.
First introduced as an internal functionality for lifecycle support https://github.com/npm/npm/commit/c8e17cef720875c1f7cea1b49b... on 1 Mar 2010
and later extend to run arbitrary targets https://github.com/npm/npm/commit/9b8c0cf87a9d4ef560e17e060f... on 13 Dec 2010
This is the entire design backstory https://github.com/npm/npm/issues/298 .
Needless to say that GNU Make’s equivalent (or any other build system) is not to be found in npm’s scripts.
by limonkufu on 3/14/22, 5:29 PM
The main advantage for us is it's same everywhere and it's agnostic to underlying technologies. (we are only supporting unix based environments and have guidelines to setup gnumake in macos). By using this way, we ensure that the general SDLC is same across different repositories and underlying tooling can change anytime without inducing a lot of refactoring
We are also using make targets to document themselves. How to use, what are other targets, variables you need to define etc. This makes it a powerful CLI app for us that can run and support many things.
For anyone interested: https://gitlab.com/ska-telescope/sdi/ska-cicd-makefile and the similar parsing method for self documenting makefiles: https://gitlab.com/ska-telescope/sdi/ska-cicd-makefile/-/blo.... We didn't know about magicmake that's linked here that does the similar thing
by yboris on 3/14/22, 8:02 PM
https://www.npmjs.com/package/nps
You can create a dedicated JS file (with comments and more!) that will house your scripts, which you can run by using "nps" instead of "npm" as a command.
by karmicthreat on 3/14/22, 1:27 PM
I kind of wonder what other "traditions" get passed around on a regional level?
by dncornholio on 3/14/22, 1:03 PM
I think make works well in combination with package.json, but not as a replacement. You can also do the same stuff in an NPM command (which just loads node code) that you could do in a makefile script.
by silves89 on 3/14/22, 12:49 PM
by JohnHaugeland on 3/14/22, 2:11 PM
That's a person who doesn't understand portability, tooling, or the need to stick to community norms. Everything about their library is going to be pure pain.
by jsz0 on 3/14/22, 5:11 PM
by nsonha on 3/14/22, 9:16 PM
by nwsm on 3/14/22, 5:36 PM
But as I have worked with less Windows developers over time, my projects have relied more on shell scripts and makefiles. I think the containerization movement has started to shift software development towards Linux-based tooling as well. As a cross-platform effort this is a bit ironic, but having overlapping developer experience and CI/CD tooling is pretty convenient when you're on a Unix kernel or WSL2.
However, much of the npm ecosystem and community are focused on frontend work that often does not involve infrastructure-related tooling. Without the absolute need for any OS-specific tools, and with the many composable crossplatform scripts in vogue already, package.json scripts make sense (until they get out of hand).
by molszanski on 3/14/22, 4:20 PM
People call this "self-documenting makefile".
It migrated with me from company to company, from project to projects. Through node, php, aws, docker, server management, cert updates, file processing and many many more.
by sigzero on 3/14/22, 1:31 PM
by davistreybig on 3/14/22, 3:08 PM
by efortis on 3/14/22, 6:38 PM
by changhanlee on 3/16/22, 1:33 AM
by tejohnso on 3/14/22, 2:56 PM
by ravenstine on 3/14/22, 3:29 PM
by mro_name on 3/14/22, 1:24 PM
by deepsun on 3/14/22, 1:40 PM