Spec-Zone.ru › OCaml
☰Инструменты OCaml
  • Пакетная компиляция (ocamlc)
  • Система верхнего уровня или REPL (ocaml)
  • Система выполнения (ocamlrun)
  • Компиляция в машинный код (ocamlopt)
  • Генераторы лексических и синтаксических анализаторов (ocamllex, ocamlyacc)
  • Генератор зависимостей (ocamldep)
  • Генератор документации (ocamldoc)
  • Отладчик (ocamldebug)
  • Профилирование (ocamlprof)
  • Интерфейсы C с OCaml
  • Оптимизация с Flambda
  • Тестирование на уязвимости с afl-fuzz
  • Отслеживание выполнения с событиями runtime
  • Преобразование программы «Tail Modulo Constructor»
  • Обнаружение гонок данных в runtime с ThreadSanitizer

Глава 16 Компиляция в машинный код (ocamlopt)

В этой главе описывается высокопроизводительный компилятор OCaml для машинного кода ocamlopt, который компилирует исходные файлы OCaml в файлы объектов машинного кода и связывает эти файлы объектов, чтобы создать автономные исполняемые файлы.

Компилятор машинного кода доступен только на определённых платформах. Он генерирует код, работающий быстрее, чем байткод, созданный ocamlc, за счёт увеличения времени компиляции и размера исполняемого файла. Совместимость с компилятором байткода очень высока: тот же исходный код должен работать одинаково, когда компилируется с помощью ocamlc и ocamlopt.

Невозможно смешивать файлы объектов машинного кода, созданные ocamlopt, с файлами объектов байткода, созданными ocamlc: программа должна быть скомпилирована полностью с ocamlopt или полностью с ocamlc. Файлы объектов машинного кода, созданные ocamlopt, не могут быть загружены в систему верхнего уровня ocaml.

1 Обзор компилятора

Команда ocamlopt имеет интерфейс командной строки, очень похожий на интерфейс ocamlc. Она принимает те же типы аргументов и обрабатывает их последовательно после обработки всех опций:

  • Аргументы, заканчивающиеся на .mli, рассматриваются как исходные файлы для интерфейсов единиц компиляции. Интерфейсы определяют имена, экспортируемые единицами компиляции: они объявляют имена значений с их типами, определяют публичные типы данных, объявляют абстрактные типы данных и так далее. Из файла x.mli компилятор ocamlopt генерирует скомпилированный интерфейс в файле x.cmi. Сгенерированный интерфейс идентичен интерфейсу, сгенерированному компилятором байткода ocamlc.
  • Аргументы, заканчивающиеся на .ml, рассматриваются как исходные файлы для реализации единиц компиляции. Реализации предоставляют определения имён, экспортируемых единицей, а также содержат выражения, которые должны выполняться для их побочных эффектов. Из файла x.ml компилятор ocamlopt генерирует два файла: x.o, содержащий машинный код, и x.cmx, содержащий дополнительную информацию для связывания и оптимизации клиентов единицы. Скомпилированную реализацию всегда следует называть x.cmx (если предоставлен файл .o или .obj, ocamlopt предполагает, что он содержит код, скомпилированный из C, а не из OCaml).

    Реализация проверяется по файлу интерфейса x.mli (если он существует) так, как описано в руководстве для ocamlc (глава ‍13).

  • Аргументы, заканчивающиеся на .cmx, рассматриваются как скомпилированный машинный код. Эти файлы связываются вместе с файлами объектов, полученными из аргументов .ml (если таковые имеются), и стандартной библиотекой OCaml, чтобы создать исполняемый файл машинного кода. Порядок представления аргументов .cmx и .ml в командной строке важен: единицы компиляции инициализируются в этом порядке во время выполнения, и это ошибка на этапе компоновки, если компонент единицы используется до его инициализации. Поэтому, данный файл x.cmx должен предшествовать всем файлам .cmx, которые ссылаются на единицу x.
  • Аргументы, заканчивающиеся на .cmxa, рассматриваются как библиотеки машинного кода. Такая библиотека содержит два файла (lib.cmxa и lib.a/.lib) набор файлов объектов (.cmx и .o/.obj файлы). Библиотеки строятся с помощью ocamlopt -a (см. описание опции -a ниже).
  • Аргументы, заканчивающиеся на .c, передаются компилятору C, который генерирует файл объекта .o/.obj. Этот файл объекта связывается с программой.
  • Аргументы, заканчивающиеся на .o, .a или .so (.obj, .lib и .dll в Windows) предполагаются файлами объектов C и библиотеками. Они связываются с программой.

Выходной файл этапа связывания — обычный исполняемый файл Unix или Windows. Он не требует ocamlrun для запуска.

Компилятор может выводить информацию о своих внутренних этапах:

  • Файлы .cmt для реализации единицы компиляции и .cmti для сигнатур, если передана опция -bin-annot (см. описание -bin-annot ниже). Каждый такой файл содержит типизированное абстрактное синтаксическое дерево (AST), которое генерируется во время проверки типов. Это дерево содержит всю доступную информацию о местоположении и типе каждого термина в исходном файле. AST является частичным, если проверка типов была неуспешной.

    Файлы .cmt и .cmti обычно полезны для инструментов инспекции кода.

  • Файлы .cmir-linear для реализации единицы компиляции, если передана опция -save-ir-after scheduling. Каждый такой файл содержит низкоуровневое промежуточное представление, полученное при прохождении планирования инструкций.

    Внешний инструмент может выполнить низкоуровневую оптимизацию, такую как компоновка кода, преобразуя файл .cmir-linear. Для продолжения компиляции компилятор может быть вызван с (возможно изменённым) файлом .cmir-linear в качестве аргумента вместо соответствующего исходного файла.

2 Опции

Следующие опции командной строки распознаются компилятором ocamlopt. Опции -pack, -a, -shared, -c, -output-obj и -output-complete-obj являются взаимоисключающими.

-a
Создать библиотеку (.cmxa и .a/.lib файлы) из файлов с объектным кодом (.cmx и .o/.obj файлы), переданных в командной строке, вместо их объединения в исполняемый файл. Имя библиотеки должно быть задано с помощью опции -o.

Если опции -cclib или -ccopt переданы в командной строке, эти опции сохраняются в результирующей библиотеке .cmxa. Затем, связывание с этой библиотекой автоматически добавляет обратно опции -cclib и -ccopt, как если бы они были заданы в командной строке, если не указана опция -noautolink.

-absname
Принудительно отображать сообщения об ошибках с абсолютными путями для имён файлов.
-no-absname
Не пытаться отображать абсолютные имена файлов в сообщениях об ошибках.
-annot
Устарело начиная с OCaml 4.11. Используйте -bin-annot вместо этого.
-args filename
Читать дополнительные аргументы командной строки, завершённые новой строкой, из файла filename.
-args0 filename
Читать дополнительные аргументы командной строки, завершённые нулём, из файла filename.
-bin-annot
Выводить подробную информацию о компиляции (типы, связи, вызовы с хвостовой рекурсией и т.д.) в двоичном формате. Информация для файла src.ml (соответственно, src.mli) помещается в файл src.cmt (соответственно, src.cmti). В случае ошибки типизации выводить всю информацию, полученную проверкой типов, перед ошибкой. Файлы *.cmt и *.cmti, созданные с помощью -bin-annot, содержат больше информации и значительно компактнее, чем файлы, созданные с помощью -annot.
-c
Только компиляция. Игнорировать этап компоновки компиляции. Файлы исходного кода преобразуются в скомпилированные файлы, но исполняемый файл не создаётся. Эта опция полезна для компиляции модулей по отдельности.
-cc ccomp
Использовать ccomp как компоновщик C для создания конечного исполняемого файла и как компилятор C для компиляции файлов исходного кода .c. При связывании файлов объектов, созданных с помощью компилятора C++ (например, g++ или clang++), рекомендуется использовать -cc c++.
-cclib -llibname
Передать опцию -llibname компоновщику. Это приводит к тому, что указанная библиотека C связывается с программой.
-ccopt option
Передать данную опцию компилятору и компоновщику C. Например, -ccopt -Ldir заставляет компоновщик C искать библиотеки C в каталоге dir.
-cmi-file filename
Использовать указанный интерфейсный файл для проверки типов файла исходного кода ML для компиляции. Когда эта опция не указана, компилятор ищет файл .mli с тем же базовым именем, что и реализация, которую он компилирует, и в том же каталоге. Если такой файл найден, компилятор ищет соответствующий файл .cmi в включённых каталогах и сообщает об ошибке, если не может его найти.
-color mode
Включить или выключить цвета в сообщениях компилятора (особенно предупреждения и ошибки). Поддерживаются следующие режимы:
auto
использовать эвристику, чтобы включить цвета только если вывод их поддерживает (терминал, совместимый с ANSI);
always
включить цвета безусловно;
never
отключить вывод цвета.
Переменная окружения OCAML_COLOR учитывается, если -color не указана. Её значения — auto/always/never, как указано выше.

Если -color не указана, OCAML_COLOR не задана, и переменная окружения NO_COLOR задана, то вывод цвета отключается. В противном случае, значение по умолчанию — ’auto’, и текущая эвристика проверяет, что переменная окружения TERM существует и не пуста или dumb, и что ’isatty(stderr)’ истинно.

-error-style mode
Управление способом вывода сообщений об ошибках и предупреждений. Поддерживаются следующие режимы:
short
выводить только ошибку и её расположение;
contextual
как short, но также отображать фрагмент исходного кода, соответствующий расположению ошибки.
Значение по умолчанию — contextual.

Переменная окружения OCAML_ERROR_STYLE учитывается, если -error-style не указана. Её значения — short/contextual, как указано выше.

-compact
Оптимизировать производимый код для занимаемого места, а не для скорости. Это приводит к немного меньшим, но немного медленным программам. По умолчанию оптимизация для скорости.
-config
Вывести номер версии ocamlopt и подробный обзор его конфигурации, затем выйти.
-config-var var
Вывести значение конкретной переменной конфигурации из вывода -config, затем выйти. Если переменная не существует, код выхода не равен нулю. Эта опция доступна только начиная с OCaml 4.08, поэтому авторы скриптов должны иметь резервный вариант для более старых версий.
-depend ocamldep-args
Вычислять зависимости, как делала бы команда ocamldep. Остальные аргументы интерпретируются так, как если бы они были переданы команде ocamldep.
-for-pack module-path
Создать объектный файл (.cmx и .o/.obj файлы), который впоследствии можно включить в качестве подмодуля (с заданным путем доступа) в единицу компиляции, созданную с помощью -pack. Например, ocamlopt -for-pack P -c A.ml сгенерирует файлы a..cmx и a.o, которые позже можно использовать с ocamlopt -pack -o P.cmx a.cmx. Примечание: вы по-прежнему можете упаковать модуль, который был скомпилирован без -for-pack, но в этом случае исключения будут выведены с неправильными именами.
-g
Добавить отладочную информацию во время компиляции и компоновки. Этот параметр необходим для создания отслеживания стека при завершении программы с необработанным исключением (см. раздел ‍15.2).
-no-g
Не записывать отладочную информацию (по умолчанию).
-i
Принудить компилятор вывести все определенные имена (с их выведенными типами или определениями) при компиляции реализации (.ml файл). Никаких скомпилированных файлов (.cmo и .cmi файлы) не создается. Это может быть полезно для проверки типов, выведенных компилятором. Кроме того, поскольку вывод соответствует синтаксису интерфейсов, это может помочь в написании явного интерфейса (.mli файл) для файла: просто перенаправьте стандартный вывод компилятора в .mli файл и отредактируйте этот файл, чтобы удалить все объявления неэкспортированных имен.
-I directory
Добавить заданный каталог в список каталогов, в которых ищутся скомпилированные файлы интерфейсов (.cmi), файлы скомпилированного объектного кода (.cmx) и библиотеки (.cmxa). По умолчанию сначала ищется текущий каталог, а затем — каталог стандартной библиотеки. Каталоги, добавленные с помощью -I, ищутся после текущего каталога в порядке, в котором они были указаны в командной строке, но перед каталогом стандартной библиотеки. См. также параметр -nostdlib.

Если заданный каталог начинается с +, он берется относительно каталога стандартной библиотеки. Например, -I +unix добавляет подкаталог unix стандартной библиотеки в путь поиска.

-H directory
Ведёт себя идентично -I, за исключением того, что (а) программы не могут напрямую ссылаться на модули, добавленные в путь поиска таким образом, и (б) эти каталоги ищутся после любых каталогов -I. Это позволяет предоставить компилятору скомпилированные файлы интерфейсов и объектного кода для транзитивных зависимостей текущей программы (зависимости от зависимостей) без их молчаливого превращения в прямые зависимости.
-impl filename
Скомпилировать файл filename как файл реализации, даже если его расширение не .ml.
-inline n
Установить агрессивность встраивания в n, где n — положительное целое число. Указание -inline 0 предотвращает встраивание всех функций, за исключением тех, тело которых меньше места вызова. Таким образом, встраивание не приводит к увеличению размера кода. По умолчанию агрессивность -inline 1 позволяет встраивать несколько более крупные функции, что приводит к небольшому увеличению размера кода. Более высокие значения для параметра -inline приводят к тому, что всё более и более крупные функции становятся кандидатами на встраивание, но могут привести к серьёзному увеличению размера кода.
-intf filename
Скомпилировать файл filename как файл интерфейса, даже если его расширение не .mli.
-intf-suffix string
Распознавать имена файлов, оканчивающиеся на string, как файлы интерфейсов (вместо стандартного .mli).
-labels
Метки не игнорируются в типах, метки могут использоваться в приложениях, и помеченные параметры могут быть заданы в любом порядке. Это значение по умолчанию.
-linkall
Принудительно подключать все модули, содержащиеся в библиотеках. Если этот флаг не задан, неиспользуемые модули не подключаются. При построении библиотеки (параметр -a), установка параметра -linkall принудительно подключает все последующие ссылки программ, использующих эту библиотеку, к подключению всех модулей, содержащихся в библиотеке. При компиляции модуля (параметр -c), установка параметра -linkall гарантирует, что этот модуль всегда будет подключён, если он помещён в библиотеку, и эта библиотека подключается.
-linscan
Использовать линейный сканирующий алгоритм выделения регистров. Компиляция с этим алгоритмом быстрее, чем с обычным алгоритмом окраски графов, иногда значительно для длинных функций и модулей. С другой стороны, сгенерированный код может быть немного медленнее.
-match-context-rows
Установить количество строк контекста, используемых для оптимизации при компиляции сопоставления с образцом. Значение по умолчанию равно 32. Более низкие значения ускоряют компиляцию, но создают менее оптимизированный код. Этот расширенный параметр предназначен для использования в случае, если программа с интенсивным сопоставлением с образцом приводит к значительному увеличению времени компиляции.
-no-alias-deps
Не записывать зависимости для псевдонимов модулей. См. раздел ‍12.8 для получения дополнительной информации.
-no-app-funct
Деактивирует прикладное поведение функторов. С этим параметром каждое применение функтора генерирует новые типы в своём результате, а применение того же функтора дважды к одному и тому же аргументу даёт две несовместимые структуры.
-no-float-const-prop
Деактивирует распространение констант для операций с плавающей точкой. Этот параметр следует использовать, если программа изменяет режим округления чисел с плавающей точкой во время выполнения.
-noassert
Не компилировать проверки утверждений. Обратите внимание, что специальная форма assert false всегда компилируется, потому что она специально типизируется. Этот флаг не имеет эффекта при компоновке уже скомпилированных файлов.
-noautolink
При компоновке .cmxa библиотек игнорировать параметры -cclib и -ccopt, которые могут содержаться в библиотеках (если эти параметры были заданы при построении библиотек). Это может быть полезно, если библиотека содержит некорректные спецификации C-библиотек или C-параметров; в этом случае во время компоновки установите -noautolink и передайте правильные C-библиотеки и параметры в командной строке.
-nodynlink
Разрешить компилятору использовать некоторые оптимизации, которые справедливы только для кода, статически связанного для создания неперемещаемого исполняемого файла. Сгенерированный код не может быть связан для создания динамической библиотеки или исполняемого файла с позиционной независимостью (PIE). Многие операционные системы по умолчанию создают PIE, вызывая ошибки при компоновке кода, скомпилированного с -nodynlink. Либо не используйте -nodynlink, либо передайте параметр -ccopt -no-pie во время компоновки.
-nolabels
Игнорировать необов'язательные метки в типах. Метки нельзя использовать в приложениях, и порядок параметров становится жёстким.
-nostdlib
Не добавлять автоматически каталог стандартной библиотеки в список каталогов, проверяемых при поиске скомпилированных файлов интерфейса (.cmi), скомпилированных файлов объектного кода (.cmx) и библиотек (.cmxa). См. также опцию -I.
-o output-file
Указать имя выходного файла. Для исполняемых файлов по умолчанию имя выходного файла — a.out в Unix и camlprog.exe в Windows. Если указана опция -a, указать имя создаваемой библиотеки. Если указана опция -pack, указать имя создаваемого упакованного файла объекта. Если указаны опции -output-obj или -output-complete-obj, указать имя создаваемого файла объекта. Если указана опция -shared, указать имя создаваемого файла плагина.
-opaque
При компиляции реализации родным компилятором по умолчанию генерируется файл .cmx содержащий информацию для межмодульной оптимизации. Также ожидаются файлы .cmx для зависимостей текущего компилируемого источника, которые используются для оптимизации. Начиная с OCaml 4.03, компилятор выводит предупреждение, если не может найти файл .cmx одной из этих зависимостей.

Опция -opaque, доступная с версии 4.04, отключает информацию о межмодульной оптимизации для текущей компилируемой единицы. При компиляции интерфейса .mli с использованием -opaque отмечается скомпилированный интерфейс .cmi так, что последующие компиляции модулей, зависящих от него, не будут полагаться на соответствующий файл .cmx, а также не будут предупреждать, если он отсутствует. При компиляции реализации .ml родным компилятором с использованием -opaque генерируется .cmx, который не содержит никакой информации о межмодульной оптимизации.

Использование этой опции может ухудшить качество генерируемого кода, но уменьшает время компиляции, как при чистых, так и при инкрементных сборках. Действительно, с родным компилятором, когда изменяется реализация компиляционной единицы, все единицы, от неё зависящие, могут потребовать перекомпиляции — потому что информация о межмодулях может измениться. Если компиляционная единица, чья реализация изменилась, была скомпилирована с -opaque, такая перекомпиляция не требуется. Таким образом, эта опция может использоваться, например, для получения более быстрых циклов обратной связи «редактирование—компиляция—тестирование».

-open Module
Открывает указанный модуль перед обработкой файлов интерфейса или реализации. Если задано несколько опций -open, они обрабатываются в порядке, точно так же, как если бы операторы open! Module1;; ... open! ModuleN;; были добавлены в начало каждого файла.
-output-obj
Заставляет компоновщик создавать файл объекта C вместо исполняемого файла. Это полезно для упаковки кода OCaml в библиотеку C, вызываемую из любой программы C. См. главу ‍22, раздел ‍22.7.5. Имя выходного файла объекта необходимо задать с помощью опции -o. Эта опция также может использоваться для создания скомпилированной общей/динамической библиотеки (.so расширение, .dll в Windows).
-output-complete-obj
То же, что и опция -output-obj, за исключением того, что создаваемый файл объекта включает runtime и библиотеки автоподключения.
-pack
Создать файл объекта (.cmx и .o/.obj файлы) и его связанный скомпилированный интерфейс (.cmi), который объединяет файлы объектов .cmx, указанные в командной строке, представляя их как подмодули выходного файла .cmx. Имя выходного файла .cmx необходимо указать с помощью опции -o. Например,
        ocamlopt -pack -o P.cmx A.cmx B.cmx C.cmx
генерирует скомпилированные файлы P.cmx, P.o и P.cmi, описывающие компиляционную единицу, имеющую три подмодуля A, B и C, соответствующие содержимому файлов объектов A.cmx, B.cmx и C.cmx. Это содержимое можно ссылаться как P.A, P.B и P.C в остальной части программы.

Объединяемые файлы объектов .cmx должны быть скомпилированы с соответствующей опцией -for-pack. В приведенном выше примере A.cmx, B.cmx и C.cmx должны быть скомпилированы с помощью ocamlopt -for-pack P.

Несколько уровней упаковки могут быть достигнуты путем комбинирования -pack с -for-pack. Рассмотрим следующий пример:

        ocamlopt -for-pack P.Q -c A.ml
        ocamlopt -pack -o Q.cmx -for-pack P A.cmx
        ocamlopt -for-pack P -c B.ml
        ocamlopt -pack -o P.cmx Q.cmx B.cmx

Полученный файл объекта P.cmx имеет подмодули P.Q, P.Q.A и P.B.

-pp command
Заставить компилятор вызвать заданную команду как препроцессор для каждого файла исходного кода. Вывод команды перенаправляется во временный файл, который компилируется. При отсутствии ошибок компиляции временный файл удаляется после этого.
-ppx command
После анализа, передать абстрактное синтаксическое дерево в препроцессор command. Модуль Ast_mapper, описанный в главе ‍30: Ast_mapper , реализует внешний интерфейс препроцессора.
-principal
Проверить путь информации во время проверки типов, чтобы убедиться, что все типы получены главным образом. При использовании помеченных аргументов и/или полиморфных методов этот флаг необходим для обеспечения того, что будущие версии компилятора смогут правильно выводить типы, даже если внутренние алгоритмы изменятся. Все программы, принятые в режиме -principal, также принимаются в режиме по умолчанию с эквивалентными типами, но различными бинарными сигнатурами, что может замедлить проверку типов; тем не менее, рекомендуется использовать его один раз перед публикацией исходного кода.
-rectypes
Разрешить произвольные рекурсивные типы во время проверки типов. По умолчанию поддерживаются только рекурсивные типы, где рекурсия проходит через тип объекта. Обратите внимание, что после создания интерфейса с помощью этого флага необходимо использовать его снова для всех зависимостей.
-runtime-variant suffix
Добавьте строку приставки к имени библиотеки выполнения, используемой программой. В настоящее время поддерживается только один такой суффикс: d, и только если компилятор OCaml был сконфигурирован с опцией -with-debug-runtime. Этот суффикс указывает на отладочную версию выполнения, которая полезна для отладки проблем с указателями в коде низкого уровня, таком как C-стыки.
-S
Сохранить ассемблерный код, сгенерированный во время компиляции. Ассемблерный код для исходного файла x.ml сохраняется в файле x.s.
-safe-string
Принудительно разделить типы string и bytes, тем самым сделав строки неизменяемыми. Это значение по умолчанию и применяется с OCaml 5.0.
-safer-matching
Не использовать информацию о типе для оптимизации сопоставления с образцом. Это позволяет обнаруживать ошибки совпадения даже если сопоставление с образцом ошибочно предполагалось исчерпывающим. Это влияет только на компиляцию GADT и полиморфных вариантов.
-save-ir-after pass
Сохранить промежуточное представление после указанного этапа компиляции в файл. В настоящее время поддерживаются следующие этапы и соответствующие расширения файлов: scheduling (.cmir-linear).

Эта экспериментальная функция позволяет внешним инструментам инспектировать и манипулировать промежуточным представлением программы компилятора с использованием библиотеки compiler-libs (см. главу ‍30 и Compiler_libs ).

-shared
Создать плагин (обычно .cmxs), который можно динамически загрузить с помощью модуля Dynlink. Имя плагина должно быть установлено с помощью опции -o. Плагин может включать в себя несколько модулей и библиотек OCaml, а также дополнительные нативные объекты (.o, .obj, .a, .lib файлы). Создание нативных плагинов поддерживается только для некоторых операционных систем. В некоторых системах (в настоящее время только Linux AMD 64) весь код OCaml, связанный с плагином, должен быть скомпилирован без флага -nodynlink. Также могут быть ограничения на способ компиляции дополнительных нативных объектов (в Linux AMD 64 они должны содержать только позиционно-независимый код).
-short-paths
Если тип виден по нескольким путям модулей, используйте самый короткий при печати имени типа в вывод интерфейсов, сообщений об ошибках и предупреждениях. Имена идентификаторов, начинающиеся с подчеркивания _ или содержащие двойные подчеркивания __ увеличивают длину на +10.
-stop-after pass
Остановите компиляцию после данного этапа компиляции. В настоящее время поддерживаются следующие этапы: parsing, typing, scheduling, emit.
-strict-sequence
Принудительно задать тип левой части каждой последовательности как unit.
-strict-formats
Отклонять некорректные форматы, которые принимались в реализациях старых форматов. Необходимо использовать этот флаг для обнаружения и исправления таких некорректных форматов, поскольку они будут отклоняться будущими версиями OCaml.
-unboxed-types
Если тип может быть не упакован (т.е. запись с одним аргументом или конкретный тип данных с одним конструктором одного аргумента), он будет не упакован, если не помечен [@@ocaml.boxed].
-no-unboxed-types
Если тип может быть не упакован, он будет упакован, если не помечен [@@ocaml.unboxed]. Это значение по умолчанию.
-unsafe
Отключить проверку границ для доступа к массивам и строкам (v.(i) и s.[i] конструкции). Программы, скомпилированные с -unsafe, поэтому быстрее, но небезопасны: все может произойти, если программа обращается к массиву или строке за пределами его границ. Кроме того, отключить проверку на ноль делителя в операциях целочисленного деления и модуля. С -unsafe, целочисленное деление (или модуль) на ноль может остановить программу или продолжить с неопределенным результатом вместо повышения исключения Division_by_zero.
-unsafe-string
Идентифицировать типы string и bytes, тем самым сделав строки изменяемыми. Это предназначено для совместимости со старым исходным кодом и не должно использоваться с новым ПО. Эта опция вызывает ошибку безусловно с OCaml 5.0.
-v
Вывести номер версии компилятора и местоположение каталога стандартной библиотеки, а затем выйти.
-verbose
Вывести все внешние команды перед их выполнением, в частности вызовы ассемблера, компилятора C и компоновщика. Полезно для отладки проблем с библиотеками C.
-version or -vnum
Вывести номер версии компилятора в краткой форме (например, 3.11.0), а затем выйти.
-w warning-list
Включить, отключить или пометить как критическое предупреждения, указанные аргументом warning-list. Каждое предупреждение может быть включено или выключено, а также критическим или некритическим. Если предупреждение выключено, оно не отображается и никак не влияет на компиляцию (даже если оно критическое). Если предупреждение включено, оно отображается компилятором обычным образом, когда исходный код его вызывает. Если оно включено и критическое, компилятор также остановится с ошибкой после его отображения.

Аргумент warning-list — это последовательность спецификаторов предупреждений без разделителей между ними. Спецификатор предупреждения — это одно из следующего:

+num
Включить предупреждение номер num.
-num
Отключить предупреждение номер num.
@num
Включить и пометить как критическое предупреждение номер num.
+num1..num2
Включить предупреждения в заданном диапазоне.
-num1..num2
Отключить предупреждения в заданном диапазоне.
@num1..num2
Включить и пометить как критическое предупреждения в заданном диапазоне.
+letter
Включить набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
-letter
Отключить набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
@letter
Включить и пометить как критическое набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
uppercase-letter
Включить набор предупреждений, соответствующих uppercase-letter.
lowercase-letter
Отключить набор предупреждений, соответствующих lowercase-letter.

В качестве альтернативы, warning-list может указать одно предупреждение по его мнемоническому имени (см. ниже), следующим образом:

+name
Включить предупреждение name.
-name
Отключить предупреждение name.
@name
Включить и пометить как критическое предупреждение name.

Номера предупреждений, буквы и имена, которые в настоящее время не определены, игнорируются. Предупреждения следующие (имя после каждого номера указывает мнемонику для этого предупреждения).

1 comment-start
Подозрительная метка начала комментария.
2 comment-not-end
Подозрительная метка конца комментария.
3
Устаревшее синоним для предупреждения ’deprecated’.
4 fragile-match
Хрупкое сопоставление шаблонов: соответствие, которое останется полным, даже если к одному из типов вариантов, с которыми сравнивается, будут добавлены дополнительные конструкторы.
5 ignored-partial-application
Частично примененная функция: выражение, результат которого имеет тип функции и игнорируется.
6 labels-omitted
Метка опущена в применении функции.
7 method-override
Метод перезаписан.
8 partial-match
Частичное соответствие: отсутствующие случаи в сопоставлении шаблонов.
9 missing-record-field-pattern
Отсутствующие поля в шаблоне записи.
10 non-unit-statement
Выражение в левой части последовательности, у которого нет типа unit (и которое не является функцией, см. предупреждение номер 5).
11 redundant-case
Избыточный случай в сопоставлении шаблонов (неиспользуемый случай соответствия).
12 redundant-subpat
Избыточный подшаблон в сопоставлении шаблонов.
13 instance-variable-override
Переопределён переменная экземпляра.
14 illegal-backslash
Неправильный обратный слэш в строковой константе.
15 implicit-public-methods
Приватный метод неявно сделан публичным.
16 unerasable-optional-argument
Неудаляемый необязательный аргумент.
17 undeclared-virtual-method
Необъявленный виртуальный метод.
18 not-principal
Неглавный тип.
19 non-principal-labels
Тип без принципиальности.
20 ignored-extra-argument
Неиспользуемый аргумент функции.
21 nonreturning-statement
Невозвращающее выражение.
22 preprocessor
Предупреждение препроцессора.
23 useless-record-with
Бесполезная запись with части.
24 bad-module-name
Неправильное имя модуля: имя исходного файла не является допустимым именем модуля OCaml.
25
Проигнорировано: теперь часть предупреждения 8.
26 unused-var
Подозрительная неиспользуемая переменная: неиспользуемая переменная, связанная с let или as и не начинающаяся с символа подчёркивания (_).
27 unused-var-strict
Безобидная неиспользуемая переменная: неиспользуемая переменная, которая не связана с let ни с as и не начинается с символа подчёркивания (_).
28 wildcard-arg-to-constant-constr
Дикий шаблон, данный как аргумент константного конструктора.
29 eol-in-string
Неэкранированный конец строки в строковой константе (непереносимый код).
30 duplicate-definitions
Два метки или конструктора с одинаковым именем определены в двух взаимно рекурсивных типах.
31 module-linked-twice
Модуль связан дважды в одной исполняемой программе.
I
Игнорируется: теперь жёсткая ошибка (с версии 5.1).
32 unused-value-declaration
Неиспользуемое объявление значения. (с версии 4.00)
33 unused-open
Неиспользуемое оператор open. (с версии 4.00)
34 unused-type-declaration
Неиспользуемое объявление типа. (с версии 4.00)
35 unused-for-index
Неиспользуемый индекс цикла for. (с версии 4.00)
36 unused-ancestor
Неиспользуемый предковый переменная. (с версии 4.00)
37 unused-constructor
Неиспользуемый конструктор. (с версии 4.00)
38 unused-extension
Неиспользуемый расширенный конструктор. (с версии 4.00)
39 unused-rec-flag
Неиспользуемый флаг rec. (с версии 4.00)
40 name-out-of-scope
Имя конструктора или метки использовано вне области видимости. (с версии 4.01)
41 ambiguous-name
Размытое имя конструктора или метки. (с версии 4.01)
42 disambiguated-name
Ясность имени конструктора или метки (предупреждение совместимости). (с версии 4.01)
43 nonoptional-label
Необязательная метка применена как необязательная. (с версии 4.01)
44 open-shadow-identifier
Оператор open затеняет уже определённый идентификатор. (с версии 4.01)
45 open-shadow-label-constructor
Оператор open затеняет уже определённую метку или конструктор. (с версии 4.01)
46 bad-env-variable
Ошибка в переменной среды. (с версии 4.01)
47 attribute-payload
Некорректная нагрузка атрибута. (с версии 4.02)
48 eliminated-optional-arguments
Неявное удаление необязательных аргументов. (с версии 4.02)
49 no-cmi-file
Отсутствует файл cmi при поиске псевдонима модуля. (с версии 4.02)
50 unexpected-docstring
Неожиданный комментарий документации. (с версии 4.03)
51 wrong-tailcall-expectation
Вызов функции с неправильным атрибутом @tailcall. (с версии 4.03)
52 fragile-literal-pattern (см. 13.5.3)
Хрупкий шаблон константы. (с версии 4.03)
53 misplaced-attribute
Атрибут не может быть в этом контексте. (с версии 4.03)
54 duplicated-attribute
Атрибут используется более одного раза в выражении. (с версии 4.03)
55 inlining-impossible
Внедрение невозможно. (с версии 4.03)
56 unreachable-case
Недостижимый случай в шаблоне сопоставления (на основе информации о типе). (с версии 4.03)
57 ambiguous-var-in-pattern-guard (см. 13.5.4)
Неоднозначные переменные в шаблоне или с условием. (с версии 4.03)
58 no-cmx-file
Отсутствует файл cmx. (с версии 4.03)
59 flambda-assignment-to-non-mutable-value
Присваивание неизменяемому значению. (с версии 4.03)
60 unused-module
Неиспользуемое объявление модуля. (с версии 4.04)
61 unboxable-type-in-prim-decl
Тип, который нельзя распаковать, в примитивном объявлении. (с версии 4.04)
62 constraint-on-gadt
Ограничение типа на объявлении типа GADT. (с версии 4.06)
63 erroneous-printed-signature
Ошибочная напечатанная сигнатура. (с версии 4.08)
64 unsafe-array-syntax-without-parsing
-unsafe используется с препроцессором, возвращающим дерево синтаксического анализа. (с версии 4.08)
65 redefining-unit
Объявление типа, определяющее новый конструктор ’()’. (с версии 4.08)
66 unused-open-bang
Неиспользуемое утверждение open!. (с версии 4.08)
67 unused-functor-parameter
Неиспользуемый параметр функтора. (с версии 4.10)
68 match-on-mutable-state-prevent-uncurry
Шаблон сопоставления, зависящий от изменяемого состояния, предотвращает раскрутку оставшихся аргументов. (с версии 4.12)
69 unused-field
Неиспользуемое поле записи. (с версии 4.13)
70 missing-mli
Отсутствует файл интерфейса. (с версии 4.13)
71 unused-tmc-attribute
Неиспользуемый атрибут @tail_mod_cons. (с версии 4.14)
72 tmc-breaks-tailcall
При преобразовании @tail_mod_cons хвостовой вызов превращается в нехвостовой. (с версии 4.14)
73 generative-application-expects-unit
Генеративный функтор применяется к пустой структуре (конец структуры) вместо (). (с версии 5.1)
A
все предупреждения
C
предупреждения 1, 2.
D
Псевдоним для предупреждения 3.
E
Псевдоним для предупреждения 4.
F
Псевдоним для предупреждения 5.
K
предупреждения 32, 33, 34, 35, 36, 37, 38, 39.
L
Псевдоним для предупреждения 6.
M
Псевдоним для предупреждения 7.
P
Псевдоним для предупреждения 8.
R
Псевдоним для предупреждения 9.
S
Псевдоним для предупреждения 10.
U
предупреждения 11, 12.
V
Псевдоним для предупреждения 13.
X
предупреждения 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 30.
Y
Псевдоним для предупреждения 26.
Z
Псевдоним для предупреждения 27.

Значение по умолчанию — -w +a-4-6-7-9-27-29-32..42-44-45-48-50-60. Оно отображается с помощью ocamlopt -help. Обратите внимание, что предупреждения 5 и 10 не всегда срабатывают, в зависимости от внутренней работы проверяющего типа.

-warn-error warning-list
Отметить как фатальные предупреждения, указанные в аргументе warning-list. Компилятор остановится с ошибкой, когда будет выведено одно из этих предупреждений. warning-list имеет такое же значение, как и для опции -w: знак + (или заглавная буква) помечает соответствующие предупреждения как фатальные, знак - (или строчная буква) возвращает их в нефатальные предупреждения, а знак @ одновременно включает и помечает соответствующие предупреждения как фатальные.

Примечание: Не рекомендуется использовать наборы предупреждений (т. е. буквы) как аргументы к -warn-error в производственном коде, потому что это может нарушить сборку при добавлении новых предупреждений в будущие версии OCaml.

Значение по умолчанию — -warn-error -a (ни одно предупреждение не является фатальным).

-warn-help
Отобразить описание всех доступных номеров предупреждений.
-where
Распечатать расположение стандартной библиотеки, а затем завершить работу.
-with-runtime
Включить систему времени выполнения в сгенерированную программу. Это значение по умолчанию.
-without-runtime
Компилятор не включает систему времени выполнения (ни ссылку на неё) в сгенерированную программу; её нужно предоставить отдельно.
- file
Обработать file как имя файла, даже если оно начинается с символа дефиса (-).
-help or --help
Отобразить краткое описание использования и завершить работу.
Параметры для 64-битной архитектуры x86

Генератор 64-битного кода для процессоров Intel/AMD x86 (amd64 архитектура) поддерживает следующие дополнительные параметры:

-fPIC
Сгенерировать позиционно-независимый машинный код. Это значение по умолчанию.
-fno-PIC
Сгенерировать позиционно-зависимый машинный код.
Управление параметрами командной строки в контексте

Командную строку компилятора можно изменять «извне» с помощью следующих механизмов. Они экспериментальны и могут быть изменены. Их следует использовать только для экспериментальной работы и разработки, а не в выпускаемых пакетах.

OCAMLPARAM (переменная окружения)
Набор аргументов, которые будут вставлены перед или после аргументов из командной строки. Аргументы задаются в виде списка через запятую пар имя=значение. Символ _ используется для указания позиции аргументов командной строки, т.е. a=x,_,b=y означает, что a=x должно быть выполнено до разбора аргументов, а b=y — после. Наконец, альтернативный разделитель может быть задан как первый символ строки в наборе :|; ,.
ocaml_compiler_internal_params (файл в каталоге stdlib)
Сопоставление имён файлов со списками аргументов, которые будут добавлены в командную строку (и аргументы OCAMLPARAM).

3 Распространённые ошибки

Сообщения об ошибках почти идентичны сообщениям об ошибках ocamlc. См. раздел ‍13.4.

4 Запуск исполняемых файлов, созданных ocamlopt

Исполняемые файлы, сгенерированные ocamlopt, являются нативными, автономными исполняемыми файлами, которые можно вызывать непосредственно. Они не зависят от системы выполнения байткода ocamlrun и от динамически загружаемых подключаемых библиотек C/OCaml.

Во время выполнения исполняемого файла, сгенерированного ocamlopt, также проверяются следующие переменные среды:

OCAMLRUNPARAM
То же использование, что и в ocamlrun (см. раздел ‍15.2), за исключением того, что параметр l игнорируется (вместо него используется ограничение размера стека операционной системы).
CAMLRUNPARAM
Если OCAMLRUNPARAM не найдено в среде, то используется CAMLRUNPARAM. Если CAMLRUNPARAM также не найдено, используются значения по умолчанию.

5 Совместимость с компилятором байткода

В этом разделе перечислены известные несовместимости между компилятором байткода и компилятором нативного кода. За исключением этих пунктов, два компилятора должны генерировать код, который ведет себя идентично.

  • Сигналы обнаруживаются только тогда, когда программа выполняет выделение памяти в куче. То есть, если сигнал получен во время выполнения кода, не производящего выделение, его обработчик не будет вызван до следующего выделения памяти в куче.
  • На процессорах ARM и PowerPC (32 и 64 бита) инструкции FMA (fused multiply-add) могут генерироваться для умножения с плавающей точкой, за которым следует сложение или вычитание с плавающей точкой, как в x *. y +. z. Инструкция FMA избегает округления промежуточного результата x *. y, что, как правило, полезно, но приводит к результатам с плавающей точкой, немного отличающимся от результатов, полученных интерпретатором байткода.
  • Компилятор нативного кода выполняет ряд оптимизаций, которые не выполняет компилятор байткода, особенно когда активен оптимизатор Flambda. В частности, компилятор нативного кода идентифицирует и устраняет «мертвый код», т.е. вычисления, которые не влияют на результаты программы. Например,
            let _ = ignore M.f
    
    содержит ссылку на модуль компиляции M при компиляции в байт код. Эта ссылка заставляет M подключаться и выполнять его код инициализации. Компилятор нативного кода устраняет ссылку на M, поэтому модуль компиляции M может не подключаться и не выполняться. Решением является компиляция M с флагом -linkall, чтобы он всегда подключался и выполнялся, даже если на него нет ссылки. См. также функцию Sys.opaque_identity из стандартного модуля библиотеки Sys.
  • До версии 4.10 переполнения стека, обычно вызванные чрезмерной рекурсией, не всегда преобразуются в исключение Stack_overflow, как это происходит при использовании компилятора байткода. Система выполнения прилагает все усилия для перехвата переполнения стека и возбуждения исключения Stack_overflow, но иногда это не удаётся, и вместо этого возникает «ошибка сегментации» или другая системная ошибка.
« Система выполнения (ocamlrun)Генераторы лексических и синтаксических анализаторов (ocamllex, ocamlyacc) »
Авторское право © 2024 Institut National de Recherche en Informatique et en Automatique

© 1995-2024 INRIA.
https://ocaml.org/manual/5.2/native.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API