--- /dev/null
+Return-Path: <amdragon@mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 18AD1431FC9\r
+ for <notmuch@notmuchmail.org>; Fri, 17 May 2013 13:13:50 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+ tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id vo4gRRxCiyal for <notmuch@notmuchmail.org>;\r
+ Fri, 17 May 2013 13:13:42 -0700 (PDT)\r
+Received: from dmz-mailsec-scanner-3.mit.edu (DMZ-MAILSEC-SCANNER-3.MIT.EDU\r
+ [18.9.25.14])\r
+ by olra.theworths.org (Postfix) with ESMTP id DC1BF431FC7\r
+ for <notmuch@notmuchmail.org>; Fri, 17 May 2013 13:13:41 -0700 (PDT)\r
+X-AuditID: 1209190e-b7f4f6d000005142-85-51968f75759e\r
+Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])\r
+ by dmz-mailsec-scanner-3.mit.edu (Symantec Messaging Gateway) with SMTP\r
+ id 3F.92.20802.57F86915; Fri, 17 May 2013 16:13:41 -0400 (EDT)\r
+Received: from outgoing.mit.edu (OUTGOING-AUTH-1.MIT.EDU [18.9.28.11])\r
+ by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id r4HKDct6013850; \r
+ Fri, 17 May 2013 16:13:38 -0400\r
+Received: from drake.dyndns.org (26-4-182.dynamic.csail.mit.edu [18.26.4.182])\r
+ (authenticated bits=0)\r
+ (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+ by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id r4HKDaMa004347\r
+ (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
+ Fri, 17 May 2013 16:13:37 -0400\r
+Received: from amthrax by drake.dyndns.org with local (Exim 4.77)\r
+ (envelope-from <amdragon@mit.edu>)\r
+ id 1UdR20-0006Hn-BQ; Fri, 17 May 2013 16:13:36 -0400\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] emacs: Compute build dependencies to fix byte compile issues\r
+Date: Fri, 17 May 2013 16:13:31 -0400\r
+Message-Id: <1368821611-24110-1-git-send-email-amdragon@mit.edu>\r
+X-Mailer: git-send-email 1.7.10.4\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=UTF-8\r
+Content-Transfer-Encoding: 8bit\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFnrNIsWRmVeSWpSXmKPExsUixCmqrVvaPy3Q4Mw7SYvrN2cyOzB6PFt1\r
+ izmAMYrLJiU1J7MstUjfLoErY8HcdWwFm1QqjjQfYGxgnCfbxcjJISFgIvHp3TdGCFtM4sK9\r
+ 9WwgtpDAPkaJObMtuxi5gOyNjBILTvayQThHmCSaTm5ngaiayyixeFIhiM0moCGxbf9ysEki\r
+ AtISO+/OZu1i5OBgFlCT+NOlAhIWFiiUOLf+PDOIzSKgKjF55xWwMbwCDhKNVxezQByhKNH9\r
+ bAIbRFxQ4uTMJywQY9Ql1s8TAgkzC8hLNG+dzTyBUWAWkqpZCFWzkFQtYGRexSibklulm5uY\r
+ mVOcmqxbnJyYl5dapGusl5tZopeaUrqJERyOknw7GL8eVDrEKMDBqMTD+8F1WqAQa2JZcWXu\r
+ IUZJDiYlUV6HbqAQX1J+SmVGYnFGfFFpTmrxIUYJDmYlEd7nxUA53pTEyqrUonyYlDQHi5I4\r
+ 75WUm/5CAumJJanZqakFqUUwWRkODiUJ3ug+oEbBotT01Iq0zJwShDQTByfIcB6g4aIgNbzF\r
+ BYm5xZnpEPlTjLocbV8nv2MUYsnLz0uVEud1BikSACnKKM2DmwNLI68YxYHeEuaNAKniAaYg\r
+ uEmvgJYwAS1hvTYVZElJIkJKqoExegbzzKctLEe4vqeKJdx6GVjpFBSW16X0W3T/alWOtDPR\r
+ IY+OaSxhXu9xsXSVTJbmrs1/ONMDqw/M1Ntt3nZWredbQINs2RMjTp1Jd73TnZafnSiXHGn+\r
+ Ma3x8z2TV99nqiks/xGzxCDSzvZ7+cag/0IJH2t4+sQOLLia3sEjEf688MTURYxKLMUZiYZa\r
+ zEXFiQC79NZG/gIAAA==\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Fri, 17 May 2013 20:13:50 -0000\r
+\r
+Previously, we simply byte compiled each Elisp source file\r
+independently. This is actually the wrong thing to do and can lead to\r
+issues with macros and performance issues with substitutions because\r
+1) when the byte compiler encounters a (require 'x) form, it will load\r
+x.elc in preference to x.el, even if x.el is newer, and as a result\r
+may load old macro and substitution definitions and 2) if we update a\r
+macro or substitution definition in one file, we currently won't\r
+re-compile other files that depend on the file containing the\r
+definition.\r
+\r
+This patch addresses these problems by computing make dependency rules\r
+from the (require 'x) forms in the Elisp source files, which we inject\r
+into make's dependency database.\r
+---\r
+ emacs/Makefile.local | 12 +++++++++\r
+ emacs/make-deps.el | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++\r
+ 2 files changed, 78 insertions(+)\r
+ create mode 100644 emacs/make-deps.el\r
+\r
+diff --git a/emacs/Makefile.local b/emacs/Makefile.local\r
+index fb82247..456700a 100644\r
+--- a/emacs/Makefile.local\r
++++ b/emacs/Makefile.local\r
+@@ -22,6 +22,18 @@ emacs_images := \\r
+ \r
+ emacs_bytecode = $(emacs_sources:.el=.elc)\r
+ \r
++# Because of defmacro's and defsubst's, we have to account for load\r
++# dependencies between Elisp files when byte compiling. Otherwise,\r
++# the byte compiler may load an old .elc file when processing a\r
++# "require" or we may fail to rebuild a .elc that depended on a macro\r
++# from an updated file.\r
++$(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources)\r
++ $(call quiet,EMACS) --directory emacs -batch -l make-deps.el \\r
++ -f batch-make-deps $(emacs_sources) > $@.tmp && \\r
++ (cmp -s $@.tmp $@ || mv $@.tmp $@)\r
++-include $(dir)/.eldeps\r
++CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp\r
++\r
+ %.elc: %.el $(global_deps)\r
+ $(call quiet,EMACS) --directory emacs -batch -f batch-byte-compile $<\r
+ \r
+diff --git a/emacs/make-deps.el b/emacs/make-deps.el\r
+new file mode 100644\r
+index 0000000..a1cd731\r
+--- /dev/null\r
++++ b/emacs/make-deps.el\r
+@@ -0,0 +1,66 @@\r
++;; make-deps.el --- compute make dependencies for Elisp sources\r
++;;\r
++;; Copyright © Austin Clements\r
++;;\r
++;; This file is part of Notmuch.\r
++;;\r
++;; Notmuch is free software: you can redistribute it and/or modify it\r
++;; under the terms of the GNU General Public License as published by\r
++;; the Free Software Foundation, either version 3 of the License, or\r
++;; (at your option) any later version.\r
++;;\r
++;; Notmuch is distributed in the hope that it will be useful, but\r
++;; WITHOUT ANY WARRANTY; without even the implied warranty of\r
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
++;; General Public License for more details.\r
++;;\r
++;; You should have received a copy of the GNU General Public License\r
++;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.\r
++;;\r
++;; Authors: Austin Clements <aclements@csail.mit.edu>\r
++\r
++(defun batch-make-deps ()\r
++ "Invoke `make-deps' for each file on the command line."\r
++\r
++ (setq debug-on-error t)\r
++ (dolist (file command-line-args-left)\r
++ (let ((default-directory command-line-default-directory))\r
++ (find-file-literally file))\r
++ (make-deps command-line-default-directory))\r
++ (kill-emacs))\r
++\r
++(defun make-deps (&optional dir)\r
++ "Print make dependencies for the current buffer.\r
++\r
++This prints make dependencies to `standard-output' based on the\r
++top-level `require' expressions in the current buffer. Paths in\r
++rules will be given relative to DIR, or `default-directory'."\r
++\r
++ (setq dir (or dir default-directory))\r
++ (save-excursion\r
++ (goto-char (point-min))\r
++ (condition-case nil\r
++ (while t\r
++ (let ((form (read (current-buffer))))\r
++ ;; Is it a (require 'x) form?\r
++ (when (and (listp form) (= (length form) 2)\r
++ (eq (car form) 'require)\r
++ (listp (cadr form)) (= (length (cadr form)) 2)\r
++ (eq (car (cadr form)) 'quote)\r
++ (symbolp (cadr (cadr form))))\r
++ ;; Find the required library\r
++ (let* ((name (cadr (cadr form)))\r
++ (fname (locate-library (symbol-name name))))\r
++ ;; Is this file and the library in the same directory?\r
++ ;; If not, assume it's a system library and don't\r
++ ;; bother depending on it.\r
++ (when (and fname\r
++ (string= (file-name-directory (buffer-file-name))\r
++ (file-name-directory fname)))\r
++ ;; Print the dependency\r
++ (princ (format "%s.elc: %s.elc\n"\r
++ (file-name-sans-extension\r
++ (file-relative-name (buffer-file-name) dir))\r
++ (file-name-sans-extension\r
++ (file-relative-name fname dir)))))))))\r
++ (end-of-file nil))))\r
+-- \r
+1.7.10.4\r
+\r