Hacker News new | past | comments | ask | show | jobs | submit login

I'd say that most people should not write makefiles by hand. You should use some higher level build system, that knows how to deal with source files in your language, track their dependencies, etc. A "hello world" makefile with one source file looks simple, but once the project gets more complicated, you quickly end up building such a high level build system yourself, with the additional disadvantage of restricting your build system to only work on systems with GNU make, even though there might be other native build systems available for the platform.



Makefiles, once you have learned the syntax, are very simple to write, as they can be naturally decomposed into individual steps, and rules are easily generalized for similar file types.

Their reputation has been tarnished by autotools, but in that case you're using autotools as your build system, not make.


The problem is that C/C++ files have internal depenedencies which make needs to know about. Yes, for gcc you can use a simple trick to extract the dependencies to makefile rules, but in case you use a different compiler, you need to do it yourself. If you are compiling a different language, you need to do it yourself again. Using something like CMake or even automake, which can automatically track the dependencies, saves you a lot of work.


How do they track the dependencies automatically?


With gcc/clang it's a set of flags starting with -M, and with MSVC it's /showIncludes. They're discussed a bit here:

http://martine.github.io/ninja/manual.html#ref_headers


What if we're using a different compiler, then?

The comment that I was replying to sounds like CMake or something has more magic thus power for a future unknown compiler.


The point I was trying to make is that when you use CMake on any not-completely-unknown compiler, it will do this for you. If you are writing your own makefile, you either need to take the different compilers into account or implement it just for gcc ("screw the other guys") or simply resolve to "make clean && make".


Back in the (not so) good old days we used makedepend.

http://en.wikipedia.org/wiki/Makedepend


Once you start to need loops, conditions, functions to factor common code, switches for production/staging/development builds etc. I don't find Make elegant or easy to maintain even when knowing the syntax personally.


It may be my inexperience speaking, but every time I come across code that was built not by hand I visibly cringe and search for something else. It's not that it's bad, it's just that if I don't understand it then there is nothing for me to fix or play around with.


I am old enough to remember when assembly programmers used to use that complaint as a reason not to program in C. And when C programmers would use that complaint as a reason not to program with templates in C++. And when C++ programmers used that complaint as a reason not to program in languages with garbage collection.

The truth is that no matter what level you program at, you are depending on a long toolchain that you don't understand the details of. You are explicitly aware of not understanding autogenerated stuff at your level. But are ignoring how little you understand of what is underneath the level you are used to programming at.

Get used to it. A few years back I remember an article that started by diving into what actually happens between pressing a key on the keyboard and a letter appearing on the screen. I wish I could find it for you. It was a long article. And repeatedly got into too much detail, then narrowed down the scope and got into more detail. Over and over again.

You don't actually understand how your computer or code works. Instead you create a useful working model and proceed with that. Said working models can include both lower levels than your usual, or you can build up higher levels. Get used to it, take advantage of good tools, and you will accomplish more. The alternative is to get stuck in what you know, refuse to go outside of that boundary, and be less productive. The choice is yours.


I interpreted the comment a bit more generously. The admonition wasn't to avoid using higher level tools, but not to try editing the low level output of a high level tool. I prefer writing in C to writing in assembler, but I would never want to modify the assembler produced by a compiler. Similarly, I prefer scheme to C, but I would prefer handwritten C to editing the output of the Chicken-to-C compiler.

That comes back to the complaint about the auto-build tools. Using the tools, by themselves, is perfectly reasonable. On the other hand, writing Makefiles by hand isn't particularly onerous. What is frustrating, however, is when I'm expected to edit a Makefile that was generated by a tool without having access to the script that generated said Makefile.


I've seen cases where the low level output is perfectly reasonable. And other cases where the low level output contains a section explicitly meant so that people can insert into it. And other cases where it is unreasonable.

That said, if you find autogenerated "stuff", that is not evidence you can't work on the project. It is evidence that you need to understand something before doing so.


I'm sure that, when those skilled engineers cringed at the next higher layer of the stack, that higher layer wasn't reliable yet, it probably had some stability issues and serious performance issues. When it was fully solid they moved on.

I have a degree in electrical engineering, though these days I work on server / infrastructure software. Yeah I have a pretty good idea how stuff works at the c/c++ level and below.


I am not sure of that at all. My experience is that early negative opinions of the next level up don't readily get updated for a very long time, if ever. And the longer you spend holding on to your opinion, the harder it becomes to learn better.


Here's the post you were thinking of, be sure to bookmark it this time! :)

https://plus.google.com/+JeanBaptisteQueru/posts/dfydM2Cnepe


Thank you, that is the link. :-)


It's best to treat it the same way you treat assembler when compiling a C++ program. Normally, you wouldn't inspect the generated assembler. If you do, you will find it very hard to follow, but that's the disadvantage that comes with the benefit that you don't have to write it all by hand. I consider generated makefiles the same. I don't commit them to my repository, most of the times I don't look inside them, it's just an intermediate product of my build system.




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

Search: