Spec-Zone.ru › Haskell 9

5.11. Параметры, относящиеся к определённой фазе

5.11.1. Замена программы для одной или нескольких фаз

Можно указать, что для одной из фаз системы компиляции будет использоваться другая программа вместо той, которую ghc встроил в неё. Например, может понадобиться попробовать другой ассемблер. Следующие параметры позволяют изменить внешнюю программу, используемую на определённой фазе компиляции:

-pgmL ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве препроцессора literate.

-pgmP ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве препроцессора C для Haskell (только вместе с -cpp). Обратите внимание, что препроцессор C для Haskell обрабатывает только файлы Haskell.

-pgmJSP ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве препроцессора C для JavaScript (только для бэкенда JavaScript).

-pgmCmmP ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве препроцессора C для C–.

-pgmc ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве компилятора C.

-pgmcxx ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве компилятора C++.

-pgmlo ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве оптимизатора LLVM.

-pgmlc ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве компилятора LLVM.

-pgmlas ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве ассемблера LLVM

-pgms ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве разделителя.

-pgma ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве ассемблера.

-pgml ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве компоновщика.

-pgmlm ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве компоновщика при объединении объектных файлов (например, при создании объединённых объектных файлов для загрузки в GHCi).

-pgmF ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве препроцессора (только вместе с -F).

-pgmotool ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве программы для анализа динамических библиотек и исполняемых файлов Mach-O с целью чтения зависимостей динамических библиотек. Мы вычислим необходимый вызов runpath``s to embed for the dependencies based on the result of the ``otool.

-pgminstall_name_tool ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве программы для добавления вызова runpath``s into mach-o dynamic libraries and executables.  As detected by the ``otool.

-pgmwindres ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве программы для встраивания манифестов в Windows. Обычно это программа windres, поставляемая вместе с установкой GHC. См. -fno-embed-manifest в разделе Параметры, влияющие на компоновку.

-pgmi ⟨cmd⟩

Использовать ⟨cmd⟩ в качестве команды внешнего интерпретатора (см. Запуск интерпретатора в отдельном процессе). По умолчанию: ghc-iserv-prof, если включён параметр -prof; ghc-iserv-dyn, если включён параметр -dynamic; или ghc-iserv в остальных случаях.

5.11.2. Передача параметров определённой фазе

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

-optL ⟨option⟩

Передать ⟨option⟩ препроцессору literate

-optP ⟨option⟩

Передать ⟨option⟩ препроцессору CPP для Haskell (имеет смысл только при включённом параметре -cpp). Обратите внимание, что параметры препроцессора Haskell применяются только при предварительной обработке файлов Haskell; например, чтобы использовать другие параметры для предварительной обработки JavaScript или Cmm, следует использовать соответственно -optJSP или -optCmmP.

-optJSP ⟨option⟩

Передать ⟨option⟩ препроцессору C для JavaScript (только для бэкенда JavaScript).

-optCmmP ⟨option⟩

Передать ⟨option⟩ препроцессору C для C–.

Препроцессор C для C– также получает флаги компилятора C. Эти флаги указываются _перед_ флагами, добавленными этим параметром. В результате совокупный эффект следующей пары флагов равен нулю: -optCmmP-UFOO -optc-DFOO.

-optF ⟨option⟩

Передать ⟨option⟩ пользовательскому препроцессору (см. Параметры, влияющие на препроцессор Haskell).

-optc ⟨option⟩

Передать ⟨option⟩ компилятору C и, для совместимости, препроцессору C–.

-pgmc-supports-no-pie

Выполняет то же действие, что и -pgml-supports-no-pie, заменивший этот параметр.

-pgml-supports-no-pie

При использовании -pgml GHC по умолчанию никогда не передаёт флаг командной строки -no-pie. Причина в том, что неизвестно, поддерживает ли его указанный компилятор, используемый для компоновки (напомним, что мы вызываем компоновщик от своего имени с помощью компилятора C). Этот флаг позволяет указать, что -no-pie поддерживается. Его необходимо передать после -pgml.

Этот флаг не требуется, если -pgmc не используется, поскольку GHC хранит сведения о поддержке -no-pie компилятором C по умолчанию во внутреннем файле настроек.

-optcxx ⟨option⟩

Передать ⟨option⟩ компилятору C++.

-optlo ⟨option⟩

Передать ⟨option⟩ оптимизатору LLVM.

-optlc ⟨option⟩

Передать ⟨option⟩ компилятору LLVM.

-optlas ⟨option⟩

Передать ⟨option⟩ ассемблеру LLVM (обычно clang).

-opta ⟨option⟩

Передать ⟨option⟩ ассемблеру.

-optl ⟨option⟩

Передать ⟨option⟩ компоновщику.

-optlm ⟨option⟩

Передать ⟨option⟩ компоновщику при объединении объектных файлов. В случае стандартного компоновщика в стиле ld сюда обычно следует включить флаг -r.

-optwindres ⟨option⟩

Передать ⟨option⟩ программе windres при встраивании манифестов в Windows. См. -fno-embed-manifest в разделе Параметры, влияющие на компоновку.

-opti ⟨option⟩

Передать ⟨option⟩ подпроцессу интерпретатора (см. Запуск интерпретатора в отдельном процессе). Часто это используется для передачи параметров RTS, например -opti+RTS -opti-A64m, или для включения подробного вывода с помощью -opti-v, чтобы видеть, какие сообщения передаются между GHC и интерпретатором.

Например, чтобы передать ассемблеру параметр -Ewurble, нужно указать драйверу -opta-Ewurble (дефис перед E обязателен).

GHC — это программа на Haskell, поэтому, если нужно напрямую передать параметры среде выполнения GHC, их можно заключить в +RTS ... -RTS (см. Параметры среды выполнения (RTS)).

5.11.3. Параметры, влияющие на препроцессор C

CPP
Начиная с:

6.8.1

Языковое расширение CPP включает препроцессор C. Его можно включить с помощью флага командной строки, добавив перед ним -X. Например:

$ ghc -XCPP foo.hs

Языковое расширение CPP также можно включить с помощью прагмы LANGUAGE. Например:

{-# LANGUAGE CPP #-}
-cpp

Препроцессор C cpp обрабатывает код Haskell, если указан параметр -cpp или расширение CPP. Если только вы не собираете большую систему с широким использованием условной компиляции, скорее всего, он вам не понадобится.

-D⟨symbol⟩[=⟨value⟩]

Определить макрос ⟨symbol⟩ обычным способом. Если значение не указано, ему присваивается значение 1. Например, -DUSE_MYLIB эквивалентно -DUSE_MYLIB=1.

Примечание

-D⟨symbol⟩[=⟨value⟩] не влияет на макросы -D, передаваемые компилятору C при сборке без регистрации! В этом случае используйте обходной приём с -optc-Dfoo… (см. Передача параметров определённой фазе).

-U⟨symbol⟩

Отменить определение макроса ⟨symbol⟩ обычным способом.

-I⟨dir⟩

Указать каталог для поиска файлов #include обычным для C способом.

При обработке исходного кода Haskell драйвер GHC предварительно определяет несколько макросов (для файлов .hs или .lhs).

5.11.3.1. Стандартные макросы CPP

Ниже перечислены символы, определяемые GHC. Чтобы проверить, какие символы определены в установленной у вас версии GHC, можно воспользоваться следующим приёмом:

$ ghc -E -optP-dM -cpp foo.hs
$ cat foo.hspp

(понадобится файл foo.hs, но фактически он не используется).

__GLASGOW_HASKELL__

Для версии GHC x.y.z значением __GLASGOW_HASKELL__ является целое число ⟨xyy⟩ (если ⟨y⟩ состоит из одной цифры, перед ней добавляется ноль; например, для GHC версии 6.2 значение равно __GLASGOW_HASKELL__==602). Дополнительные сведения приведены в разделе Политика нумерации версий GHC.

Можно надеяться, что во всех других реализациях с поддержкой препроцессора в стиле C макрос __GLASGOW_HASKELL__ не определён.

Примечание

Соответствующие символы для других систем: __HUGS__ для Hugs, __NHC__ для nhc98 и __HBC__ для hbc).

Примечание. Этот макрос задаётся при предварительной обработке исходного кода как Haskell, так и C, включая исходный код C, сгенерированный из модуля Haskell (то есть файлы .hs, .lhs, .c и .hc).

__GLASGOW_HASKELL_FULL_VERSION__

Этот макрос содержит полную строку версии. Например: __GLASGOW_HASKELL_FULL_VERSION__==8.11.0.20200319. Его значение берётся из переменной Autotools ProjectVersion.

Добавлен в GHC 9.0.1

__GLASGOW_HASKELL_PATCHLEVEL1__; __GLASGOW_HASKELL_PATCHLEVEL2__

Эти макросы доступны начиная с GHC 7.10.1.

Для трёхкомпонентных номеров версий GHC x.y.z значением __GLASGOW_HASKELL_PATCHLEVEL1__ является целое число ⟨z⟩.

Для четырёхкомпонентных номеров версий GHC x.y.z.z' значением __GLASGOW_HASKELL_PATCHLEVEL1__ является целое число ⟨z⟩, а значением __GLASGOW_HASKELL_PATCHLEVEL2__ — целое число ⟨z’⟩.

Эти макросы позволяют задавать более точную гранулярность, чем __GLASGOW_HASKELL__. Обычно в этом нет необходимости, поскольку предполагается, что большинство API остаются стабильными между выпусками с разными уровнями исправлений, но иногда для исправления ошибок требуются изменения внутренних API. Кроме того, условная компиляция по уровню исправлений может быть полезна для обхода ошибок в старых выпусках.

Совет

Эти макросы задаются при предварительной обработке исходного кода как Haskell, так и C, включая исходный код C, сгенерированный из модуля Haskell (то есть файлы .hs, .lhs, .c и .hc).

MIN_VERSION_GLASGOW_HASKELL(x,y,z,z')

Этот макрос доступен начиная с GHC 7.10.1.

Этот макрос предназначен для удобства при написании условий CPP, проверяющих, что используется версия GHC x.y.z.z' или более поздняя.

Если требуется совместимость с компиляторами Haskell (включая версии GHC до 7.10.1), которые не определяют MIN_VERSION_GLASGOW_HASKELL, перед его вызовом необходимо убедиться в наличии макроса MIN_VERSION_GLASGOW_HASKELL, например:

#if defined(MIN_VERSION_GLASGOW_HASKELL)
#if MIN_VERSION_GLASGOW_HASKELL(7,10,2,0)
/* code that applies only to GHC 7.10.2 or later */
#endif
#endif

Совет

Этот макрос задаётся при предварительной обработке исходного кода как Haskell, так и C, включая исходный код C, сгенерированный из модуля Haskell (то есть файлы .hs, .lhs, .c и .hc).

__GLASGOW_HASKELL_TH__

Значение этого макроса равно 1, если компилятор поддерживает Template Haskell, и 0, если не поддерживает. Последнее относится к компилятору первой стадии во время начальной загрузки или к архитектурам, для которых интерпретатор недоступен.

__GLASGOW_HASKELL_LLVM__

Определён только при указании -fllvm. Если GHC использует версию LLVM x.y.z, значением __GLASGOW_HASKELL_LLVM__ является целое число ⟨xyy⟩ (если ⟨y⟩ состоит из одной цифры, перед ней добавляется ноль; например, при использовании LLVM версии 3.7 значение равно __GLASGOW_HASKELL_LLVM__==307).

__GLASGOW_HASKELL_ASSERTS_IGNORED__

Определён только при указании -fignore-asserts. Его можно использовать для создания собственных проверок; см. раздел Проверки.

os_HOST_OS=1

Это определение позволяет выполнять условную компиляцию в зависимости от операционной системы, где ⟨os⟩ — название текущей операционной системы (например, linux, mingw32 для Windows, solaris и т. д.).

arch_HOST_ARCH=1

Это определение позволяет выполнять условную компиляцию в зависимости от архитектуры хоста, где ⟨arch⟩ — название текущей архитектуры (например, i386, x86_64, aarch64, powerpc, sparc и т. д.).

VERSION_pkgname

Этот макрос доступен начиная с GHC 8.0. Он определён для каждого экспортируемого пакета. Макрос раскрывается в строку, содержащую версию pkgname, доступную для импорта модулей. По поведению он идентичен макросам VERSION_pkgname, определяемым Cabal.

MIN_VERSION_pkgname(x,y,z)

Этот макрос доступен начиная с GHC 8.0. Он определён для каждого экспортируемого пакета. Макрос предназначен для удобства при написании условий CPP, проверяющих, что версия пакета не ниже x.y.z. По поведению он идентичен макросам MIN_VERSION_pkgname, определяемым Cabal.

Макросы SIMD

Они определяются условно в зависимости от флагов SIMD, используемых при компиляции:

__SSE__, __SSE2__, __SSE4_2__, __FMA__, __AVX__, __AVX2__, __AVX512CD__, __AVX512ER__, __AVX512F__, __AVX512PF__,

5.11.3.2. CPP и промежутки в строках

Небольшое предупреждение: -cpp плохо работает с «промежутками в строках». Иными словами, следующие строки:

strmod = "\
\ p \
\ "

не работают с -cpp; /usr/bin/cpp удаляет пары «обратная косая черта — перевод строки».

Однако, похоже, если добавить пробел в конец строки, то cpp (по крайней мере GNU cpp и, возможно, другие cpp) оставляет пары «обратная косая черта — пробел» без изменений, и промежуток в строке работает как ожидается.

5.11.4. Параметры, влияющие на препроцессор Haskell

-F

Пользовательский препроцессор обрабатывает исходный файл Haskell только при указании параметра -F.

В некоторых случаях запуск пользовательского препроцессора во время компиляции уместен и полезен. Параметр -F позволяет запускать препроцессор в составе общего конвейера компиляции GHC. Это даёт преимущество перед отдельным запуском препроцессора Haskell: такой подход работает в режиме интерпретации, и при этом можно продолжать пользоваться преимуществами проверки перекомпиляции GHC.

Препроцессор запускается непосредственно перед тем, как собственно компилятор Haskell обрабатывает входные данные Haskell, но после удаления разметки literate и (возможно) обработки входных данных Haskell препроцессором C.

Используйте -pgmF ⟨cmd⟩, чтобы выбрать программу для препроцессора. При запуске препроцессор ⟨cmd⟩ получает в командной строке как минимум три аргумента: первый — имя исходного файла, второй — имя файла с входными данными, третий — имя файла, в который ⟨cmd⟩ должен записать результат.

Дополнительные аргументы препроцессору можно передать с помощью параметра -optF ⟨option⟩. Они передаются ⟨cmd⟩ в командной строке после трёх стандартных аргументов ввода и вывода.

Пример использования препроцессора — преобразование исходных файлов в кодировку, ожидаемую GHC: для этого создайте скрипт convert.sh со следующим содержимым:

#!/bin/sh
( echo "{-# LINE 1 \"$1\" #-}" ; iconv -f l1 -t utf-8 $2 ) > $3

и передайте GHC параметр -F -pgmF convert.sh. Параметр -f l1 указывает iconv преобразовать файл в кодировке Latin-1, переданный в аргументе $2, а параметры «-t utf-8» указывают iconv вернуть файл в кодировке UTF-8. Результат перенаправляется в аргумент $3. Параметр echo "{-# LINE 1 \"$1\" #-}" лишь обеспечивает вывод позиций ошибок относительно исходного файла.

5.11.5. Параметры, влияющие на генерацию кода

-fasm

Используйте генератор машинного кода GHC вместо компиляции с помощью LLVM. -fasm используется по умолчанию.

-fllvm

Компилируйте с помощью LLVM вместо использования генератора машинного кода. Обычно компиляция занимает немного больше времени, чем с генератором машинного кода. Получаемый код, как правило, работает так же быстро или быстрее, чем при использовании двух других генераторов кода. Для компиляции с помощью LLVM исполняемые файлы opt и llc из LLVM должны находиться в PATH.

Примечание

Обратите внимание: этот выпуск GHC рассчитан на версии LLVM от 13 до 21.

-fno-code

Полностью пропустить генерацию кода (и все последующие этапы). Это полезно, если вас интересует только проверка типов кода.

Если модуль содержит вставку Template Haskell, то в режиме --make генерация кода будет автоматически включена для всех зависимостей. По умолчанию создаются объектные файлы, но если включён ghc-flag:-fprefer-byte-code, вместо них будет создан байт-код.

Генерация кода включается только для модулей, необходимых для вычислений во время компиляции. С помощью расширения ExplicitLevelImports программист может точнее указать, какие именно модули к ним относятся.

-fwrite-interface

Всегда записывать файлы интерфейсов. Обычно GHC записывает файлы интерфейсов автоматически, но этот флаг полезен вместе с -fno-code, который обычно отключает создание файлов интерфейсов. Это полезно, если вы хотите выполнять проверку типов в нескольких запусках GHC без компиляции зависимостей.

-fwrite-if-simplified-core

Файл интерфейса будет содержать все привязки модуля. На основе этого файла интерфейса можно возобновить генерацию кода для получения байт-кода.

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

-fwrite-if-self-recomp
По умолчанию:

включено

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

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

-fwrite-if-self-recomp-flags

Включать в файл интерфейса подробные сведения о флагах, использованных при компиляции. Это упрощает отладку проблем с перекомпиляцией, предоставляя больше контекста о среде компиляции. Этот флаг предназначен прежде всего для отладки проблем перекомпиляции с помощью -ddump-hi-diffs

-fobject-code

Создавать объектный код. Это значение используется по умолчанию вне GHCi; этот флаг также можно использовать в GHCi, чтобы предпочесть создание объектного кода байт-коду. Поэтому этот флаг отключает -fbyte-code-and-object-code.

-fbyte-code

Создавать байт-код вместо объектного кода. Это значение используется по умолчанию в GHCi. В настоящее время байт-код можно использовать только в интерактивном интерпретаторе, но нельзя сохранить на диск. Этот параметр полезен только для отмены действия -fobject-code.

-fbyte-code-and-object-code

Создавать объектный код и байт-код. Это полезно вместе с флагами -fprefer-byte-code и -fwrite-if-simplified-core.

Этот флаг подразумевает -fwrite-if-simplified-core.

Флаги -fbyte-code и -fobject-code отключают этот флаг, поскольку указывают, что GHC должен записывать только объектный код или байт-код соответственно.

-fPIC

Создавать позиционно-независимый код (код, который можно помещать в разделяемые библиотеки). В настоящее время это работает в Linux на x86 и x86-64. В Windows позиционно-независимый код не используется, поэтому на этой платформе флаг не действует.

-fexternal-dynamic-refs

При создании кода считать, что сущности, импортированные из другого модуля, могут быть связаны динамически. Этот флаг автоматически включается флагом -dynamic.

-fPIE

Создавать код, который можно компоновать в позиционно-независимый исполняемый файл. В настоящее время это работает в Linux на x86 и x86-64. В Windows позиционно-независимый код не используется, поэтому на этой платформе флаг не действует. Для компоновки итогового исполняемого файла используйте -pie.

-dynamic

Создавать код для динамической компоновки. Это может значительно уменьшить размер кода, но замедлить вызовы невстраиваемых функций между модулями. Сочетание -shared с этим флагом может вызвать некоторые сложности при компоновке RTS в Linux. См. #10352.

Обратите внимание: при компоновке с этим параметром GHC использует разделяемые библиотеки.

-dynamic-too

За один запуск GHC создаёт как динамические, так и статические объектные файлы. Этот параметр функционально эквивалентен двум запускам GHC, во втором из которых добавлен -dynamic -osuf dyn_o -hisuf dyn_hi.

Хотя это эквивалентно двум запускам GHC, использование -dynamic-too эффективнее, поскольку ранние этапы компилятора вплоть до генерации кода выполняются только один раз.

При использовании -dynamic-too параметры -dyno, -dynosuf и -dynhisuf являются аналогами -o, -osuf и -hisuf соответственно, но применяются к динамической компиляции.

Параметр -dynamic-too игнорируется, если также указан -dynamic.

-fexpose-internal-symbols

Запросить у GHC вывод подробных таблиц символов, включающих локальные символы для внутренних функций модуля. Они могут быть полезны таким инструментам, как perf, но увеличивают размер объектных файлов. Этот флаг подразумевается параметром -g2 и более высокими уровнями.

-fno-expose-internal-symbols подавляет все записи таблицы символов, не являющиеся глобальными, уменьшая размер объектных файлов за счёт ухудшения возможностей отладки.

-fprefer-byte-code

Если для модуля домашнего пакета доступен байт-код, использовать его вместо объектного файла (если он доступен) для вычисления и выполнения вставок TH.

Это полезно с такими флагами, как -fbyte-code-and-object-code, который указывает компилятору создавать байт-код, и -fwrite-if-simplified-core, который позволяет создавать байт-код на основе файла интерфейса.

Этот флаг также взаимодействует с -fno-code: если он включён, для всех модулей, которые необходимо скомпилировать для вычислений Template Haskell, будет создаваться байт-код вместо объектного кода.

5.11.6. Параметры, влияющие на компоновку

GHC должен скомпоновать ваш код с различными библиотеками, в том числе, возможно, предоставленными пользователем, GHC и системой (например, -lm).

-l ⟨lib⟩

Подключить библиотеку ⟨lib⟩. В системах Unix она будет находиться в файле с именем liblib.a или liblib.so, расположенном где-либо в пути к каталогам библиотек.

Из-за несовершенства большинства компоновщиков UNIX порядок таких параметров имеет значение. Если библиотека ⟨foo⟩ требует библиотеку ⟨bar⟩, то, как правило, -l ⟨foo⟩ должна указываться перед -l ⟨bar⟩ в командной строке.

При использовании внешних библиотек следует учитывать ещё один нюанс: если библиотека содержит функцию main(), это приведёт к конфликту при компоновке с собственной функцией main() GHC (например, у libf2c и libl есть собственные main()).

Вы можете использовать внешнюю главную функцию, если вручную инициализируете RTS и передадите -no-hs-main. См. также Использование собственной main().

-c

Пропустить этап компоновки. Этот параметр можно использовать с --make, чтобы избежать автоматической компоновки, выполняемой, если программа содержит модуль Main.

-package ⟨name⟩

Если вы используете Haskell-пакет (см. Пакеты), не забудьте также добавить соответствующий параметр -package при компоновке программы: он обеспечит подключение нужных библиотек к программе. Если забыть параметр -package, скорее всего, возникнет несколько страниц ошибок компоновки.

-framework ⟨name⟩

Только в Darwin/OS X/iOS: подключить фреймворк ⟨name⟩. Этот параметр соответствует параметру -framework компоновщика Apple. Обратите внимание, что фреймворки и пакеты — разные вещи: фреймворки не содержат код Haskell. Это способ Apple упаковывать разделяемые библиотеки. Например, чтобы подключить API Apple «Carbon», используйте -framework Carbon.

-staticlib
Подразумевает:

-flink-rts

Скомпоновать все переданные файлы в статическую библиотеку, пригодную для компоновки. Чтобы задать имя, используйте, как обычно, параметр -o ⟨file⟩. Имя по умолчанию — liba.a.

-L ⟨dir⟩

Где искать пользовательские библиотеки… Добавить каталог ⟨dir⟩ в начало пути к каталогам библиотек.

-fuse-rpaths

Этот параметр включён по умолчанию и задаёт rpath скомпонованного объекта, указывающий на каталоги библиотек зависимых пакетов.

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

-framework-path ⟨dir⟩

Только в Darwin/OS X/iOS: добавить каталог ⟨dir⟩ в начало пути к каталогам фреймворков. Этот параметр соответствует параметру -F компоновщика Apple (-F уже имеет в GHC другое значение).

-fsplit-sections
-split-sections

Помещать каждую сгенерированную функцию или элемент данных в отдельную секцию выходного файла, если целевая платформа поддерживает произвольные секции. Имя функции или элемента данных определяет имя секции в выходном файле.

При компоновке компоновщик может автоматически удалить все неиспользуемые секции и тем самым уменьшить размер исполняемого файла.

-static

Указать компоновщику по возможности не использовать разделяемые библиотеки Haskell. Это поведение по умолчанию.

-dynamic

Этот параметр указывает GHC компоновывать программу с разделяемыми библиотеками Haskell. Он влияет только на выбор зависимых библиотек, но не на формат текущего целевого файла (см. -shared). О создании таких библиотек см. раздел Использование разделяемых библиотек.

Обратите внимание, что этот параметр также влияет на генерацию кода (см. выше).

-shared

При указании этого параметра компоновщика GHC создаёт разделяемый объект вместо исполняемого файла. В зависимости от целевой операционной системы это может быть ELF DSO, DLL Windows или dylib Mac OS. GHC скрывает особенности операционной системы за этим единым параметром.

Параметры -dynamic и -static управляют тем, связывается ли результирующий разделяемый объект статически или динамически с библиотеками пакетов Haskell, указанными параметром -package ⟨pkg⟩. Библиотеки, не относящиеся к Haskell, компонуются так, как это обычно делает gcc в вашей системе; например, в большинстве систем ELF компоновщик использует динамические библиотеки, если они найдены.

Объектные файлы, включаемые в разделяемые объекты, должны быть скомпилированы с параметром -fPIC; см. раздел Параметры, влияющие на генерацию кода.

При создании разделяемых объектов для пакетов Haskell им нужно задать правильные имена, чтобы GHC распознавал их при компоновке с этим пакетом. Подробности см. в разделе изменение имён разделяемых объектов.

-dynload

Этот параметр выбирает один из режимов поиска разделяемых библиотек во время выполнения. Описание каждого режима см. в разделе Поиск разделяемых библиотек во время выполнения.

-flink-rts

При компоновке разделяемых библиотек (-shared) GHC автоматически не подключает RTS. Это позволяет выбрать вариант RTS (-threaded, -eventlog и т. д.) при компоновке исполняемого файла. Однако, если разделяемая библиотека является конечным продуктом, полезно иметь возможность изменить это поведение по умолчанию. Пример использования см. в разделе Разделяемые библиотеки, экспортирующие API C.

При компоновке статической библиотеки (-staticlib) GHC автоматически подключает RTS; изменить это поведение можно, инвертировав действие данного параметра: -fno-link-rts.

-main-is ⟨thing⟩

Обычно в Haskell программа должна предоставлять функцию main в модуле Main. При тестировании часто удобно изменить функцию, которая считается главной, и параметр -main-is позволяет это сделать. Значение ⟨thing⟩ может быть одним из следующих:

  • Идентификатор в нижнем регистре foo. GHC считает главной функцией Main.foo.
  • Имя модуля A. GHC считает главной функцией A.main.
  • Квалифицированное имя A.foo. GHC считает главной функцией A.foo.

Строго говоря, -main-is вообще не является параметром этапа компоновки; он не влияет на компоновку. Этот параметр необходимо указывать при компиляции модуля, содержащего указанную главную функцию (например, модуля A в двух последних пунктах выше). На другие модули он не влияет, поэтому его можно безопасно передавать ghc --make. Однако если все модули уже актуальны, может понадобиться принудительно перекомпилировать как модуль с новой главной функцией, так и модуль, в котором раньше находилась функция «main»; ghc недостаточно интеллектуален, чтобы определить, что перекомпилировать нужно оба модуля. Принудительно запустить перекомпиляцию можно, удалив объектный файл или указав параметр -fforce-recomp.

-no-hs-main

Если вы хотите включить скомпилированный GHC код в другую (не на Haskell) программу, RTS не будет предоставлять своё определение main() на этапе компоновки — вам придётся сделать это самостоятельно. Чтобы сообщить об этом компилятору при компоновке, используйте -no-hs-main. См. также Использование собственной main().

Поскольку командная строка, передаваемая компоновщику, довольно сложна, для финальной компоновки приложения на нескольких языках, вероятно, стоит использовать ghc. Это необязательно, однако попробуйте выполнить компоновку с параметром -v, чтобы увидеть, какие параметры драйвер передаёт компоновщику.

Параметр -no-hs-main также можно использовать, чтобы заставить компилятор выполнить этап компоновки в режиме --make, если модуль Haskell Main отсутствует (обычно компилятор не пытается выполнять компоновку, если отсутствует Main).

Параметры -rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] и -with-rtsopts=⟨opts⟩ не действуют вместе с -no-hs-main, поскольку реализованы путём изменения определения main, генерируемого GHC. О том, как добиться эффекта параметров -rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] и -with-rtsopts=⟨opts⟩ при использовании собственной функции main, см. раздел Использование собственной main().

-debug

Скомпоновать программу с отладочной версией системы времени выполнения. Отладочная система включает множество утверждений и проверок корректности, а также предоставляет дополнительные параметры для вывода отладочной информации во время выполнения (запустите программу с +RTS -?, чтобы увидеть список).

-threaded

Скомпоновать программу с «многопоточной» версией системы времени выполнения. Она называется многопоточной, поскольку управляет несколькими потоками ОС, в отличие от системы времени выполнения по умолчанию, которая является однопоточной.

Обратите внимание: для использования параллелизма параметр -threaded не нужен; однопоточная система времени выполнения вполне поддерживает параллелизм между потоками Haskell.

Многопоточная система времени выполнения предоставляет следующие возможности:

  • Она позволяет использовать параметр RTS -N ⟨x⟩, благодаря которому потоки могут выполняться параллельно на многопроцессорном или многоядерном компьютере. См. раздел Использование параллелизма SMP.
  • Если поток выполняет внешний вызов (и этот вызов не помечен как unsafe), другие потоки Haskell в программе продолжают выполняться, пока внешний вызов не завершится. Кроме того, функции Haskell с пометкой foreign export могут одновременно вызываться из нескольких потоков ОС. См. раздел Многопоточность и FFI.
-single-threaded
Появился в версии:

9.8

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

-eventlog
Появился в версии:

Безусловно включён в версиях 9.4 и новее

Скомпоновать программу с версией системы времени выполнения, поддерживающей «журнал событий». Скомпонованная таким образом программа может записывать трассировку событий во время выполнения (например, запуск и остановку потоков) в двоичный файл program.eventlog, который затем можно обработать различными инструментами. Дополнительную информацию см. в разделе Трассировка.

Обратите внимание, что начиная с GHC 9.4 поддержка журнала событий включена в RTS по умолчанию, а параметр -eventlog устарел.

-rtsopts[=⟨none|some|all|ignore|ignoreAll⟩]
По умолчанию:

some, если параметр -rtsopts не передан; all, если параметр -rtsopts передан без аргумента.

Этот параметр влияет на обработку управляющих параметров RTS, переданных либо в командной строке, либо через переменную окружения GHCRTS. Возможны шесть вариантов:

-rtsopts=none

Отключить обработку всех параметров RTS. Если +RTS встречается где-либо в командной строке, программа завершится с сообщением об ошибке. Если задана переменная окружения GHCRTS, программа выдаст предупреждение, проигнорирует GHCRTS и продолжит работу в обычном режиме.

-rtsopts=ignore

Отключить обработку всех параметров RTS. В отличие от none, все флаги RTS в командной строке рассматриваются как обычные аргументы (и передаются программе в виде аргументов). Параметры GHCRTS обрабатываются обычным образом.

-rtsopts=ignoreAll

То же, что и ignore, за исключением параметров GHCRTS, которые также игнорируются.

-rtsopts=some

[значение по умолчанию, если параметр -rtsopts не передан] Разрешить только «безопасные» параметры RTS (в настоящее время только -? и --info). Любой другой параметр RTS в командной строке или переменной окружения GHCRTS приведёт к завершению программы с сообщением об ошибке.

-rtsopts=all

Разрешить обработку всех параметров RTS как в командной строке, так и через переменную окружения GHCRTS.

-rtsopts

Эквивалентно -rtsopts=all.

В GHC 6.12.3 и более ранних версиях по умолчанию обрабатывались все параметры RTS. Однако параметры RTS можно использовать для записи данных журналирования в произвольные файлы с правами доступа запущенной программы, что создаёт потенциальную угрозу безопасности. Поэтому в GHC 7.0.1 и новее по умолчанию используется -rtsopts=some.

Обратите внимание, что параметр -rtsopts не действует вместе с -no-hs-main; подробности см. в разделе Использование собственной main().

Параметр -rtsopts не влияет на параметры RTS, переданные через -with-rtsopts; они используются независимо от -rtsopts.

-with-rtsopts=⟨opts⟩

Этот параметр позволяет задать параметры RTS по умолчанию на этапе компоновки. Например, -with-rtsopts="-H128m" задаёт размер кучи по умолчанию, равный 128 МБ. Для этой программы это значение всегда будет размером кучи по умолчанию, если пользователь не переопределит его. (В зависимости от значения параметра -rtsopts пользователь может не иметь возможности изменять параметры RTS во время выполнения; в таком случае -with-rtsopts будет единственным способом их задать.)

Чтобы увидеть параметры, заданные с помощью -with-rtsopts, запустите исполняемую программу с флагом времени выполнения --info.

Обратите внимание, что параметр -with-rtsopts не действует вместе с -no-hs-main; подробности см. в разделе Использование собственной main().

-no-rtsopts-suggestions

Этот параметр отключает рекомендации RTS о компоновке с -rtsopts[=⟨none|some|all|ignore|ignoreAll⟩], если эти возможности недоступны. Такие рекомендации бесполезны, если пользователи установили программы Haskell через менеджеры пакетов. При включённом параметре эти рекомендации отображаться не будут. Распространяющим бинарные файлы рекомендуется собирать их с параметром -rtsopts или -no-rtsopts-suggestions.

-fno-gen-manifest

В Windows при компоновке бинарного файла GHC обычно создаёт файл манифеста. Манифест помещается в файл prog.exe.manifest`, где ⟨prog.exe⟩ — имя исполняемого файла. Сейчас у файла манифеста только одна функция: он отключает «обнаружение установщика» в Windows Vista, которое пытается повысить привилегии для исполняемых файлов с определёнными именами (например, содержащими «install», «setup» или «patch»). Без манифеста, отключающего обнаружение установщика, попытка запустить исполняемый файл, который Windows считает установщиком, возвращает вызывающей стороне код ошибки доступа. В зависимости от вызывающей стороны результатом может быть диалоговое окно с запросом на повышение привилегий или просто ошибка отказа в доступе.

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

Параметр -fno-gen-manifest отключает создание файла манифеста. Например, это может понадобиться, если у вас есть собственный файл манифеста.

В будущем GHC может использовать файл манифеста и для других целей, например для указания расположения зависимых DLL.

-fno-gen-manifest также подразумевает -fno-embed-manifest; см. ниже.

-fno-embed-manifest

По умолчанию файл манифеста, который GHC создаёт при компоновке бинарного файла в Windows, также встраивается в сам исполняемый файл. Благодаря этому бинарный файл можно распространять без отдельного файла манифеста. Встраивание выполняется запуском windres; чтобы точно узнать, как GHC встраивает манифест, используйте параметр -v. По этой причине в комплект установки GHC входит собственная копия windres.

См. также -pgmwindres ⟨cmd⟩ (Замена программы на одном или нескольких этапах) и -optwindres ⟨option⟩ (Передача параметров определённому этапу).

-fno-shared-implib

В Windows DLL обычно подключают, компонуя с соответствующим файлом .lib или .dll.a — так называемой библиотекой импорта. Обычно GHC создаёт такой файл для каждой DLL, созданной при компиляции в режиме -shared. Однако иногда не хочется тратить место на диске для этой библиотеки импорта, размер которой может быть значительным: ей может потребоваться столько же места, сколько и самому коду, поскольку DLL Haskell обычно экспортируют много символов.

Если вас устраивает возможность компоновки с DLL только с помощью GetProcAddress и подобных инструментов, можно указать параметр -fno-shared-implib, чтобы полностью отключить создание библиотеки импорта.

-dylib-install-name ⟨path⟩

В Darwin/OS X динамическим библиотекам во время сборки присваивается «имя установки» — окончательный путь установки файла библиотеки. Все библиотеки и исполняемые файлы, которые впоследствии компонуются с ней, используют этот путь для поиска библиотеки во время выполнения. По умолчанию ghc задаёт в качестве имени установки расположение, в котором собирается библиотека. Этот параметр позволяет переопределить имя указанным путём к файлу. (Он передаёт компоновщику Apple параметр -install_name.) На других платформах игнорируется.

-rdynamic

Указывает компоновщику добавить в таблицу динамических символов все символы, а не только используемые. Поддерживается только в Linux и Windows/MinGW32. Эквивалентен использованию -optl -rdynamic в Linux и -optl -export-all-symbols в Windows.

-fwhole-archive-hs-libs

При компоновке исполняемого бинарного файла этот параметр добавляет флаг -Wl,--whole-archive перед всеми флагами -l для библиотек Haskell и -Wl,--no-whole-archive после них (в OS X используется флаг -Wl,-all_load; эквивалента для -Wl,--no-whole-archive нет). Этот параметр также отключает использование -Wl,--gc-sections (в OS X — -Wl,-dead_strip).

Параметр предназначен для специализированных приложений, которым во время выполнения могут понадобиться символы из этих библиотек Haskell, даже если на них не ссылается никакой другой код, скомпонованный с исполняемым файлом. Если вы используете -fwhole-archive-hs-libs, вам, вероятно, также понадобится -rdynamic.

-pie
Появился в версии:

8.2.2

Этот параметр указывает компоновщику создать позиционно-независимый исполняемый файл. Он допустим только при создании исполняемых файлов, и весь компонуемый объектный код должен быть создан с параметром -fPIE.

Некоторым платформам необходимы позиционно-независимые исполняемые файлы, поскольку они позволяют использовать рандомизацию размещения адресного пространства (ASLR) — распространённую меру безопасности. Такие файлы также могут быть полезны, поскольку их можно динамически загружать и использовать как разделяемые библиотеки в других исполняемых файлах.

Позиционно-независимые исполняемые файлы следует компоновать динамически (например, собирать с параметром -dynamic) и загружать только в другие динамически скомпонованные исполняемые файлы. Это гарантирует, что при загрузке в адресное пространство другого процесса Haskell будет присутствовать только один libHSrts.

Кроме того, может понадобиться параметр -rdynamic, чтобы предотвратить удаление символов из объектов PIE.

-no-pie

При необходимости компилятор C всё равно создаст PIE. В противном случае это поведение по умолчанию. Дополнительную информацию о PIE см. в описании параметра -pie.

-fkeep-cafs
Появился в версии:

8.8.1

Отключает обычное поведение RTS, при котором сборщик мусора удаляет CAF (Constant Applicative Forms, то есть выражения верхнего уровня). Этот параметр полезен для специализированных приложений, выполняющих динамическую компоновку во время выполнения, когда позднее динамически подключённому коду может понадобиться значение CAF, которое иначе было бы удалено сборщиком мусора.

-fcompact-unwind
По умолчанию:

включено

Появился в версии:

9.4.1

Этот параметр указывает компоновщику создать исполняемый файл с поддержкой компактных секций раскрутки стека Apple. Код на C++ и Objective-C использует их для раскрутки стека при возникновении исключения.

Теоретически для этой цели должна подходить и более старая секция __eh_frame, однако это работает не всегда.

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/9.14.1/docs/users_guide/phases.html

Spec-Zone.ru

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