Spec-Zone.ru › OCaml 4.14

Глава 14 Компиляция нативного кода (ocamlopt)

  • 14.1 Обзор компилятора
  • 14.2 Опции
  • 14.3 Распространенные ошибки
  • 14.4 Запуск исполняемых файлов, сгенерированных ocamlopt
  • 14.5 Совместимость с байткод-компилятором

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

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

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

14.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 (глава 11).

  • Аргументы, заканчивающиеся на .cmx, рассматриваются как скомпилированный объектный код. Эти файлы связываются вместе с файлами объектного кода, полученными при компиляции аргументов .ml (если таковые имеются), и стандартной библиотекой OCaml, чтобы создать исполняемый файл нативного кода. Порядок, в котором представлены аргументы .cmx и .ml в командной строке, имеет значение: единицы компиляции инициализируются в этом порядке во время выполнения, и при линковке возникает ошибка, если компонент единицы используется до его инициализации. Следовательно, данный файл x.cmx должен предшествовать всем файлам .cmx, которые ссылаются на единицу x.
  • Аргументы, заканчивающиеся на .cmxa, рассматриваются как библиотеки объектного кода. Такая библиотека упаковывает в два файла (lib.cmxa и lib.a/.lib) набор файлов объектного кода (.cmx и .o/.obj файлы). Библиотеки создаются с помощью ocamlopt -a (см. описание опции -a ниже). Файлы объектного кода, содержащиеся в библиотеке, связываются как обычные файлы .cmx (см. выше), в указанном при создании библиотеки порядке. Единственное отличие заключается в том, что если файл объектного кода, содержащийся в библиотеке, нигде не упоминается в программе, то он не подключается к линковке.
  • Аргументы, заканчивающиеся на .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 в качестве аргумента вместо соответствующего исходного файла.

14.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.
-color mode
Включить или отключить цвета в сообщениях компилятора (особенно предупреждения и ошибки). Поддерживаются следующие режимы:
auto
использовать эвристику для включения цветов только в том случае, если вывод поддерживает их (терминал ANSI-совместимый tty);
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
Добавить отладочную информацию во время компиляции и компоновки. Эта опция необходима для создания обратных трассировок стека, когда программа завершается из-за неперехваченного исключения (см. раздел 13.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
Не записывать зависимости для псевдонимов модулей. См. раздел 10.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. См. главу 20, раздел 20.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, описанный в главе 27: 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 (см. главу 27 и 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, тем самым сделав строки неизменяемыми. Это значение по умолчанию.
-short-paths
Когда тип виден по нескольким путям модуля, использовать самый короткий при печати имени типа в выведенных интерфейсах, сообщениях об ошибках и предупреждениях. Имена идентификаторов, начинающиеся с подчеркивания _ или содержащие двойные подчеркивания __, имеют штраф в +10 при вычислении их длины.
-strict-sequence
Принудительно установить тип левой части каждой последовательности в единицу.
-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, тем самым сделав строки изменяемыми. Это предназначено для совместимости со старым кодом и не должно использоваться с новым ПО.
-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
Модуль подключается дважды в одном исполняемом файле.
32 unused-value-declaration
Неиспользуемое объявление значения.
33 unused-open
Неиспользуемый оператор open.
34 unused-type-declaration
Неиспользуемое объявление типа.
35 unused-for-index
Неиспользуемый индекс цикла for.
36 unused-ancestor
Неиспользуемый предковый объект.
37 unused-constructor
Неиспользуемый конструктор.
38 unused-extension
Неиспользуемый расширяющий конструктор.
39 unused-rec-flag
Неиспользуемый флаг rec.
40 name-out-of-scope
Имя конструктора или метки используется вне области видимости.
41 ambiguous-name
Неоднозначное имя конструктора или метки.
42 disambiguated-name
Разрешённое имя конструктора или метки (предупреждение совместимости).
43 nonoptional-label
Необязательная метка применена как необязательная.
44 open-shadow-identifier
Оператор open затеняет уже определённый идентификатор.
45 open-shadow-label-constructor
Оператор open затеняет уже определённую метку или конструктор.
46 bad-env-variable
Ошибка в переменной среды.
47 attribute-payload
Неправильная нагрузка атрибута.
48 eliminated-optional-arguments
Неявное исключение необязательных аргументов.
49 no-cmi-file
Отсутствует файл cmi при поиске псевдонима модуля.
50 unexpected-docstring
Неожиданный комментарий документации.
51 wrong-tailcall-expectation
Вызов функции с неправильным атрибутом @tailcall
END_OF_DOCUMENT_MARKER
52 fragile-literal-pattern (см. 11.5.3)
Хрупкий шаблон констант.
53 misplaced-attribute
Атрибут не может появиться в данном контексте.
54 duplicated-attribute
Атрибут используется более одного раза в выражении.
55 inlining-impossible
Встраивание невозможно.
56 unreachable-case
Недостижимый случай в шаблоне сопоставления (на основе информации о типе).
57 ambiguous-var-in-pattern-guard (см. 11.5.4)
Неоднозначные переменные в шаблоне с условием.
58 no-cmx-file
Файл cmx отсутствует.
59 flambda-assignment-to-non-mutable-value
Присваивание неизменяемому значению.
60 unused-module
Неиспользуемое объявление модуля.
61 unboxable-type-in-prim-decl
Нераспаковываемый тип в примитивном объявлении.
62 constraint-on-gadt
Ограничение типа на объявлении GADT.
63 erroneous-printed-signature
Некорректная напечатанная сигнатура.
64 unsafe-array-syntax-without-parsing
-unsafe используется с препроцессором, возвращающим синтаксическое дерево.
65 redefining-unit
Объявление типа, определяющее новый конструктор ’()’.
66 unused-open-bang
Неиспользуемое утверждение open!.
67 unused-functor-parameter
Неиспользуемый параметр функтора.
68 match-on-mutable-state-prevent-uncurry
Сопоставление с образцом, зависящее от изменяемого состояния, препятствует раскрутке оставшихся аргументов.
69 unused-field
Неиспользуемое поле записи.
70 missing-mli
Отсутствует интерфейсный файл.
71 unused-tmc-attribute
Неиспользуемый атрибут @tail_mod_cons.
72 tmc-breaks-tailcall
При помощи преобразования @tail_mod_cons хвостовая рекурсия преобразуется в не-хвостовую.
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 вместо заданного значения. В основном используется для загрузки.

14.3 Общие ошибки

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

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

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

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

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

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

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

  • Сигналы обнаруживаются только при выделении памяти в куче. То есть, если сигнал доставлен во время выполнения кода, не выполняющего выделение, его обработчик не будет вызван до следующего выделения памяти.
  • На процессорах ARM и PowerPC (32 и 64 бита) инструкции FMA (fused multiply-add) могут генерироваться для умножения с плавающей запятой, за которым следует сложение или вычитание с плавающей запятой, как в 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/4.14/htmlman/native.html

Spec-Zone.ru

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