title: Global Makefile with scoped variables
body: <p>I am attempting to convert my entire project to a single Makefile at the behest if <a href="http://aegis.sourceforge.net/auug97.pdf" rel="nofollow">this</a> paper that I see littering all of my search results whenever I have a recursive makefile question.  However, I have run into quite a fundamental problem that I'm not sure how to address.  I would like to define a couple common but not identical variables for every Makefile module.  To do this, I have created a <code>Makefile.var</code> file first:</p>
  
  
  
  <pre class="lang-perl prettyprint-override"><code># ============================================================================
  # Common aliases for local dirs
  # ============================================================================
  # Every make module must define WORKING_DIR :=
  BIN = $(WORKING_DIR)/bin
  OBJ = $(WORKING_DIR)/obj
  SRC = $(WORKING_DIR)/src
  DEP = $(WORKING_DIR)/obj
  INC = $(WORKING_DIR)/include
  INCLUDES = -I$(INC)
  
  ALL_SRCS   = $(wildcard $(SRC)/*.C)
  ALL_INCS   = $(wildcard $(INC)/*.h)
  ALL_OBJS   = $(subst $(SRC),$(OBJ),$(ALL_SRCS:%.C=%.o))
  ALL_DEPS   = $(subst $(SRC),$(DEP),$(ALL_SRCS:%.C=%.d))
  </code></pre>
  
  <p>This is in a <code>Makefile.var</code> file that is included first in the master file.  After this, subsequent makefile modules are included.  Here is my master <code>Makefile</code>:</p>
  
  <pre class="lang-perl prettyprint-override"><code>include MakeModules/Makefile.var
  include MakeModules/Makefile.tools
  
  clean: $(CLEAN_LIST)
  
  all: $(MAKE_LIST)
  </code></pre>
  
  <p>Finally, here is what a module would look like.  For ease, I'll just copy and paste the same module twice, and tweak the name for the second instantion.  This is <code>Makefile.tools</code>:</p>
  
  <pre class="lang-perl prettyprint-override"><code># ============================================================================
  # queuing (QUE)
  # ============================================================================
  WORKING_DIR := $(TOP)/tools/queuing
  QUE_TARGET  := libqueue.so
  
  -include $(DEP)/*.d
  
  $(QUE_TARGET): $(ALL_OBJS)
      $(CPP) $(CFLAGS) -shared -o $@ $(ALL_OBJS)
  
  que-clean:
      -rm -f $(OBJ)/*.o $(DEP)/*.d
  
  CLEAN_LIST += que-clean
  MAKE_LIST += $(QUE_TARGET)
  
  # ============================================================================
  # queuing2 (QUE2)
  # ============================================================================
  WORKING_DIR := $(TOP)/tools/queuing2
  QUE2_TARGET := libqueue2.so
  
  -include $(DEP)/*.d
  
  $(QUE2_TARGET): $(ALL_OBJS)
      $(CPP) $(CFLAGS) -shared -o $@ $(ALL_OBJS)
  
  que2-clean:
      -rm -f $(OBJ)/*.o $(DEP)/*.d
  
  CLEAN_LIST += que2-clean
  MAKE_LIST += $(QUE2_TARGET)
  </code></pre>
  
  <p>As you can see, <code>Makefile.tools</code> uses the derived variables from <code>Makefile.var</code> based on the value of <code>WORKING_DIR</code>.  Well, this doesn't actually work because of the 2-phase reading that <code>make</code> does.  The <code>WORKING_DIR</code> variable will only take on the last known assignment, and <code>ALL_OBJS</code> will be the same value for all rules regardless of where they are located.  This means only the last defined module actually has the correct rules.</p>
  
  <p>Is there a way to give access to the common <code>BIN, OBJ, SRC, ...</code> variables to each module without just c/ping over and over again with new prefixes?  That is, can I scope a variable definition to a Makefile section and then change it later while retaining the old rules?  I have an itching feeling that this isn't possible, but it would be really nice if I'm missing some nice trick that will wrap this up nicely.  Otherwise, this global Makefile thing isn't really feasible (there are TONS of common variables used that derive values from the <code>WORKING_DIR</code>, which was scoped by recursive make previously).</p>