6 ms·
Rant incoming; I really don’t like Make for the common use-cases it is being used for in the modern day, such as the Golang ecosystem or in many cases: creatin
by dijit 4y ago
Rant incoming;
I really don’t like Make for the common use-cases it is being used for in the modern day, such as the Golang ecosystem or in many cases: creating docker files.
Make, at its core, is a tool that is meant to help you structure your dependencies for incrementally building things, but people use it as a glorified task runner simply due to the fact that it’s such a common build tool that it is nearly always installed if you have a development toolchain on your machine.
Go and docker already have incremental compilation built in, and docker doesn’t give definable artifacts so you can’t make other things depend on them either
It is a powerful tool, but the syntax is hideous and has more jagged edges than bash does, and we aren’t even using it in a way that justifies this. Makes me so frustrated for some reason.
Like everyone deciding to use a supercar to do farmwork.
- tyingq 4y agoAgree, though it can be handy for sort of non-standard dependency stuff. Like if you need to pull some thing with curl before a build, and you want "curl succeeded (exited zero)" to be a pre-requisite for that build. It's often less work to get a Makefile to do that than a script, or the make-like things that come with some other languages. Maybe not the best example, but if you have a project with several weird things like that, make is often easier.
- mongol 4y agoBut is there not a "minimal Makefile" type of subset that you can use that appears really clean and tidy? My Makefiles are super basic and are basically task runners. Perhaps there are traps I have not fallen into but I value that I can count on them working on whatever distro I run in 5 years time.
- assbuttbuttass 4y agoA shell script will also work in whatever distro in whatever years time
- kevin_thibedeau 4y agoA distro running a Busybox userland doesn't necessarily support the same command options as one running GNU or BSD.
- paulddraper 4y agoYeah, but Make is parallel+incremental. And can do what a shell script can.
- LeBit 4y agogo-task is a very good task runner. Better than “just" IMO. I am now using go-task with every project. Right after creating the gitignore, I create the Taskfile. https://github.com/go-task/task https://github.com/go-task/task
- leetrout 4y agoSecond time that has been mentioned today. I wish it wasn't YAML.
- fbdab103 4y agoYou were not kidding, I am not loving that syntax.
- dividedbyzero 4y ago> Better than “just" IMO. Could you elaborate on its advantages vs just?
- antipaul 4y agoThat's a fine opinion, but I haven't found a more widely available tool to describe a project "recipe", where project is written in one or more, of many possible languages * Snakefile -> requires installation * bash -> macOS is now ZSH. (Is bash a better choice than Make?) * python -> what if I'm not using python? What else is as "accessible" as Makefile? EDIT: formatting
- jjnoakes 4y agoThe Makefile is going to be running external commands, no? So you still have the same problem (what are those external commands written in?) - whatever the answer to that question is, your task runner could be written in as well, probably. At least, that's how I prefer to do it. A project that's heavy JS? Use a JS task runner. Heavy python? Python task runner. Heavy shell? And so on.
- alwillis 4y ago> A project that's heavy JS? Use a JS task runner. Trying to keep up with JS task runners for web projects is why I started using Make and haven’t looked back.
- jjnoakes 3y agoSure but if a developer already has a JS runtime and they don't have Make installed, you've added unnecessary friction to the development process. I hate JS as much as the next guy, but if I'm developing in JS, I use a JS task runner. Even a simple one. There's not much to "keep up with" IMO - they are quite easy to create and use, if the common/popular ones are missing features or move too fast for you.
- taeric 4y agoI have seen few hells as bad as "just use the target runtime for build."
- jjnoakes 3y ago
- Izkata 4y agoI use it as a task runner with dependencies in python projects. In particular, it checks requirements files against the virtualenv to see if anything needs to be installed/updated, then all the tasks depend on that. If you're up-to-date the task runs immediately, if you're not it'll update for you. > and docker doesn’t give definable artifacts so you can’t make other things depend on them either Similar to how old projects have "make configure" to do some initial setup before "make" actually builds the project, I've done stuff on occasion where something like "make check" would pull information out of a system and create timestamped files in a scratch/ directory. Then the normal "make" would compare those files to the codebase to see if the system needed to be updated. It is different from the first use I just mentioned, since you need two commands and it's not entirely automatic, but it's still simpler than checking each of the dependencies yourself.
- silverwind 4y agoI too use Make to install `node_modules` and `.venv`. It is very convenient never having to ask oneself "Is my node_modules up to date?" after pulling or switching branches. I'll just let Make figure that out.
- tpoacher 3y agoMake is great. But. In your specific case, you may also be interested to check out Luigi. https://luigi.readthedocs.io/en/stable/ https://luigi.readthedocs.io/en/stable/
- clintonc 4y agoTrue. I do, however, like having some of the amenities of a task runner without bringing in the "cruft" that's suited toward incremental builds. I like using Just (https://just.systems/ https://just.systems/) for those cases.
- evancordell 4y agoI have long held similar opinions on make, and I've recently started using mage[0] in more and more go projects and have been happy with the result. It's more task-oriented, the way people tend to write Makefiles with .PHONY rules, but it's all in go. It can be bootstrapped just with go too, and comes with some utilities to do make-like incremental builds if you need to. [0]: https://magefile.org/ https://magefile.org/
- emptysongglass 4y agoHow does it compare to Just?
- evancordell 3y agoI looked at both and came away thinking mage was more convenient for go-only projects. Just looked good and I would probably pick it for something that wasn't go-only (if make didn't make sense instead).
- tpoacher 4y agoCouldn't you have achieved this even more simply by using make with a go shell? Btw, from the linked page: > Makefiles are hard to read and hard to write. Mostly because makefiles are essentially fancy bash scripts with significant white space and additional make-related syntax. Wait what? What does bash have to do with anything? Mage may well be amazing, but it doesn't sound like this person knows make that well at all. Which makes me think they're simply trying to reinvent the wheel -- in 'go'.
- evancordell 3y ago> Couldn't you have achieved this even more simply by using make with a go shell? Make is still really about file to file transformations, and `go` already wraps up all of the behavior one would normally use make for. Plus you need make + a shell + go, vs. mage where all that's needed is go. I can't speak for the author, but I assume they're reacting to how Makefiles tend to be used in go projects and not how make works generally.
- paulddraper 4y agoHard disagree. GO_SRCS=$(shell find src -name '*.go' -not -name '*_test.go) GO_TESTS=$(shell find src -name '*_test.go') .PHONY: run docker-run: target/image.target docker run example .PHONY: integration-test integration-test: target/integration-test.target .PHONY: test test: target/test.target target/bin: $(GO_SRCS) mkdir -p $(@D) GOOS=linux-amd64 go build -ldflags='-s -w' -o $@ target/context.target: Dockerfile target/bin rm -fr $(@:.target=) mkdir -p $(@:.target=) cp Dockerfile target/bin $(@:.target=) target/image.target: target/context.target docker build -t example $(<:.target=) target/integration-test.target: target/image.target # TODO: test the docker image target/test.target: $(GO_SRCS) $(GO_TESTS) go test What is your better thing? (The answer is Bazel, but if you think Make is a "supercar".......)
- rgoulter 4y agoMost (all?) of your Makefile targets don't represent actual files to 'make'. You're using make to run a bunch of tasks, including where tasks may depend on other tasks having been run before. A task-runner tool like `just` is better suited to this task. https://github.com/casey/just https://github.com/casey/just `just` has some nice UX improvements over `make`. (e.g. doesn't require soft tabs, can list recipes out of the box, recipes can take command line arguments, supports .env files, can be run from any subdirectory).
- paulddraper 4y ago> Most (all?) of your Makefile targets don't represent actual files to 'make'. > You're using make to run a bunch of tasks, including where tasks may depend on other tasks having been run before. And the cool thing is....it works for both! It can represent an actual file (e.g. a compiled binary) or abstract result (e.g., a successful test).
- deleted 4y ago[deleted]
- therein 4y ago
- jimbob45 4y agoWhat’s your preferred alternative?
- zie 4y agoYou are correct that Make is being abused because it's common. Me, I'm going to keep abusing Make vs bothering to find something supposedly better, that will then inject dependency startup problems I'd rather avoid. Yes, abusing Make the way I and many others do is not the ideal use case, but it works just fine. It's good enough at being a task manager.
- Groxx 4y agoYeah. And it's wildly misunderstood too, so you get random people writing and running `make clean test` stuff that inherently disagrees with itself, which can do all kinds of nonsense if your system isn't normal/clean/running on Thursday. I do still use it for simple automation, because it's nice to have a language-agnostic way to do simple things. But once it grows beyond about a page of text it tends to become a real nightmare, and is nigh impossible for most people to help maintain... which is not at all helped by its absolute lack of clear best-practices or warnings when misconfigured, and poor meshing with many common systems (like source-modifying tools, e.g. gofmt). It doesn't help that every guide starts out with # so easy! thing: ./build thing When in reality you pretty much always need at least how this page ends, to be even slightly stable and maintainable: # The final build step. $(BUILD_DIR)/$(TARGET_EXEC): $(OBJS) $(CXX) $(OBJS) -o $@ $(LDFLAGS) # Build step for C source $(BUILD_DIR)/%.c.o: %.c mkdir -p $(dir $@) $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ # Build step for C++ source $(BUILD_DIR)/%.cpp.o: %.cpp mkdir -p $(dir $@) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ It's a horrifying bait-and-switch that a lot of people never fully learn their way through to the end.
- paulddraper 4y agoFYI if you care to, you can prevent `make clean test` by looking at `$(MAKECMDGOALS)`.
- Groxx 3y agoI have some copypasta that I stick in every makefile that has too many people abusing it blindly, yeah. It works but it's a real pain that there isn't a standard way to do it. Which is an immediate consequence of make being built to make things, not run tasks. So it goes.
- radiospiel 3y agoWhat's the problem with "make clean test"? A test target would have a test-build prerequisite anyways, so - clean out build artefacts - rebuild test builds - run tests sounds very much ok to me.
- gigatexal 4y agoI take the other side of this and find that it being so useful its use as a task runner just means make is really awesome. Even when “misused” it’s super useful. That being said I really do like this article. I want to learn how to use make properly.
- r0l1 4y agoI agree. That's why we use the small grml tool as task/command runner in all our projects. https://github.com/desertbit/grml https://github.com/desertbit/grml
- magoon 4y agoI always include Makefiles as a way of documenting useful (short) tasks for developers that are onboarding to projects. It gives them confidence in their ability to pick things up quickly. Whether or not they want to actually use make is up to them, but it’s one more thing they can reference.