Подтвердить что ты не робот

Как автоматически (повторно) компилировать пакеты ELPA?

Теперь я устанавливаю столько, сколько могу, через MELPA и Marmalade, и я управляю своим ~/.emacs.d с помощью git. Однако у меня есть файлы git ignore *.elc.

Это означает, что, когда я устанавливаю пакет в одной системе и затем запускаю другую систему, git pull дает мне только файлы *.el. Использование этих файлов часто медленнее, чем при использовании *.elc.

Я попытался добавить следующее к ~/.emacs.d/init.el:

;; load the packages we've installed. Note that package-install
;; byte-compiles the packages, but .elc is ignored by git so we force recompilation here
(byte-recompile-directory (expand-file-name "~/.emacs.d/elpa") 0)
(package-initialize)

К сожалению, это не эквивалентно компиляции, сделанной package.el. Например, если я устанавливаю emacs-eclim, package.el не компилирует emacs-eclim/company-emacs-eclim.el, и я получаю следующую ошибку:

Leaving directory `/home/wilfred/.emacs.d/elpa'

Compiling file /home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/company-emacs-eclim.el at Mon Mar 11 15:40:01 2013
Entering directory `/home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/'
company-emacs-eclim.el:35:1:Error: Cannot open load file: eclim
Warning: reference to free variable `multiple-cursors-mode'
Warning: reference to free variable `mc--read-char'
Warning: assignment to free variable `mc--read-char'
Warning: reference to free variable `multiple-cursors-mode'
Warning: reference to free variable `mc--read-quoted-char'
Warning: assignment to free variable `mc--read-quoted-char'
Warning: reference to free variable `rectangular-region-mode'
Warning: reference to free variable `rectangular-region-mode'

Как сделать Emacs байт-компилировать только те же файлы, что и package.el?

4b9b3361

Ответ 1

package.el фактически использует точно такой же метод, он просто перекомпилирует при запуске, что делает ошибки более заметными.

Используемая функция package--make-autoloads-and-compile, которая вызывает:

(byte-recompile-directory pkg-dir 0 t)

Итак, исходный код в вопросе правильный. Однако, чтобы перекомпилировать каталог, который еще не скомпилирован, вы можете сделать следующее:

(require 'dash)
(require 'f)

(defun was-compiled-p (path)
  "Does the directory at PATH contain any .elc files?"
  (--any-p (f-ext? it "elc") (f-files path)))

(defun ensure-packages-compiled ()
  "If any packages installed with package.el aren't compiled yet, compile them."
  (--each (f-directories package-user-dir)
    (unless (was-compiled-p it)
      (byte-recompile-directory it 0))))

(ensure-packages-compiled)

Ответ 2

Я рекомендую не хранить пакеты в управлении версиями (вы не ставили бы файлы .o под контролем версий, не так ли?). Вот код, который я использую, чтобы синхронизировать мои пакеты:

(setq jpk-packages
      '(
        ac-dabbrev
        ...
        yasnippet
        ))

(package-initialize)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/"))
(add-to-list 'package-archives
             '("org" . "http://orgmode.org/elpa/"))

(when (not package-archive-contents)
  (package-refresh-contents))

(dolist (pkg jpk-packages)
  (when (and (not (package-installed-p pkg))
           (assoc pkg package-archive-contents))
    (package-install pkg)))

(defun package-list-unaccounted-packages ()
  "Like `package-list-packages', but shows only the packages that
  are installed and are not in `jpk-packages'.  Useful for
  cleaning out unwanted packages."
  (interactive)
  (package-show-package-list
   (remove-if-not (lambda (x) (and (not (memq x jpk-packages))
                            (not (package-built-in-p x))
                            (package-installed-p x)))
                  (mapcar 'car package-archive-contents))))

Я поставил выше в init.el(который, конечно же, находится под управлением версиями), и он устанавливает все пакеты, которые еще не существуют, когда emacs запускается. Обновление выполняется из буфера package-list-packages. package-list-unaccounted-packages показывает все пакеты, которые были установлены, но не в моем списке jpk-packages, и упрощает удаление тех, которые я вынул из списка.

Чтобы ответить на ваш конкретный вопрос, я просто удалю каталог elpa и переустановит все (используя приведенный выше код).

Ответ 3

Решение, которое мне нравится в более общем вопросе "Как автоматически перекомпилировать устаревший файл .elc", заключается в использовании https://github.com/tarsius/auto-compile

Раньше у меня было множество пользовательских решений, которые охватывали большинство ситуаций, с которыми я столкнулся, но эта библиотека охватывает все, что я делал, и, кроме того,. Просто инициализируйте его перед загрузкой чего-либо еще, и вы отсортированы.

Что касается первоначального вопроса об отсутствии компиляции файлов, которые не были первоначально скомпилированы, то что аргумент 0 для byte-recompile-directory делает, поэтому вы явно просите об этом. По умолчанию используется только перекомпилирование существующих устаревших файлов .elc, поэтому вы должны просто удалить это 0.

Ответ 4

Я не знаю ответа на вашу конкретную проблему о байтовых компиляциях пакетов точно так же, как package.el.

Однако для вашей более общей проблемы сохранения вашего каталога конфигурации emacs в git при установке расширений через Melpa или marmalade, я предлагаю вам взглянуть на pallet, который был разработан для решения этой самой проблемы.

Ответ 5

Проблема заключается в том, что вы байт-компилируете файлы перед инициализацией своих пакетов. Если вы переключаете две линии, ваша проблема должна исчезнуть. Ошибка, которую вы получаете (Cannot open load file: eclim), потому что ~/.emacs.d/elpa/emacs-eclim-20130310.1237/ еще не находится в вашем load-path, а package-initialize добавит ее в ваш load-path (наряду с несколькими другими вещами).

Ответ 6

(byte-compile-file) работал у меня, когда мне нужно вручную перекомпилировать пакеты, которые я ранее установил с помощью elpa.

В частности, для этой ситуации: https://github.com/yjwen/org-reveal/issues/76t