aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2015-06-30 14:59:04 -0400
committerGlenn Morris2015-06-30 14:59:04 -0400
commit5200c2baefbc855d36c07e2d6a9c1adeb693a542 (patch)
treee2c67a0c9e71041a150b38fec60cedeb2d69fe7d
parent0dfea4562e19f5cc90c77ff5f9a96f9e94caf57c (diff)
downloademacs-5200c2baefbc855d36c07e2d6a9c1adeb693a542.tar.gz
emacs-5200c2baefbc855d36c07e2d6a9c1adeb693a542.zip
Improve reproducibility of generated loaddefs file.
* lisp/emacs-lisp/autoload.el (autoload-generate-file-autoloads): Make the return value the modtime of the input file (if no autoloads). (update-directory-autoloads): In the "no autoloads" section, use "most recent modtime" rather than "current time". ; http://lists.gnu.org/archive/html/emacs-devel/2015-06/msg00688.html
-rw-r--r--lisp/emacs-lisp/autoload.el281
1 files changed, 144 insertions, 137 deletions
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el
index a6fefebf3f5..9d1abdddb2b 100644
--- a/lisp/emacs-lisp/autoload.el
+++ b/lisp/emacs-lisp/autoload.el
@@ -522,116 +522,119 @@ If OUTFILE is non-nil and FILE specifies a `generated-autoload-file'
522different from OUTFILE, then OUTBUF is ignored. 522different from OUTFILE, then OUTBUF is ignored.
523 523
524Return non-nil if and only if FILE adds no autoloads to OUTFILE 524Return non-nil if and only if FILE adds no autoloads to OUTFILE
525\(or OUTBUF if OUTFILE is nil)." 525\(or OUTBUF if OUTFILE is nil). The actual return value is
526 (catch 'done 526FILE's modification time."
527 (let (load-name 527 (let (load-name
528 (print-length nil) 528 (print-length nil)
529 (print-level nil) 529 (print-level nil)
530 (print-readably t) ; This does something in Lucid Emacs. 530 (print-readably t) ; This does something in Lucid Emacs.
531 (float-output-format nil) 531 (float-output-format nil)
532 (visited (get-file-buffer file)) 532 (visited (get-file-buffer file))
533 (otherbuf nil) 533 (otherbuf nil)
534 (absfile (expand-file-name file)) 534 (absfile (expand-file-name file))
535 ;; nil until we found a cookie. 535 ;; nil until we found a cookie.
536 output-start) 536 output-start)
537 (with-current-buffer (or visited 537 (when
538 ;; It is faster to avoid visiting the file. 538 (catch 'done
539 (autoload-find-file file)) 539 (with-current-buffer (or visited
540 ;; Obey the no-update-autoloads file local variable. 540 ;; It is faster to avoid visiting the file.
541 (unless no-update-autoloads 541 (autoload-find-file file))
542 (or noninteractive (message "Generating autoloads for %s..." file)) 542 ;; Obey the no-update-autoloads file local variable.
543 (setq load-name 543 (unless no-update-autoloads
544 (if (stringp generated-autoload-load-name) 544 (or noninteractive (message "Generating autoloads for %s..." file))
545 generated-autoload-load-name 545 (setq load-name
546 (autoload-file-load-name absfile))) 546 (if (stringp generated-autoload-load-name)
547 ;; FIXME? Comparing file-names for equality with just equal 547 generated-autoload-load-name
548 ;; is fragile, eg if one has an automounter prefix and one 548 (autoload-file-load-name absfile)))
549 ;; does not, but both refer to the same physical file. 549 ;; FIXME? Comparing file-names for equality with just equal
550 (when (and outfile 550 ;; is fragile, eg if one has an automounter prefix and one
551 (not 551 ;; does not, but both refer to the same physical file.
552 (if (memq system-type '(ms-dos windows-nt)) 552 (when (and outfile
553 (equal (downcase outfile) 553 (not
554 (downcase (autoload-generated-file))) 554 (if (memq system-type '(ms-dos windows-nt))
555 (equal outfile (autoload-generated-file))))) 555 (equal (downcase outfile)
556 (setq otherbuf t)) 556 (downcase (autoload-generated-file)))
557 (save-excursion 557 (equal outfile (autoload-generated-file)))))
558 (save-restriction 558 (setq otherbuf t))
559 (widen) 559 (save-excursion
560 (when autoload-builtin-package-versions 560 (save-restriction
561 (let ((version (lm-header "version")) 561 (widen)
562 package) 562 (when autoload-builtin-package-versions
563 (and version 563 (let ((version (lm-header "version"))
564 (setq version (ignore-errors (version-to-list version))) 564 package)
565 (setq package (or (lm-header "package") 565 (and version
566 (file-name-sans-extension 566 (setq version (ignore-errors (version-to-list version)))
567 (file-name-nondirectory file)))) 567 (setq package (or (lm-header "package")
568 (setq output-start (autoload--setup-output 568 (file-name-sans-extension
569 otherbuf outbuf absfile load-name)) 569 (file-name-nondirectory file))))
570 (let ((standard-output (marker-buffer output-start)) 570 (setq output-start (autoload--setup-output
571 (print-quoted t)) 571 otherbuf outbuf absfile load-name))
572 (princ `(push (purecopy 572 (let ((standard-output (marker-buffer output-start))
573 ',(cons (intern package) version)) 573 (print-quoted t))
574 package--builtin-versions)) 574 (princ `(push (purecopy
575 (princ "\n"))))) 575 ',(cons (intern package) version))
576 576 package--builtin-versions))
577 (goto-char (point-min)) 577 (princ "\n")))))
578 (while (not (eobp)) 578
579 (skip-chars-forward " \t\n\f") 579 (goto-char (point-min))
580 (cond 580 (while (not (eobp))
581 ((looking-at (regexp-quote generate-autoload-cookie)) 581 (skip-chars-forward " \t\n\f")
582 ;; If not done yet, figure out where to insert this text. 582 (cond
583 (unless output-start 583 ((looking-at (regexp-quote generate-autoload-cookie))
584 (setq output-start (autoload--setup-output 584 ;; If not done yet, figure out where to insert this text.
585 otherbuf outbuf absfile load-name))) 585 (unless output-start
586 (autoload--print-cookie-text output-start load-name file)) 586 (setq output-start (autoload--setup-output
587 ((looking-at ";") 587 otherbuf outbuf absfile load-name)))
588 ;; Don't read the comment. 588 (autoload--print-cookie-text output-start load-name file))
589 (forward-line 1)) 589 ((looking-at ";")
590 (t 590 ;; Don't read the comment.
591 (forward-sexp 1) 591 (forward-line 1))
592 (forward-line 1)))))) 592 (t
593 593 (forward-sexp 1)
594 (when output-start 594 (forward-line 1))))))
595 (let ((secondary-autoloads-file-buf 595
596 (if otherbuf (current-buffer)))) 596 (when output-start
597 (with-current-buffer (marker-buffer output-start) 597 (let ((secondary-autoloads-file-buf
598 (save-excursion 598 (if otherbuf (current-buffer))))
599 ;; Insert the section-header line which lists the file name 599 (with-current-buffer (marker-buffer output-start)
600 ;; and which functions are in it, etc. 600 (save-excursion
601 (goto-char output-start) 601 ;; Insert the section-header line which lists the file name
602 (let ((relfile (file-relative-name absfile))) 602 ;; and which functions are in it, etc.
603 (autoload-insert-section-header 603 (goto-char output-start)
604 (marker-buffer output-start) 604 (let ((relfile (file-relative-name absfile)))
605 () load-name relfile 605 (autoload-insert-section-header
606 (if secondary-autoloads-file-buf 606 (marker-buffer output-start)
607 ;; MD5 checksums are much better because they do not 607 () load-name relfile
608 ;; change unless the file changes (so they'll be 608 (if secondary-autoloads-file-buf
609 ;; equal on two different systems and will change 609 ;; MD5 checksums are much better because they do not
610 ;; less often than time-stamps, thus leading to fewer 610 ;; change unless the file changes (so they'll be
611 ;; unneeded changes causing spurious conflicts), but 611 ;; equal on two different systems and will change
612 ;; using time-stamps is a very useful optimization, 612 ;; less often than time-stamps, thus leading to fewer
613 ;; so we use time-stamps for the main autoloads file 613 ;; unneeded changes causing spurious conflicts), but
614 ;; (loaddefs.el) where we have special ways to 614 ;; using time-stamps is a very useful optimization,
615 ;; circumvent the "random change problem", and MD5 615 ;; so we use time-stamps for the main autoloads file
616 ;; checksum in secondary autoload files where we do 616 ;; (loaddefs.el) where we have special ways to
617 ;; not need the time-stamp optimization because it is 617 ;; circumvent the "random change problem", and MD5
618 ;; already provided by the primary autoloads file. 618 ;; checksum in secondary autoload files where we do
619 (md5 secondary-autoloads-file-buf 619 ;; not need the time-stamp optimization because it is
620 ;; We'd really want to just use 620 ;; already provided by the primary autoloads file.
621 ;; `emacs-internal' instead. 621 (md5 secondary-autoloads-file-buf
622 nil nil 'emacs-mule-unix) 622 ;; We'd really want to just use
623 (nth 5 (file-attributes relfile)))) 623 ;; `emacs-internal' instead.
624 (insert ";;; Generated autoloads from " relfile "\n"))) 624 nil nil 'emacs-mule-unix)
625 (insert generate-autoload-section-trailer)))) 625 (nth 5 (file-attributes relfile))))
626 (or noninteractive 626 (insert ";;; Generated autoloads from " relfile "\n")))
627 (message "Generating autoloads for %s...done" file))) 627 (insert generate-autoload-section-trailer))))
628 (or visited 628 (or noninteractive
629 ;; We created this buffer, so we should kill it. 629 (message "Generating autoloads for %s...done" file)))
630 (kill-buffer (current-buffer)))) 630 (or visited
631 (or (not output-start) 631 ;; We created this buffer, so we should kill it.
632 ;; If the entries were added to some other buffer, then the file 632 (kill-buffer (current-buffer))))
633 ;; doesn't add entries to OUTFILE. 633 (or (not output-start)
634 otherbuf)))) 634 ;; If the entries were added to some other buffer, then the file
635 ;; doesn't add entries to OUTFILE.
636 otherbuf))
637 (nth 5 (file-attributes absfile)))))
635 638
636(defun autoload-save-buffers () 639(defun autoload-save-buffers ()
637 (while autoload-modified-buffers 640 (while autoload-modified-buffers
@@ -757,7 +760,7 @@ write its autoloads into the specified file instead."
757 t files-re)) 760 t files-re))
758 dirs))) 761 dirs)))
759 (done ()) 762 (done ())
760 (this-time (current-time)) 763 (last-time)
761 ;; Files with no autoload cookies or whose autoloads go to other 764 ;; Files with no autoload cookies or whose autoloads go to other
762 ;; files because of file-local autoload-generated-file settings. 765 ;; files because of file-local autoload-generated-file settings.
763 (no-autoloads nil) 766 (no-autoloads nil)
@@ -782,14 +785,14 @@ write its autoloads into the specified file instead."
782 ;; There shouldn't be more than one such entry. 785 ;; There shouldn't be more than one such entry.
783 ;; Remove the obsolete section. 786 ;; Remove the obsolete section.
784 (autoload-remove-section (match-beginning 0)) 787 (autoload-remove-section (match-beginning 0))
785 (let ((last-time (nth 4 form))) 788 (setq last-time (nth 4 form))
786 (dolist (file file) 789 (dolist (file file)
787 (let ((file-time (nth 5 (file-attributes file)))) 790 (let ((file-time (nth 5 (file-attributes file))))
788 (when (and file-time 791 (when (and file-time
789 (not (time-less-p last-time file-time))) 792 (not (time-less-p last-time file-time)))
790 ;; file unchanged 793 ;; file unchanged
791 (push file no-autoloads) 794 (push file no-autoloads)
792 (setq files (delete file files))))))) 795 (setq files (delete file files))))))
793 ((not (stringp file))) 796 ((not (stringp file)))
794 ((or (not (file-exists-p file)) 797 ((or (not (file-exists-p file))
795 ;; Remove duplicates as well, just in case. 798 ;; Remove duplicates as well, just in case.
@@ -811,24 +814,28 @@ write its autoloads into the specified file instead."
811 (push file done) 814 (push file done)
812 (setq files (delete file files))))) 815 (setq files (delete file files)))))
813 ;; Elements remaining in FILES have no existing autoload sections yet. 816 ;; Elements remaining in FILES have no existing autoload sections yet.
814 (dolist (file files) 817 (let ((no-autoloads-time (or last-time '(0 0 0 0))) file-time)
815 (cond 818 (dolist (file files)
816 ((member (expand-file-name file) autoload-excludes) nil) 819 (cond
817 ;; Passing nil as second argument forces 820 ((member (expand-file-name file) autoload-excludes) nil)
818 ;; autoload-generate-file-autoloads to look for the right 821 ;; Passing nil as second argument forces
819 ;; spot where to insert each autoloads section. 822 ;; autoload-generate-file-autoloads to look for the right
820 ((autoload-generate-file-autoloads file nil buffer-file-name) 823 ;; spot where to insert each autoloads section.
821 (push file no-autoloads)))) 824 ((setq file-time
822 825 (autoload-generate-file-autoloads file nil buffer-file-name))
823 (when no-autoloads 826 (push file no-autoloads)
824 ;; Sort them for better readability. 827 (if (time-less-p no-autoloads-time file-time)
825 (setq no-autoloads (sort no-autoloads 'string<)) 828 (setq no-autoloads-time file-time)))))
826 ;; Add the `no-autoloads' section. 829
827 (goto-char (point-max)) 830 (when no-autoloads
828 (search-backward "\f" nil t) 831 ;; Sort them for better readability.
829 (autoload-insert-section-header 832 (setq no-autoloads (sort no-autoloads 'string<))
830 (current-buffer) nil nil no-autoloads this-time) 833 ;; Add the `no-autoloads' section.
831 (insert generate-autoload-section-trailer)) 834 (goto-char (point-max))
835 (search-backward "\f" nil t)
836 (autoload-insert-section-header
837 (current-buffer) nil nil no-autoloads no-autoloads-time)
838 (insert generate-autoload-section-trailer)))
832 839
833 (let ((version-control 'never)) 840 (let ((version-control 'never))
834 (save-buffer)) 841 (save-buffer))