Глава 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, но также отображать фрагмент исходного кода, соответствующий местоположению ошибки.
Переменная среды 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
- 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