

How We Use Make - ianstormtaylor
https://segment.com/blog/how-we-use-make/

======
seanwilson
I avoid Make at all costs now if I can.

Makefiles are far too difficult to read and write compared to alternatives in
my opinion when you're automating anything beyond a few simple tasks. You'll
inevitably have tasks that require several lines of code, complex logic,
different settings for production, staging and development environments,
common code that has to be shared between build steps etc. I find it difficult
to make shell scripts robust and maintainable.

I'd much rather use JavaScript's Gulp (especially if my project was using Node
like in the post) or Python's Fabric if possible.

~~~
davexunit
You know that you could keep the make tasks simple and have them invoke
external scripts that are written in the language of your choosing, right?
Building a mound of spaghetti shell code in a single file isn't the only way
to construct a Makefile.

~~~
seanwilson
Sure, but once you want to start sharing code between your external scripts
and the Makefile, it makes a lot more sense to me to write it all in a single
more maintainable language.

------
bartbes
It's interesting how they list targets that have "practically become a
convention", yet they're missing "all".

I'm also intrigued by their claim they used @ in the recipes, yet they never
did.

~~~
shazow
> It's interesting how they list targets that have "practically become a
> convention", yet they're missing "all".

I think what he means is that their Makefiles effectively start having a
common API across projects, by having similar target names.

No need to use "all" if you put the default target first (see `default`
subsection in the post).

> I'm also intrigued by their claim they used @ in the recipes, yet they never
> did.

Yea seems that got stripped out.

Still, this is a good practical example for using a Makefile. I'm a fan of
this too.

~~~
bartbes
I realise their standard probably doesn't include all, but it seems like the
obvious choice. Maybe I've just been conditioned by autotools, but I think
it's standard practice to have all be your default target.

~~~
shazow
¯\\_(ツ)_/¯

As long as running `make` does the Right Thing, does it matter if it does it
via an `all` target or by defaulting to a different first target?

I do agree that generally `all` is a common convention, though.

~~~
bartbes
It's really only relevant when specifying multiple targets, like 'make clean
all', or the more common 'make all install'. It just seemed odd to me.

~~~
xyzzy_plugh
Why would you have `make all install' behave differently than `make install'?
I'm imagining specifically when you have the install target present.

~~~
Leszek
Because `make all install` would first build, then install, while `make
install` would just do the installation, regardless of build state.

~~~
wtallis
Wouldn't any sane install target depend on the build products it seeks to
install, and consequently build before installing?

------
gkya
May be selective perception, but I have seen a rather uncommon increase of
submissions regarding make here nowadays. Have I missed something?

~~~
exogen
I think it's a reaction to there being a new build system announced fairly
frequently. A while ago I actually started writing up a "Make for web
development" tutorial file similar to Isaac's gist (linked in the article). At
least for me, seeing new systems announced over and over again – especially
the ones where you're writing JS functions to build stuff instead of shell
commands – just makes me want to spread the "just use Make" word even more.

------
raverbashing
Make manages dependencies

Yes, 70's era Unix tools are not the most friendly, but there's still a lot of
uses to Make (as opposed to Autotools)

You can actually build a Make file to solve any DAG, written as dependencies,
or use its tools to not rebuilt your whole project when only one file has
changed

------
MichaelMoser123
i have a makefile/make system that uses gnu make macros;

(here
[http://mosermichael.github.io/cstuff/all/projects/2011/06/17...](http://mosermichael.github.io/cstuff/all/projects/2011/06/17/make-
system.html) )

this saves you from repeating the same make constructs many times over, in the
following example you do a static library and executable.

    
    
      1: TOPDIR=../..
      2:
      3: # - declare build targets. (built with make)
      4: TARGETS:=shlib slibuser
      5: 
      6: # - slib target is a static library -
      7: shlib_TYPE=lib
      8: shlib_SRC=slib.c
      9:
      10:
      11: # - slibuser target is a executable using slib -
      12: slibuser_TYPE=exe
      13: slibuser_SRC=slibuser.c slibuser2.c slibuser3.c
      14: slibuser_LIBS=shlib
      15:
      16: include $(TOPDIR)/rules.make

~~~
ccoggins
This is similar to how it was done on a project I recently worked on. It
worked well enough on a project that built about 300 libraries and 200
executable. It also made it really easy to add new things.

------
toolslive
It's amazing how far apart evaluations can be. Even something like `Make` has
people who love it, and people that eschew it. Moreover, both camps contain
very rational, intelligent people. I wonder why.

------
jcoffland
It seems like the kids these days would rather write a completely new tool
than just learn the basics of Make.

~~~
Peaker
I learned Make, but it is just a terrible tool:

A) It is a 2-phase build system (read DAG, traverse DAG) whereas code
generation requires an N-phase build system (build some files, detect more
dependencies, build more files, ...)

B) It has no way to express dependencies on the inexistence of files (#include
"foo.h" will behave differently if the first search directory in the include
path starts also featuring a "foo.h", but this cannot be specified),
necessarily meaning that incremental build become incorrect in various
circumstances

C) It does mtime-newer check, rather than mtime-equal check. This has numerous
problems with various file systems.

D) It does not check the mtime did not change _during_ a build, effectively
allowing the build tree to be poisoned with an incorrect build result. For
example, edit foo.c _while_ foo.o is being compiled from it. foo.o can be
correct w.r.t old foo.c, but its mtime suggests it is newer than the current
foo.c. All incremental builds thus become incorrect.

In short, make doesn't try hard enough to be a _correct_ build system, and it
is also _inflexible_.

This is why I wrote `buildsome`[1], where I resolve all these issues and more.

buildsome is only tailored for our needs at the moment, so can only build on
Linux, and not on OS X or Windows.

[1]
[https://github.com/Elastilotem/buildsome](https://github.com/Elastilotem/buildsome)

