Skip to content

Commit

Permalink
Mention Make’s “phony target” workaround in the comparison (#421)
Browse files Browse the repository at this point in the history
  • Loading branch information
roryokane authored and casey committed May 1, 2019
1 parent fdb5c4f commit a740200
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ On MacOS, `just` can be installed using the https://brew.sh[Homebrew package man
=== Scoop
On Windows, `just` can be installed using the https://scoop.sh[Scoop package manager]. Install Scoop using the instractions https://scoop.sh/[here], then run:
On Windows, `just` can be installed using the https://scoop.sh[Scoop package manager]. Install Scoop using the instructions https://scoop.sh/[here], then run:
```powershell
scoop install just
Expand Down Expand Up @@ -807,29 +807,29 @@ Before merging a particularly large or gruesome change, Janus should be run to m

== Frequently Asked Questions

=== What are the idiosyncrasies of make that just avoids?
=== What are the idiosyncrasies of Make that Just avoids?

Make has some behaviors which are either confusing, complicated, or make it unsuitable for use as a general command runner.
Make has some behaviors which are confusing, complicated, or make it unsuitable for use as a general command runner.

One example is that sometimes make won't run the commands in a recipe. For example, if you have a file called `test` and the following makefile that runs it:
One example is that under some circumstances, Make won't actually run the commands in a recipe. For example, if you have a file called `test` and the following makefile:

```make
test:
./test
```

Make will actually refuse to run it:
Make will refuse to run your tests:

```sh
$ make test
make: `test' is up to date.
```

Make sees the recipe `test` and assumes that it produces a file called `test`. It then sees that this file exists and thus assumes that the recipe doesn't need to be run.
Make assumes that the `test` recipe produces a file called `test`. Since this file exists and the recipe has no other dependencies, Make thinks that it doesn't have anything to do and exits.

To be fair, this behavior is desirable when using make as a build system, but not when using it as a command runner.
To be fair, this behavior is desirable when using Make as a build system, but not when using it as a command runner. You can disable this behavior for specific targets using Make's built-in link:https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html[`.PHONY` target name], but the syntax is verbose and can be hard to remember. The explicit list of phony targets, written separately from the recipe definitions, also introduces the risk of accidentally defining a new non-phony target. In `just`, all recipes are treated as if they were phony.

Some other examples include having to understand the difference between `=` and `:=` assignment, the confusing error messages that can be produced if you mess up your makefile, having to use `$$` to write recipes that use environment variables, and incompatibilites between different flavors of make.
Other examples of Make’s idiosyncrasies include the difference between `=` and `:=` in assignments, the confusing error messages that are produced if you mess up your makefile, needing `$$` to use environment variables in recipes, and incompatibilities between different flavors of Make.

=== What's the relationship between just and cargo build scripts?

Expand Down

1 comment on commit a740200

@Alhadis
Copy link

@Alhadis Alhadis commented on a740200 Mar 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More than one .PHONY target may be specified in a Makefile, which isn't clear from your wording:

The explicit list of phony targets, written separately from the recipe definitions, also introduces the risk of accidentally defining a new non-phony target

While I'm here, I should point out that this:

needing $$ to use environment variables in recipes

… overlooks the fact that environment variables can be interpolated with $(VAR_NAME) (the same as any other variable defined in the makefile). E.g.:

MakefileShell
foo:
	@ echo $(TERM)
.PHONY: foo

bar: foo
	@ echo $(HOME)
.PHONY: bar
$ make HOME=/Users/Shared bar
xterm-256color
/Users/Shared
$ TERM=vt220 make foo
vt200

Please sign in to comment.