Minority Opinions

Not everyone can be mainstream, after all.

Making in the Future

leave a comment »

I have twice come across James Hague’s commentary on the Death of a Prominent DSL.  The DSL in question is, oddly enough, that of the makefile.  Granted, there are enough alternative build systems to think there might be something legitimately wrong, but I simply haven’t seen any real problems.  On the other hand, I only use it for small to mid-size personal or internal projects, not for code distribution.

In an ideal world, I could control the environment of each machine on which the makefile would be used.  In practice, there have been a few differences between machines, but I can at least work around them.  In fact, I’ve been known to do some of that in the makefile itself, depending on a particular executable and invoking apt-get if it doesn’t exist.

Meanwhile, a few random tips I’ve collected over time:

  • Start with the commands you’ve been running by hand.  After all, that’s why you’re using a makefile in the first place, right?
  • If a rule gets too complex, particularly when it starts needing its own control statements, split it out into a shell script.
  • Use “# $@: $?” at the top of each rule to determine why each one is getting invoked.
  • Don’t let file targets depend on pseudo targets.  They end up getting made every time, particularly when using the previous tip.
  • Replace target names with $@, and the main dependency with $< where appropriate.  That will help down the road, when you start wanting to re-use them.
  • Use pattern rules when you have multiple rules that look sufficiently similar.  You may need $* to get the stem, depending on the complexity of the rule.
  • Use a clean target to remove everything auto-generated.  This will be particularly helpful when determining whether it’s bad code or a bad dependency search causing a problem.
  • Don’t invoke make recursively.  Put everything into a single makefile.  If you really need to, include other files.
  • Depend on everything at first.  If a file could even remotely been involved in a rule, depend on it.  That includes the makefile itself.
  • When things get too slow, trim out some of the dependencies with generated and included dependency files.
  • When a dependency file lists a file that no longer exists, use a pseudo target to skip it and move on.  Don’t remove it from the dependency file itself, though; recompile instead.
  • Use simply expanded variables (:= instead of =) where possible, particularly when the value has any sort of function call.  You are using GNU make, right?

Sometime, perhaps, I may tackle the issue of running make in a subdirectory, but not until I really care.  I can think of two potential solutions:

  1. Use subdirectory makefiles that pass the real work onto the main makefile.  There has already been some work in this area, but it’s sufficiently complicated that I haven’t evaluated it.
  2. Use an external program that scans up the tree for a makefile, running it.  The big tricks are mangling the target arguments correctly (either trim off a leading ../ or prepend the directory name to each one, except perhaps for phony targets), and telling bash completion about the target names.

I may be convinced sometime to switch to another build system.  If so, it will have to be one as convenient to read as a makefile; ant scripts in particular are completely incomprehensible.  Using a high-level language might work, but fights against my use of make to automate commands that I tend to run.  I don’t want to re-implement them, even if it’s as “simple” as passing them to the shell execution function.

Perhaps, then, the issue is that I’m not really using it as a build system at all.  I’m using it as an extension to shell scripting, with the ability to avoid doing work that doesn’t need to be done.  A simple solution for a simple problem.

Advertisements

Written by eswald

6 Mar 2012 at 5:34 pm

Posted in Linux, Technology

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s