Spec-Zone.ru › Haskell 9

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

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

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

-pgmL ⟨cmd⟩

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

-pgmP ⟨cmd⟩

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

-pgmJSP ⟨cmd⟩

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

-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⟩ препроцессору для литературного языка.

-optP ⟨option⟩

Передать ⟨option⟩ в CPP (имеет смысл только если также установлен -cpp).

-optJSP ⟨option⟩

Передать ⟨option⟩ в препроцессор JavaScript C (только для javascript-backend).

-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 запоминает, поддерживает ли стандартный компилятор C -no-pie во внутреннем файле настроек.

-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
Since:

6.8.1

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

$ ghc -XCPP foo.hs

Расширение языка CPP также можно включить с помощью директивы LANGUAGE; Например:

{-# LANGUAGE CPP #-}
-cpp

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

-D⟨symbol⟩[=⟨value⟩]

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

Примечание

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

-U⟨symbol⟩

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

-I⟨dir⟩

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

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

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

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

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

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

__GLASGOW_HASKELL__

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

Надеемся, что __GLASGOW_HASKELL__ будет неопределён в других реализациях, поддерживающих препроцессирование в стиле C.

Примечание

Сопоставимые символы для других систем: __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. Его значение взято из переменной ProjectVersion Autotools.

Добавлен в 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, если нет. Последнее — в случае компилятора стадии 1 во время загрузки или на архитектурах, где интерпретатор недоступен.

__GLASGOW_HASKELL_LLVM__

Определяется только при указании `-fllvm`. Если GHC использует версию x.y.z LLVM, значение __GLASGOW_HASKELL_LLVM__ — целое число ⟨xyy⟩ (если ⟨y⟩ — однозначное число, добавляется ведущий ноль, например, при использовании версии 3.7 LLVM, __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 и, возможно, другие cpps) оставляет пары обратный слэш-пробел, и пробел в строке работает как ожидается.

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

и передачу -F -pgmF convert.sh в GHC. Параметр -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 до 20.

-fno-code

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

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

-fwrite-interface

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

-fwrite-if-simplified-core

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

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

-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 независимый от позиции код никогда не используется, поэтому флаг является no-op на этой платформе.

-fexternal-dynamic-refs

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

-fPIE

Генерировать код таким образом, чтобы его можно было связать в исполняемый файл, независимый от позиции. В настоящее время это работает на Linux x86 и x86-64. В Windows независимый от позиции код никогда не используется, поэтому флаг является no-op на этой платформе. Для компоновки конечного исполняемого файла используйте -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(), то это вызовет конфликт с собственной функцией GHC main() (например, 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’s Linker. Обратите внимание, что фреймворки и пакеты — это разные вещи; фреймворки не содержат никакого 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’s Linker (-F уже означает что-то другое для GHC).

-fsplit-sections
-split-sections

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

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

-static

Указывает линковщику избегать использования общих Haskell-библиотек, если это возможно. Это значение по умолчанию.

-dynamic

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

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

-shared

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

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

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

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

-dynload

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

-flink-rts

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

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

-main-is ⟨thing⟩

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

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

Строго говоря, -main-is — это не флаг на этапе компоновки; он не влияет на этап компоновки. Флаг должен быть указан при компиляции модуля, содержащего указанную главную функцию (например, модуль A в двух последних пунктах выше). Он не оказывает влияния на другие модули и поэтому может безопасно использоваться в ghc --make. Однако, если все модули в противном случае актуальны, вам может потребоваться принудительно перекомпилировать модуль, в котором новая функция «main», и модуль, в котором функция «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. См. Использование собственной функции main(), чтобы понять, как получить эффект -rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] и -with-rtsopts=⟨opts⟩ при использовании собственной main.

-debug

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

-threaded

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

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

Потоковая система времени выполнения обеспечивает следующие преимущества:

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

9.8

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

-eventlog
Since:

Безусловно включена начиная с 9.4

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

Обратите внимание, что начиная с GHC 9.4 и более поздних версий поддержка eventlog включена в 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 будет единственным способом их установки.)

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

Обратите внимание, что -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

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

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

-dylib-install-name ⟨path⟩

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

-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 (-Wl,-dead_strip в OS X).

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

-pie
Since:

8.2.2

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

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

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

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

-no-pie

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

-fkeep-cafs
Since:

8.8.1

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

-fcompact-unwind
Default:

on

Since:

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.12.1/docs/users_guide/phases.html

Spec-Zone.ru

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