
Notes on Writing Makefiles - mmphosis
http://eigenstate.org/notes/makefiles
======
MereInterest
One other thing in terms of organization. Your makefile should place any .o
files in a separate directory, not in the source directory. This helps keep
your source directory clean, and extends nicely when you want to have multiple
different builds with different options.

------
Julio-Guerra
Over the last few years, I wrote a GNU Make library to make people able to
write Makefiles in a very declarative way to help everyone in my company, me
included, with this serious problem. I tried to make it as simple as possible
using simple widespread concepts like UML components where you simply say a
component has interfaces you can require and implementations you can link
against. It is used to build our Operating System, our applications and even
our reactjs web application.

I decided to make it open source a few months ago but it lacks examples and
documentation, sorry... You can check out this test to see how it looks like
in the test-suite:
[https://github.com/farjump/Makefile.in/blob/dev/test/externa...](https://github.com/farjump/Makefile.in/blob/dev/test/external/Makefile.in)

It solved every problem I noticed about writing bare Makefiles: dependency
tracking and generation is automated; the Makefile can be split into multiple
sub-makefiles in your source-tree so that it matches your UML (these one
[http://agilemodeling.com/images/models/componentDiagramUML1....](http://agilemodeling.com/images/models/componentDiagramUML1.jpg\);)
you can perform out-of-source builds; generating complex software with deep
dependency trees made simple (you inherit from other components'
dependencies), etc.

Bonus: it also includes some hacks with GNU Make metaprogramming
[https://github.com/farjump/Makefile.in/blob/dev/src/mk/core/...](https://github.com/farjump/Makefile.in/blob/dev/src/mk/core/debug.mk#L31)
:D

~~~
humanrebar
Honest question: Why not use cmake?

~~~
Julio-Guerra
cmake does not really offer the declarative interface I want (i.e.
descriptions of components). It is still "low-level" and I would have to write
cmake macros too. So I preferred native gnu make. Adding another tool on top
of Make adds another layer of complexity, no matter how simple it is.

To me, the big benefit of cmake is its portability because it is able to
generate visual studio files, eclipse files, etc.

Another one is that you end up with a static Makefile while my solution is
dynamic: the makefile is evaluated at every execution (unless gnu make caches
its parsed files but I don't think it does so far). It could be a problem for
big projects like linux which would require a certain amount of parsing time
of the Makefiles before evaluating them - while cmake or autotools, you go
through this only once.

------
dahart
> Pattern rules are your friend

Amen. Been writing small makefiles for many years, and only recently learned
how to use pattern rules properly. They finally relieved my temptation to use
eval.

Speaking of eval, I have one makefile tip I've learned the hard way: the
example in the gnu make manual for eval doesn't run! It has an incorrect "="
(equals sign) in the define. I've racked my brain against that one for hours,
twice, because a couple years later I'd forgotten about the first time I
figured it out.

~~~
JupiterMoon
Can you file a bug with them? Maybe submit a patch to their documentation?

~~~
dahart
Yes, I can, and have just done so. :)

~~~
dahart
Aha. [http://stackoverflow.com/questions/13260396/gnu-
make-3-81-ev...](http://stackoverflow.com/questions/13260396/gnu-
make-3-81-eval-function-not-working)

------
vacri
I've recently been learning Make a little in order to do .deb packaging The
Official Way; that is with debuild (which expects Make), not with FPM. I enjoy
_having_ a Makefile, and I enjoyed _not having_ a Makefile, but the bit in-
between these two states wasn't particularly fun...

But once you have a Makefile that works, it's easy to extend. Overall I'm glad
I bothered to learn it (at least a little bit), and I'm rewarded with a .deb
file that can set up it's own environment rather than me having to set it up
separately. FPM can include all the boilerplate scripting to do this, but you
end up with so many flags (or wrapper scripts) that you may as well just go
with debuild/Make in the first place.

