[ Обзор C/C++ компиляторов EMX и Watcom ]
<<< 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. объявила
о прекращении продаж и установила крайний срок, после которого будет прекращена и техническая поддержка для тех, кто
еще успел купить компилятор (это было в середине 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 хоть и содержит различные
оптимизации для базовой платформы, но про особенности конкретных процессоров современности (а это кроме различных
вариантов Pentium еще и Cyrix, AMD, все сильно отличающиеся друг от друга по тому, как надо для них оптимизировать)
знает крайне мало. Цель проекта PGCC — научить GCC генерировать программы, выжимающие максимум из процессора. (PGCC —
это набор “патчей” к GCC). Последний 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, крайне примитивен, да и порой просто не работает. То же самое с profiling (поддержка заявлена, но виснет
намертво, до reset). Проблемы могут явиться сами собой. Короче говоря, будьте готовы к возникновению странных проблем
и к дубовой отладке. Компиляторы 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! Не говоря о
многих других программах меньшего размера.