Hacker News new | past | comments | ask | show | jobs | submit login
Tabs and Makefile (2015) (beebo.org)
97 points by turadg on Dec 7, 2022 | hide | past | favorite | 34 comments



Glad to see there are so many enlightened souls in this thread who wield their well-configured flaming swords of truth against the darkness between the non-whitespaces.

I for one was eternally flustered as a new programmer in college trying to edit Makefiles with the tools that I felt comfortable with and that were available to me. The tab/space debacle is a completely unnecessary footgun, even worse than the various atrocities of variable assignment spacing and test bracket spacing in `sh`. I am grateful for Make to exist in that it is an important part of the history of Unix and software development, but would rather not use it if given the option.

I for one graciously accept Stuart Feldman's apology.

  C begot Unix
  Unix begot Make
  And Make begot the 10_000 things


Speaking of the shell, Makefiles aren't the only place in Unix where tabs are significant. The sh Here-Document (aka heredoc) "<<-" operator strips leading tabs, but not spaces, from a block of text.

I'm in the tabs for indentation camp, but even I was a little surprised by this, as I had always assumed the semantics were to match and strip whatever leading whitespace was found on the first line. When I emulate this feature in other languages (e.g. heredoc function in tandem with a language's multiline string quotation), that's the semantic I employ, even though in my own code that leading whitespace will invariably be all tabs.


Eternally flustered, really? Over that? Come now.

This is not something I'd be proud to announce or expect well-configured cooling showers of sympathy.

As a developer or sysadmin, among the problems I have to solve every random hour of every day, this one rates all the way up there with the printer being across the room.


Make is actually good. I used to try and avoid it. Many have tried to make something better and its always more complex than make and probably slower.


I don't think I've ever been bitten by confusion over tabs vs other whitespace in a Makefile—Emacs out of the box is a great Makefile IDE. But I can understand the frustration if you only have access to lesser tools.

I should add that learning make well has been a great boon for my career. It's an incredibly powerful and elegant tool, assuming your project can inhabit the subset of projects that will never, ever have paths containing spaces.


You can actually avoid using tabs in makefiles, by using semicolon instead of newline: https://stackoverflow.com/a/4419361/623763


Stupid as it sounds, the fact that you can insert literal tabs with vim, even if you have tab insert spaces by default, allowed me to move on with my life!


I have never understood this. Making MAKE accept spaces in addition to tabs would be a backwards-compatible change. I see no reason why this could not be done even today.


Because make needs to tell the difference between the rules and then the recipes. Make tells the difference by requiring recipes (you shell scripts) to be preceded by tab.

If you let Make accept spaces then there’s no backwards compatible way for it to tell the difference.

You can change the behavior of make to allow a different character to be used before recipes, but then it’s not backwards compatible with other files.


> If you let Make accept spaces then there’s no backwards compatible way for it to tell the difference.

"Rules start with non-whitespace"?


That breaks backwards compatibility since a rule line can start with spaces:

    nonws:
    <tab>echo nonws
      ws:
    <tab>echo ws


> a rule line can start with spaces

Well, that's stupid.

And it's news to me. I have never seen a makefile that actually did this. So you could still fix the problem and be backwards-compatible for probably 99% of actual cases. And you could provide a --stupid-whitespace-mode flag for non-backwards-compatible makefies.

Honestly, I still see no legitimate reason to continue this insanity.


Not all that uncommon, especially in ifdef situations:

  ifdef (something,something)
    rule:
          something specific recipe
  else
    rule:
          common recipe
  endif
It's also not just rules. Variable assignments are also separate from recipes, and can be indented with spaces.

  ifdef (something)
    CFLAGS=something
  else
    CFLAGS=otherthing
  endif


OK, you've convinced me. MAKE is beyond redemption.


I've never had issues with tabs in Makefiles, but I admit it's a bad design and wonder why it hasn't been corrected in all these years. It's not like there hasn't been time to plan a path towards a better design in steps: first introduce a new way to do things still supporting the old way, then start sending warnings when the old one is used, then require an explicit opt-in to support the old syntax, finally only accept the new one.


Use any character you want then use sed to replace it with tabs. Or use some macro processor.


Anyone understand this question:

"At least, I’m pretty sure how things happened, but Wikipedia is inconclusive. Does anyone know?"

What specifically about the linked Wikipedia article are they confused about and how is it inconclusive on that issue?


You can just tell make to use a different character instead of tab. Literally.* It works fine.

What could go wrong?

* this may be a gnu extension, not sure. I did test it once and it works perfectly.


The .RECIPEPREFIX variable is indeed specific to GNU make.

https://www.gnu.org/software/make/manual/html_node/Special-V...


That's not really the point - the point is that the tabs are baked into the de facto standard, so must always be supported, forever, because people use them, so new people use them because they're supported, and so on.


That's not the problem with Make though. If it supported both tabs and spaces, everybody would win.

As noted somewhere else in this thread, this would essentially assume you don't have job names beginning with whitespaces, and that's the compatibility bit you're losing, but hey exactly why would you have a job named ' fdsfgs' in your Makefile.

Another caveat is that whitespace-Makefiles will be supported by new versions of make only. Well, if you expect your Makefile to be called by a 40 y. o. box running UNIX that can't get a new version you'll have to stick to tabs.


Notice I said I only tried it once? Adding that feature was probably a mistake, as widespread use would make other peoples' Makefiles unreadable.


the post is not mobile friendly :(


> Another is the fateful decision of the author of make to have the space character and the (visually identical) tab character do very different things.

Tell me that your editor has bad defaults and you don't know how to configure it without telling me that your editor has bad defaults and you don't know how to configure it.

I can't understand how that still gets always claimed. I can't remember when editors got clever enough to show whitespace with distinct features but Eclipse had that, so at least early 2000s?

Fun fact, on the homepage of Apache Ant, there was for years the paragraph that one reason for its existence was due to the author not being able to handle tabs in Makefiles.

> Makefiles are inherently evil as well. Anybody who has worked on them for any time has run into the dreaded tab problem. "Is my command not executing because I have a space in front of my tab!!!" said the original author of Ant way too many times. Tools like Jam took care of this to a great degree, but still have yet another format to use and remember.

https://web.archive.org/web/20100203102803/http://ant.apache...


You are making an assumption that (1) people work on a small set of computers (2) that they can customize how they like and (3) they only ever work with files using their favorite editor.

There may be some people for whom this is always true, but it is not everyone. There are plenty of people who don't use heavyweight IDEs, or debug stuff on remote servers, etc... And often, those same people decide which build system to use.


> only ever

No, usually.

It's not like it's impossible to work with semantic tabs on an editor that doesn't distinguish, it's just slightly more of a pain to debug.

And it's still much less of an issue than common fonts making 0 and O or l and I and 1 look alike.


vanilla vi handles this fine, no? search for tab and it highlights them all, creating a clear visual difference. I'm not sure about pico/nano, hopefully similar.


Vanilla vi has the ':set list' flag to make tabs and spaces visually distinct too.


Having to display a tab character differently than whatever the equivalent amount of spaces is, can be considered a failure of whatever file format is requiring that.


Or developing an editor that doesn't fully support a character set that has been used since the 1960s could also be called a failure.


It was totally normal (especially back in the day) to edit a makefile on a remote host with vanilla vi. There weren't any electron apps in 1976. Hell, vi is only a few months older than make, so when it was created I bet the usual way of editing a makefile was with ed!

Talk about a badly configured editor...


FWIW I just looked it up and ex already had the "list" option which allowed to specify how control characters are displayed.

Naturally vi had that as well.


You're forgetting about the ecosystem of cat, more, etc. Every tool would need to have perfect display of tabs vs spaces. Perhaps my pager isn't set up correctly, but a tab is indistinguishable from spaces there.


We're talking editing, not displaying. You can't screw up your Makefiles by displaying them.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: