4 ms·
Just is fine, don't get me wrong. But Make targets can take arguements too. They just have to be named, or (if you stretch the definition a bit) wildcard target
by nrclark 2y ago
Just is fine, don't get me wrong. But Make targets can take arguements too. They just have to be named, or (if you stretch the definition a bit) wildcard targets.
AFAIK, Just doesn't have any way to mark "this task is complete, so don't re-run it". It also doesn't have file-based dependendicies, which are pretty common for any kind of programming.
Why would I want to lose all of Make's flexibility and power in exchange for slightly prettier UI syntax?
- frankjr 2y ago> AFAIK, Just doesn't have any way to mark "this task is complete, so don't re-run it". It also doesn't have file-based dependendicies, which are pretty common for any kind of programming. That's fair but also not what I'm looking for in a task runner, that's why I explicitly said "not a build tool", which to me this falls under (although I realize everybody has a different definition of these terms and where they draw the line if at all).
- maccard 2y agoI think this post is well intentioned but misses the point entirely. GOOS=darwin GOARCH=arm64 go build -ldflags="-X 'main.Version=v1.2.3'" Executing this with variables for os/arch/version is not straightforward in a makefile. You might argue that it's a flaw with the `go build` command, but replace go with cargo/dotnet/maven and you have the same problem. > AFAIK, Just doesn't have any way to mark "this task is complete, so don't re-run it" What does a makefile look like for "install this list of dependencies with pip/homebrew/apt, and don't run it twice?" > It also doesn't have file-based dependendicies, which are pretty common for any kind of programming C and C++ compilers at this stage are the only places that I work with file based dependencies. Unless you explicitly declare all the headers as dependencies in a makefile, make won't rebuild a cpp file if you change a header. IME ninja (plus cmake to generate it) has entirely superseded make in this space. Tools and languages comes with it's own build tool (see above - go/cargo/dotnet/etc) or state tracking (docker) that break make's assumption of file based dependencies. > Why would I want to lose all of Make's flexibility and power in exchange for slightly prettier UI syntax? Because every make file I've ever used in recent memory has been 30% workarounds to avoid file based dependencies, and work around subtle footguns that make has, rather than actually doing what I want it to do - execute a build command.
- jgrahamc 2y agoI think this post is well intentioned but misses the point entirely. GOOS=darwin GOARCH=arm64 go build -ldflags="-X 'main.Version=v1.2.3'" Executing this with variables for os/arch/version is not straightforward in a makefile. You might argue that it's a flaw with the `go build` command, but replace go with cargo/dotnet/maven and you have the same problem. What makes that hard? I think the following works correctly: $ cat Makefile goos := FOO goarch := BAR mainversion := BAZ .PHONY: build build: ; @GOOS=$(goos) GOARCH=$(goarch) go build -ldflags="-X 'main.Version=v$(mainversion)'"* $ make -n GOOS=FOO GOARCH=BAR go build -ldflags="-X 'main.Version=vBAZ'"
- nrclark 2y ago> What does a makefile look like for "install this list of dependencies with pip/homebrew/apt, and don't run it twice?" It looks like this: default: your_task VENV_DIR := venv $(VENV_DIR)/bin/python: requirements.txt python -m venv $(VENV_DIR) . $(VENV_DIR)/bin/activate && pip install -r requirements.txt your_task: $(VENV_DIR)/bin/python do_your_thing clean: rm -rf $(VENV_DIR) > C and C++ compilers at this stage are the only places that I work with file based dependencies. Unless you explicitly declare all the headers as dependencies in a makefile, make won't rebuild a cpp file if you change a header. IME ninja (plus cmake to generate it) has entirely superseded make in this space. Tools and languages comes with it's own build tool (see above - go/cargo/dotnet/etc) or state tracking (docker) that break make's assumption of file based dependencies. In our Python example above, you have a file-based dependency between requirements.txt and your virtual environment. And then you have a file-based dependency on your virtual-environment's Python for whatever task you're trying to run. > Because every make file I've ever used in recent memory has been 30% workarounds to avoid file based dependencies, and work around subtle footguns that make has, rather than actually doing what I want it to do - execute a build command. Why would you want to avoid expressing your dependencies? File dependencies exist, and are the simplest / most correct model for 75% of all build automation. When somebody has to sit down and read your Makefile, isn't it nice to have a way to express "these are the files that actually matter for task X"?
- nrclark 2y ago> I think this post is well intentioned but misses the point entirely. > > GOOS=darwin GOARCH=arm64 go build -ldflags="-X 'main.Version=v1.2.3'" > > Executing this with variables for os/arch/version is not straightforward in a makefile. You might argue that it's a flaw with the `go build` command, but replace go with cargo/dotnet/maven and you have the same problem. This is pretty easy in Make, especially since GOOS and GOARCH are environment variables. One way to do it could look like this: export GOOS ?= darwin export GOARCH ?= arm64 VERSION ?= 0.0.0+$(shell git describe --dirty --always) build: $(if $(VERSION),,$(error VERSION was not set)) go build -ldflags="-X 'main.Version=v$(VERSION)'" you could run it as: $ make build (uses darwin/arm64/0.0.0+<git ref>) $ make build GOOS=linux VERSION=1.0.0 (uses linux/arm64/1.0.0) $ GOOS=templeos GOARCH=sparc make build VERSION=1.1.0 (uses templeos/sparc/1.1.0)
- kstrauser 2y agoBecause it makes the common things easier. We make these tradeoffs all the time in software engineering. Raw machine code is the most flexible and powerful programming language, and yet most of us here aren't using it today. Make isn't machine code and Just isn't Python, but there's an analogy: you give up something by using the latter in exchange for making it easier to do everyday things. Just doesn't replace Make. For the thousand everyday tasks where Make's power isn't needed, it's likely a better choice for most people.