Skip to content

Comment on Understanding C by learning assembly

Comments

  $ CFLAGS="-g -O0" make simple
  cc -g -O0    simple.c   -o simple
  $
This is so handy. I never knew that you could call make without writing a default Makefile. Thanks!

Note that this uses the Bourne shell feature of modifying the environment of the make process by prefixing the command with an environmental variable assignment. The more portable/shell-agnostic version is to pass such assignments as arguments to make instead, i.e:

    make CFLAGS="-g -O0" simple
(This also works with many other build tools like CMake or configure scripts generated by autoconf.)

If you're curious which rules exist by default, try running:

    make -p
(This produces a lot of output; a bit much to study in detail, but still useful to scan just to get an idea of what default rules exist.)

"make -p"

Of course this only applies to GNU make.

Works on FreeBSD's make as well (with a sligthly different output format).

Thanks. I was first exposed to this in Zed's Learn C the Hard Way: http://c.learncodethehardway.org/book/. I think it's quite handy.

You can use the default makefile with no targets to set options globally for a directory as well i.e.:

   echo 'void main() { printf("omg\n"); }' > simple.c
   echo 'CFLAGS=-g' > Makefile
   make simple
   ./simple
(yes I know that is not valid C but it serves this example and compiles fine :-)

If you set CC=c99, then you can change void to int.

You probably heard it already, but you should read make documentation. It's full of convention like this aimed at helping the C ecosystem.

And after you have read it, read the documentation of apenwarr's implementation of djb's "redo", and see how everything about make can be simplified to the point that a 150 line portable bash script can be used as a non-dependency-tracking replacement (that is, rebuild everything on each run).

redo makes everything much simpler, more consistent, more dependable, and more robust. e.g all files are atomically replaced; dependencies are checked by a crypto hash of the content; dependency setup is sane; and it's all faster than make.

I wasn't praising make design though. Just mentioning that there are implicit decisions that could be of use if you have to deal with it.

Thanks for the info, I'll look into redo. I just watched a recent talk about Shake (make-like in Haskell) interesting results like 10x smaller ~makefiles and 2x speed improvement.

Isn't dependency the whole point of make?

It's most of the point of make. The other point is templates. And it does both of them, but redo shows that it does them in an unnecessarily complex and inconsistent way.

A redo specification is generally much shorter[1] than the equivalent Makefile, yet simpler to write, can be guaranteed (unlike make / make depend) to rebuild whenever necessary and only when necessary. And while a supersmart dependency tracking incremental build version is not trivial, it's probably an order of magnitude or two shorter than make; And a 150 line bash script is enough to interpret the same specification without regard to dependencies or prior builds (that is: rebuild everything on every attempt).

There are actually a fair number of default rules you can use that way. Check the documentation for details...

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.