ГЛАВА 2. ПРОДОЛЖЕНИЕ ЗНАКОМСТВА С LF95
В начало страницы
В этой главе описывается, как использовать драйвер компилятора LF95 для
построения прикладных программ. Драйвер управляет компиляцией, компоновкой
рабочей программы, и созданием архивных библиотек и совместно используемых
библиотек.
В начало страницы
Драйвер (lf95) управляет двумя главными процессами -- компиляцией и
компоновкой, имеющими целью создание рабочей программы. Эти составляющие
процессы реализуются под управлением драйвера следующими программами:
Компилятор. Компилятор перерабатывает входные файлы в объектные и создает
файлы, необходимые для использования модулей Fortran 95. Именно эта компонента
фактически компилирует программу, хотя часто на драйвер lf95 и ссылаются как
на "компилятор."
Архивная утилита системы Linux, ar. Она может вызываться драйвером или из
командной строки для создания или изменения статических библиотек.
Компоновщик Linux'а, ld. Этот компоновщик комбинирует объектные файлы и
библиотеки в единую исполнимую программу или библиотеку совместного
пользования.
В начало страницы
Чтобы запустить драйвер, нужно напечатать в командной строке lf95 и вслед за
ним список из одного или более имен файлов или необязательных параметров
командной строки:
lf95 filenames [options]
Отметим, что по желанию параметры могут предшествовать именам файлов.
Драйвер ищет различные программные инструменты (компилятор, архивную
библиотечную утилиту и компоновщик) сначала в каталоге, в котором он
расположен, и если не найдет, то ищет на вашем пути. Параметры командной
строки расматриваются позже в этой же главе.
В начало страницы
В зависимости от указанных расширений файловых имен драйвер будет вызывать
нужные инструменты. Расширения .f95, .f90, .for, .f, .F95, .F90, .FOR и .F,
например, приводят к вызову компилятора. Расширение .s вызывает ассемблер.
Расширение .o (означающее объектный файл) вызывает компоновщик. Пожалуйста
запомните, что если суффикс для входного текста Fortran записан в верхнем
регистре (.F95, .F90, .FOR, или .F), это означает вызов препросессора Си
перед компилятором; поэтому предпочтительнее использовать для расширения имени
файла нижний регистр, если файл не нуждается в препроцессоре.
В случае суффикса в нижнем регистре препроцессор Cи можно вызвать с помощью
параметра -Cpp. Параметры препроцессора -D (define macro), -U
(un-define macro) и -P (отсылать выход препроцессора в file) также поддержаны
и действуют, как записано в man pages для gcc, GNU Cи-компилятора.
В настоящем руководстве использование препроцессора не поощряется, так как
такие действия не соответствуют стандартной практике программирования на
Fortran.
Запомните: имена файлов чувствительны к регистру. Имена файлов с пробелами
употреблять не рекомендуется, также как имена, начинающиеся с дефиса, т. е. с
"-". Заметьте также, что расширение .mod зарезервировано для порождаемых
компилятором модульных файлов. Не используйте это расширение для своих
исходных Fortran-файлов.
В начало страницы
Одно или более имен исходных файлов могут быть выделены или специальными
именами или обычными специальными символами Linux. Имена файлов должны
разделяться пробелами. Имена файлов, не соответствющие описанным ниже формам,
передаются непосредственно компоновщику.
В начало страницы
lf95 *.f90
Если файлы one.f90, two.f90 и three.for были в текущем каталоге, то
one.f90 и two.f90 будут компилированы и скомпонованы вместе и исполнимый файл
с именем a.out будет создан в текущем каталоге. Файл three.for не будет
компилироваться, потому что его расширение не соответствует расширениям,
специфичным для командной строки LF95.
Каждое исходное имя файла должно специфицироваться полностью, включая
расширение. Если отсутствует параметр, утверждающий противное (т.е. если
не указаны ни --fix ни --nfix), то
.f90, .F90, .f95 и .F95 означают интерпретацию в качестве свободной исходной
формы Fortran 95.
.for, .FOR, .f и .F означают интерпретацию в качестве фиксированной исходной
формы Fortran 95.
Еще раз напоминаем, что расширение на верхнем регистре приведет к вызову
препроцессора Си перед вызовом компилятора с Fortran; поэтому предпочтительнее
использовать в именах файлов расширения на нижнем регистре, если файл не
нуждается в обработке препроцессором. Описания свободной исходной формы и
фиксированной исходной формы см. в Справочном руководстве по языку.
В начало страницы
По умолчанию имена объектных файлов такие же как у исходных файлов, но с
расширением .o. Когда создается объектный файл, он по умолчанию помещается в
текущий рабочий каталог. Такое действие можно подавить, указав
параметр -o (или --out) с новыми именем и путем. (см. "-o name" на стр. 23).
В начало страницы
Файлы, содержащие информацию о модулях Fortran 95, будут иметь те же имена,
что и модули, определенные в исходном коде, в буквах нижнего регистра и с
расширением .mod. Когда создается файл модуля, он по умолчанию помещается
в текущий рабочий каталог. Это действие можно подавить, указав параметр
--mod или -M (см. "-M dir" на стр. 22). Расширение .mod зарезервировано
дляя генерируемых компилятором модульных файлов. Не употребляйте это
расширение для ваших исходных Fortran-файлов. Если какая-то программа
содержит код, который (в смысле оператора USE) использует некоторый модуль,
то ее объектный файл (соответствующий исходному файлу, где этот модуль был
определен), должен быть указан в командной строке. Путь поиска для
файлов .mod можно специфицировать с параметрами --mod или -M.
В начало страницы
По умолчанию имя исполнимого файла, приготовленного драйвером, есть a.out.
Если путь не указан, будет использован текущий каталог. Это можно подавить,
указав параметры --out или -o с новыми именем и путем. Если в командной
строке указан -c, то аргументом для --out или -o должно быть имя объектного
файла. (см. "-o name" на стр. 23).
В начало страницы
По умолчанию имя для библиотеки обычно имеет расширение .a для статической
библиотеки и .so для совместно используемой (динамической) библиотеки.
(См. "Архивные библиотеки " и "Совместные библиотеки " на стр. 12). Кроме
того, библиотеки обычно начинаются с букв "lib." Префикс и расширение
нужно опускать при ссылке на библиотеку во время компоновки. Например,
libsub.so есть совместно используемая библиотека в текущем каталоге,
на которую в командной строке ссылаются как
lf95 main.f90 -L. -lsub
В начало страницы
Драйвер распознает одну или более букв, предшествуемых одним или двумя
дефисами (- или --) как параметр в командной строке. Нельзя комбинировать
параметры после дефиса. Например, -x и -y нельзя указывать в виде -xy.
Некоторые параметры имеют аргументы в форме файловых имен, цепочек, букв или
цифр. Запомните пожалуйста: параметры с двойным дефисом (--) требуют
разделяющего пробела между параметром и его аргументом (аргументами);
за параметром с одним дефисом (-) аргумент (аргументы) могут следовать
непосредственно, без отделяющего пробела. Если параметр имеет несколько
аргументов, пробелы между аргументами недопустимы.
Пример
-M../MyDir/IncDir (разделительный пробел не требуется)
--mod ../MyDir/IncDir:./ModDir (разделительный пробел необходим после
--mod, но запрещен после :)
Если обнаружен неизвестный параметр, весь текст с начала неизвестного
до начала следующего параметра или конца командной строки передается
компоновщику. Хотя параметры с двойным дефисом и нечувствительны к регистру,
рекомендуется для избежания недоразумений рассматривать все параметры как
чувствительные к регистру. Некоторые аргументы для параметров драйвера
(т.е. имена файлов и каталогов) также чувствительны к регистру. Для
иллюстрации, если бы аргумент для параметра -M в предыдущем примере заменить
на ../MYDIR/INCDIR, то драйвер был бы не в состоянии найти фактический
каталог.
Параметр для другой инструментальной компоненты (компоновщика, ассемблера
или препроцессора), который всупает в конфликт с каким-то параметром LF95,
может быть без всяких изменений передан непосредственно этой компоненте
с помощью параметров -Wl, -Wa и -Wp. Эти параметры ведут себя, как написано
в man pages для gcc, т. е. для компилятора GNU Cи.
В начало страницы
Параметры командной строки обрабатываются слева направо. Если указаны
конфликтующие параметры, преимущество получает последний по порядку. Например,
если командная строка содержит lf95 foo --lst --nlst, то будет использован
параметр --nlst.
Чтобы выдать номер версии LF95 и обзор действующих параметров командной
строки, напечатайте
lf95 --version --help.
В начало страницы
В добавок к спецификации параметров командной строки вы можете указать
в файле lf95.fig множество используемых по умолчанию параметров. Когда
вызывается драйвер, параметры, указанные в файле lf95.fig, обрабатываются до
указанных в командной строке. Параметры командной строки подавляют параметры
из файла lf95.fig. Драйвер ищет lf95.fig сначала в текущем каталоге
и если не найдет, обращается к каталогу, в котором помещен он сам.
В начало страницы
Если вы имеете слишком много параметров и файлов, чтобы выписывать их в
командной строке, их можно разместить в командном файле.
Впишите аргументы командной строки lf95 в командный файл точно в том же виде,
как и в командной строке. Командные файлы могут содержать столько строк,
сколько нужно. Строки, начинающиеся с #, служат комментариями.
Для обработки командного файла напишите в начале его имени символ @.
Тогда lf95 обнаружит в командной строке имя файла с @ в начале, он откроет
файл и выполнит содержащиеся в нем команды.
Пример: lf95 @mycmds
В этом примере lf95 читает свои команды из файла mycmds.
Командные файлы могут использоваться раряду с другими параметрами командной
строки и другими командными файлами. Командные файлы могут вкладываться один
в другой. Кратные командные файлы обрабатываются слева направо в порядке, в
котором они обнаруживаются в командной строке.
В начало страницы
Драйвер lf95 (и компоненты, которыми он управляет) могут использовать
временные файлы для хранения промежуточных результатов и передачи их между
компонентами. Такие файлы автоматически создаются в временном каталоге под
случайными именами, а затем уничтожаются. Этот каталог может быть изменен
указанием значения в переменной оболочки TMPDIR.
В начало страницы
Когда драйвер lf95 получает код, сигнализирующий об ошибке, он аварийно
завершает процесс построения. Драйвер возвращает код ошибки в зависимости от
успеха вызванных инструментов. Эти коды перечислены ниже:
Таблица 1: Коды возврата драйвера
Код Условие
-------------------------------------------------------------
0 Успешная компиляция и компоновка
1 Фатальная ошибка компилятора
2 Ошибка архивной утилиты
3 Ошибка компоновки
4 Ошибка драйвера
-----------------------------------------------------------
В начало страницы
Совместная библиотека есть набор процедур , упакованных вместе в библиотеку,
загружаемую во время исполнения. На системах с Unix такие библиотеки
традиционно именуются как "совместные библиотеки" или "совместные архивы".
Термин "DLL" (Dynamic Link Library) был выбран в качестве имени для реализации
в Microsoft Windows совместных библиотек. В настоящем руководстве
используется термин "совместная библиотека", а не "DLL", хотя они могут
рассматриваться как взаимно заменимые. Совместная библиотека не может
исполняться самостоятельно; функции и подпрограммы из совместных библиотек
должны вызываться из исполнительного файла, который содержит главную программу.
Если программа на LF95, использующая совместные библиотеки, передается на
другие машины, то используемые ею совместные библиотеки должны также
передаваться или делаться доступными во время исполнения.
В начало страницы
Архивная библиотека (иногда называемая "статическая библиотека" или просто
"архив") есть набор процедур в объектной форме, образующих файл, на который
может ссылаться компоновщик. Во время компоновки, когда формируется
исполнительная программа, объектные коды процедур из библиотеки, вызываемые в
программе, включаются в текст исполнительного файла.
В начало страницы
Для создания совместной библиотеки нужно воспользоваться параметром --shared.
Пример
lf95 sub.f90 --out libsub.so --shared
lf95 main.f90 -L. -lsub
В этом примере исходный файл sub.f90 содержит подрутины или функции, и
исходный файл main.f90 содержит ссылки на эти процедуры. Происходит
следующее:
1. sub.f90 компилируется в объектный файл sub.o.
2. sub.o компонуется в libsub.so, совместную библиотеку. Объектный файл
sub.o после этого удаляется.
3. main.f90 компилируется для создания main.o.
4. main.o компонуется с исполнительной (runtime) библиотекой LF95
и комбинируется с информацией динамической связи, относящейся к
процедурам в libsub.so, создавая исполнимую программу. Объектный файл
main.o теперь удаляется.
Заметим, что имя совместной библиотеки должно иметь префикс "lib." Заметим
также, что во время исполнения libsub.so должна быть доступна в одном из
каталогов, указанных в переменной LD_LIBRARY_PATH.
В начало страницы
Для создания архивной библиотеки нужно воспользоваться параметром --nshared.
Пример
lf95 sub.f90 --out libsub.a --nshared
lf95 main.f90 -L. -lsub
Используются те же исходные файлы, что и в предыдущем примере. Производятся
следующие действия:
1. sub.f90 компилируется для создания sub.o.
2. архивная утилита ar автоматически вызывается для создания libsub.a
из sub.o.
Заметим, что libsub.a есть архивная (статическая) библиотека.
3. main.f90 компилируется и создается main.o.
4. main.o статически связывается с необходимым объектным кодом,
содержащимся в libsub.a, для создания исполнительной программы.
Заметим, что совместная библиотека libsub.so не должна присутствовать в
текущем каталоге; в противном случае компоновщик будет пытаться ссылаться на
этот файл вместо libsub.a (См. "Правила компоновки" на стр. 28.).
В начало страницы
В течение фазы компиляции драйвер передает компилятору исходные файлы для
компиляции и оптимизации. Если указан параметр -c, требующий только
компиляцию, обработка заканчивается после прохода компилятора и
создания объектных кодов и модулей (если они есть). См. "-[n]c" на стр. 15.
Иначе процесс обработки продолжается компоновкой и созданием исполнительной
программы или библиотечного файла.
В начало страницы
Если компилятор обнаруживает ошибки или сомнительные места в коде, вы можете
получить диагностику одного из следующих типов (буква перед сообщением
характеризует его серьезность)
U: неустранимая ошибка, при которой дальнейшая компиляция практически
невозможна.
S: серьезная ошибка, компиляция продолжается, но объектный код
вырабатываться не будет.
W: сообщение о возможной ошибке, недостаточно серьезной, чтобы препятствовать
исполнению программы. Может быть подавлено параметрами --nwarn или --swm.
I:информационные сообщения, предлагающие возможные усовершенствования в коде
или дающие детали оптимизации, сделанной компилятором. Нормально эти сообщения
подавляются. Их можно получить, указав параметр --info (см. "--[n]info"
на стр. 20).
Если неисправимые или серьезные ошибки компилятором не обнаружены, код ошибки
устанавливается на ноль (см. "Код возврата от драйвера" на стр. 11).
Неисправимые или серьезные ошибки, обнаруженные компилятором (например,
неправильный синтаксис) приводят к завершению процесса построения и объектный
файл не создается.
В начало страницы
Вы можете управлять компиляцией и компоновкой, используя перечисленные далее
необязательные параметры.
Параметры с одним дефисом чувствительны к регистру. Некоторые параметры
относятся только к фазе компиляции, другие -- только к фазе компоновки, а
некоторые (такие как -g) действуют в обеих фазах; это указывается сразу
за именем параметра. Если компиляция и компоновка производятся отдельно
(то есть в разных командных строках), то параметры, применимые к обеим фазам,
должна быть включены в каждую строку.
Большинство параметров LF95 начинаются двумя дефисами и являются
самодокументированными. Обычно используемые однодефисные параметры (-I, -l,
-L, -g, -o, -O, -c, и т.д.) предусмотрены для совместимости с другими
продуктами Linux products (см. описания ниже).
Компиляция и компоновка могут быть разделены в отдельные шаги с помощью
параметра -c. Если параметр -c не указан, драйвер LF95 будет пытаться
компановать и создавать исполнимую программу после завершения фазы компиляции.
Помещение -c где-нибудь в командной строке приведет к пропуску фазы
компоновки, и все параметры компоновки будут проигнорированы.
Хотя компоновка в конце концов производится программой ld, компоновщиком GNU,
лучше все же производить компоновку объектов LF95, использую драйвер LF95.
Это поможет правильно реализовать все необходимые шаги и включить все
необходимые компоненты в финальный продукт. Все параметры, не распознанные
драйвером LF95, будут переданы непосредственно к ld. Помните, что любой
параметр, переданный непосредственно к ld, будет рассматриваться как
чувствительный к регистру.
--[n]ap
Арифметическая точность
Только для компиляции. По умолчанию: --nap
Указывайте --ap для гарантии совместимости вычислений типов REAL и COMPLEX,
безотносительно к уровню оптимизации; пользовательские переменные не
кладутся в регистры. Рассмотрим следующий пример:
X = S - T
2 Y = X - U
...
3 Y = X - U
По умолчанию (--nap), во время компиляции оператора 2, компилятор распознает,
что значение X уже находится в регистре и не производит перегрузки значения
из памяти. В операторе 3 X может быть или не быть в регистре и ,таким образом,
или должно перезагружаться, или нет. Поскольку точность значения в регистре
больше чем в памяти, может возникнуть разность в точности при реализации
операторов 2 и 3.
Указывайте --ap, чтобы выбрать ссылку на память для операндов типа не-INTEGER;
Тo есть, перезагрузку регистров. --ap должно быть указано при тестировании на
равенство случайно порожденных значений.
Умолчание, --nap, позволяет компилятору использовать преимущество текущих
значений в регистрах для получения большей точности в битах низшего порядка.
Указывая --ap, обычно получают медленнее работающую исполнимую программу.
--block blocksize
По умолчанию размер блока при I/O
Только для компиляции. По умолчанию: 8192 байтов
Указывайте --block для изменения размера блока по умолчанию в операторах
OPEN. См. "BLOCKSIZE=" в справочнике по языку LF95.
blocksize нужно указывать в форме десятичной константы типа INTEGER.
Указывая оптимальный blocksize, можно значительно увеличить скорость исполнимой
программы. Программа tryblock.f90 демонстрирует, как изменение blocksize может
увеличить скорость исполнения. Для получения оптимального значения blocksize
в вашей программе нужно обычно провести несколько экспериментов. Это
оптимальное значение меняется от машины к машине; если ваша программа
передается на другую машину и там нужно получить оптимальную
производительность, размер blocksize нужно перевычислить.
-[n]c
Подавляет компоновку
Только для компилятора. По умолчанию: -nc (или -c отсутствует)
Указывайте -c для создания объектных (.o), и, если нужно, модульных (.mod)
файлов без создания исполнительной программы. Это особенно полезно при
использовании утилиты Make.
--[n]chk
Проверка
Только для компилятора. Умолчание: --nchk
Указывайте --chk для генерации сообщений о фатальных ошибках во время
исполнения, когда подцепочки и индексы массивов выходят за свои пределы,
когда переменные non-common используются до инициализации, когда
выражения-массивы не соответствуют их форме, или аргументы процедуры не
соответствуют по типу, атрибутам, размеру или форме.
Syntax
--[n]chk [[a][,e][,s][,u][,x]]
Замечание: Запятые необязательны, но рекомендуются для удобочитаемости.
Таблица 2: Аргументы параметра --chk
Предмет диагностики (класс) Аргумент параметра
------------------------------------------------
Аргументы a
Форма выражения-массива e
Индексы s
Неопределенные переменные u
Превышение (лишние) x
Указание --chk без аргументов эквивалентно указанию --chk a,e,s,u.
Указание --chk с любой комбинацией аргументов a, e, s, u и x активизирует
диагностики соответствующих классов.
Указание аргумента x должно быть использовано для компиляции всех файлов
программы, иначе можно получить некорректные результаты. Не используйте
компилированных модулей, объектных файлов или библиотек, полученных из
сомнительных источников . Специфически, аргумент x нужно использовать при
компиляции всех модулей USEd (т.е. упомянутых в списках операторов USE) и при
компиляции программных единиц, которые устанавливают значения в пределах
блоков COMMON. Указание аргумента x форсирует проверки неопределенных
переменных (u) и повышает уровень проверки, производимой по любым другим
указанным аргументам.
Указание --chk увеличивает размер программы и замедляет ее исполнение,
иногда на целый порядок. Оно принудительно вводит --trace и исключает
оптимизацию, вводя принудительно --O0. --chk также подавляет --parallel.
Пример
LF95 myprog --chk a,x
Побуждает компилятор усилить динамическую проверку аргументов и
использования значений неопределенных элементов.
hecking and
Параметр --chk не будет проверять границы в следующих условиях:
* Выражение, на которое ссылаются, имеет атрибут POINTER или есть структура,
в которой одна или более компонент имеют атрибут POINTER.
* Выражение, на которое ссылаются, есть массив предполагаемой формы.
* Выражение, на которое ссылаются, есть секция массива с векторным индексом.
* Переменная, на которую ссылаются, есть фиктивный аргумент, соответствующий
фактическому аргументу, который есть секция массива.
* Выражение, на которое ссылаются, есть присваивание замаскированному массиву.
* Выражение, на которое ссылаются, есть операторы FORALL и конструкты.
* Выражение, на которое ссылаются, имеет атрибут PARAMETER.
* Родительская цепочка есть скалярная константа.
--[n]chkglobal
В начало страницы
Только компиляция. По умолчанию: --nchkglobal
Указывайте --chkglobal, чтобы компилятор генерировал сообщения об ошибках,
связанных с отношениями между программными единицами, а также для полной
проверки действий как во время компиляции, так и при исполнении программы.
Глобальная проверка будет производиться только на исходном файле,
компилированном однократным вызовом компилятора (в одной командной строке)
Например, проверки не будет для USEd модуля, если этот модуль не
компилировался вместе с оператором USE в одном исходном файле. Проверки не
будет также в объектных файлах или библиотеках, указанных в командной строке.
Поскольку спецификация --chkglobal принудительно использует --chk x,
указание --chkglobal должно присутствовать при компиляции всех файлов
программы. В противном случае результаты могут оказаться некорректными.
Не используйте модулей, объектных файлов или библиотек, происхождение которых
сомнительно. Для полноты картины см. описание --chk
Диагностики глобальной проверки не показываются в листинге. Указание
--chkglobal увеличивает размер программы и замедляет ее исполнение иногда на
целый порядок. Оно принудительно использует --chk a,e,s,u,x --trace, и
удаляет оптимизации принудительным --O0.
Параметр --chkglobal не проверяет границы при следующих условиях:
* Используемое выражение имеет атрибут POINTER или есть структура,
в которой
одна или более оконечных компонент имеют атрибут POINTER.
* Используемое выражение есть массив предполагаемой формы.
* Используемое выражение есть секция массива с векторным индексом.
* Используемая переменная есть фиктивный аргумент соответствующий
фактическому, являющемуся секцией массива.
* Используемое выражение есть присваивание маскированному массиву.
* Используемое выражение есть оператор FORALL или конструкт.
* Используемое выражение имеет атрибут PARAMETER.
* Родительская цепочка есть скалярная константа.
--[n]co
Параметр компилятора
Компилировать и компоновать. Умолчание: --nco
Указывайте --co для показа текущих установок параметров компилятора;
указывайте --nco для подавления их.
--cpus N (только версия PRO)
Количество CPU
Только для компилятора. Умолчание: количество CPU в системе.
Этот параметр эффективен, когда указывается с параметром --openmp для
главной программы. N указывает количество используемых CPU и должно быть
положительным целым, меньшим чем 2147483648. Если --cpus не указано, то N
есть количество CPU в системе. --cpus требует -- openmp.
--[n]dal
Освободить размещаемые (Deallocate Allocatables)
Только для компилятора. Умолчание Default: --dal
Указывайте --dal для освобождения размещаемых массивов (не фигурирующих в
операторах DEALLOCATE или SAVE всякий раз когда операторы RETURN, STOP или
END встречаются в программной единице, содержащей размещаемый массив.
Заметим, что --ndal будет подавлять автоматическую деаллокацию, даже для
файлов Fortran 95 (автоматическая деаллокация есть стандартное свойство
в Fortran 95).
--[n]dbl
Двойной
Только для компилятора. По умолчанию: --ndbl
Указывайте --dbl для расширения всех REAL и COMPLEX переменных, массивов,
констант и функций простой точности до REAL (KIND=8) и COMPLEX (KIND=8)
соответственно. Если вы используете --dbl, то все исходные файлы (включая
модули) в программе должны компилироваться с --dbl. Указание --dbl обычно
приводит к несколько более медленной исполнительной программе.
Параметр --dbl отменяется при указании --openmp.
--[n]f95
Конформность с Fortran 95
Только для компилятора. По умолчанию: --nf95
Указание --f95 генерирует предупреждающие сообщения, когда компилятор
обнаруживает не стандартный для Fortran 95 код.
Заметим, что --nf95 допускает эквивалентность данных всякого встроенного типа
всем другим типам.
--file filename
Имя файла
Для компилятора и компоновщика. По умолчанию: отсутствует
Предварение имени файла записью --file гарантирует, что драйвер будет
интерпретировать filename именно как название файла, а не как параметр или
аргумент для параметра.
--[n]fix
Фиксированная исходная форма
Только для компилятора. По умолчанию: отсутствует
Указывайте --fix как инструкцию компилятору интерпретировать исходные файлы
как фиксированную исходную форму Fortran 90.
--nfix инструктирует компилятор воспринимать исходные файлы как свободную форму
Fortran 90.
Пример
lf95 @bob.rsp bill.f90
Если командный файл bob.rsp содержит --fix, то bill.f90 будет
рассматриваться как фиксированная исходная форма даже если он есть расширение
свободной формы.
Если не указаны ни --fix , ни --nfix, то LF95 будет интерпретировать
исходную форму согласно расширению имени файла (см. "Имена файлов и расширения
имен" на стр.8). LF95 не будет компилировать файлы (включая файлы INCLUDE),
содержащие в одном и том же файле фиксированную и свободную формы.
-g
В начало страницы
Умолчание: -g отсутствует
Указывайте -g для инструкции компилятору генерировать расширенную таблицу
символов и другую информацию для отладчика. -g автоматически подавляет
всякую оптимизацию и параллелизацию и принудительно указывает -O0, никакой
оптимизации, так что ваша исполнительная программа будет исполняться медленнее,
чем было бы при использовании оптимизации. -g требует использования
отладчика.
--help
Выдает параметры компилятора и синтаксис
Для компилятора и компоновщика. Умолчание: отсутствует
Указание этого параметра в отдельной командной строке побудит LF95 печатать
обзор параметров командной строки и синтаксиса на стандартов выводе с
последующим выходом.
-I dir
--include dir[:dir1[:dir2 ...]]
Вводит путь
Только для компиляторы. Умолчание: текущий каталог
Указывайте -I dir или --include dir для указания компилятору искать в
указанном каталоге (каталогах) файлы Fortran INCLUDE. Несколько каталогов
можно указывать для --include с разделенным двоеточиями списком путей, которые
надо перебирать в указанном порядке. Заметим, что -I воздействует также
на поиск модулей. Текущий каталог просматривается всегда.
Пример
lf95 demo.f90 --include ../dir2/includes:../dir3/includes
В этом примере компилятор сначала ведет поиск в текущем каталоге, затем
в ..\dir2\includes и наконец в ..\dir3\includes файлов INCLUDE, указанных в
исходном файле demo.f90
--[n]in
Никаких Implicit
Только для компилятора. Умолчание: --nin
Указание --in эквивалентно включению оператора IMPLICIT NONE в каждую
программную единицу в исходном файле: никакого неявного определения типов
нет в исходном файле.
Если указано --nin, действуют стандартные правила неявного определения типов.
--[n]info
Выдавать информационные сообщения
Только для компилятора. Умолчание: --ninfo
Указание --info приводит к выдаче информационных
сообщений, включая советы
по улучшению частей кода и информацию о действиях,
предпринятых компилятором
для оптимизации и параллелизации.
--nwarn принудительно устанавливает
--ninfo.
-l (L на нижнем регистре) name
Указывает библиотечный файл
Только для компоновщика.
По умолчанию отсутствует.
Указывайте библиотечный файл, имя которого имеет форму libname.a или
libname.so. Несколько библиотечных файлов можно указывать несколькими
параметрами -l. Библиотеки ищутся в том порядке, в каком они стоят в
командной строке (см. "Правила компоновки" на стр. 28.) Этот параметр и
аргументы для него передаются непосредственно компоновщику.
-L path
Путь поиска библиотеки
Только для компилятора. По умолчанию: переменная LD_LIBRARY_PATH.
Параметр -L добавляет путь к списку каталогов, в которых компоновщик ищет
библиотеки, т.е., файлы с началом имени "lib" и с расширениями .a или .so.
Заметим: если "." (текущий каталог) не указана в вашей переменной
LD_LIBRARY_PATH, то нужно указывать -L. в командной строке для поиска файлов
в текущем каталоге. Этот параметр и его аргумент передаются непосредственно
компоновщику.
Пример
Следующая команда компонует main.o с libmine.a и libyours.so (расположенные
в соседних каталогах mylibs и yourlibs соответственно):
lf95 main.o -L../mylibs -lmine -L../yourlibs -lyours
Помните, что по умолчанию компоновщик сначала ищет совместные библиотеки.
--[n]long
Длинные целые
Только для компилятора. По умолчанию: --nlong
Указывайте --long для расширения всех по умолчанию INTEGER переменных,
массивов, констант и функций до INTEGER (KIND=8). При использовании --long
все исходные файлы в программе (включая модули) должны компилироваться с
--long для предотвращения конфликтов в типах аргументов.
--[n]lst [ [spec=sval[, spec=sval]] ]
Листинг
Только для компилятора. Умолчание: --nlst
Указывайте --lst для порождения файла с листингом, содержащим исходную
программу, параметры компилятора, дату и время компиляции и диагностику
компилятора. Компилятор выдает отдельный файл с листингом для каждого
указанного входного файла. По умолчанию имя файла листинга состоит из
базисного имени входного файла плюс расширение ".lst". Листинг помещается в
текущем рабочем каталоге (для подавления используйте подпараметр f=sval, как
показано ниже). Ширина страницы листинга составляет 274 колонки, страницы не
разделяются и дополнительные заголовки не вставляются в листинг. Заметим,
что --nlst подавляется параметром --xref.
Syntax
--[n]lst [[spec=sval[, spec=sval]]]
Здесь:
spec есть f для имени файла с листингом или i для включения файлов
INCLUDE. Каждый подпараметр должен быть отделен запятой и пробелом,
и весь список подпараметров должен быть заключен в квадратные скобки ("[]").
При f=sval, имя файла листинга, sval определяет имя листинга для использования
вместо имени по умолчанию. Если файл с таким именем уже существует, он
перезаписывается. Если пользователь указал имя файла с листингом и более чем
один исходный файл, драйвер выдает сообщение об ошибке и абортируется.
При i=sval, sval есть один из символов [YyNn], где Y и y указывают, что
файлы include должны быть включены в листинг, а N и n указывают, что нет.
По умолчанию файлы include в листинг не входят.
Пример
lf95 myprog.f90 --lst [i=y]
создает листинг с именем myprog.lst , который содержит файлы include.
См. также --[n]xref
--[n]maxfatals number
Максимальное количество фатальных ошибок
Только для компилятора. По умолчанию: --maxfatals 50
Указывайте --maxfatals чтобы ограничить количество сообщений о фатальных
ошибках, которые LF95 будет генерировать до абортирования.
--ml target
Смешанный язык
Только для компилятора. По умолчанию: отсутствует
Параметр --ml иногда нужен, если ваш код вызывает или вызывается кодом,
написанном на другом языке. Значение target относится только к процедурам,
объявленным в операторе ML_EXTERNAL. В настоящее время единственным возможным
значением для target есть cdecl, которое нужно для обращений к ядру системы.
Параметр --ml нужен для интерфейса с программами g77. См. подробности в
разделе "Программирование на смешанном языке" на стр. 30.
--mldefault target
Подразумеваемый смешанный язык
Только для компилятора. По умолчанию: -mldefault
Указывайте --mldefault switch для установки decoration/calling-соглашения
об имени языка target для всех программных единиц. --mldefault предотвращает
искажение имен процедур в оперраторах ML_EXTERNAL. В настоящее время
для target поддерживается только имя cdecl, которое нужно для обращений к
ядру системы. Параметр --mldefault не нужен для интерфейса с программами
g77. См. "Программирование на смешанном языке" на стр. 30 для получения
более подробной информации.
-M dir
-mod dir[:dir1[:dir2 ...]]
Путь к модулям
Только для компилятора. По умолчанию: текущий каталог
Указывайте --mod dir, чтобы побудить компилятор к поиску указанного каталога
или каталогов с модульными файлами LF95 (.mod). Несколько каталогов можно
указать посредством --mod с разделенным двоеточиями списком каталогов, который
будет просматриваться в указанном порядке. Текущий рабочий каталог будет
просматриваться следующим, если он не указан с параметром --mod.
Каталоги, указанные с параметром -I и не указанные с параметром --mod,
обследуются в последнюю очередь. При создании нового модуля, сам модуль
и его объектный файл будут помещены в первый указанный каталог (если этого
каталога нет, то он будет создан). Заметим, что всякий нужный модульный
объектный файл из предыдущей компиляции должен быть добавлен в командную
строку LF95 при компоновке.
Пример
lf95 modprog.f90 mod.o othermod.o --mod ../mods:../other
В этом примере компилятор сначала ищет в ../mods, затем в ../other,
и в последнюю очередь просматривает текущий рабочий каталог ( если нужный
модуль не найдется ни в одном из этих каталогов, компилятор будет стараться
найти его в каталогах, указанных с параметром -I). В рассматриваемом примере
всякий модуль и модульные объектные файлы, произведенные программой
modprog.f90, помещаются в каталог ../mods. Отметим, что -I не влияет никак
на размещение модулей на выходе, хотя и воздействует на их поиск. Если -M
не указано, то выходные модульные файлы будут помещены в текущий рабочий
каталог.
-O0 и -O
--o0 и --o1
Уровень оптимизации
Только компилятор. Умолчание: -O (полная оптимизация)
Указывайте -O0 для исключения оптимизации. -O0 включается автоматически, когда
указываются параметры -g, --chk или --chkglobal. См. "-g" на стр.19.
Указывайте -O для оптимизации по скорости. Чтобы увидеть в деталях действия
компилятора по оптимизации, укажите параметр --info. См. "--[n]info" на
стр. 20.
-o name
--out name
Выходное имя файла
Компиляция: по умолчанию выдает результат с корневым именем входного файла с
расширением .o
Компоновка: по умолчанию есть a.out, в текущем рабочем каталоге
При отсутствии компоновки ( то-есть при указании -c), указывайте -o для
подавления выдаваемого по умолчанию имени объектного файла и пути.
Этот путь есть текущий рабочий каталог. При компоновке (когда указано -nc
или не указано c), указывайте -o для подавления выходного исполнительного или
библиотечного имени по умолчанию. По умолчанию результат поступает в текущий
рабочий каталог. Действие --out идентично действию -o.
Пример
lf95 hello.f90 -c -o/home/mydir/hello.o
lf95 main.o --out maintest
--[n]ocl (только для версии PRO)
Обрабатывает строки управления оптимизацией
Только для компилятора. По умолчанию: --nocl
--ocl предписывает обрабатывать строки управления оптимизацией (сокращенно
называемые OCL). См. "Строка управления оптимизацией" на стр. 73 для
дополнительной информации.
--[n]openmp (только для версии PRO)
Обрабатывать директивы OpenMP.
Только для компилятора. Умолчание: --nopenmp
--openmp предписывает компилятору обрабатывать директивы OpenMP в коде Fortran.
См. "OpenMP" на стр. 85.
--[n]parallel (только для версии PRO)
Попытка автоматической параллелизации.
Только для компилятора. По умолчанию: --nparallel
--parallel принудительно вызывает -O (полная оптимизация). Заметим, что
--parallel игнорируется, если указаны параметры -g, --chk или --chkglobal.
Чтобы увидеть действия компилятора по параллелизации, укажите параметр --info.
См. "Обзор мульти-процессинга" на стр. 65 для получения дополнительной
информации.
--[n]pca
Защита постоянных аргументов
Только для компилятора. По умолчанию: --npca
Указывайте --pca для предотвращения записи в константы вызываемыми
подпрограммами.
Пример
call sub(5)
print *, 5
end
subroutine sub(i)
i = i + 1
end
Этот пример напечатает 5 при использовании --pca и 6 при --npca.
--[n]private
Доступность модулей по умолчанию
Только для компилятора. По умолчанию: --nprivate
Указывайте --private для замены характеристики доступности модуля с PUBLIC на
PRIVATE (см. операторы "PUBLIC" и "PRIVATE" в справочнике по языку).
--[n]quad
Четырехкратная точность
Только для компилятора. По умолчанию: --nquad
Указывайте --quad для расширения всех REAL и COMPLEX переменных двойной
точности, массивов, констант и функций до REAL (KIND=16) и COMPLEX (KIND=16)
соответственно. Определяемые по умолчанию (простой точности) объекты REAL
остаются неизменными. Если используете --quad, то все исходные файлы
программы (включая модули) должны компилироваться с --quad. Указание --quad
обычно приводит к немного более медленной исполнительной программе. Заметим,
что указание -dbl -quad не увеличит точность объектов с простой
точностью (single-precision) до точности quad.
--[n]quiet
Тихая компиляция
Только для компилятора. По умолчанию: --quiet
Указание --quiet подавляет сообщения о том, что текущий файл или программная
единица скомпилированы. Вместо этого выдаются только сообщения об ошибках,
предупреждения (при наличии --warn) и информационные сообщения (при --info).
--[n]sav
SAVE для локальных переменных
Тлько для компилятора. По умолчанию: --nsav
Указывайте --sav для размещения локальных переменных в создаваемой
компилятором области SAVE. --nsav располагает переменные в стеке. --sav
эквивалентно помещению оператора SAVE в каждую подпрограмму, за исключением
того, что --sav не применяется к локальным переменным в рекурсивных
функциях, где оператор SAVE действует. Указание --sav замедляет выполнение
исполнительной программы, особенно при наличии многих подпрограмм. Указание
--nsav может иногда требовать большего программного стека.
--[n]shared
Создать совместную библиотеку
Только для компоновщика. По умолчанию: --nshared
Указывайте --shared для создания совместной библиотеки вместо архивной
(статической) библиотеки (подробности см. в "Совместные библиотеки" на стр. 12).
--[n]staticlink
Статические библиотеки времени исполнения
Только для компоновщика. По умолчанию: --nstaticlink
Указывайте --staticlink для создания исполнительной программы, скомпонованной
со статической версией библиотечного исполнительного файла. Указание
--nstaticlink will приведет к созданию более короткой исполнительной программы,
но она не будет работать на другой машине, если там не будет совместных
исполнительных библиотек. Параметр --staticlinc будет особенно полезен при
создании приложений для исполнения на другой машине (см. "Распространение
приложений LF95 " на стр. 43).
--[n]swm msg[,msg[,...]]
Подавление предостерегающего сообщения(сообщений)
Только для компилятора. По умолчанию: --nswm
Подавить конкретное предостерегающее или информационное сообщение, которое
появляется во время компиляции, можно, указав его четырехзначный номер после
--swm. Для подавления нескольких сообщений укажите список их номеров через
запятую без пробелов.
Пример--swm 1040,2005
Этот пример будет подавлять сообщения с номерами 1040 и 2005. Чтобы подавить
все предостережения и информационные сообщения, используйте --nwarn. Список
номеров предостережений и ошибок находится в файле RTERRMSG.
--t4, --tp и --tpp
Целевой процессор
Только для компилятора. Default: --tp
Указывайте --t4 для генерации кода, оптимизированного для процессоров
Intel 80386 или 80486.
Указывайте --tp для генерации кода, оптимизированного для Intel Pentium или
Pentium MMX или эквивалентов в их серии.
Указывайте --tpp для генерации кода, оптимизированного для процессоров
Intel Pentium Pro, Pentium II, Pentium III, Celeron или их эквивалентов.
Пожалуйста запомните: коды, порожденные с --tpp, несовместимы с процессорами,
изготовленными ранее чем Pentium Pro.
--threads N (только версия PRO)
Количество потоков
Только для компилятора. Умолчание: количество активных процессоров в системе.
--threads указывает количество экземпляров (потоков), которые должны быть
созданы, 2 <= N <= количества CPU, активных во время исполнения.
Если этот параметр указан, он исключает для компилятора необходимость выдавать
служебный код, показывающий, сколько CPU доступны во время исполнения.
Это также полезно, если задача естественным образом разделяется на параллельные
сегменты и количество этих сегментов отлично от количества доступных CPU.
Убедитесь, что переменная окружения PARALLEL установлена на указанное
значение (N) во время исполнения программы. Исполнительная программа, которая
порождена по указанию этого параметра, всегда исполняется с N CPU, даже
если программа перенесена на машину с другим количеством CPU.
--threads требует --parallel. -g, --chk или --chkglobal приводят к
игнорированию --threads.
--threadstack N (PRO version only)
Размер стека для потока (Thread)
Только для компилятора. По умолчанию: размер исполнительного стека.
--threadstack устанавливает размер стека для каждого потока в N килобайт,
где N лежит между 16 и 2048 включительно. Максимальный размер стека для
потока Linux есть 2048 килобайт. Этот параметр имеет преимущество перед
переменной окружения THREAD_STACK_SIZE (см. "Переменная окружения
THREAD_STACK_SIZE" на стр. 68).--threadstack требует --openmp или --parallel
и должен быть указан для файлов с главной программной единицей. -g, --chk или
--chkglobal приводят к игнорированию --threadstack.
--threadheap [size] (только в версии PRO)
Размер динамической области потока (Thread Heap Size)
Только для компилятора. По умолчанию: 4096 байтов
Если указан параметр --threadheap, то локальные массивы в процедуре или
параллельной области, которые больше чем size байтов, располагаются в
динамической области (heap), за исключением следующих массивов:
* приравненных (equivalenced) массивов
* массивов, которые являются объектами в namelist
* массивов производного типа, которые указывают инициализацию
по умолчанию
* массивов в common, которые имеют атрибут PRIVATE.
size должен быть положительным числом, меньшим чем 2147483648. Если size
опущено, то для size выбирается значение 4096.
Производительность исполнительной программы может уменьшиться, если указан
--threadheap. Используйте этот параметр только когда требуемый размер
поточного стека превышает 2048 байтов.
--threadheap требует --openmp. -g, --chk --chkglobal приводят к игнорированию
параметра --threadheap.
--[n]trace
Размещение и вызов Traceback для ошибок при исполнении
Только для компилятора. По умолчанию: --trace
Параметр --trace приводит к вызову Traceback с именами процедур и номерами
строк, генерируемых с сообщениями о динамических ошибках. При --ntrace номера
строк не генерируются. --trace может замедлить выполнение программы.
--[n]trap
Ловить числовые ошибки
Только для компилятора. По умолчанию: --ntrap
Параметр --trap побуждает исполнительную библиотеку подпрограмм Fortran
выдавать сообщения об ошибках при делении на ноль или переполнении. При этом
исполнение прекращается. Если указаны параметры времени исполнения -WI,-i
(см. "Обработка прерываний" на стр. 117), то ошибки переполнения
отлавливаться не будут. Если указаны параметры времени исполнения -WI,-u,
то будут ловиться исчезновения знаков (см. "Обработка прерываний по пропаданию
знаков" на стр. 119).
--[n]verbose
Подробный вывод
Указывайте --verbose, чтобы увидеть детали команд, передаваемых всем
программным средствам, используемым при создании объектных файлов, выполнимых
файлов и библиотек.
--[n]version
Напечатать информацию о версии
Компилятор и компоновщик. По умолчанию: --nversion
Указывайте --version для выдачи серийного номера продукта, copyright и
информации о версии при компиляции или компоновке.
--[n]warn
Предупреждения
Только для компилятора. По умолчанию: --warn
Указывайте --warn для выдачи предупреждений во время компиляции. Заметим, что
--nwarn принудительно выдает --ninfo.
--[n]wide
Расширенный формат исходного кода
Только для компилятора. По умолчанию: --nwide
Указывайте --wide при компиляции исходного кода в фиксированном формате,
который простирается до колонки 255. Этот параметр не действует при
компиляции источника в свободном формате.
--[n]wisk (только в версии PRO)
Winteracter Starter Kit
Компилятор и компоновщик. По умолчанию: -nwisk (для компилятора и
компоновки)
Указывайте --wisk для создания приложения, использующего Winteracter Starter
Kit (WiSK, см. руководство по Winteracter Starter Kit). Заметим, что
имя ресурсного файла должно быть указано в командной строке при спецификации
-wisk. См. руководство по Winteracter Starter Kit для ознакомления с
деталями.
--[n]wo
Предупреждения об устаревших средствах
Только для компилятора. По умолчанию: --nwo
Указывайте --wo для выдачи предупреждающих сообщений, когда компилятор
обнаруживает устаревшие средства Fortran 95.
--[n]xref
Листинг с перекрестными ссылками
Только для компилятора. По умолчанию: --nxref
Указывайте --xref для генерации перекрестных ссылок в листинге. По умолчанию
имена файлов в перекрестных ссылках состоят из базисного имени исходного
файла плюс расширение ".lst" , и размещается листинг в текущем рабочем
каталоге (см. "--[n]lst [ [spec=sval[, spec=sval]] ]" на стр. 20).
Указание --xref подавляет --nlst.
См. также
--[n]lst
В начало страницы
Во время фазы компоновки драйвер передает объектные файлы и объектные
библиотеки компоновщику для создания исполнимого выходного файла или
выходного файла совместной библиотеки.
В начало страницы
Если ваша программа использует модули Fortran 95, которые были компилированы
ранее, вы должны добавить имена объектных модулей (то есть исходные файловые
имена с расширением .o) в командную строку LF95 для компоновки. Компилирование
модуля Fortran 95 породит объектный файл (.o) и file модуля (.mod), если
исходный файл содержит исполнимый код. Если исходный файл не содержит
исполнимого кода, но содержит объекты public, то будет скомпилирован
только файл с расширением .mod.
В начало страницы
Компоновщик читает отдельные объектные файлы и библиотеки объектных модулей,
разрешает ссылки на внешние символы и записывает единый исполнимый файл
(или совместную библиотеку).
Если объектный файл или библиотека были указаны в командной строке и содержат
информацию о пути к ним, они должны находиться там, где указано. Если путь не
был указан, компоновщик ищет файл в следующим порядке:
1. в любом каталоге, указанном с параметром -L;
2. в любом каталоге, указанном в переменной окружения
LD_LIBRARY_PATH.
Замечание: текущий рабочий каталог просматриваться не будет, если он не
указан параметром -L или в переменной окружения LD_LIBRARY_PATH. В любом
случае компоновщик будет сначала пытаться найти совместную библиотеку ( с
с расширением .so файлового имени), содержащую желаемое имя (имена).
Если она не обнаружена, то компоновщик будет искать архив или статическую
библиотеку (с расширением имени .a). Параметр --staticlink не влияет на эти
действия; этот параметр определяет только специальную группу исполнительных
библиотек, которые будут привязаны к исполнительной программе. Правила поиска
файлов INCLUDE и модулей Fortran 95 определяются компилятором, а не
компоновщиком. См. "-I dir" на стр. 19 и "-M dir" на стр. 22 по этому поводу.
В начало страницы
Объектные файлы обрабатываются в том порядке, в котором они фигурируют в
командной строке.
В начало страницы
Компоновщик ld пользуется следующими правилами, когда ищет объектные
библиотеки:
1. Любые библиотеки, указанные с использованием параметра -l, отыскиваются
в том порядке, в каком они фигурируют в командной строке LF95, раньше чем
исполнительные библиотеки LF95 или любые библиотеки, находящиеся в каталогах,
указанных параметром -L или в переменной окружения LD_LIBRARY_PATH. Компилятор
записывает имена подразумеваемых библиотек в каждый объектный файл, который он
генерирует.
2. Каждая библиотека просматривается до тех пор, пока не будут разрешены все
возможные внешние ссылки. Если необходимо, просматриваются также системные
библиотеки в /lib или /usr/lib.
В начало страницы
В большинстве случаев LF95 передает нераспознанные параметры компоновщику;
однако, некоторые параметры компоновщика могут вступать в конфликт с
имеющимися параметрами LF95 options. В таком случае, параметр может быть
передан непосредственно компоновщику из командной строки LF95 с помощью
параметра -Wl. Этот параметр действует так, как указано в man pages
для gcc, компилятора GNU Cи (случайно, -Wl есть тот же параметр, который
используется для указания параметров времени исполнения, как это описано в
приложении B, Параметры времени исполнения). Дополнительную информацию см.
в man pages для ld, компоновщика GNU.
В начало страницы
Код LF95 может вызывать и быть вызванным кодом, написанном на других языках.
С помощью LF95 можно создавать объектные и библиотечные файлы для
использования с языковыми системами из приведенной ниже таблицы. Вызовы
могут быть от Fortran к Fortran, от Fortran к другому языку, и от другого
языка к Fortran. Если вы вызываете подпрограммы LF95 из языка системы,
отличной от LF95, может оказаться необходимым ознакомиться с документацией
этой системы для получения дополнительной информации.
В начало страницы
Lahey/Fujitsu Fortran 95 поддерживает межязыковые интерфейсы с следующими
языками и операционными системами (этот список может изменяться -- см.
READ_ML относительно изменений):
Таблица 3: Поддержка компилятором смешения языков
Языковая система --ml параметр
(см. ниже)
..........................................
Ядро Linux и стандартные
библиотеки Cи --ml cdecl
Gnu Cи --ml cdecl
Fujitsu Cи --ml cdecl
Gnu Fortran77 (ничего)
В начало страницы
Для организации ссылки на процедуру в смешанном языковом интерфейсе, компилятор LF95
должен быть информирован об имени процедуры и о том, как "декорировать" это
имя, когда оно появляется в объектном файле. Такие процедурные имена
определяются по оператору ML_EXTERNAL (см. "Оператор ML_EXTERNAL" в
справочнике по языку LF95). Операторы DLL_EXPORT и DLL_IMPORT, используемые
в LF95 Windows product, все еще поддерживаются, но их действие аналогично
ML_EXTERNAL, поскольку соглашения о вызове -- те же что и для статических и
совместных библиотек Linux.
Заметим, что вообще говоря, имена процедур смешанного языка чувствительны к
регистру ( в отличие от соглашений по наименованию в Fortran, которые
игнорируют регистр). ML_EXTERNAL используется при определении процедуры
Fortran и при ссылке на внешнюю процедуру. Тип интерфейса со смешанным
языком определяется при использовании параметра компиляции --ml. Нельзя
употреблять параметр --ml в отдельных вызовах LF95. Если вам нужно ссылаться
на процедуры из разных языков, вы можете сделать это, помещая ссылки в
отдельные исходные файлы и компилируя их отдельно.
Таблица 4 описывает варианты процедур, которые можно найти в программе
LF95, вместе с формой, принятой подразумеваемым внешним именем процедуры
(т.е., именем, увиденным компоновщиком). Процедуры MAIN__() и main()
играют специальную роль в программах со мешанным языком. Это описывается в
разделе "Program Control: main() and MAIN__()" на стр. 43.
Таблица 4: Подразумеваемые внешние имена для процедур Fortran'а
.................................................................
Имя процедуры Видится извне как:
................................................................
FUNCTION MyFunc() myfunc_
SUBROUTINE MySub() mysub_
f_proc1
встроенная процедура proc1() или
g_proc1
программа main MAIN__
Инициализирующая/запускающая процедура Fortran main
common блок a a_
Внешние имена функций Fortran и подрутин могут быть изменены использованием
оператора ML_EXTERNAL вместе с параметром компилятора --ml. Цель оператора
ML_EXTERNAL состоит в модификации "декорации имени" или "искажения имени",
То есть в применении для внешней процедуры имени (в соответствии с параметром
компилятора --ml) и разрешении сохранить регистр.
Таблица 5: Действие параметра --ml на внешнее имя процедуры Fortran
MySub1(), объявленной как ML_EXTERNAL
.............................................................................
--ml option Видима извне как:
............................................................................
--ml cdecl MySub1
--ml not specified MySub1_
не объявлена как mysub1_
ML_EXTERNAL (--ml не действует)
Заметим, что если MySub1() не объявлена как ML_EXTERNAL, то параметр --ml
не действует, и ее внешнее имя будет всегда mysub1_. Соглашение о наименовании в
Fortran может быть адаптировано в Cи объявлением функции Си в нижнем регистре
и добавлением в конец знака подчеркивания, исключая тем самым необходимость
оператора ML_EXTERNAL или параметра --ml компилятора. С другой стороны,
если Fortran вызывает библиотеку Си, исходный сод которой недоступен, то
оператор ML_EXTERNAL и параметр компилятора --ml необходимы.
В начало страницы
Когда пишется процедура на LF95, которая будет вызывать (или вызываться из)
g77, не обязательно указывать параметр --ml в командной строке или применять
оператор ML_EXTERNAL к имени процедуры. вместе с тем, важно скомпоновать
нужные библиотеки так, чтобы ссылки на встроенные процедуры могли быть
разрешены. См. каталог examples/mix_lang каталог в вашем установочном корневом
каталоге с примерами компоновки с объектными файлами g77.
В начало страницы
Когда вы создаете библиотеку Fortran или объектный файл, вы обычно указываете
каждую процедуру, которую хотите сделать доступной, с помощью оператора
ML_EXTERNAL. Процедура может быть или подрутиной или функцией. Когда функция
Fortran возвращает значение, вызывающий язык должен привести это значение к
соответствующему типу данных, как описано в таблице 7 на стр. 36.
integer function half(x)
ml_external half !имя чувствительно к регистру.
integer :: x
half = x/2
end
Когда вы пишете программу на Fortran, которая ссылается на процедуру(ы),
написанные не на Fortran, вы объявляете имена этих процедур в операторе
ML_EXTERNAL в вашей Fortran-программе. Синтаксис оператора ML_EXTERNAL
в таком случаее будет:
ML_EXTERNAL external-name-list
где external-name-list есть список разделенных запятыми имен процедур, на
которые есть ссылки из данной единицы видимости. Процедуры могут быть
подрутинами или функциями. Не Фортрановские функции могут возвращать только
данные типов, перечисленных в Таблице 6 на стр. 34.
program main
implicit none
real :: My_C_Func, x
ml_external My_C_Func !имя чувствительно к регистру
x = My_C_Func()
write (*,*) x
end program main
Эти коды должны компилироваться с использованием в LF95 параметра --ml target,
чтобы их можно было вызывать из языка target (см. "--ml target" на стр.21).
Заметим, что ML_EXTERNAL есть оператор, а не атрибут. Другими словами,
ML_EXTERNAL не может появиться в списке атрибутов в операторах INTEGER,
REAL, COMPLEX, LOGICAL, CHARACTER или TYPE.
Другие примеры см. в каталогах под каталогами примеров для LF95 (directories
below LF95's examples directory.
В начало страницы
Данные можно передавать к или от других языковых систем как аргументы,
результаты функций, внешние (COMMON) переменные или в файлах. LF95 не
поддерживает передачу массивов указателей от Cи, или указателей более чем
первого уровня. Соглашение по вызовам в LF95 таковы:
* Все аргументы передаются по адресу, а не по значению, как в Cи. LF95 может
передавать аргументы по значению другим языкам, используя встроенную VAL().
* Массивы указателей не могут передаваться от Cи в Fortran.
* COMPLEX и производные типы аргументов могут передаваться как указатели
на структуры.
Так как Cи не имеет своего типа для комплексных данных, они должны
объявляться как структуры. Например , Fortran default COMPLEX объявляется
в Cи как
struct {
float real;
float imaginary;
} complex;
* При передаче данных через файл, файл должен быть закрыт до вызова
не Фортрановской процедуры.
* Fortran common-блоки могут быть доступны из Си как внешние или "global"
структуры.
Например, именованный блок common,
/my_common/ a, b, c
real a, b, c
может быть доступен как
extern struct
{float a, b, c;
} my_common_;
/* my_common_ должен быть весь на нижнем регистре */
"Blank" (безымянный) common рассматривается так же; структура именуется
_BLNK_ вместо my_common_.
Данные, передаваемые между программами на Fortran и на Cи, должны иметь
соответствующие атрибуты. Следующая таблица описывает соответствие типов
данных между Cи и Fortran. Заметим, что некоторые из перечисленных типов
данных недоступны для некоторых компиляторов Cи.
Таблица 6: соответствие типов данных в Fortran и Cи
Data Type Fortran C Comments
....................................................................
one-byte logical LOGICAL(1) L1 char L1; 1 byte
two-byte logical LOGICAL(2) L2 short int L2; 2 bytes
four-byte logical LOGICAL(4) L4 long int L4; 4 bytes
eight-byte logical LOGICAL(8) L8 long long int
L8; 8 bytes
one-byte integer INTEGER(1) I1 signed char
I1; 1 byte
two-byte integer INTEGER(2) I2 short int I2; 2 bytes
four-byte integer INTEGER(4) I4 long int I4; 4 bytes
Таблица 6 : соответствие типов данных в Fortran и C
Тип даных Fortran C Примечания
eight-byte integer NTEGER(8) I8 long long int 8 bytes
18
real REAL(4) R4 float R4; 4 bytes
double-precision
real REAL(8) R8 double R8; 8 bytes
quadruple-preci-
sion real REAL(16) R16 long double
16; 16 bytes
struct
complex COMPLEX(4) C8 {float r, i;} 8 bytes
C8;
double-precision struct
complex COMPLEX(8) C16 {double r, i;} 16 bytes
C16;
quad-precision struct
complex COMPLEX(16)C32 {long double 32 bytes
r, i;} C32;
character (фикс. см. примеры для
длина) CHARACTER*10 S char S[10] предпол. длины
TYPE TAG
SEQUENCE struct tag
{ разм. в байтах =
прооизв. тип INTEGER I4
REAL(8) R8 int I4; сумме всех компо-
END TYPE double R8; нент
TYPE(TAG) D } D;
array of pointers недопустим *myarray[10]
**hisarray
В начало страницы
Функции Fortran вызываются из Cи как функции, возвращающие значение, со всеми
аргументами, передаваемыми по ссылке. Значения передаются на стек, за
исключением данных типа COMPLEX и CHARACTER. В этом случае значения передаются
через список аргументов. В следующей таблице перечисляются типы данных, которые
могут возвращаться в Cи от функций Fortran. В третьей колонке таблицы
(колонка "примеры"), переменный результат представляет значение, возвращаемое
Fortran-функцией myfunc(). В последнем примере, переменная strlen
представляет длину символьного значения, возвращенного функцией myfunc().
В этом разделе не рассматриваются подрутины Fortran'а, вызываемые из Cи как
"void" функции. Это понятие иллюстрируется в следующем разделе "Передача и
получение аргументов" на стр. 38.
Таблица 7: Объявление в Cи типов результатов от типов функций в Fortran
Тип функции Fortran Тип результата в Си Пример
INTEGER(1) signed char result = myfunc_();
INTEGER(2) short int result = myfunc_();
INTEGER(4) long int result = myfunc_();
INTEGER(8) long long int result = myfunc_();
LOGICAL(1) unsigned char result = myfunc_();
LOGICAL(2) short int result = myfunc_();
LOGICAL(4) long int result = myfunc_();
LOGICAL(8) long long int result = myfunc_();
REAL(4) float result = myfunc_();
REAL(8) double result = myfunc_();
REAL(16) long double result = myfunc_();
COMPLEX(4) void myfunc_(&result);
COMPLEX(8) void myfunc_(&result);
COMPLEX(16) void myfunc_(&result);
CHARACTER(LEN=*) void myfunc_(&result,len);
Производный тип не применяется не применяется
Например, функция Fortran:
integer function foo(i,j)
integer :: i, j
:
:
end function foo
соответствует прототипу в Cи:
long int foo(long int *i, long int *j);
Чтобы проиллюстрировать возврат символьного значения предполагаемой длины,
функция Fortran:
function cfun()
character(len=*) :: cfun
cfun = `1234567890'
end function cfun
вызывается из Си следующим образом:
void cfun_(char *str1, int strlen);
MAIN__()
{ char mystr[10];
cfun_(mystr,10);
}
Этот пример может показаться немного странным, поскольку он действует
против интуитивного представления о функции, возвращающей значение.
Дальнейшие объяснения см. в "Передача символьных данных" на стр. 40.
В начало страницы
Функции Cи также вызываются из Fortran как функции, возвращающие значение.
По умолчанию, все аргументы передаются в Cи по ссылке. Аргументы могут также
передаваться в Cи по значению с помощью встроенной в LF95' функции VAL().
Нельзя вернуть из Си строки символов или структуры. Fortran вызывает функции
Си вида "void" так же как подрутины Fortran. Это иллюстрируется в следующем
разделе "Передача и получение аргументов" на стр. 38.
Table 8: Объявление типов результатов для типов функций Cи
..........................................................................
Тип функции Си Тип результата в Fortran Пример
.........................................................................
void неприменим call my_c_func()
signed char INTEGER(1) result = my_c_func()
short int INTEGER(2) result = my_c_func()
long int INTEGER(4)
LOGICAL(4) result = my_c_func()
long long int INTEGER(8) result = my_c_func()
float REAL(4) result = my_c_func()
double REAL(8) result = my_c_func()
long double REAL(16) result = my_c_func()
char не может быть принят не применим
structure не может быть принят не применим
В начало страницы
По умолчанию Fortran передает аргументы "по ссылке" (т.e., передает адрес
каждой переменной в списке аргументов, а не значения аргументов,
на программный стек); Но многие функции Cи ожидают передачу переменных "по
значению" на программный стек. В таком случае можно применять встроенную VAL(),
как это делается в списке аргументов при обращении к функции Fortran.
Во всех последующих примерах кода Си объявление int есть синоним long int.
Заметим, что всякие аргументы- массивы или аргументы типа COMPLEX не должны
передаваться в В Си по значению; они должны всегда передаваться по ссылке.
Символьные данные представляют специальный случай -- они могут передаваться,
используя или встроенное CARG или VAL(OFFSET()). См. следующий раздел
"Передача символьных данных" на стр. 40 для дальнейших пояснений.
Пример: Передача аргументов по значению из Fortran в Cи
Функция Cи
void mysum_(i, j, k)
int *i, j, k;
{i = j + k;
}
вызывается из Fortran так:
integer i, j, k
j = 3
k = 4
call mysum(i, val(j), val(k))
write (*,*) ` Результат: j+k = `, i
Пример: Передача аргументов по ссылке из Cи в Fortran
Переменные можно передавать по ссылке из Cи, используя l-value оператор (&).
Функция Fortran
integer function myfunc(x, y)
integer x, y
myfunc = x + y
return
end function
вызывается из Cи как
MAIN__()
{ long int myfunc_(*long int i, *long int j);
long int i, j, k;
i = 5
j = 7
k = myfunc_(&i, &j)
}
В начало страницы
Поскольку в Cи многомерные массивы располагаются в памяти в порядке следования
строк, а в Fortran -- в порядке следования столбцов, необходимы специальные
приемы при обработке массивов Fortran. Исключая одномерные массивы (они
располагаются одинаково и в Cи и в Fortran), вы должны переставлять в
обратном порядке индексы при доступе к массиву Fortran в Cи.
Причина в том, что в Cи самый правый индекс изменяется наиболее часто, а в
Fortran этим свойством обладает самый левый индекс. В массиве из массивов
столбцы располагаются последовательно: за строка 1-столбец 1 следует
строка 1-столбец 2, и т.д. В многомерном массиве строки располагаются
последовательно: за строка 1-столбец 1 следует строка 2-столбец 1, и т.д.
Заметим также, что индексы всех массивов Cи начинаются с 0. Мы не рекомендуем
вам использовать в качестве нижней границы измерения значение, отличное от
нуля (0), так как тогда ваш Си-код должен будет модифицировать индексы,
основанные на этом значении. И настоятельно рекомендуем не использовать
отрицательных нижних и верхних границ!
Если границы индексов не известны во время компиляции, они могут передаваться
во время исполнения, но вы должны обеспечить код преобразования индексов для
получения нужных компонент массива.
Рассмотрим пример, поясняющий разницу между массивами. Пусть код на Fortran
выглядит так:
subroutine test(real_array)
real :: real_array(0:4,0:5,0:6,0:7,0:8,0:9,0:10)
integer :: i,j,k,l,m,n,o
do o = 0, 10
do n = 0, 9
do m = 0, 8
do l = 0, 7
do k = 0, 6
do j = 0, 5
do i = 0, 4
real_array(i,j,k,l,m,n,o) = 12.00
end do
end do
end do
end do
end do
end do
end do
end subroutine test
Эквивалентный код на Си будет выглядеть так:
void test(float real_array[10][9][8][7][6][5][4])
int i,j,k,l,m,n,o;
/*
** так индексы выглядят со стороны Cи
*/
for(o = 0; o < 11; o++)
for(n = 0; n < 10; n++)
for(m = 0; m < 9; m++)
for(l = 0; l < 8; l++)
for(k = 0; k < 7; k++)
for(j = 0; j < 6; j++)
for(i = 0; i < 5; i++)
real_array[o][n][m][l][k][j][i] = 12.000;
return;
}
На Fortran-стороне вызова аргумент-массив не должен объявляться как массив
предполагаемой формы. Вы должны использовать явную форму, предполагаемый
размер или настраиваемый массив.
В начало страницы
Символьные аргументы передаются как указатели на цепочки. Если программная
единица Fortran содержит фиктивные аргументы типа character, то каждая
процедура, обращающаяся к этой программной единице, должна добавлять к концу
списка аргументов длину каждого из соответствующих фактических аргументов
типа character. Длина должна передаваться в Fortran по значению как
четырехбайтовое целое.
Например, подрутина Fortran:
subroutine example3 (int1, char1, int2, char2)
integer int1, int2
character (len=*) :: char1
character (len=25) :: char2
end
соответствует такому прототипу в Cи:
void example3 (long int *int1, \
char *char1, \
long int *int2, \
char *char2, \
long int char1_len);
При передаче цепочки символов из Fortran в Cи Fortran будет по умолчанию
добавлять "скрытое" целое значение, представляющее длину цепочки, в конец
списка аргументов. Это целое передается по значению. Если передается более
одной символьной цепочки, значения длин появляются в том же порядке, что и
сами цепочки, в конце списка аргументов. Чтобы предотвратить это добавление
длин, применяйте встроенную CARG() или комбинируйте встроенные VAL(OFFSET()),
тогда передается только указатель на цепочку.
Кроме того, Cи требует NULL terminator (т.е., CHAR(0), байт с нулевым
значением) в конце символьной цепочки, необходимый для ее обработки. LF95
не вырабатывает этот байт; его нужно добавлять к символьному литералу или
символьной переменной до передачи в Cи. Нужно сказать также, что Fortran
дополняет конец цепочки пробелами, доводя ее длину до объявленной. Если такое
расширение нежелательно, пробелы надо удалить с помощью встроенной процедуры
TRIM() и затем добавить в конец NULL перед передачей в Cи.
Пример: Передача переменных и констант типа Character из Fortran в Cи.
Следующая программа на Fortran:
program strtest
character*20 mystr
mystr = 'abcde'
call sub(mystr)
call sub('abcde'//char(0))
call sub2(carg(trim(mystr)//char(0)))
call sub2(val(offset(mystr)))
call sub2(carg('abcde'//char(0)))
end
и следующая подрутина на Си
void sub_(str1,i)
char *str1;
long int i;
{
printf("hidden length = %i\n",i);
printf("%sHi!\n",str1);
}
void sub2_(str1)
char *str1;
{
printf("%sEnd.\n",str1);
}
производят следующий вывод:
hidden length = 20
abcde Hi!
hidden length = 6
abcdeHi!
abcdeEnd.
abcde End.
abcdeEnd.
Пример: Передача переменных String из Cи в Fortran
Следующая функция Fortran имеет символьный фиктивный аргумент подразумеваемой
длины и возвращает символьный результат подразумеваемой длины:
function MYFUNC(str1, str2)
character(len=*) :: str1, str2, myfunc
myfunc = str1//str2//char(0)
return
end
Когда она вызывается из следующей программы на Си:
void myfunc_(char *str1, int i, char *str2, \
char *str3, int j, int k);
MAIN__()
{/* Leave space for NULL in character declarations */
char res[10], ch[4], msg[7];
strcpy(ch, "Hi ");
strcpy(msg, "there!");
myfunc_(res, 10, ch, msg, 3, 6);
printf("Result received by C: %s\n", res);
}
то генерируется следующий вывод:
Result received by C: Hi there!
При вызове MYFUNC из Cи первый и второй аргументы есть соответственно значение
и длина результата, возвращаемого из MYFUNC. Два последние аргумента есть
длины символьных аргументов, переданных в MYFUNC.
В начало страницы
На переменные в блоках Fortran common можно ссылаться как на члены структур
Cи.
Пример: именованный Common
В следующей Fortran-программе переменные в блоке common "ext"
common /ext/ i, j
i = 1
j = 2
call sub()
end
доступны посредством функции Си следующим способом:
extern struct tab {
int i, j;
} ext_;
void sub_()
{printf("i=%i j=%i\n", ext_.i, ext_.j);
}
Пример: безымянный Common
Передача данных через безымянный common реализуется тем же способом, как и
в предыдущем примере, за исключением того, что имя ext_ заменяется на _BLNK_.
Управление в программе: main() and MAIN__()
Если старший уровень управления в программе со смешанными языками принадлежит
системе, отличной от Fortran (т.е., управление сначала передается
в не Фортрановскую часть программы), процедуре старшего уровня должно быть
дано имя MAIN__(). Ей нельзя давать имя main(), так как оно зарезервировано
для запуска и инициализации окружения Fortran времени исполнения.
Пример: Управление сначала передается в программу на Си
Следующая Cи-программа вызывает Fortran-подрутину SUB() и затем кончает
работу.
void sub_();
MAIN__()
{sub_();
}
В начало страницы
При вызове функций из ядра Linux и стандартных библиотек Cи,
необходимо применять оператор ML_EXTERNAL к имени функции и компилировать
с параметром компилятора --ml.
Пример: вызов функции из ядра Linux.
Следующая программа Fortran иллюстрирует вызов стандартной функции usleep().
program callsys
ml_external usleep
write(*,*) 'Going to sleep...'
! сон на 10 секунд
call usleep(10000000)
write (*,*) ' Wake up!'
end program
Эта программа должна быть скомпилирована использованием командной строки
lf95 callsys.f90 --ml cdecl
В начало страницы
Если вы передаете на другую машину приложения, построенные с совместными
библиотеками LF95, вы должны передать на нее построенные вами библиотеки и
также все другие, необходимые при исполнении LF95 (если LF95 уже не
установлена на целевой машине). Все библиотеки должны быть доступны на
LD_LIBRARY_PATH. Можно использовать команду Linux ldd, чтобы найти, какие
из совместных библиотек требуются для некоторого приложения.
Можно избежать необходимость передачи библиотек времени исполнения, компилируя
с параметром --staticlink, что приведет к статической привязке исполнительных
библиотек к исполнимой программе (см. "--[n]staticlink" на стр. 25).
Заметим, что прикладные программы должны исполняться на машинах с ядром
Linux той же самой или более поздней версии, что и ядро Linux на
машине, на которой приложение было создано. Другими словами, программа,
построенная на машине, использующей kernel 2.2.5, не будет правильно
исполняться на машине, использующей kernel 2.0.36.
В начало страницы
OpenGL есть программный интерфейс для прикладных программ, позволяющий
генерировать компьютерную графику 2D и 3D независимо от операционной системы и
аппаратных операций. Он состоит в основном из графической библиотеки 2D/3D,
которая первоначально была разработана в Silicon Graphics с целью создать
эффективный, не зависящий от платформы интерфейс для графических
приложений (Заметим: OpenGL есть торговая марка корпорации Silicon Graphics).
Он доступен на многих системах Win32, Linux и Unix ms, и хорош (strong) для
визуализации и анимации на 3D
f90gl есть бесплатная (public domain) реализация официальной Fortran 90
привязки (bindings) для OpenGL, состоящая из набора библиотек и модулей,
которые определяют функциональные интерфейсы. Полный набор демонстрационных
программ можно загрузить с сайта Lahey web. Интерфейс f90gl был разработан
William F. Mitchell из Математического и Вычислительного подразделения
национального института стандартов и технологий, Gaithersburg, MD, в USA.
По поводу информации о f90gl см. f90gl web page в http://math.nist.gov/f90gl.
В начало страницы
Если файл lf95.fig есть в текущем каталоге, обследуйте его содержимое, чтобы
убедиться, что он содержит желаемые параметры.
Для отладки мы рекомендуем следующую установку параметров:
--ap --chkglobal --f95 -g --lst --pca --sav --trace --info --xref
Для получения кода рекомендуется следующая установка:
--nap --nchk --ng -O --npca --nsav --ntrace
Также используйте --t4, --tp или --tpp в зависимости от предпочитаемого
целевого процессора. Заметим, что код, скомпилированный с --tpp, может
исполняться только на Pentium Pro или более новых совместимых чипах.
Если оптимизация (параметр -O) дает радикально отличные результаты или
приводит к ошибкам исполнения, попробуйте компилировать с --info, чтобы
увидеть точно, какие шаги предприняты при оптимизации. Параметр --info также
генерирует предупреждения о частях кодов, которые неустойчивы и тем самым
могут привести к проблемам при оптимизации. Обычным примером такого кода
может служить оператор IF, который проверяет на равенство переменные с
плавающей точкой.