Глава 16 Компиляция в машинный код (ocamlopt)
В этой главе описывается высокопроизводительный компилятор OCaml для машинного кода ocamlopt, который компилирует исходные файлы OCaml в файлы объектов машинного кода и связывает эти файлы объектов, чтобы создать автономные исполняемые файлы.
Компилятор машинного кода доступен только на определённых платформах. Он генерирует код, работающий быстрее, чем байткод, созданный ocamlc, за счёт увеличения времени компиляции и размера исполняемого файла. Совместимость с компилятором байткода очень высока: тот же исходный код должен работать одинаково, когда компилируется с помощью ocamlc и ocamlopt.
Невозможно смешивать файлы объектов машинного кода, созданные ocamlopt, с файлами объектов байткода, созданными ocamlc: программа должна быть скомпилирована полностью с ocamlopt или полностью с ocamlc. Файлы объектов машинного кода, созданные ocamlopt, не могут быть загружены в систему верхнего уровня ocaml.
1 Обзор компилятора
Команда ocamlopt имеет интерфейс командной строки, очень похожий на интерфейс ocamlc. Она принимает те же типы аргументов и обрабатывает их последовательно после обработки всех опций:
- Аргументы, заканчивающиеся на .mli, рассматриваются как исходные файлы для интерфейсов единиц компиляции. Интерфейсы определяют имена, экспортируемые единицами компиляции: они объявляют имена значений с их типами, определяют публичные типы данных, объявляют абстрактные типы данных и так далее. Из файла x.mli компилятор ocamlopt генерирует скомпилированный интерфейс в файле x.cmi. Сгенерированный интерфейс идентичен интерфейсу, сгенерированному компилятором байткода ocamlc.
- Аргументы, заканчивающиеся на .ml, рассматриваются как исходные файлы для реализации единиц компиляции. Реализации предоставляют определения имён, экспортируемых единицей, а также содержат выражения, которые должны выполняться для их побочных эффектов. Из файла x.ml компилятор ocamlopt генерирует два файла: x.o, содержащий машинный код, и x.cmx, содержащий дополнительную информацию для связывания и оптимизации клиентов единицы. Скомпилированную реализацию всегда следует называть x.cmx (если предоставлен файл .o или .obj, ocamlopt предполагает, что он содержит код, скомпилированный из C, а не из OCaml).
Реализация проверяется по файлу интерфейса x.mli (если он существует) так, как описано в руководстве для ocamlc (глава 13).
- Аргументы, заканчивающиеся на .cmx, рассматриваются как скомпилированный машинный код. Эти файлы связываются вместе с файлами объектов, полученными из аргументов .ml (если таковые имеются), и стандартной библиотекой OCaml, чтобы создать исполняемый файл машинного кода. Порядок представления аргументов .cmx и .ml в командной строке важен: единицы компиляции инициализируются в этом порядке во время выполнения, и это ошибка на этапе компоновки, если компонент единицы используется до его инициализации. Поэтому, данный файл x.cmx должен предшествовать всем файлам .cmx, которые ссылаются на единицу x.
- Аргументы, заканчивающиеся на .cmxa, рассматриваются как библиотеки машинного кода. Такая библиотека содержит два файла (lib.cmxa и lib.a/.lib) набор файлов объектов (.cmx и .o/.obj файлы). Библиотеки строятся с помощью ocamlopt -a (см. описание опции -a ниже).
- Аргументы, заканчивающиеся на .c, передаются компилятору C, который генерирует файл объекта .o/.obj. Этот файл объекта связывается с программой.
- Аргументы, заканчивающиеся на .o, .a или .so (.obj, .lib и .dll в Windows) предполагаются файлами объектов C и библиотеками. Они связываются с программой.
Выходной файл этапа связывания — обычный исполняемый файл Unix или Windows. Он не требует ocamlrun для запуска.
Компилятор может выводить информацию о своих внутренних этапах:
- Файлы .cmt для реализации единицы компиляции и .cmti для сигнатур, если передана опция -bin-annot (см. описание -bin-annot ниже). Каждый такой файл содержит типизированное абстрактное синтаксическое дерево (AST), которое генерируется во время проверки типов. Это дерево содержит всю доступную информацию о местоположении и типе каждого термина в исходном файле. AST является частичным, если проверка типов была неуспешной.
Файлы .cmt и .cmti обычно полезны для инструментов инспекции кода.
- Файлы .cmir-linear для реализации единицы компиляции, если передана опция -save-ir-after scheduling. Каждый такой файл содержит низкоуровневое промежуточное представление, полученное при прохождении планирования инструкций.
Внешний инструмент может выполнить низкоуровневую оптимизацию, такую как компоновка кода, преобразуя файл .cmir-linear. Для продолжения компиляции компилятор может быть вызван с (возможно изменённым) файлом .cmir-linear в качестве аргумента вместо соответствующего исходного файла.
2 Опции
Следующие опции командной строки распознаются компилятором ocamlopt. Опции -pack, -a, -shared, -c, -output-obj и -output-complete-obj являются взаимоисключающими.
- -a
- Создать библиотеку (.cmxa и .a/.lib файлы) из файлов с объектным кодом (.cmx и .o/.obj файлы), переданных в командной строке, вместо их объединения в исполняемый файл. Имя библиотеки должно быть задано с помощью опции -o.
Если опции -cclib или -ccopt переданы в командной строке, эти опции сохраняются в результирующей библиотеке .cmxa. Затем, связывание с этой библиотекой автоматически добавляет обратно опции -cclib и -ccopt, как если бы они были заданы в командной строке, если не указана опция -noautolink.
- -absname
- Принудительно отображать сообщения об ошибках с абсолютными путями для имён файлов.
- -no-absname
- Не пытаться отображать абсолютные имена файлов в сообщениях об ошибках.
- -annot
- Устарело начиная с OCaml 4.11. Используйте -bin-annot вместо этого.
- -args filename
- Читать дополнительные аргументы командной строки, завершённые новой строкой, из файла filename.
- -args0 filename
- Читать дополнительные аргументы командной строки, завершённые нулём, из файла filename.
- -bin-annot
- Выводить подробную информацию о компиляции (типы, связи, вызовы с хвостовой рекурсией и т.д.) в двоичном формате. Информация для файла src.ml (соответственно, src.mli) помещается в файл src.cmt (соответственно, src.cmti). В случае ошибки типизации выводить всю информацию, полученную проверкой типов, перед ошибкой. Файлы *.cmt и *.cmti, созданные с помощью -bin-annot, содержат больше информации и значительно компактнее, чем файлы, созданные с помощью -annot.
- -c
- Только компиляция. Игнорировать этап компоновки компиляции. Файлы исходного кода преобразуются в скомпилированные файлы, но исполняемый файл не создаётся. Эта опция полезна для компиляции модулей по отдельности.
- -cc ccomp
- Использовать ccomp как компоновщик C для создания конечного исполняемого файла и как компилятор C для компиляции файлов исходного кода .c. При связывании файлов объектов, созданных с помощью компилятора C++ (например, g++ или clang++), рекомендуется использовать -cc c++.
- -cclib -llibname
- Передать опцию -llibname компоновщику. Это приводит к тому, что указанная библиотека C связывается с программой.
- -ccopt option
- Передать данную опцию компилятору и компоновщику C. Например, -ccopt -Ldir заставляет компоновщик C искать библиотеки C в каталоге dir.
- -cmi-file filename
- Использовать указанный интерфейсный файл для проверки типов файла исходного кода ML для компиляции. Когда эта опция не указана, компилятор ищет файл .mli с тем же базовым именем, что и реализация, которую он компилирует, и в том же каталоге. Если такой файл найден, компилятор ищет соответствующий файл .cmi в включённых каталогах и сообщает об ошибке, если не может его найти.
- -color mode
- Включить или выключить цвета в сообщениях компилятора (особенно предупреждения и ошибки). Поддерживаются следующие режимы:
- auto
- использовать эвристику, чтобы включить цвета только если вывод их поддерживает (терминал, совместимый с ANSI);
- always
- включить цвета безусловно;
- never
- отключить вывод цвета.
Если -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
- Добавить отладочную информацию во время компиляции и компоновки. Этот параметр необходим для создания отслеживания стека при завершении программы с необработанным исключением (см. раздел 15.2).
- -no-g
- Не записывать отладочную информацию (по умолчанию).
- -i
- Принудить компилятор вывести все определенные имена (с их выведенными типами или определениями) при компиляции реализации (.ml файл). Никаких скомпилированных файлов (.cmo и .cmi файлы) не создается. Это может быть полезно для проверки типов, выведенных компилятором. Кроме того, поскольку вывод соответствует синтаксису интерфейсов, это может помочь в написании явного интерфейса (.mli файл) для файла: просто перенаправьте стандартный вывод компилятора в .mli файл и отредактируйте этот файл, чтобы удалить все объявления неэкспортированных имен.
- -I directory
- Добавить заданный каталог в список каталогов, в которых ищутся скомпилированные файлы интерфейсов (.cmi), файлы скомпилированного объектного кода (.cmx) и библиотеки (.cmxa). По умолчанию сначала ищется текущий каталог, а затем — каталог стандартной библиотеки. Каталоги, добавленные с помощью -I, ищутся после текущего каталога в порядке, в котором они были указаны в командной строке, но перед каталогом стандартной библиотеки. См. также параметр -nostdlib.
Если заданный каталог начинается с +, он берется относительно каталога стандартной библиотеки. Например, -I +unix добавляет подкаталог unix стандартной библиотеки в путь поиска.
- -H directory
- Ведёт себя идентично -I, за исключением того, что (а) программы не могут напрямую ссылаться на модули, добавленные в путь поиска таким образом, и (б) эти каталоги ищутся после любых каталогов -I. Это позволяет предоставить компилятору скомпилированные файлы интерфейсов и объектного кода для транзитивных зависимостей текущей программы (зависимости от зависимостей) без их молчаливого превращения в прямые зависимости.
- -impl filename
- Скомпилировать файл filename как файл реализации, даже если его расширение не .ml.
- -inline n
- Установить агрессивность встраивания в n, где n — положительное целое число. Указание -inline 0 предотвращает встраивание всех функций, за исключением тех, тело которых меньше места вызова. Таким образом, встраивание не приводит к увеличению размера кода. По умолчанию агрессивность -inline 1 позволяет встраивать несколько более крупные функции, что приводит к небольшому увеличению размера кода. Более высокие значения для параметра -inline приводят к тому, что всё более и более крупные функции становятся кандидатами на встраивание, но могут привести к серьёзному увеличению размера кода.
- -intf filename
- Скомпилировать файл filename как файл интерфейса, даже если его расширение не .mli.
- -intf-suffix string
- Распознавать имена файлов, оканчивающиеся на string, как файлы интерфейсов (вместо стандартного .mli).
- -labels
- Метки не игнорируются в типах, метки могут использоваться в приложениях, и помеченные параметры могут быть заданы в любом порядке. Это значение по умолчанию.
- -linkall
- Принудительно подключать все модули, содержащиеся в библиотеках. Если этот флаг не задан, неиспользуемые модули не подключаются. При построении библиотеки (параметр -a), установка параметра -linkall принудительно подключает все последующие ссылки программ, использующих эту библиотеку, к подключению всех модулей, содержащихся в библиотеке. При компиляции модуля (параметр -c), установка параметра -linkall гарантирует, что этот модуль всегда будет подключён, если он помещён в библиотеку, и эта библиотека подключается.
- -linscan
- Использовать линейный сканирующий алгоритм выделения регистров. Компиляция с этим алгоритмом быстрее, чем с обычным алгоритмом окраски графов, иногда значительно для длинных функций и модулей. С другой стороны, сгенерированный код может быть немного медленнее.
- -match-context-rows
- Установить количество строк контекста, используемых для оптимизации при компиляции сопоставления с образцом. Значение по умолчанию равно 32. Более низкие значения ускоряют компиляцию, но создают менее оптимизированный код. Этот расширенный параметр предназначен для использования в случае, если программа с интенсивным сопоставлением с образцом приводит к значительному увеличению времени компиляции.
- -no-alias-deps
- Не записывать зависимости для псевдонимов модулей. См. раздел 12.8 для получения дополнительной информации.
- -no-app-funct
- Деактивирует прикладное поведение функторов. С этим параметром каждое применение функтора генерирует новые типы в своём результате, а применение того же функтора дважды к одному и тому же аргументу даёт две несовместимые структуры.
- -no-float-const-prop
- Деактивирует распространение констант для операций с плавающей точкой. Этот параметр следует использовать, если программа изменяет режим округления чисел с плавающей точкой во время выполнения.
- -noassert
- Не компилировать проверки утверждений. Обратите внимание, что специальная форма assert false всегда компилируется, потому что она специально типизируется. Этот флаг не имеет эффекта при компоновке уже скомпилированных файлов.
- -noautolink
- При компоновке .cmxa библиотек игнорировать параметры -cclib и -ccopt, которые могут содержаться в библиотеках (если эти параметры были заданы при построении библиотек). Это может быть полезно, если библиотека содержит некорректные спецификации C-библиотек или C-параметров; в этом случае во время компоновки установите -noautolink и передайте правильные C-библиотеки и параметры в командной строке.
- -nodynlink
- Разрешить компилятору использовать некоторые оптимизации, которые справедливы только для кода, статически связанного для создания неперемещаемого исполняемого файла. Сгенерированный код не может быть связан для создания динамической библиотеки или исполняемого файла с позиционной независимостью (PIE). Многие операционные системы по умолчанию создают PIE, вызывая ошибки при компоновке кода, скомпилированного с -nodynlink. Либо не используйте -nodynlink, либо передайте параметр -ccopt -no-pie во время компоновки.
- -nolabels
- Игнорировать необов'язательные метки в типах. Метки нельзя использовать в приложениях, и порядок параметров становится жёстким.
- -nostdlib
- Не добавлять автоматически каталог стандартной библиотеки в список каталогов, проверяемых при поиске скомпилированных файлов интерфейса (.cmi), скомпилированных файлов объектного кода (.cmx) и библиотек (.cmxa). См. также опцию -I.
- -o output-file
- Указать имя выходного файла. Для исполняемых файлов по умолчанию имя выходного файла — a.out в Unix и camlprog.exe в Windows. Если указана опция -a, указать имя создаваемой библиотеки. Если указана опция -pack, указать имя создаваемого упакованного файла объекта. Если указаны опции -output-obj или -output-complete-obj, указать имя создаваемого файла объекта. Если указана опция -shared, указать имя создаваемого файла плагина.
- -opaque
- При компиляции реализации родным компилятором по умолчанию генерируется файл .cmx содержащий информацию для межмодульной оптимизации. Также ожидаются файлы .cmx для зависимостей текущего компилируемого источника, которые используются для оптимизации. Начиная с OCaml 4.03, компилятор выводит предупреждение, если не может найти файл .cmx одной из этих зависимостей.
Опция -opaque, доступная с версии 4.04, отключает информацию о межмодульной оптимизации для текущей компилируемой единицы. При компиляции интерфейса .mli с использованием -opaque отмечается скомпилированный интерфейс .cmi так, что последующие компиляции модулей, зависящих от него, не будут полагаться на соответствующий файл .cmx, а также не будут предупреждать, если он отсутствует. При компиляции реализации .ml родным компилятором с использованием -opaque генерируется .cmx, который не содержит никакой информации о межмодульной оптимизации.
Использование этой опции может ухудшить качество генерируемого кода, но уменьшает время компиляции, как при чистых, так и при инкрементных сборках. Действительно, с родным компилятором, когда изменяется реализация компиляционной единицы, все единицы, от неё зависящие, могут потребовать перекомпиляции — потому что информация о межмодулях может измениться. Если компиляционная единица, чья реализация изменилась, была скомпилирована с -opaque, такая перекомпиляция не требуется. Таким образом, эта опция может использоваться, например, для получения более быстрых циклов обратной связи «редактирование—компиляция—тестирование».
- -open Module
- Открывает указанный модуль перед обработкой файлов интерфейса или реализации. Если задано несколько опций -open, они обрабатываются в порядке, точно так же, как если бы операторы open! Module1;; ... open! ModuleN;; были добавлены в начало каждого файла.
- -output-obj
- Заставляет компоновщик создавать файл объекта C вместо исполняемого файла. Это полезно для упаковки кода OCaml в библиотеку C, вызываемую из любой программы C. См. главу 22, раздел 22.7.5. Имя выходного файла объекта необходимо задать с помощью опции -o. Эта опция также может использоваться для создания скомпилированной общей/динамической библиотеки (.so расширение, .dll в Windows).
- -output-complete-obj
- То же, что и опция -output-obj, за исключением того, что создаваемый файл объекта включает runtime и библиотеки автоподключения.
- -pack
- Создать файл объекта (.cmx и .o/.obj файлы) и его связанный скомпилированный интерфейс (.cmi), который объединяет файлы объектов .cmx, указанные в командной строке, представляя их как подмодули выходного файла .cmx. Имя выходного файла .cmx необходимо указать с помощью опции -o. Например,
ocamlopt -pack -o P.cmx A.cmx B.cmx C.cmx
генерирует скомпилированные файлы P.cmx, P.o и P.cmi, описывающие компиляционную единицу, имеющую три подмодуля A, B и C, соответствующие содержимому файлов объектов A.cmx, B.cmx и C.cmx. Это содержимое можно ссылаться как P.A, P.B и P.C в остальной части программы.Объединяемые файлы объектов .cmx должны быть скомпилированы с соответствующей опцией -for-pack. В приведенном выше примере A.cmx, B.cmx и C.cmx должны быть скомпилированы с помощью ocamlopt -for-pack P.
Несколько уровней упаковки могут быть достигнуты путем комбинирования -pack с -for-pack. Рассмотрим следующий пример:
ocamlopt -for-pack P.Q -c A.ml ocamlopt -pack -o Q.cmx -for-pack P A.cmx ocamlopt -for-pack P -c B.ml ocamlopt -pack -o P.cmx Q.cmx B.cmxПолученный файл объекта P.cmx имеет подмодули P.Q, P.Q.A и P.B.
- -pp command
- Заставить компилятор вызвать заданную команду как препроцессор для каждого файла исходного кода. Вывод команды перенаправляется во временный файл, который компилируется. При отсутствии ошибок компиляции временный файл удаляется после этого.
- -ppx command
- После анализа, передать абстрактное синтаксическое дерево в препроцессор command. Модуль Ast_mapper, описанный в главе 30: Ast_mapper , реализует внешний интерфейс препроцессора.
- -principal
- Проверить путь информации во время проверки типов, чтобы убедиться, что все типы получены главным образом. При использовании помеченных аргументов и/или полиморфных методов этот флаг необходим для обеспечения того, что будущие версии компилятора смогут правильно выводить типы, даже если внутренние алгоритмы изменятся. Все программы, принятые в режиме -principal, также принимаются в режиме по умолчанию с эквивалентными типами, но различными бинарными сигнатурами, что может замедлить проверку типов; тем не менее, рекомендуется использовать его один раз перед публикацией исходного кода.
- -rectypes
- Разрешить произвольные рекурсивные типы во время проверки типов. По умолчанию поддерживаются только рекурсивные типы, где рекурсия проходит через тип объекта. Обратите внимание, что после создания интерфейса с помощью этого флага необходимо использовать его снова для всех зависимостей.
- -runtime-variant suffix
- Добавьте строку приставки к имени библиотеки выполнения, используемой программой. В настоящее время поддерживается только один такой суффикс: d, и только если компилятор OCaml был сконфигурирован с опцией -with-debug-runtime. Этот суффикс указывает на отладочную версию выполнения, которая полезна для отладки проблем с указателями в коде низкого уровня, таком как C-стыки.
- -S
- Сохранить ассемблерный код, сгенерированный во время компиляции. Ассемблерный код для исходного файла x.ml сохраняется в файле x.s.
- -safe-string
- Принудительно разделить типы string и bytes, тем самым сделав строки неизменяемыми. Это значение по умолчанию и применяется с OCaml 5.0.
- -safer-matching
- Не использовать информацию о типе для оптимизации сопоставления с образцом. Это позволяет обнаруживать ошибки совпадения даже если сопоставление с образцом ошибочно предполагалось исчерпывающим. Это влияет только на компиляцию GADT и полиморфных вариантов.
- -save-ir-after pass
- Сохранить промежуточное представление после указанного этапа компиляции в файл. В настоящее время поддерживаются следующие этапы и соответствующие расширения файлов: scheduling (.cmir-linear).
Эта экспериментальная функция позволяет внешним инструментам инспектировать и манипулировать промежуточным представлением программы компилятора с использованием библиотеки compiler-libs (см. главу 30 и Compiler_libs ).
- -shared
- Создать плагин (обычно .cmxs), который можно динамически загрузить с помощью модуля Dynlink. Имя плагина должно быть установлено с помощью опции -o. Плагин может включать в себя несколько модулей и библиотек OCaml, а также дополнительные нативные объекты (.o, .obj, .a, .lib файлы). Создание нативных плагинов поддерживается только для некоторых операционных систем. В некоторых системах (в настоящее время только Linux AMD 64) весь код OCaml, связанный с плагином, должен быть скомпилирован без флага -nodynlink. Также могут быть ограничения на способ компиляции дополнительных нативных объектов (в Linux AMD 64 они должны содержать только позиционно-независимый код).
- -short-paths
- Если тип виден по нескольким путям модулей, используйте самый короткий при печати имени типа в вывод интерфейсов, сообщений об ошибках и предупреждениях. Имена идентификаторов, начинающиеся с подчеркивания _ или содержащие двойные подчеркивания __ увеличивают длину на +10.
- -stop-after pass
- Остановите компиляцию после данного этапа компиляции. В настоящее время поддерживаются следующие этапы: parsing, typing, scheduling, emit.
- -strict-sequence
- Принудительно задать тип левой части каждой последовательности как unit.
- -strict-formats
- Отклонять некорректные форматы, которые принимались в реализациях старых форматов. Необходимо использовать этот флаг для обнаружения и исправления таких некорректных форматов, поскольку они будут отклоняться будущими версиями OCaml.
- -unboxed-types
- Если тип может быть не упакован (т.е. запись с одним аргументом или конкретный тип данных с одним конструктором одного аргумента), он будет не упакован, если не помечен [@@ocaml.boxed].
- -no-unboxed-types
- Если тип может быть не упакован, он будет упакован, если не помечен [@@ocaml.unboxed]. Это значение по умолчанию.
- -unsafe
- Отключить проверку границ для доступа к массивам и строкам (v.(i) и s.[i] конструкции). Программы, скомпилированные с -unsafe, поэтому быстрее, но небезопасны: все может произойти, если программа обращается к массиву или строке за пределами его границ. Кроме того, отключить проверку на ноль делителя в операциях целочисленного деления и модуля. С -unsafe, целочисленное деление (или модуль) на ноль может остановить программу или продолжить с неопределенным результатом вместо повышения исключения Division_by_zero.
- -unsafe-string
- Идентифицировать типы string и bytes, тем самым сделав строки изменяемыми. Это предназначено для совместимости со старым исходным кодом и не должно использоваться с новым ПО. Эта опция вызывает ошибку безусловно с OCaml 5.0.
- -v
- Вывести номер версии компилятора и местоположение каталога стандартной библиотеки, а затем выйти.
- -verbose
- Вывести все внешние команды перед их выполнением, в частности вызовы ассемблера, компилятора C и компоновщика. Полезно для отладки проблем с библиотеками C.
- -version or -vnum
- Вывести номер версии компилятора в краткой форме (например, 3.11.0), а затем выйти.
- -w warning-list
- Включить, отключить или пометить как критическое предупреждения, указанные аргументом warning-list. Каждое предупреждение может быть включено или выключено, а также критическим или некритическим. Если предупреждение выключено, оно не отображается и никак не влияет на компиляцию (даже если оно критическое). Если предупреждение включено, оно отображается компилятором обычным образом, когда исходный код его вызывает. Если оно включено и критическое, компилятор также остановится с ошибкой после его отображения.
Аргумент warning-list — это последовательность спецификаторов предупреждений без разделителей между ними. Спецификатор предупреждения — это одно из следующего:
- +num
- Включить предупреждение номер num.
- -num
- Отключить предупреждение номер num.
- @num
- Включить и пометить как критическое предупреждение номер num.
- +num1..num2
- Включить предупреждения в заданном диапазоне.
- -num1..num2
- Отключить предупреждения в заданном диапазоне.
- @num1..num2
- Включить и пометить как критическое предупреждения в заданном диапазоне.
- +letter
- Включить набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
- -letter
- Отключить набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
- @letter
- Включить и пометить как критическое набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
- uppercase-letter
- Включить набор предупреждений, соответствующих uppercase-letter.
- lowercase-letter
- Отключить набор предупреждений, соответствующих lowercase-letter.
В качестве альтернативы, warning-list может указать одно предупреждение по его мнемоническому имени (см. ниже), следующим образом:
- +name
- Включить предупреждение name.
- -name
- Отключить предупреждение name.
- @name
- Включить и пометить как критическое предупреждение name.
Номера предупреждений, буквы и имена, которые в настоящее время не определены, игнорируются. Предупреждения следующие (имя после каждого номера указывает мнемонику для этого предупреждения).
- 1 comment-start
- Подозрительная метка начала комментария.
- 2 comment-not-end
- Подозрительная метка конца комментария.
- 3
- Устаревшее синоним для предупреждения ’deprecated’.
- 4 fragile-match
- Хрупкое сопоставление шаблонов: соответствие, которое останется полным, даже если к одному из типов вариантов, с которыми сравнивается, будут добавлены дополнительные конструкторы.
- 5 ignored-partial-application
- Частично примененная функция: выражение, результат которого имеет тип функции и игнорируется.
- 6 labels-omitted
- Метка опущена в применении функции.
- 7 method-override
- Метод перезаписан.
- 8 partial-match
- Частичное соответствие: отсутствующие случаи в сопоставлении шаблонов.
- 9 missing-record-field-pattern
- Отсутствующие поля в шаблоне записи.
- 10 non-unit-statement
- Выражение в левой части последовательности, у которого нет типа unit (и которое не является функцией, см. предупреждение номер 5).
- 11 redundant-case
- Избыточный случай в сопоставлении шаблонов (неиспользуемый случай соответствия).
- 12 redundant-subpat
- Избыточный подшаблон в сопоставлении шаблонов.
- 13 instance-variable-override
- Переопределён переменная экземпляра.
- 14 illegal-backslash
- Неправильный обратный слэш в строковой константе.
- 15 implicit-public-methods
- Приватный метод неявно сделан публичным.
- 16 unerasable-optional-argument
- Неудаляемый необязательный аргумент.
- 17 undeclared-virtual-method
- Необъявленный виртуальный метод.
- 18 not-principal
- Неглавный тип.
- 19 non-principal-labels
- Тип без принципиальности.
- 20 ignored-extra-argument
- Неиспользуемый аргумент функции.
- 21 nonreturning-statement
- Невозвращающее выражение.
- 22 preprocessor
- Предупреждение препроцессора.
- 23 useless-record-with
- Бесполезная запись with части.
- 24 bad-module-name
- Неправильное имя модуля: имя исходного файла не является допустимым именем модуля OCaml.
- 25
- Проигнорировано: теперь часть предупреждения 8.
- 26 unused-var
- Подозрительная неиспользуемая переменная: неиспользуемая переменная, связанная с let или as и не начинающаяся с символа подчёркивания (_).
- 27 unused-var-strict
- Безобидная неиспользуемая переменная: неиспользуемая переменная, которая не связана с let ни с as и не начинается с символа подчёркивания (_).
- 28 wildcard-arg-to-constant-constr
- Дикий шаблон, данный как аргумент константного конструктора.
- 29 eol-in-string
- Неэкранированный конец строки в строковой константе (непереносимый код).
- 30 duplicate-definitions
- Два метки или конструктора с одинаковым именем определены в двух взаимно рекурсивных типах.
- 31 module-linked-twice
- Модуль связан дважды в одной исполняемой программе.
- I
- Игнорируется: теперь жёсткая ошибка (с версии 5.1).
- 32 unused-value-declaration
- Неиспользуемое объявление значения. (с версии 4.00)
- 33 unused-open
- Неиспользуемое оператор open. (с версии 4.00)
- 34 unused-type-declaration
- Неиспользуемое объявление типа. (с версии 4.00)
- 35 unused-for-index
- Неиспользуемый индекс цикла for. (с версии 4.00)
- 36 unused-ancestor
- Неиспользуемый предковый переменная. (с версии 4.00)
- 37 unused-constructor
- Неиспользуемый конструктор. (с версии 4.00)
- 38 unused-extension
- Неиспользуемый расширенный конструктор. (с версии 4.00)
- 39 unused-rec-flag
- Неиспользуемый флаг rec. (с версии 4.00)
- 40 name-out-of-scope
- Имя конструктора или метки использовано вне области видимости. (с версии 4.01)
- 41 ambiguous-name
- Размытое имя конструктора или метки. (с версии 4.01)
- 42 disambiguated-name
- Ясность имени конструктора или метки (предупреждение совместимости). (с версии 4.01)
- 43 nonoptional-label
- Необязательная метка применена как необязательная. (с версии 4.01)
- 44 open-shadow-identifier
- Оператор open затеняет уже определённый идентификатор. (с версии 4.01)
- 45 open-shadow-label-constructor
- Оператор open затеняет уже определённую метку или конструктор. (с версии 4.01)
- 46 bad-env-variable
- Ошибка в переменной среды. (с версии 4.01)
- 47 attribute-payload
- Некорректная нагрузка атрибута. (с версии 4.02)
- 48 eliminated-optional-arguments
- Неявное удаление необязательных аргументов. (с версии 4.02)
- 49 no-cmi-file
- Отсутствует файл cmi при поиске псевдонима модуля. (с версии 4.02)
- 50 unexpected-docstring
- Неожиданный комментарий документации. (с версии 4.03)
- 51 wrong-tailcall-expectation
- Вызов функции с неправильным атрибутом @tailcall. (с версии 4.03)
- 52 fragile-literal-pattern (см. 13.5.3)
- Хрупкий шаблон константы. (с версии 4.03)
- 53 misplaced-attribute
- Атрибут не может быть в этом контексте. (с версии 4.03)
- 54 duplicated-attribute
- Атрибут используется более одного раза в выражении. (с версии 4.03)
- 55 inlining-impossible
- Внедрение невозможно. (с версии 4.03)
- 56 unreachable-case
- Недостижимый случай в шаблоне сопоставления (на основе информации о типе). (с версии 4.03)
- 57 ambiguous-var-in-pattern-guard (см. 13.5.4)
- Неоднозначные переменные в шаблоне или с условием. (с версии 4.03)
- 58 no-cmx-file
- Отсутствует файл cmx. (с версии 4.03)
- 59 flambda-assignment-to-non-mutable-value
- Присваивание неизменяемому значению. (с версии 4.03)
- 60 unused-module
- Неиспользуемое объявление модуля. (с версии 4.04)
- 61 unboxable-type-in-prim-decl
- Тип, который нельзя распаковать, в примитивном объявлении. (с версии 4.04)
- 62 constraint-on-gadt
- Ограничение типа на объявлении типа GADT. (с версии 4.06)
- 63 erroneous-printed-signature
- Ошибочная напечатанная сигнатура. (с версии 4.08)
- 64 unsafe-array-syntax-without-parsing
- -unsafe используется с препроцессором, возвращающим дерево синтаксического анализа. (с версии 4.08)
- 65 redefining-unit
- Объявление типа, определяющее новый конструктор ’()’. (с версии 4.08)
- 66 unused-open-bang
- Неиспользуемое утверждение open!. (с версии 4.08)
- 67 unused-functor-parameter
- Неиспользуемый параметр функтора. (с версии 4.10)
- 68 match-on-mutable-state-prevent-uncurry
- Шаблон сопоставления, зависящий от изменяемого состояния, предотвращает раскрутку оставшихся аргументов. (с версии 4.12)
- 69 unused-field
- Неиспользуемое поле записи. (с версии 4.13)
- 70 missing-mli
- Отсутствует файл интерфейса. (с версии 4.13)
- 71 unused-tmc-attribute
- Неиспользуемый атрибут @tail_mod_cons. (с версии 4.14)
- 72 tmc-breaks-tailcall
- При преобразовании @tail_mod_cons хвостовой вызов превращается в нехвостовой. (с версии 4.14)
- 73 generative-application-expects-unit
- Генеративный функтор применяется к пустой структуре (конец структуры) вместо (). (с версии 5.1)
- A
- все предупреждения
- C
- предупреждения 1, 2.
- D
- Псевдоним для предупреждения 3.
- E
- Псевдоним для предупреждения 4.
- F
- Псевдоним для предупреждения 5.
- K
- предупреждения 32, 33, 34, 35, 36, 37, 38, 39.
- L
- Псевдоним для предупреждения 6.
- M
- Псевдоним для предупреждения 7.
- P
- Псевдоним для предупреждения 8.
- R
- Псевдоним для предупреждения 9.
- S
- Псевдоним для предупреждения 10.
- U
- предупреждения 11, 12.
- V
- Псевдоним для предупреждения 13.
- X
- предупреждения 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 30.
- Y
- Псевдоним для предупреждения 26.
- Z
- Псевдоним для предупреждения 27.
Значение по умолчанию — -w +a-4-6-7-9-27-29-32..42-44-45-48-50-60. Оно отображается с помощью ocamlopt -help. Обратите внимание, что предупреждения 5 и 10 не всегда срабатывают, в зависимости от внутренней работы проверяющего типа.
- -warn-error warning-list
- Отметить как фатальные предупреждения, указанные в аргументе warning-list. Компилятор остановится с ошибкой, когда будет выведено одно из этих предупреждений. warning-list имеет такое же значение, как и для опции -w: знак + (или заглавная буква) помечает соответствующие предупреждения как фатальные, знак - (или строчная буква) возвращает их в нефатальные предупреждения, а знак @ одновременно включает и помечает соответствующие предупреждения как фатальные.
Примечание: Не рекомендуется использовать наборы предупреждений (т. е. буквы) как аргументы к -warn-error в производственном коде, потому что это может нарушить сборку при добавлении новых предупреждений в будущие версии OCaml.
Значение по умолчанию — -warn-error -a (ни одно предупреждение не является фатальным).
- -warn-help
- Отобразить описание всех доступных номеров предупреждений.
- -where
- Распечатать расположение стандартной библиотеки, а затем завершить работу.
- -with-runtime
- Включить систему времени выполнения в сгенерированную программу. Это значение по умолчанию.
- -without-runtime
- Компилятор не включает систему времени выполнения (ни ссылку на неё) в сгенерированную программу; её нужно предоставить отдельно.
- - file
- Обработать file как имя файла, даже если оно начинается с символа дефиса (-).
- -help or --help
- Отобразить краткое описание использования и завершить работу.
Параметры для 64-битной архитектуры x86
Генератор 64-битного кода для процессоров Intel/AMD x86 (amd64 архитектура) поддерживает следующие дополнительные параметры:
- -fPIC
- Сгенерировать позиционно-независимый машинный код. Это значение по умолчанию.
- -fno-PIC
- Сгенерировать позиционно-зависимый машинный код.
Управление параметрами командной строки в контексте
Командную строку компилятора можно изменять «извне» с помощью следующих механизмов. Они экспериментальны и могут быть изменены. Их следует использовать только для экспериментальной работы и разработки, а не в выпускаемых пакетах.
- OCAMLPARAM (переменная окружения)
- Набор аргументов, которые будут вставлены перед или после аргументов из командной строки. Аргументы задаются в виде списка через запятую пар имя=значение. Символ _ используется для указания позиции аргументов командной строки, т.е. a=x,_,b=y означает, что a=x должно быть выполнено до разбора аргументов, а b=y — после. Наконец, альтернативный разделитель может быть задан как первый символ строки в наборе :|; ,.
- ocaml_compiler_internal_params (файл в каталоге stdlib)
- Сопоставление имён файлов со списками аргументов, которые будут добавлены в командную строку (и аргументы OCAMLPARAM).
3 Распространённые ошибки
Сообщения об ошибках почти идентичны сообщениям об ошибках ocamlc. См. раздел 13.4.
4 Запуск исполняемых файлов, созданных ocamlopt
Исполняемые файлы, сгенерированные ocamlopt, являются нативными, автономными исполняемыми файлами, которые можно вызывать непосредственно. Они не зависят от системы выполнения байткода ocamlrun и от динамически загружаемых подключаемых библиотек C/OCaml.
Во время выполнения исполняемого файла, сгенерированного ocamlopt, также проверяются следующие переменные среды:
- OCAMLRUNPARAM
- То же использование, что и в ocamlrun (см. раздел 15.2), за исключением того, что параметр l игнорируется (вместо него используется ограничение размера стека операционной системы).
- CAMLRUNPARAM
- Если OCAMLRUNPARAM не найдено в среде, то используется CAMLRUNPARAM. Если CAMLRUNPARAM также не найдено, используются значения по умолчанию.
5 Совместимость с компилятором байткода
В этом разделе перечислены известные несовместимости между компилятором байткода и компилятором нативного кода. За исключением этих пунктов, два компилятора должны генерировать код, который ведет себя идентично.
- Сигналы обнаруживаются только тогда, когда программа выполняет выделение памяти в куче. То есть, если сигнал получен во время выполнения кода, не производящего выделение, его обработчик не будет вызван до следующего выделения памяти в куче.
- На процессорах ARM и PowerPC (32 и 64 бита) инструкции FMA (fused multiply-add) могут генерироваться для умножения с плавающей точкой, за которым следует сложение или вычитание с плавающей точкой, как в x *. y +. z. Инструкция FMA избегает округления промежуточного результата x *. y, что, как правило, полезно, но приводит к результатам с плавающей точкой, немного отличающимся от результатов, полученных интерпретатором байткода.
- Компилятор нативного кода выполняет ряд оптимизаций, которые не выполняет компилятор байткода, особенно когда активен оптимизатор Flambda. В частности, компилятор нативного кода идентифицирует и устраняет «мертвый код», т.е. вычисления, которые не влияют на результаты программы. Например,
let _ = ignore M.f
содержит ссылку на модуль компиляции M при компиляции в байт код. Эта ссылка заставляет M подключаться и выполнять его код инициализации. Компилятор нативного кода устраняет ссылку на M, поэтому модуль компиляции M может не подключаться и не выполняться. Решением является компиляция M с флагом -linkall, чтобы он всегда подключался и выполнялся, даже если на него нет ссылки. См. также функцию Sys.opaque_identity из стандартного модуля библиотеки Sys. - До версии 4.10 переполнения стека, обычно вызванные чрезмерной рекурсией, не всегда преобразуются в исключение Stack_overflow, как это происходит при использовании компилятора байткода. Система выполнения прилагает все усилия для перехвата переполнения стека и возбуждения исключения Stack_overflow, но иногда это не удаётся, и вместо этого возникает «ошибка сегментации» или другая системная ошибка.
© 1995-2024 INRIA.
https://ocaml.org/manual/5.2/native.html