Spec-Zone.ru › OCaml 5.0

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

  • 16.1 Обзор компилятора
  • 16.2 Параметры
  • 16.3 Распространённые ошибки
  • 16.4 Запуск исполняемых файлов, созданных ocamlopt
  • 16.5 Совместимость с компилятором байт-кода

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

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

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

16.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 в качестве аргумента вместо соответствующего исходного файла.

16.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
Вынуждает сообщения об ошибках отображать абсолютные пути к файлам.
-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.
-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).
-i
Принудить компилятор выводить все определённые имена (с их выведенными типами или определениями) при компиляции реализации (.ml-файл). Никакие скомпилированные файлы (.cmo и .cmi-файлы) не генерируются. Это может быть полезно для проверки типов, выведенных компилятором. Кроме того, поскольку вывод следует синтаксису интерфейсов, это может помочь в написании явного интерфейса (.mli-файл) для файла: просто перенаправьте стандартный вывод компилятора в .mli-файл и отредактируйте этот файл, удалив все объявления неэкспортированных имён.
-I каталог
Добавить указанный каталог в список каталогов, проверяемых при поиске скомпилированных файлов интерфейса (.cmi), скомпилированных файлов объектного кода (.cmx) и библиотек (.cmxa). По умолчанию сначала проверяется текущий каталог, затем каталог стандартной библиотеки. Каталоги, добавленные с помощью -I, проверяются после текущего каталога в порядке их указания в командной строке, но перед каталогом стандартной библиотеки. Также см. параметр -nostdlib.

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

-impl имя_файла
Скомпилировать файл имя_файла как файл реализации, даже если его расширение не .ml.
-inline n
Установить агрессивность встраивания в n, где n — положительное целое число. Указание -inline 0 предотвращает встраивание всех функций, кроме тех, тело которых меньше, чем место вызова. Таким образом, встраивание не приводит к увеличению размера кода. Значение по умолчанию, -inline 1, позволяет встраивать несколько более длинные функции, что приводит к незначительному увеличению размера кода. Более высокие значения параметра -inline приводят к тому, что всё более длинные функции становятся кандидатами для встраивания, но могут привести к серьёзному увеличению размера кода.
-intf имя_файла
Скомпилировать файл имя_файла как файл интерфейса, даже если его расширение не .mli.
-intf-suffix строка
Распознавать имена файлов, заканчивающиеся на строку, как файлы интерфейсов (вместо стандартного .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 файл_вывода
Указать имя файла вывода. Для исполняемых файлов имя вывода по умолчанию — 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 Модуль
Открывает указанный модуль перед обработкой файлов интерфейса или реализации. Если задано несколько опций -open, они обрабатываются в порядке следования, так же, как будто операторы open! Модуль1;; ... open! МодульN;; были добавлены в начало каждого файла.
-output-obj
Принуждает компоновщик создать файл объекта C вместо исполняемого файла. Это полезно для обертывания OCaml-кода в библиотеку C, вызываемую из любой C-программы. См. главу 22, раздел 22.7.5. Имя выходного файла объекта должно быть задано опцией -o. Эта опция также может быть использована для создания скомпилированной общей/динамической библиотеки (.so-расширение, .dll под Windows).
-output-complete-obj
Аналогично опции -output-obj, за исключением того, что создаваемый файл объекта включает в себя библиотеки времени выполнения и автоматической компоновки.
-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 команда
Принуждает компилятор вызвать указанную команду в качестве препроцессора для каждого файла исходного кода. Вывод команды перенаправляется в промежуточный файл, который компилируется. Если ошибок компиляции нет, промежуточный файл удаляется после этого.
-ppx команда
После разбора, абстрактное синтаксическое дерево передаётся в препроцессор команда. Модуль Ast_mapper, описанный в главе 29: Ast_mapper , реализует внешний интерфейс препроцессора.
-principal
Проверяет пути информации во время проверки типов, чтобы убедиться, что все типы получены главным способом. При использовании помеченных аргументов и/или полиморфных методов, этот флаг необходим для обеспечения того, что будущие версии компилятора смогут правильно выводить типы, даже если внутренние алгоритмы изменятся. Все программы, принятые в режиме -principal, также принимаются в стандартном режиме с эквивалентными типами, но различными бинарными подписями, и это может замедлить проверку типов; тем не менее, рекомендуется использовать его один раз перед публикацией исходного кода.
-rectypes
Разрешает произвольные рекурсивные типы во время проверки типов. По умолчанию поддерживаются только рекурсивные типы, где рекурсия проходит через тип объекта. Обратите внимание, что после создания интерфейса с использованием этого флага, его необходимо использовать снова для всех зависимостей.
-runtime-variant суффикс
Добавляет строку суффикс к имени библиотеки времени выполнения, используемой программой. В настоящее время поддерживается только один такой суффикс: d, и только если OCaml-компилятор был сконфигурирован с опцией -with-debug-runtime. Этот суффикс предоставляет отладочную версию среды выполнения, которая полезна для отладки проблем указателей в коде низкого уровня, таком как C-заглушки.
-stop-after этап
Останавливает компиляцию после указанного этапа компиляции. В настоящее время поддерживаются следующие этапы: parsing, typing, scheduling, emit.
-save-ir-after этап
Сохраняет промежуточное представление после указанного этапа компиляции в файл. В настоящее время поддерживаются следующие этапы и соответствующие расширения файлов: scheduling (.cmir-linear).

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

-S
Сохраняйте код ассемблера, сгенерированный во время компиляции. Код ассемблера для исходного файла x.ml сохраняется в файле x.s.
-shared
Создайте плагин (обычно .cmxs), который можно динамически загрузить с помощью модуля Dynlink. Имя плагина должно быть установлено с помощью опции -o. Плагин может включать в себя несколько модулей и библиотек OCaml, а также дополнительные нативные объекты (.o, .obj, .a, .lib файлы). Создание нативных плагинов поддерживается только для некоторых операционных систем. В некоторых системах (в настоящее время только Linux AMD 64) весь код OCaml, связанный с плагином, должен быть скомпилирован без флага -nodynlink. Также могут быть некоторые ограничения на способ компиляции дополнительных нативных объектов (в Linux AMD 64 они должны содержать только позиционно-независимый код).
-safe-string
Обеспечивает разделение между типами string и bytes, делая строки неизменяемыми. Это значение по умолчанию и используется с OCaml 5.0.
-short-paths
Если тип виден под несколькими путями модулей, используйте кратчайший при отображении имени типа в выведенных интерфейсах, сообщениях об ошибках и предупреждениях. Имена идентификаторов, начинающиеся с подчеркивания _ или содержащие двойные подчеркивания __, увеличивают длину на +10.
-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 или -vnum
Выводит номер версии компилятора в краткой форме (например, 3.11.0), затем завершается.
-w список-предупреждений
Включает, выключает или отмечает как критическое предупреждения, указанные в аргументе список-предупреждений. Каждое предупреждение может быть включено или выключено, и каждое может быть критическим или нет. Если предупреждение выключено, оно не отображается и никак не влияет на компиляцию (даже если оно критическое). Если предупреждение включено, оно нормально отображается компилятором всякий раз, когда исходный код его вызывает. Если оно включено и критическое, компилятор также остановится с ошибкой после его отображения.

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

+номер
Включает предупреждение с номером номер.
-номер
Выключает предупреждение с номером номер.
@номер
Включает и отмечает как критическое предупреждение с номером номер.
+номер1..номер2
Включает предупреждения в указанном диапазоне.
-номер1..номер2
Выключает предупреждения в указанном диапазоне.
@номер1..номер2
Включает и отмечает как критическое предупреждения в указанном диапазоне.
+буква
Включает набор предупреждений, соответствующий букве буква. Буква может быть прописной или строчной.
-буква
Выключает набор предупреждений, соответствующий букве буква. Буква может быть прописной или строчной.
@буква
Включает и отмечает как критическое набор предупреждений, соответствующий букве буква. Буква может быть прописной или строчной.
прописная-буква
Включает набор предупреждений, соответствующий прописная-буква.
строчная-буква
Выключает набор предупреждений, соответствующий строчная-буква.

В качестве альтернативы список-предупреждений может указать одно предупреждение по его мнемоническому имени (см. ниже):

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

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

1 comment-start
Подозрительная метка начала комментария.
2 comment-not-end
Подозрительная метка конца комментария.
3
Устаревший синоним предупреждения ’устаревший’.
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
Модуль подключается дважды в одном исполняемом файле. (с версии 4.00)
32 unused-value-declaration
Неиспользуемое объявление значения. (с версии 4.00)
33 unused-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)
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+31 (только предупреждение 31 является фатальным).

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

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

-ffast-math
Используйте инструкции процессора для вычисления тригонометрических и экспоненциальных функций вместо вызова соответствующих библиотечных процедур. Затронутые функции: atan, atan2, cos, log, log10, sin, sqrt и tan. Результирующий код выполняется быстрее, но диапазон поддерживаемых аргументов и точность результата могут быть уменьшены. В частности, тригонометрические операции cos, sin, tan имеют свой диапазон, ограниченный [−264, 264].
Параметры для 64-битной архитектуры x86

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

-fPIC
Генерация позиционно-независимого машинного кода. Это значение по умолчанию.
-fno-PIC
Генерация позиционно-зависимого машинного кода.
Параметры для архитектуры PowerPC

Генератор кода для PowerPC поддерживает следующие дополнительные параметры:

-flarge-toc
Включает большую модель PowerPC, позволяющую таблице содержимого (TOC) быть произвольно большой. Это значение по умолчанию с версии 4.11.
-fsmall-toc
Включает малую модель PowerPC, позволяющую TOC иметь размер до 64 КБайт на единицу компиляции. До версии 4.11 это было значением по умолчанию.
Контекстуальное управление параметрами командной строки

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

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

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

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

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

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

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

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

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

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

  • Сигналы обнаруживаются только тогда, когда программа выполняет выделение памяти в куче. То есть, если сигнал подаётся во время выполнения кода, не выполняющего выделение памяти, его обработчик не будет вызван до следующего выделения памяти.
  • На процессорах ARM и PowerPC (32 и 64 бита) инструкции умножения-сложения (FMA) могут быть сгенерированы для операций умножения с плавающей точкой, за которыми следуют операции сложения или вычитания с плавающей точкой, как в x *. y +. z. Инструкция FMA избегает округления промежуточного результата x *. y, что обычно полезно, но приводит к результатам с плавающей точкой, которые немного отличаются от результатов, полученных интерпретатором байткода.
  • На процессорах Intel/AMD x86 в 32-битном режиме некоторые промежуточные результаты в вычислениях с плавающей точкой хранятся с расширенной точностью, а не округляются до двойной точности, как это всегда делается компилятором байткода. Поэтому результаты с плавающей точкой могут незначительно отличаться между байткодом и машинным кодом.
  • Компилятор машинного кода выполняет ряд оптимизаций, которые не выполняет компилятор байткода, особенно когда активирован оптимизатор Flambda. В частности, компилятор машинного кода определяет и устраняет «мёртвый код», то есть вычисления, которые не вносят вклад в результаты программы. Например,
            let _ = ignore M.f
    
    содержит ссылку на единицу компиляции M при компиляции в байт-код. Эта ссылка заставляет M быть связанным и выполняется код его инициализации. Компилятор машинного кода устраняет ссылку на M, поэтому единица компиляции M может не быть связана и не выполняется. Обходным путём является компиляция M с флагом -linkall, чтобы она всегда связывалась и выполнялась, даже если не упоминается. См. также функцию Sys.opaque_identity из стандартного модуля библиотеки Sys.
  • До версии 4.10 переполнение стека, обычно вызванное чрезмерной рекурсией, не всегда превращалось в исключение Stack_overflow, как с компилятором байткода. Система времени выполнения делает всё возможное, чтобы перехватить переполнение стека и поднять исключение Stack_overflow, но иногда терпит неудачу и вместо этого возникает ошибка «сегментация по памяти» или другая системная ошибка.

© 1995-2022 INRIA.
https://v2.ocaml.org/releases/5.0/htmlman/native.html

Spec-Zone.ru

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