Командная строка компилятора
Пример 11.1. Командная строка компилятора
ее main.С c-code.c asm-code.s obj-code.o\ libraryl.a Iibrary2.so -o program
Например, стандартный драйвер компилятора в системах семейства Unix — программа со — определяет тип файла именно по расширению. Командная строка, приведенная в примере 11.1, будет интерпретироваться следующим образом.
- main.С — текст на языке C++. Его нужно обработать препроцессором и откомпилировать компилятором C++, а затем передать то, что получится, редактору связей. Большинство компиляторов в Unix генерируют код на ассемблере, т. е. вывод компилятора еще нужно пропустить через ассемблер.
- c-code.c — текст на языке С. Он обрабатывается так же, как и программа на С ++, только вместо компилятора C++ используется компилятор С.
- asm-code.s — программа на языке ассемблера. Ее нужно обработать ассемблером и получить объектный модуль.
- obj-code.o — объектный модуль, который непосредственно можно передавать редактору связей.
- library1.a — объектная библиотека, которую нужно использовать для разрешения внешних ссылок наравне со стандартными библиотеками.
- library2.so — разделяемая библиотека, которую надо связать с создаваемым динамическим модулем.
Многие ОС, разработанные в 70-е годы, такие как RT-11, RSX-11, VAX/VMS, CP/M, навязывают программисту разделение имени на собственно имя и расширение, интерпретируя точку в имени файла как знак препинания. В таких системах имя может содержать только одну точку и соответственно иметь только одно расширение. Напротив, в ОС нового поколения — OS/2, Windows NT и даже в Windows 95 — реализована поддержка имен файлов свободного формата, которые могут иметь несколько каскадированных расширений, как и в Unix.
Однако никакие средства операционной системы не могут навязать прикладным программам правил выбора расширения для файлов данных. Это приводит к неприятным коллизиям. Например, почти все текстовые процессоры от Лексикона до Word 2000 включительно используют расширение Файла .doc (сокращение от document), хотя форматы файлов у различных процессоров и даже у разных версий одного процессора сильно различаются.
Другая проблема связана с исполняемыми загрузочными модулями. Обычно система использует определенное расширение для исполняемых файлов.
Так, VMS и системы семейства СР/М используют расширение .ехе: сокращение от executable (исполняемый). Однако по мере развития системы формат загрузочного модуля может изменяться. Так, например, OS/2 v3.0 поддерживает по крайней мере шесть различных форматов загрузочных модулей.
- 16-разрядные сегментированные загрузочные модули: формат OS/2 х
- 32-разрядные загрузочные модули, использующие "плоскую" (flat) модец, памяти: формат OS/2 2.x (LE — Linear Executable).
- 32-разрядные модули нового формата, использующие упаковку кода данных: формат OS/2 3.x (LX — Linear executable extended).
- ехе- и corn-модули DOS.
- Загрузочные модули Win 16 (NE).
- Загрузочные модули Win32s (РЕ — Portable Executable).
Для исполнения последних трех типов программ OS/2 создает виртуальную машину, работающую в режиме совместимости с 8086. Эта задача запускает копию ядра DOS и, если это необходимо, копию MS Windows, которые уже выполняют загрузку программы. Загрузочные модули всех трех "родных" форматов загружаются системой непосредственно. Так или иначе, загрузчик должен уметь правильно распознавать все форматы. При этом он не может использовать расширение файла: файлы всех перечисленных форматов имеют одинаковое расширение ЕХЕ.
Похожая ситуация имеет место в системах семейства Unix, где бинарные загрузочные модули и командные файлы вообще не имеют расширения. При этом большинство современных версий системы также поддерживает несколько различных исторически сложившихся форматов загрузочного модуля.
Разработчики Unix столкнулись с этой проблемой еще в 70-е годы. В качестве решения они предложили использовать магические числа (magic number) или сигнатуры (signature— подпись) — соглашение о том, что файлы определенного формата содержат в начале определенный байт или последовательность байтов. Первоначально это были численные коды; файл /etc/magic содержал коды, соответствующие известным типам файлов. Позднее в качестве магических чисел стали использоваться длинные текстовые строки. Так, например, изображения в формате CompuServe GIF 87а должны начинаться с символов GIF87a.
Легко понять, что магические числа ничуть не лучше расширении, а во многих отношениях даже хуже. Например, пользователь, просмотрев содержимое каталога, не может сразу узнать типы содержащихся в нем файлов. Еще хуже ситуация, когда расширение файла не соответствует его реальному типу. Это будет вводить в заблуждение не только пользователя, но и некоторые программы, полагающиеся при определении формата на расширение вместо магического числа.
С длинными мнемоническими текстовыми строками связана еще одна забавная проблема, которая может иметь неприятные последствия. Например-текстовый файл следующего содержания:
GIF87a — это очень плохой формат хранения изображений. Он будет воспринят некоторыми программами как изображение в формате CompuServe (GIF 87а, каковым он, безусловно, не является.
Оригинальное развитие идея магических чисел получила в современных системах семейства Unix, где сигнатура вида #!/bin/sh означает, что данный файл представляет собой интерпретируемую программу, интерпретатор которой хранится в файле /bin/sh (в данном случае это стандартный командный процессор).
Пытаясь как-то решить проблему идентификации типа файла, разработчики Macintoch отказались как от расширений, так и от магических чисел. В MacOS каждый файл состоит из двух частей или ветвей (forks): ветви данных (data fork) и ветви ресурсов (resource fork). Кроме идентификатора типа файла, ветвь ресурсов хранит информацию о:
- значке, связанном с этим файлом;
- расположении значка в открытой папке (folder);
- программе, которую нужно запустить при "открытии" этого файла.
Еще дальше в этом же направлении пошли разработчики системы OS/2. В этой системе с каждым файлом связан набор расширенных атрибутов (extended attributes). Атрибуты имеют вид "ИМЯ:Значение". При этом значение может быть как текстовой строкой, так и блоком двоичных данных произвольного формата и размера. Некоторые расширенные атрибуты используются оболочкой Workplace Shell (WPS) как эквивалент ветви ресурсов в MacOS: для идентификации типа файла, связанного с ним значка и размещения этого значка в открытом окне. Тип файла идентифицируется текстовой строкой. Например, программа на языке С идентифицируется строкой С code. Это резко уменьшает вероятность конфликта имен типов — ситуацию, довольно часто возникающую при использовании расширений или магических чисел.
Другие атрибуты могут применяться для других целей. Например, LAN Server — файловый сервер фирмы IBM — использует расширенные атрибуты для хранения информации о владельце файла и правах доступа к нему. Некоторые текстовые редакторы применяют расширенные атрибуты для хранения положения курсора при завершении последней сессии редактирования, так что пользователь всегда попадает в то место, где он остановился в прошлый раз.
Кроме того, расширенные атрибуты могут использоваться и для хранения сведений о назначении файла. В OS/2 существуют предопределенные расширенные атрибуты с именами subject (тема), comment (комментарии) и Key phrases (ключевые фразы), которые могут, например, использоваться для поиска документов, относящихся к заданной теме. К сожалению, такой поиск возможен, только если создатель документа позаботился о присвое нии этим атрибутам правильных значений.