5.1.1. Начало работы: компиляция программ
В этой главе вы найдете полную справку по синтаксису командной строки GHC, включая более 400 флагов. Это большая и сложная система, и есть много деталей, поэтому разобраться, как начать, может быть довольно сложно. С учетом этого, данный вводный раздел предоставляет краткое введение в базовое использование GHC для компиляции программы на Haskell, прежде чем последующие разделы углубятся в полный синтаксис.
Давайте создадим программу «Hello, World», скомпилируем и запустим ее. Сначала создайте файл hello.hs содержащий код Haskell:
main = putStrLn "Hello, World!"
Для компиляции программы используйте GHC следующим образом:
$ ghc hello.hs
(где $ представляет собой приглашение: не вводите его). GHC скомпилирует исходный файл hello.hs, создаст объектный файл hello.o и файл интерфейса hello.hi, а затем свяжет объектный файл с библиотеками, поставляемыми с GHC, для создания исполняемого файла, называемого hello на Unix/Linux/Mac или hello.exe на Windows.
По умолчанию GHC будет молчаливым в отношении того, что он делает, печатая только сообщения об ошибках. Если вы хотите увидеть более подробную информацию о происходящем, добавьте -v в командную строку.
Затем мы можем запустить программу следующим образом:
$ ./hello Hello World!
Если ваша программа содержит несколько модулей, то вам нужно только указать GHC имя исходного файла, содержащего Main модуль, и GHC проанализирует import объявления, чтобы найти другие модули, составляющие программу, и найти их исходные файлы. Это означает, что за исключением Main модуля, каждый исходный файл должен быть назван по имени модуля, который он содержит (с точками, замененными разделителями каталогов). Например, модуль Data.Person будет находиться в файле Data/Person.hs на Unix/Linux/Mac или Data\Person.hs на Windows.
5.1.2. Обзор опций
Поведение GHC контролируется опциями, которые по историческим причинам также иногда называются флагами или аргументами командной строки. Опции могут быть указаны тремя способами:
5.1.2.1. Аргументы командной строки
Вызов GHC имеет следующий вид:
ghc [argument...]
Аргументы командной строки — это либо опции, либо имена файлов.
Опции командной строки начинаются с -. Их нельзя группировать: -vO отличается от -v -O. Опции не обязательно должны предшествовать именам файлов: например, ghc *.o -o foo. Все опции обрабатываются, а затем применяются ко всем файлам; например, вы не можете вызвать ghc -c -O1 Foo.hs -O2 Bar.hs для применения различных уровней оптимизации к файлам Foo.hs и Bar.hs.
В дополнение к передаче аргументов через командную строку, аргументы могут быть переданы через файлы ответов в стиле GNU. Например,
$ cat response-file -O1 Hello.hs -o Hello $ ghc @response-file
Примечание
Обратите внимание, что опции командной строки зависят от порядка, при этом аргументы оцениваются слева направо. Это может иметь кажущиеся странными последствия при наличии подразумевания флагов. Например, рассмотрите -fno-specialise и -O1 (который подразумевает -fspecialise). Эти две командные строки означают совершенно разные вещи:
-fno-specialise -O1
-fspecialise будет включено, так как -fno-specialise переопределяет -O1.
-O1 -fno-specialise
-fspecialise не будет включено, так как -fno-specialise переопределяет -fspecialise подразумеваемый -O1.
5.1.2.2. Опции командной строки в исходных файлах
Иногда полезно установить достаточно тесную связь между исходным файлом и опциями командной строки, которые он требует. Например, если файл исходного кода Haskell намеренно использует затенение имен, его следует скомпилировать с опцией -Wno-name-shadowing. Вместо того чтобы хранить список опций по файлам в Makefile, это можно сделать непосредственно в исходном файле, используя OPTIONS_GHC псевдодирективу
{-# OPTIONS_GHC -Wno-name-shadowing #-}
module X where
...
OPTIONS_GHC — это псевдодиректива заголовка файла (см. псевдодирективу OPTIONS_GHC).
В псевдодирективе OPTIONS_GHC могут использоваться только динамические флаги (см. Динамические и опции режима).
Обратите внимание, что ваша оболочка командной строки не получает доступ к опциям исходного файла; они просто буквально включены в массив аргументов командной строки, которые компилятор поддерживает во внутреннем формате, поэтому вы будете очень разочарованы, если попытаетесь использовать glob и т. п. внутри OPTIONS_GHC.
Примечание
Содержимое OPTIONS_GHC добавляется к опциям командной строки, поэтому опции, заданные в исходном файле, переопределяют опции, заданные в командной строке.
Не рекомендуется перемещать все содержимое ваших Makefiles в исходные файлы, но в некоторых обстоятельствах псевдодиректива OPTIONS_GHC является правильным решением. (Если вы используете -keep-hc-file и у вас есть OPTION флаги в вашем модуле, OPTIONS_GHC будут включены в сгенерированный .hc файл).
5.1.2.3. Установка опций в GHCi
Опции также можно изменить внутри GHCi, используя команду :set.
5.1.3. Динамические и опции режима
Каждая опция командной строки GHC классифицируется как динамическая или режимная:
Режим: режим может использоваться только в командной строке. Вы можете передать только один флаг режима. Например, --make или -E. Доступные режимы перечислены в Режимы работы.
Динамический: динамический флаг может использоваться в командной строке, в псевдодирективе OPTIONS_GHC в исходном файле или устанавливаться с помощью :set в GHCi.
В таблицах справок по флагам (Справочник по флагам) указан статус каждого флага.
5.1.4. Значимые расширения файлов
Имена файлов со «значимыми» расширениями (например, .lhs или .o) вызывают выполнение «правильного действия» с этими файлами.
-
.hs -
Модуль Haskell.
-
.lhs -
Модуль «literate Haskell».
-
.hspp -
Файл, созданный препроцессором.
-
.hi -
Файл интерфейса Haskell, вероятно, сгенерированный компилятором.
-
.hie -
Расширенный файл интерфейса Haskell, созданный компилятором Haskell.
-
.hc -
Промежуточный файл C, созданный компилятором Haskell.
-
.c -
Файл C, не созданный компилятором Haskell.
-
.ll -
Исходный файл llvm-intermediate-language, обычно создаваемый компилятором.
-
.bc -
Файл bitcode llvm-intermediate-language, обычно создаваемый компилятором.
-
.s -
Исходный файл ассемблерного языка, обычно создаваемый компилятором.
-
.o -
Объектный файл, созданный ассемблером.
Файлы с другими расширениями (или без расширений) передаются непосредственно компоновщику.