Глава
1
Глава
2
Глава
3
Глава
4
Глава
5
Глава
6
Глава
7
Глава
8
Глава
9
Глава
10  navigation 
Глава
12
Глава
13
Глава
14 

Глава 11 . Компиляция во внутренний код (ocamlopt)

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

Этот компилятор доступен не на всех платформах. Генерируемый им код работает быстрее байткода, создаваемого ocamlc, однако возрастает как время компиляции, так и размер исполняемых файлов. Тем не менее, совместимость с байткодом исключительно выскока: один и тот же код работает одинаково вне зависимости от того, скомпилирован он ocamlc или ocamlopt.

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

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

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

Результатом стадии компоновки является обычный исполняемый файл. Для запуска ему не нужна ocamlrun.

11 . 2 Параметры

ocamlc разпознает следующие параметры командной строки:

-a

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

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

-cclib -llibname

Передать компилятору и компоновщику С опцию -llibname. В результате указанная библиотека С будет скомпонована с программой.

-ccopt option

Передать указанную опцию компилятору и компоновщику С. Например, -ccopt -Ldir заставит его искать библиотеки С в каталоге dir.

-compact

Оптимизировать код по размеру, а не быстродействию. В результате получаются программы чуть меньшего размера, работающие чуть медленее. По умолчанию используется оптимизация по быстродействию.

-i

Компилятор выводит все определенные имена, а также выведенные типы или определения при компиляции реализации (файла .ml). Это бывает полезно для проверки типов, распознанных компилятором. Кроме того, поскольку вывод соответствует синтаксису интерфейсов, он может помочь явно написать интерфейс (файл .mli) для файла: достаточно перенаправить вывод компилятора в файл .mli и убрать из результата декларации имен, экспорт которых не предполагается.

-I directory

Добавляет directory к списку каталогов, в которых ищутся компилированные файлы интерфейсов (.cmi), компилированные объектные файлы (.cmx) и библиотеки (.cmxa). По умолчанию в первую очередь файлы ищутся в текущем каталоге, затем - в каталоге стандартной библиотеки. Каталоги, заданные опцией -I учитываются после текущего, в том же порядке, как они заданы в командной строке, но перед стандартной библиотекой.

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

-inline n

Устанавливает агрессивность встраиваемости в значение n, где n - положительное целое число. Значение -inline 0 приводит к тому, что функции вовсе не становятся встраиваемыми, за исключением тех, тело которых меньше точки вызова. Таким образом, встраиваемость не приводит к увеличению объема кода. Агрессивность по умолчанию (-inline 1 предусматривает встраиваемость чуть больших по размеру функций, что дает небольшой прирост кода. Дальнейнее увеличение значения этого параметра приводит к том, что все более и более объемные функции становятся кандидатами на встраивание, но и код от этого может значительно вырасти.

-linkall

Форсирует компоновку всех модулей библиотеки. Без этого параметра модули, на которых ссылок нет, не компонуются. При построении библиотеки (флаг -a) установка флага -linkall приводит к тому, что в последующем при компиляции программ, использующих эту библиотеку, все модули библиотеки будут компоноваться заново.

-noassert

Отключает проверку утверждений, и утверждения не компилируются. При компоновке ранее скомпилированных файлов этот флаг не работает.

-noautolink

При компоновке библиотек .cmxa опции -custom, -cclib и -ccopt, вероятно хранящиеся в библиотеках (если они были указаны при построении библиотек), игнорируются. Этот флаг полезен, если библиотека содержит неправильные спецификации библиотек или опций С. В этом случае надо указать в командной строке правильные библиотеки и опции С.

-nolabels

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

-o exec-file

Имя файла, создаваемого компоновщиком. По умолчанию по традициям Unix создается файл a.out. Если используется опция -a, укажите имя библиотеки. Если используется опция -output-obj, укажите имя объектного файла.

-output-obj

Вместо исполняемого файла компоновщик создает объектный файл С. Это позволяет при необходимости оформить код Caml как библиотеку С, которую можно вызывать из любой программы С. Более подробно см. раздел 18.7.5. По умолчанию создается файл camlprog.o, но имя может быть задано с помощью опции -o.

-p

Генерировать дополнительный код для записи профилировочной информации при исполнении программы. Такую информацию можно изучить с помощью программы gprof (см. подробнее гл. 17). Параметр должен быть задан как во время компиляции, так и во время компоновки. Можно компоновать объектные файлы, скомпилированные в обычном режиме, но профилирование в этом случае будет менее точным.

Unix

Подробную информацию о профайлах см. в страницах руководства Unix gprof(1).

Полная поддержка gprof есть только на некоторых платформах (в настоящее время - Intel x86/Linux и Alpha/Digital Unix). На других платформах профайлы менее точны (нет графов вызова, только профайл по времени).

Windows

Этот параметр не работает под Windows.

-pack

Создает объектный файл (.cmx/.o) и связанный с с ним скомпилированный интерфейс (.cmi), которые включают все объектные файлы .cmx, перечисленные в командной строке. Эти файлы становятся субмодулями результирующего файла .cmx. Имя последнего задается опцией -o. Например,

ocamlopt -pack -o p.cmx a.cmx b.cmx c.cmx

создает компилированные файлы p.cmx и p.cmi, описывающие единицу компиляции, включающую субмодули A, B и C, соотвествующие содержанию объектных файлов a.cmx, b.cmx и c.cmx. В дальнейшем на них можно ссылаться как P.A, P.B и P.C.

Unix

Параметр -pack доступен лишь на тех платформах, для которых существуют инструменты GNU binutils nm и objcopy.

-pp command

Компилятр вызывает заданную команду command как препроцессор для каждого исходного файла. Вывод команды перенаправляется в промежуточный файл, который и компилируется. Если компиляция проходит без ошибок, по ее завершении промежуточный файл удаляется. Имя файла конструируется на основе имени исходного файла и получает расширение .ppi для интерфейса (.mli) или .ppo для реализации (.ml).

-principal

Во время проверки типов компилятор проверяет также информацию о путях, следя чтобы все типы выводились приниципально. Программы, допустимые в режиме -principal, допустимы и в режиме по умолчанию с эквивалентными типами, однако бинарные сигнатуры в этом случае другие.

-rectypes

Разрешает во время проверки типа произвольные рекурсивные типы. По умолчанию поддерживаются только рекурсивные типы с рекурсией по типу объекта.

-S

Сохранять код ассемблера, полученный во время компиляции. Код для файла X.ml сохраняется как X.s.

-thread

Компилирует или компонует многопоточные программы с использованием библиотеки thread, описанной в главе 24. На самом деле, эта опция просто подключает особую версию стандартной библиотеки, безопасную по потокам.

-unsafe

Отключает проверку границ на массивах и обращении к строкам (конструкции v.(i) и s.[i]). Программы, собранные с этой опцией несколько быстрее, но не являются безопасными: при обращении к элементу за пределами массива или границы строки может произойти все, что угодно.

-v

Выводит номер версии компилятора и путь к стандартной библиотеке, после чего прекращает работу.

-verbose

Выводит все внешние команды перед их выполнением. В частности это касается ассемблера, компилятора и компоновщика C.

-version

Выводит номер версии компилятора в краткой форме (например 3.06) и прекращает работу.

-w warning-list

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

A/a

включить/выключить все предупреждения.

C/c

включить/выключить предупреждения о подозрительных комментариях.

D/d

Включить/выключить предупреждения об использовании устаревших функций.

F/f

Включить/выключить предупреждения о неполном применении функций (например, f x; expr при том, что вызов f x имеет тип функции).

L/l

Включить/выключить предупреждения о пропуске меток в вызовах.

M/m

Включить/выключить предупреждения о переопределенных методах.

P/p

Включить/выключить предупреждения о неполных совпадениях (пропущенные ветки в поиске по образцу).

S/s

Включить/выключить предупреждения о предложениях с типом, отличным от unit (например, expr1; expr2, когда expr1 не имеет тип unit.

U/u

Включить/выключить предупреждения о неиспользуемых (избыточных) совпадениях с образцом.

V/v

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

X/x

Включить/выключить все остальные предупреждения.

По умолчанию используется установка -w Al (все предупреждения, кроме меток).

-warn-error

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

-where

Выводит путь к стандартной библиотеке и прекращает работу.

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

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

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

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

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