18.2 Переменные нативной компиляции

В этом разделе документируются переменные, управляющие нативной компиляцией.

Пользовательская опция: native-comp-speed

Эта переменная задаёт уровень оптимизации для нативной компиляции. Её значение должно быть числом от −1 до 3. Значения от 0 до 3 задают уровни оптимизации, эквивалентные соответствующим параметрам командной строки компилятора -O0, -O1 и т.д. Значение −1 означает отключение нативной компиляции: функции и файлы будут только байт-компилироваться; однако файлы *.eln всё равно будут создаваться, но они будут содержать скомпилированный код в байт-коде. (Этого можно добиться на уровне функций, используя форму (declare (speed -1)), см. Форма declare.) Значение по умолчанию — 2.

Пользовательская опция: compilation-safety

Эта переменная задаёт уровень безопасности для генерируемого машинного кода. Значение должно быть числом 0 или 1 со следующим смыслом:

0

Сгенерированный код может работать некорректно (вплоть до аварийного завершения Emacs), если объявление функции не описывает правильно, что функция делает или как она вызывается, и функция скомпилирована нативно.

1

Сгенерированный код должен создаваться безопасным способом, даже если функции объявлены неверно.

Это также можно контролировать на уровне функций с помощью формы declare с атрибутом safety, см. Форма declare.

Пользовательская опция: native-comp-debug

Эта переменная задаёт уровень отладочной информации, создаваемой при нативной компиляции. Её значение должно быть числом от нуля до 3 со следующим смыслом:

0

Без отладочного вывода. Это значение по умолчанию.

1

Включить отладочные символы в машинный код. Это упрощает отладку машинного кода с помощью отладчиков, таких как gdb.

2

Как 1, и дополнительно выгружать псевдо-C код.

3

Как 2, и дополнительно выгружать промежуточные проходы GCC и файл журнала libgccjit.

При генерации псевдо-C код помещается в тот же каталог, что и соответствующий файл .eln.

Пользовательская опция: native-comp-verbose

Эта переменная управляет подробностью вывода при нативной компиляции, подавляя часть или все сообщения журнала, выдаваемые ею. Если её значение равно нулю (по умолчанию), все сообщения журнала подавляются. Установка значения от 1 до 3 разрешает журналирование сообщений, уровень которых выше указанного значения. Значения имеют следующую интерпретацию:

0

Без журналирования. Это значение по умолчанию.

1

Журналировать финальное представление кода в LIMPLE.

2

Журналировать LAP, финальный LIMPLE и некоторую дополнительную информацию о проходах.

3

Максимальная подробность: журналировать всё.

Пользовательская опция: native-comp-async-jobs-number

Эта переменная определяет максимальное число подпроцессов нативной компиляции, запускаемых одновременно. Она должна быть неотрицательным числом. Значение по умолчанию — ноль, что означает использовать половину количества исполнительных блоков CPU, или 1, если CPU имеет только один исполнительный блок.

Пользовательская опция: native-comp-async-report-warnings-errors

Если значение этой переменной не равно nil, предупреждения и ошибки из асинхронных подпроцессов нативной компиляции сообщаются в основном сеансе Emacs в буфере с именем *Warnings*. Значение по умолчанию t означает отображение полученного буфера. Чтобы записывать предупреждения без всплывания буфера *Warnings*, установите эту переменную в silent.

Частой причиной возникновения предупреждений при асинхронной нативной компиляции является компиляция файла, в котором отсутствует некоторый require необходимого компонента. Этот компонент может быть загружен в основной Emacs, но поскольку нативная компиляция всегда запускается из подпроцесса с чистой средой, для подпроцесса это может быть не так.

Пользовательская опция: native-comp-async-query-on-exit

Если значение этой переменной не равно nil, Emacs при выходе запросит подтверждение на завершение и уничтожение всё ещё работающих асинхронных подпроцессов нативной компиляции, что предотвратит запись соответствующих файлов .eln. Если значение равно nil (по умолчанию), Emacs завершит эти подпроцессы без запроса.

Переменная native-comp-eln-load-path содержит список каталогов, в которых Emacs ищет файлы *.eln (см. Поиск библиотек); в этой роли она является аналогом load-path, используемого для поиска файлов *.el и *.elc. Каталоги из этого списка также используются для записи файлов *.eln, создаваемых асинхронной нативной компиляцией; в частности, Emacs будет записывать эти файлы в первый доступный для записи каталог из списка. Таким образом, вы можете управлять местом хранения результатов нативной компиляции, изменяя значение этой переменной.

Переменная: native-comp-jit-compilation

Эта переменная, если не равна nil, включает асинхронную (т.н. точно-вовремя, или JIT) нативную компиляцию файлов *.elc, загружаемых Emacs, для которых соответствующие файлы *.eln ещё не существуют. Эта JIT-компиляция использует отдельные подпроцессы Emacs, работающие в пакетном режиме, в соответствии со значением native-comp-async-jobs-number. Когда JIT-компиляция Lisp-файла успешно завершается, полученный файл .eln загружается, и его код заменяет определения функций, предоставленных файлом .elc.

Установка значения native-comp-jit-compilation в nil отключает JIT-нативную компиляцию. Однако даже когда JIT-нативная компиляция отключена, Emacs всё равно может запускать асинхронные подпроцессы нативной компиляции для создания трамплинов. Для управления этим используется отдельная переменная, описанная ниже.

Переменная: native-comp-enable-subr-trampolines

Эта переменная управляет генерацией трамплинов. Трамплин — это небольшой фрагмент машинного кода, необходимый для разрешения вызовов примитивов Lisp, которые были переопределены или обёрнуты советами, из Lisp-кода, скомпилированного нативно с native-comp-speed, установленным в 2 или выше. Emacs сохраняет сгенерированные трамплины в отдельных файлах *.eln. По умолчанию значение этой переменной равно t, что включает генерацию файлов трамплинов; установка её в nil отключает генерацию трамплинов. Учтите, что если трамплин, необходимый для переопределения или обёртывания примитива, недоступен и не может быть сгенерирован, вызовы этого примитива из нативно скомпилированного Lisp будут игнорировать переопределения и советы и будут вести себя так, как если бы примитив вызывался напрямую из C. Поэтому мы не рекомендуем отключать генерацию трамплинов, если вы не уверены, что все трамплины, необходимые вашим Lisp-программам, уже скомпилированы и доступны Emacs.

Значение этой переменной также может быть строкой, в этом случае она задаёт имя каталога для хранения сгенерированных файлов трамплинов *.eln, переопределяя каталоги из native-comp-eln-load-path. Это полезно, если вы хотите, чтобы трамплины генерировались по мере необходимости, но не хотите хранить их в домашнем каталоге пользователя HOME или в других общедоступных каталогах, где хранятся файлы *.eln. Однако, в отличие от каталогов в native-comp-eln-load-path, трамплины будут сохраняться в каталоге, указанном значением этой переменной, а не в его подкаталоге, зависящем от версии. Если имя этого каталога не является абсолютным, оно интерпретируется относительно invocation-directory (см. Окружение операционной системы)

Если эта переменная не равна nil и Emacs должен создать трамплин, но не может найти ни одного доступного для записи каталога для его хранения, он сохранит его в temporary-file-directory (см. Генерация уникальных имён файлов).

Трамплины, созданные, когда не найден доступный для записи каталог для их хранения, или когда эта переменная является строкой, будут доступны только в течение текущего сеанса Emacs, поскольку Emacs не ищет трамплины ни в одном из этих мест.