               (make-hash-table :test #'equal)))))
 
 (defun straight--save-build-cache ()
-  "Write the build cache from `straight--build-cache' into build-cache.el."
+  "Write the build cache from `straight--build-cache' into build-cache.el.
+Also remove this function from `after-init-hook' and
+`straight--after-reinit-hook', the latter allowing further
+reinits to properly detect whether loading has taken place at
+least once."
   (with-temp-file (straight--file "build-cache.el")
-    (pp straight--build-cache (current-buffer))))
+    (pp straight--build-cache (current-buffer)))
+  (remove-hook 'after-init-hook #'straight--save-build-cache)
+  (remove-hook 'straight--after-reinit-hook #'straight--save-build-cache))
 
 (defvar straight--finalization-guaranteed nil
   "Non-nil if `straight-declare-init-finished' is guaranteed to be called.

            t))))))

;;;###autoload
(defun straight-rebuild-package (package &optional recursive)
  "Rebuild a PACKAGE.
PACKAGE is a string naming a package. Interactively, select
PACKAGE from the known packages in the current Emacs session
using `completing-read'. With prefix argument RECURSIVE, rebuild
all dependencies as well."
  (interactive
   (list
    (straight--select-package "Rebuild package")


;;;###autoload
(defun straight-rebuild-all ()
  "Rebuild all packages.
See also `straight-check-all' and `straight-rebuild-package'."
  (interactive)
  (let ((straight--packages-to-rebuild :all)
        (straight--packages-not-to-rebuild
         (make-hash-table :test #'equal))
        ;; See `straight-check-all' for discussion.
        (straight--reinit-in-progress t))
    (unwind-protect
        (dolist (package (hash-table-keys straight--recipe-cache))
          (straight-use-package (intern package)))
      (run-hooks 'straight--after-reinit-hook))))

;;;###autoload
(defun straight-update-package (package)
