title: How can I improve the speed of my Makefile?
body: <p>I am building a multiple binaries in C++ &amp; CUDA with a couple of files in Fortran.  I found <a href="https://stackoverflow.com/questions/5407048">this question</a> and I'm having a similar problem.  A user recently asked me to re-build a three year old version of the repository (before we had performed a massive migration and renaming) and I was <em>shocked to see how quickly it built</em>.  It would be impossible / incredibly time consuming to determine exactly which of changes between that version and now caused the build to take so friggin' long.</p>
  
  <p><strong>However</strong>, I noticed in an answer's comment to the aforementioned question:</p>
  
  <blockquote>
    <p>In particular, remember to use := instead of =, as := does the expansion
    immediately, which saves time. – Jack Kelly Mar 23 at 22:38</p>
  </blockquote>
  
  <p>Are there other suggestions that I should be aware of?</p>
  
  <p>Note:</p>
  
  <ul>
  <li>I use the 'include' paradigm where each directory I want to build has a <code>module.mk</code> file which is directly included into the one and only Makefile.</li>
  <li>I do use several functions like:</li>
  </ul>
  
  <p>(markdown..)</p>
  
  <pre><code>#
  # CUDA Compilation Rules
  #
  
  define cuda-compile-rule
    $1: $(call generated-source,$2) \
      $(call source-dir-to-build-dir, $(subst .cu,.cubin, $2)) \
      $(call source-dir-to-build-dir, $(subst .cu,.ptx, $2))
      $(NVCC) $(CUBIN_ARCH_FLAG) $(NVCCFLAGS) $(INCFLAGS) $(DEFINES) -o $$@ -c $$&lt;
  
    $(call source-dir-to-build-dir, $(subst .cu,.cubin, $2)): $(call generated-source,$2)
      $(NVCC) -cubin -Xptxas -v $(CUBIN_ARCH_FLAG) $(NVCCFLAGS) $(INCFLAGS) $(DEFINES) $(SMVERSIONFLAGS) -o $$@ $$&lt;
  
    $(call source-dir-to-build-dir, $(subst .cu,.ptx, $2)): $(call generated-source,$2)
      $(NVCC) -ptx $(CUBIN_ARCH_FLAG) $(NVCCFLAGS) $(INCFLAGS) $(DEFINES) $(SMVERSIONFLAGS) -o $$@ $$&lt;
  
    $(subst .o,.d,$1): $(call generated-source,$2)
      $(NVCC) $(CUBIN_ARCH_FLAG) $(NVCCFLAGS) $3 $(TARGET_ARCH) $(INCFLAGS) $(DEFINES) -M $$&lt; | \
      $(SED) 's,\($$(notdir $$*)\.o\) *:,$$(dir $$@)\1 $$@: ,' &gt; $$@.tmp
      $(MV) $$@.tmp $$@
  endef
  </code></pre>
  
  <ul>
  <li>But most of these functions I used in the older version...</li>
  </ul>
  
  <p><strong>Lastly:</strong> How can I determine if it's the compilation time or the <code>make</code> time which is really slowing things down?</p>
  
  <p>I didn't want to append the entire Makefile.  It's 914 lines, but I'd be happy to update the question with snippets if it would help.</p>
  
  <p><strong>Update:</strong> Here is my dependency generation rule &amp; compile rule:</p>
  
  <pre><code>#
  # Dependency Generation Rules
  #
  
  define dependency-rules
  
    $(subst .o,.d,$1): $2
      $(CC) $(CFLAGS) $(DEFINES) $(INCFLAGS) $3 $(TARGET_ARCH) -M $$&lt; | \
      $(SED) 's,\($$(notdir $$*)\.o\) *:,$$(dir $$@)\1 $$@: ,' &gt; $$@.tmp
      $(MV) $$@.tmp $$@
  
  endef
  
  %.d: %.cpp
      $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -M $&lt; | \
      $(SED) 's,\($(notdir $*)\.o\) *:,$(dir $@)\1 $@: ,' &gt; $@.tmp
      $(MV) $@.tmp $@
  </code></pre>
  
  <p><strong>Update 2:</strong> Using @Beta's suggestion, I was able to parcel out the dependency generation and Makefile time was roughly 14.2% of the overall compiling time.  So I'm going focus on minimizing header inclusion in my C++ code first.  Thanks to both of you for your suggestions!!</p>