News for hackers. Stuff that matters.
Re:I Like Makefiles by chipdart on Saturday September 21, 2024 @05:25AM (#41608724)
> Make does exactly one thing: it takes input files, some dependencies and generates _exactly_one_ output file.

Not true. Your dependency graph might culminate on a single final target, but nothing prevents you from adding as many targets that generate as many output files as you feel like adding and set them as dependencies of your final target.

Think about it for a second. If Make was only able to output a single file, how in the world do you think it's used extensively to compile all source files of a project, generate multiple libraries, link all libraries, generate executables, and even output installers and push them to a remote repository?

> To have rules which don't generate output (like `install` or `all` or `clean` or all targets in the article) we need to resort to a hack, a special magic target like `.PHONY`

I don't understand what point you thought you were making. So a feature that boils down to syntactic sugar was added many years ago. So what? As you showed some gross misconceptions on what the tool does and how to use it, this point seems terribly odd.

> And the problem isn't that they use it, but that they are proposing it as a solution to "everybody".

I think you're making stuff up. No one wants Make to rule the world. I don't know where you got that from.

I think the whole point is that Make excels at a very specific usecase: implement workflows comprised of interdependent steps that can be resumed and incrementally updated. Being oblivious of Make leads many among us to reinvent the wheel poorly, using scripting languages to do much of the same thing but requiring far more work. If you can do this with a dozen lines of code in a Makefile, why on earth would you be churning out hundreds of lines of any random scripting language?

Re:I Like Makefiles by ReleaseCandidat on Saturday September 21, 2024 @05:49AM (#41608811)
> Not true. Your dependency graph might culminate on a single final target, but nothing prevents you from adding as many targets that generate as many output files as you feel like adding and set them as dependencies of your final target.

Sorry, I did phrase that badly. A better version of that sentence would be

   A single target (a single node in the dependency graph) of Make does exactly one thing: it takes input files, some dependencies and generates _exactly_one_ output file.
> I think the whole point is that Make excels at a very specific usecase [..]

Excatly what I wanted to express with my post above. But the article isn't about such a case, but for something for which a single shell script (or, better, just adding the commands to the `scripts` stanza of `package.json`, which is the more common, expected way to do it) is actually better suited and way less error prone.

Re:I Like Makefiles by robinsonb5 on Saturday September 21, 2024 @07:35AM (#41609319)
> A single target (a single node in the dependency graph) of Make does exactly one thing: it takes input files, some dependencies and generates _exactly_one_ output file.

I'm still not really following the point about one output file? That might be Make's stated purpose, but a Makefile rule can certainly create extra files as a side effect (or do pretty much anything a shell user could do, from creating directories and downloading files to launching applications)

One of my projects has a single makefile rule which downloads and unzips a tarball, applies a patch to it, then builds the application within, resulting in half a dozen binaries which are then used in building the rest of the project.

Edit: Ah - I see what you mean now, in your subsequent comment.

Re:I Like Makefiles by chongli on Saturday September 21, 2024 @07:05AM (#41609179)
A single target (a single node in the dependency graph) of Make does exactly one thing: it takes input files, some dependencies and generates _exactly_one_ output file.

Yes, but this is not particularly relevant to the user. With pattern rules it's trivial to define a large number of targets automatically, such as in the example (from the manual):

    objects = foo.o bar.o

    all: $(objects)

    $(objects): %.o: %.c
            $(CC) -c $(CFLAGS) $< -o $@
Re:I Like Makefiles by ReleaseCandidat on Saturday September 21, 2024 @07:32AM (#41609305)
I have been unclear in my formulation, sorry.

The problem is a target with more than one output files, that target would look something like, which does work

    foo bar: baz
         compile $< -o foo -o bar
but as this is the same as writing

    foo: baz
         compile $< -o foo -o bar

    bar: baz
         compile $< -o foo -o bar
to generate `foo` and `bar` the rule is run twice in a parallel build (`make -j 2`. Which may just be unnecessary or it may break the whole build.
Re:I Like Makefiles by frumiousirc on Saturday September 21, 2024 @07:48AM (#41609375)
https://www.gnu.org/software/make/manual/html_node/Multiple-...

Scroll down to "Grouped targets". I think these address the concern you raise.

The snippet you have shown is an example of the "independent targets" pattern which the first half of that page also covers.

Re:I Like Makefiles by ReleaseCandidat on Saturday September 21, 2024 @10:15AM (#41610126)
Thanks, that's it. It has been introduced with GNU Make 4.3, January 2020 https://lists.gnu.org/archive/html/info-gnu/2020-01/msg00004...
Re:I Like Makefiles by robinsonb5 on Saturday September 21, 2024 @07:45AM (#41609359)
So can that be solved like this, or is there some other subtlety I'm missing?

  foo: baz
    compile $< -o foo -o bar

  bar: foo
(Can someone tell me how to do code tags on HN please? :) Edit: fixed now, thanks!)
Re:I Like Makefiles by oneeyedpigeon on Saturday September 21, 2024 @07:54AM (#41609398)
> Text after a blank line that is indented by two or more spaces is reproduced verbatim. (This is intended for code.)

(from https://news.ycombinator.com/formatdoc)

Re:I Like Makefiles by mauvehaus on Saturday September 21, 2024 @08:36AM (#41609580)
Among other things, now you have to maintain a set of dummy targets. If you have a variable (possibly generated) that is basically

  A_MESS_OF_FILES := foo bar zot
You now have to create dummy targets for bar, baz, and zot and not forget to add them. Or maybe break it into

  MAIN_FILE := foo
  SUBORDINATE_FILES := bar zot

  foo: baz
    sudo make me a foo

  $(SUBORDINATE_FILES): %: foo
Re:I Like Makefiles by ReleaseCandidat on Saturday September 21, 2024 @10:18AM (#41610151)
Subtlety. Now the dependencies are `baz` -> `foo` -> `bar`, that is `foo` is a temporary target and won't be (re)build if `bar` already exists. Which may or may not be a problem. This temporary target (whatever the actual term is) can be "elevated" to a "normal" target with the use of some special target (which I'm too lazy to look up right now).