|
|
C/C++ Visual C++ >Статьи
Обзор C/C++ компиляторов EMX и Watcom
В предлагаемой статье описывается мое
видение некоторых компиляторов С/C++ под OS/2. Должен сразу оговориться,
что не претендую ни на полноту изложения, ни на энциклопедическую
точность; это, скорее, просто ощущения и впечатления, разбавленные
общеизвестными фактами, а где-то и наоборот. Где-то изложение может
показаться претенциозным, но это во всяком случае не нарочно - больше от
вероятного незнания мной некоторых фактов.
Watcom C/C++
Watcom - звезда прошлого. Основные черты -
многоплатформенность и качество кода. В лучшие времена генерировал код
для DOS real mode, DOS protected mode (DOS/4G, DOS/4GW, Phar Lap),
Win16, Win32, Win32s, QNX, OS/2 (16- & 32-bit), Netware NLM. Причем,
работая под любой системой, можно было генерировать код для всех
остальных (к примеру, программу под Win32 можно было скомпилировать и
слинковать из-под OS/2 и т.д.). Watcom стал весьма популярен во времена
DOS-игр, работающих в защищенном режиме (DOOM и пр.).
К моменту появления версии 11.0 (1997 г.)
фирма, разрабатывавшая Watcom, была куплена Sybase Inc., и это, к
сожалению, возвестило о кончине компилятора. Дальнейшая разработка была
практически заморожена, а в 1999 г. Sybase Inc. объявила о прекращении
продаж и установила крайний срок, после которого будет прекращена и
техническая поддержка для тех, кто еще успел купить компилятор (это было
30 июня 2000 г.). Дальнейшая судьба продукта пока неизвестна.
Последняя версия - 11.0B. C++ компилятор в
ней не поддерживает namespaces и не содержит STL. Впрочем, существуют
многие реализации STL, поддерживающие Watcom C++ (к примеру,
STLPort ).
Под любую поддерживаемую систему есть набор
стандартных утилит: компиляторы, линкер, отладчик(и), make, lib, strip и
пр. В системах с GUI (OS/2, Windows) есть также IDE (хотя и не очень
удобная).
Кодогенерация застыла на уровне 1997 г., и
теперь даже MS Visual C++ обгоняет Watcom (естественно, сравнения
проводились под Windows, но некоторое представление это дать может).
При работе с Watcom C++ под OS/2 нужно знать
следующее:
-
В версиях 11.0* в линкере есть досадная
ошибка, и вызовы 16-разрядных функций OS/2 (Vio*, Kbd*, Mou* и др.)
будут давать трапы. Для борьбы с этим предназначена утилита LXFix,
которая запускается после линкера и исправляет fixups.
-
В комплект входит весьма древний OS/2
Toolkit (от OS/2 2.x). Поэтому крайне рекомендуется установить Toolkit
из последних (4.0, 4.5).
-
Кроме разработки "родных" OS/2-программ,
Watcom C/C++ можно рекомендовать для компиляции кода, слабо
привязанного к ОС. Наличие в стандартной библиотеке функций вроде
_dos_setdrive(), поддерживаемых под всеми системами (ну, или как
минимум под OS/2, Win32 и DOS) позволяет писать в этом смысле
платформонезависимо (для пользовательского интерфейса в данном случае
можно использовать Turbo Vision).
И напоследок стоит еще раз напомнить про то,
что компилятор более не развивается и не поддерживается. Имеющиеся
проблемы никуда не денутся и не будут теперь решены.
Ссылки:
EMX (GNU C/C++)
EMX - представительство Unix в OS/2 и одно
из представительств Unix в DOS. Это целый комплект из компиляторов,
сопутствующих утилит и библиотек поддержки. В первую очередь
предназначен для портирования программ из среды Unix в OS/2, для чего
эмулирует множество функций в "первозданном" виде, включая даже и
fork(). Основывается на одном из наибольших достижений мира бесплатных
программ - системе компиляторов GCC (gcc означает "GNU Compiler
Collection"). GCC состоит из собственно трансляторов с языков
программирования (в настоящее время это C, C++, Objective C, Fortran 77,
Chill и Java, хотя ничто не мешает встроить в систему свой язык),
превращающих исходный код в программу на внутреннем языке компилятора
(он называется RTL - Register Transfer Language) и стартующих уже от
представления на RTL генераторов машинного кода для различных платформ.
В частности, поддерживается и нужная нам платформа i386.
Сам EMX является портом GCC под OS/2 / DOS и
содержит измененные версии компиляторов, линкера, отладчика gdb и многих
других программ; стандартную библиотеку C, содержащую множество функций
из мира Unix; DLL поддержки и многое другое. Кроме того, с помощью EMX
под OS/2 были скомпилированы многие другие Unix-программы, к примеру GNU
Make, который обязательно понадобится при мало-мальски серьезной
разработке.
Кроме всего прочего, EMX позволяет создавать
"родные" программы для OS/2, используя OS/2 API. Можно также
использовать в программах одновременно и "родные", и "заимствованные"
функции.
Программы же, не использующие OS/2 API и
некоторых функций Unix, будут "контрабандой" работать и из-под голого
DOS во flat mode (в комплекте с EMX поставляется DOS-расширитель). К
тому же, и под Windows есть расширитель rsx.exe, позволяющий запускать
файлы в формате a.out, сгенерированные EMX!
Но сам GCC родом из мира Unix, и поэтому EMX
также привносит с собой кое-что оттуда. Вот основные моменты:
-
Прямой слэш ('/'). Как известно, в Unix
для разделения каталогов в файловом пути вместо обратных слэшей
используются прямые. Нет, все стандартные функции (open(), fopen() и
др.) понимают оба варианта, но вот при указании файлов и путей
компилятору придется использовать прямые. (Не пугайтесь,
c:/aaa/bbb/ccc это нормально :-)
-
Нестандартные форматы файлов. Да,
объектные файлы имеют расширение .o и формат a.out, отличный от
привычных .obj-файлов. То же самое верно и для файлов объектных
библиотек (.a в сравнении с .lib). И даже исполняемые файлы фактически
являются файлами формата a.out, содержащими пришпиленный в начале
LX-загрузчик.
Но это еще не все. Существует возможность
делать и .obj файлы, и нормальные LX .exe (для этого вызываются
всяческие конверторы и на финальном этапе link386). Все эти
многочисленные варианты (еще отметим широкие возможности по созданию
различных типов DLL) разнятся предоставляемыми возможностями. К
примеру, если работать с .obj и LX .exe, то программа не будет
запускаться под DOS и ее нельзя будет отлаживать. Если к тому же
выбрать статическую линковку, то еще и список поддерживаемых функций
уменьшится. В общем, есть простор для экспериментирования (хотя
наиболее часто используемый вариант - a.out формат исполняемого файла
+ динамическая линковка с EMX runtime).
-
Расширения C, C++. Не будем их здесь
перечислять, отметим лишь, что они есть и что их применение делает
программу непереносимой.
-
Компиляция всегда идет через ассемблер.
Т.е. кодогенераторы генерируют лишь ассемблерный текст и переваливают
проблему на плечи ассемблера. Не стоит пугаться, с ней он справляется
весьма быстро. К тому же, существуют возможности:
-
всем частям компилятора общаться друг
между другом с помощью pipes (выход препроцессора поступает сразу на
вход компилятору, а выход последнего ассемблеру) и обойтись без
временных файлов.
-
всем частям компилятора висеть некоторое
время в памяти после последнего обращения и тем самым экономить
время на их запуске.
-
Нестандартная библиотека. Работавшие с
какими-либо другими компиляторами могут не найти привычных функций,
зато могут найти множество других, доселе неизвестных. :-) Но основное
отличие EMX от остальных - это объединение хендлов файлов и сокетов в
одну группу. К примеру, используя EMX, не нужно вызывать sock_init(),
можно использовать read() и write(), а задачу soclose() выполняет
обычный close(). Кроме этого, функция select(), работающая в IBM
TCP/IP только для сокетов, в EMX расширена до поддержки любых хендлов,
как и полагается в Unix'e. :-)
Как уже отмечалось выше, GCC
распространяется под лицензией GNU. Разработка GCC, инициированная
где-то в конце 80-х гг. - начале 90-х гг., поначалу велась командой
разработчиков, возглавлявшейся идеологом GNU Ричардом М. Столлменом
(rms); в 1996 г. ими была выпущена версия 2.7.2.1 и затем
экспериментальная версия 2.8.1. Если поддержка C в последней была на
уровне ANSI C + расширения (см. выше), то ситуация с C++ была тяжелой; к
тому же, разработка фактически остановилась. Но еще до выпуска 2.8.1 за
развитие GCC взялась фирма Cygnus, особенно направив свои усилия на
выправление ситуации с C++ (к тому времени до принятия стандарта C++
оставалось не так уж и много). Эта фирма выпустила несколько версий EGCS
(Enhanced GNU Compiler Suite), после чего Столлмен и компания решили и
вовсе их благословить. Развитие версии 2.8.1, содержавшей кучу ошибок в
реализации C++, было заброшено, последняя к тому времени версия EGCS
автоматически превратилась в последнюю версию GCC (2.95), а развитие GCC
фактически продолжилось командой из Cygnus. Последняя выпущенная ими
версия - 2.95.2, это случилось 27 октября 1999 г. (А сама Cygnus не так
давно была приобретена небезызвестной компанией Red Hat Inc.)
Последняя версия GCC довольно близка к
стандарту, поддерживает все последние добавления к C++ (вроде namespace)
и включает в себя также реализацию STL от SGI (она включена в libstdc++,
последняя версия 2.90.8). STL из libstdc++ близка к стандарту, но
iostreams там все еще не template-based, а взяты из совсем старой
libg++. Впрочем, можно опять же обратиться к
STLport , она поддерживает и GCC.
Таково состояние GCC на сегодняшний момент.
Однако, использовать GCC под OS/2 означает использовать EMX, последняя
версия которого (v0.9d) включает в себя старый GCC 2.8.1. Но все не так
плохо. Ибо есть еще проект под названием PGCC, суть Pentium-optimized
GCC. Сам GCC хоть и содержит различные оптимизации для базовой платформы
i386, но про особенности конкретных процессоров современности (а это
кроме различных вариантов Pentium еще и Cyrix, AMD, все сильно
отличающиеся друг от друга по тому, как надо для них оптимизировать)
знает крайне мало. Цель проекта PGCC - научить GCC генерировать
программы, выжимающие максимум из процессора. (PGCC - это набор "патчей"
к GCC). А что самое приятное, в команде PGCC есть Андрей Заболотный
(автор lxlite), кроме всего прочего компилирующий релизы PGCC для OS/2.
Последний PGCC - 2.95.3, основан на GCC 2.95.2. Оптимизация для
конкретного процессора производится при указании определенного ключа в
командной строке, так что если его не указывать, то мы получаем
"честный" GCC 2.95.2, со всеми его прелестями.
А теперь о прелестях применительно к OS/2.
Сам компилятор версии 2.95.2 уже вполне неплох. Он параноидален в духе
последнего стандарта (по моим субъективным ощущениям предупреждений об
ошибках в сравнении с версией EGCS 1.1.2 стало раза в два больше), не
падает, генерирует приемлемый код. Смелые могут даже поставить ключ
'-O6' и попробовать оптимизацию под Pentium (здесь имеется в виду PGCC).
Но про нормальную отладку PM-приложений можно сразу же забыть.
Нацеленный на это PMGDB, входящий в состав EMX, крайне примитивен, да и
порой просто не работает (у меня на Авроре при выходе попросту виснет и
приходится срубать его по kill -9). То же самое с profiling (поддержка
заявлена, но опять же на Авроре виснет намертво, до reset). EMX runtime
версии до 0.9d FIX 2 не работал на Авроре, а равно и любая программа,
его использовавшая. Проблемы могут явиться сами собой (к примеру, у меня
PrfOpenProfile("test.ini", ...) давал трап до тех пор, пока через пару
месяцев не догадался поставить ключ '-fwritable-strings'). Короче
говоря, будьте готовы к возникновению странных проблем и к дубовой
отладке.
Компиляторы GCC (C и C++), как уже
говорилось выше, можно рекомендовать для переноса программ из Unix под
OS/2. Впрочем, как раз в этой области весьма мало вариантов, если не
сказать, что как раз один. Можно наоборот, с помощью EMX разрабатывать
программы, которые потом будут работать под Unix. Правда, к сожалению,
многие функции не поддерживаются EMX. Как минимум, нет очередей
сообщений, семафоров, shared memory (ни BSD, ни POSIX). Здесь стоит
также заметить, что порты GCC существуют и под win32, и под DOS (а еще
вспомним про возможность запуска a.out-программ, сделанных EMX, под DOS
и win32!), так что теоретически с помощью EMX можно писать программы,
которые будут компилироваться и работать под OS/2, Unix, DOS и Windows.
Главное же достоинство EMX - он абсолютно
бесплатен и доступен в исходных текстах. А если вы не верите, что он
работает, вот доказательство: такая большая вещь, как XFree86,
компилируется с помощью EMX и работает под OS/2! Не говоря о многих
других программах меньшего размера.
Ссылки:
|