unix.port

win32 завоевывает UNIX\\ или портили, портили и спортили

крис касперски ака мыщъх, no email

задачи, решаемые с помощью компьютера, нередко самим компьютером и порождаются.

Пол Грэм

последнее время много говорят о переносе UNIX программ на Windows. только так, и никак не наоборот. но ведь существует большое количество Windows-программ, аналога которых на других платформах нет (прежде всего, это ваши собственные программы). стоит ли их переносить на UNIX и если да, то как?

Абсолютного переносимого программного обеспечения не существует, как не существует абсолютного нуля. Понятие «переносимости» еще не означает, что портирование сводится к простой перекомпиляции. Всегда требуется дополнительные усилия по его адаптации. Иногда трудозатраты [эти усилия]настолько значительны, что проще переписать программу с нуля, чем гонять ее между платформами. Системно-ориентированные пакеты (FAR, soft-ice) переносить вообще бессмысленно, – это все равно, что вешать сруль на гусеничный трактор (ну не срулья, так чебурашку!).

В любом случае, вы должны полностью разобраться в исходных текстах, которые переносите. При доминирующем стиле кодирования интерфейс программы перемешан с «вычислительной» частью (спасибо визуальными средам разработки!), и разделить их не проще чем сиамских близнецов (но разделять все же придется, потому что интерфейс в UNIX очень сильно другой). Типичный код нашпигован большим количеством системно-зависимых функций – вместо стандартных библиотечных функций преобладают вызовы API и MFC. Активно используется ассемблерные вставки и повсеместно – умолчания компилятора. Это в Багдаде char по умолчанию unsigned, но в других компиляторах он ведет себя совсем не так! Про «умолчанную» кратность выравнивая структур я и вовсе молчу. Хуже этого только нестандартные расширения компилятора и специфические особенности его поведения. Большинство программ, созданных современными «программистами», не компилируются MS VC, если написаны на BCC и, соответственно, наоборот. До переноса на UNIX им так же далеко, как их авторам до звания «программиста» (необязательно даже «почетного программиста», можно просто «стажера», путающего язык со средой разработки).

Считается, что перенос сокращает издержки на развитие и сопровождение проекта. Имея независимые версии для Windows и UNIX, вы вынуждены вносить исправления и гонять багов в обоих программах одновременно. Портабельный код этих недостатков лишен. Якобы. Скажите, когда-нибудь вы пробовали писать программу, компилируемую более, чем одним компилятором? Матерились при этом? И правильно! Я бы тоже заматерился. Ограничения, налагаемые переносимым кодом, лишают нас многих «вкусностей» языка и значительно увеличивают трудоемкость разработки. Допустим, вы используете шаблоны (templates) и на MS VC все работает, но при переходе на другой компилятор программа разваливается к черту. А некоторые компиляторы не инициализируют статические экземпляры класса. Ну не инициализируют и все тут! Забудьте о стандартах. Компиляторы все равно их не придерживаются. Чем же тогда руководствоваться? А ничем! Это уж как повезет/не повезет.

При каждом внесении изменений в программу, прогоняйте ее через все целевые компиляторы. Код, специфичный для данной платформы, заботливо окружайте #ifdef или выносите в отельный файл, ну и т. д. В конечном счете, вы получите все те же два независимых проекта, но тесно переплетенные друг с другом, причем, внесение изменений в один из них дает непредсказуемый эффект в другом. Нет-нет, не подумайте! Я вовсе не противник переносимого кода, просто, не понимаю тех, для кого переносимость цель, а не средство. Никто не спорит, что такие проекты как Apache или GCC должны изначально разрабатываться как переносимые (процент системного-независимого кода в них очень велик), но вот мелкую утварь типа почтового клиента лучше затачивать под индивидуальную платформу, а при переходе на UNIX переписывать заново.

Если нужно быстро перенести программу – воспользуйтесь WINE или Willows. Это бесплатно распространяемые имитаторы Windows, оборачивающие UNIX-функции толстым слоем переходного кода, реализующего win32 API и работающие на: Windows 9x/NT/2000/XP, Linux, Free BSD, Solaris, а Willows еще и на QNX (есть такой клон UNIX, управляющий истребителями, атомными реакторами и прочими mission-critical системами, кстати говоря, бесплатный и свободно умещающийся на одной дискетке).

Обратите внимание: не эмуляторы, а именно имитаторы (WINE именно так и расшифровывается: «Wine Is Not Emulator« –это вам не эмулятор). Портируемая программа исполняется на «живом» процессоре, практически не теряя в скорости. Во всяком случае, реклама говорит именно так. А что реальная жизнь? При всей схожести между UNIX и Windows NT (их ядра наследуют общий набор концепций), они во многом различны. В UNIX есть замечательная функция fork, расщепляющая процесс напополам. В NT ее нет. CreateProcess/CreateThread – это фуфло. И вот почему. Накладные расходы на расщепление процесса fork'ом ничтожны, чего нельзя сказать о создании процесса/потока с нуля. Кстати говоря, с потоками в LINUX сплошной напряг (внутреннее потоки представляют те же процессы, но только с «извращениями»). Всегда заменяйте CreateThread на fork, когда это только возможно (процессы, в отличии от потоков исполняются в различных адресных пространствах и могут обмениваться данными только через IPC, например, проецируемые в память файлы). К тому же, средства синхронизации потоков в Windows и UNIX очень различны, а в LINUX синхронизация не поддерживается вовсе и реализуется внешними библиотеками. Все это делает отображение win32 API на UNIX-функции неоднозначным и выбор предпочтительного системного вызова в каждом конкретном случае должен определяется индивидуально. Человеком. Имитатор на это не способен и падения производительности не избежать (другое дело, что при современных аппаратных мощностях на производительность можно покласть).

Конструктивно большинство имитаторов состоят из двух основных компонентов: бинарного интерфейса (Binary Interface) и библиотеки разработчика (Library). Некоторые имитаторы (например, Willows) включают еще и уровень абстрагирования от платформы (Platform-abstraction Layer), что упрощает их перенос на другие системы, но это уже детали реализации.

Бинарный интерфейс включает в себя win32-загрузчик, «переваривающий» PE-файлы и в максимальной точностью воссоздающий привычное для них окружение. Необходимость в перекомпиляции при этом отпадает, однако, совместимость остается на уровне слабого подобия левой руки. Реально удается запустить лишь небольшое количество офисных приложений типа Office, Acrobat, Photoshop и т. д. Системные утилиты скорее всего откажут в работе и тут на помощь приходит библиотека – заголовочные файлы полюс lib-файл. Адоптировав приложение, мы может компилировать его как в ELF (тогда необходимость иметь на машине установленный имитатор отпадает), либо в PE. Красота! (что такое красота? это женщина, использующая банан не по назначению).

В крайнем случае, можно воспользоваться полноценным эмулятором PC – VMWare или Win4Lin, однако, полезность этого решения сомнительна. Дело даже не в аппаратных требованиях (я вполне успешно гоняю VMWare на P-III 733), а удобстве использования (точнее, его отсутствии). Достаточно сказать, что обмениваться данными с эмулятором придется через виртуальную локальную сеть, гоняя их в обе стороны в хвост и в гриву.

тута дожна быть картина, но ее нет, патаму что тяжелая сволочь, просьба скачать самостоятельно http://www.winehq.org/images/shots/full/wine_11.png

Рисунок 1 Windows-приложение, запущенное под WINE

Для переноса игр и других графических приложений лучше всего подходит WineX, в настоящее время переименованный в Cedega, – коммерческая версия имитатора WINE от компании Transgaming, ориентированная на DirectX, Direct3D, Open GL и прочие технологии этого уровня. Работает в Linux, Mac, PlayStation 2, XBoxи Next Gen. Хотите «поквакать» (Word почему-то упорно предлагает заменить это слово на «покакать») в LINUX? Нет проблем! А еще можно «подумать» или погонять в Need-of-Speed. Список поддерживаемых игр очень велик и счет идет на тысячи наименований.

unix.port_image_0.jpg

Рисунок 2QUAKE 3 на LINUX

Копания Mainsoft (та самая у которой свистнули исходные тексты Windows 2000) выпустила замечательный продукт Visual MainWin, позволяющий писать код в Microsoft Visual Studio и тут же компилировать его под разные платформы (Windows, LINUX, HP-UP, AXI, Solaris), причем количество поддерживаемых платформ планомерно растет.

Пакет состоит из нескольких частей – это и инспектор кода, позволяющий обнаружить системно-зависимые участки (пускай программист сам решает как он будет их исправлять!), и препроцессор, подготавливающий исходный код к последующей трансляции GCC (или любым другим UNIX-компилятором), и конечно же обширная библиотека функций, реализующая: а) Windows-примитивы (SEH, DLL, процессы/потоки, средства их синхронизации, реестр, буфер обмена и поддержку национальных языков); б) графический и пользовательский интерфейс (GDI32, USER32); в) COM-модель (ActiveX, OLE, MIDL, DCOM); г) библиотеку времени исполнения (ALT, MFC, C Runtime library). Полный перечень поддерживаемых фич на www.mainsoft.com/solutions/vmw5_wp.html.

Это – коммерческий продукт, причем очень сильно коммерческий (лицензия на одного разработчика стоит свыше двух тысяч долларов), правда, доступна 30-дневная полнофункциональная демо-версия, так что… решайте сами: иметь или не иметь.

Рисунок 3 портирование приложений под Visual WinMain, интегрированного в Microsoft Visual Studio

тута дожна быть картина, но ее нет, патаму что тяжелая сволочь, http://www.mainsoft.com/images/products/fullscreenshot.jpg

Рисунок 4 так выглядит Visual WinMain

MainWin, конечно, мощная штука, но иногда требуется софтина помельче. Основной камень преткновения – это, конечно же, MFC. В Microsoft Visual Studio все визуальные средства разработки построены именно на нем. И хотя исходные тексты MFC доступны, перенести его на UNIX намного сложнее, чем создать с нуля, сохранив иерархию классов и прототипы функций.

wxWindows – это бесплатная библиотека, практически полностью совместимая с MFC и работающая на всех UNIX-платформах где есть GTK+, Motif или его бесплатный клон Lesstif. Единственное отличие заключается в том, что вместо префикса «C» здесь используется «wx», в результате чего CWnd превращается в wxWnd.Некоторые классы еще не реализованы (например, отсутствует CEditView) и когда они появятся – неизвестно.Это, конечно, неприятно, но и не смертельно. Без недостающих классов можно кое-как обойтись, заменив CEditVIew на wxTextCtrl; а операцию «перебивки» префиксов загнать в препроцессор или повесить на макрос. Самое главное – wxWindows прекрасно работает на Windows, а, значит, один проект не распадется на два!

На сайте IBM есть замечательная статья по переносу MFC приложений на wxWindows (см. врезку ссылки), а на сайте самой wxWindows еще немного материалов на эту тему. Судя по баннерам, проекту покровительствуют весьма влиятельные компании – VMWare и Helpware, поэтому, за его дальнейшую судьбу можно не волноваться.

Рисунок 5 иерархия классов

Рисунок 6 иерархия классов wxWindows

unix.port_image_4.jpg

Рисунок 7 оригинальное MFC-приложение

unix.port_image_5.jpg

Рисунок 8 …то же приложение, портированное на UNIX с помощью wxWindows

Множество полезных библиотек можно найти на www.sourceforge.net, например, библиотеку для работы с ini-файлами (не анализировать же ее с помощью Бизона!) – libini.lib. Все они бесплатны, распространяются в исходных текстах и легко подключаются к любому проекту. Никогда не бросайтесь писать никакой код, предварительно не поискав в Сети. Скорее всего, он написан до вас, так зачем же изобретать велосипед, когда есть готовые чертежи?

классMFC классwxWindows класс
DocumentCDocumentwxDocument
ViewCViewwxView
EditviewCEditViewотсутствует
Template classCMultiDocTemplatewxDocTemplate
MDI parent frame CMDIFrameWndwxDocMDIParentFrame
MDI child frameCMDIChildWndwxDocMDIChildFrame
Document managerотсутствуетwxDocManager

Таблица 1 соответствие основных классов между MFC и wxWindows

Багдад – великая фирма! Это она создала Turbo Pascal и Turbo Debugger (точнее не создала, а спи… то есть купила). Это она создала Turbo Vision и определила облик интегрированной среды разработки. Скажу честно. Я не считаю Borland C++ хорошим компилятором (он как-то странно трактует ANSI Стандарт, да и оптимизирует хреново), Билдер я обхожу стороной, а от Дельфи меня натурально тошнит. Но это – личный впечатления. Мой любимый MS VC на UNIX'е оказывается в глубокой жопе (перенес требует больших денежных вложений и телодвижений), а на Багдаде – просто перкомпилируешь на Kylix'e и все!

Kylix – это DELPHI и BUILDER для LINUX, распространяющийся по лицензии GPL (то есть на халяву) и включающий в себя интегрированную среду разработки (экранный редактор, интерактивный отладчик, ну в общем кто не понял, тот в Багдаде не бывал) со всеми необходимыми библиотеки и слоями абстрагирования на борту. При условии, что программа не использует прямых вызовов win32 API, перенос не представляет никакой проблемы (на самом деле же, все намного сложнее и если это не чисто вычислительная задача типа бухгалтерии, без прямых вызов ей никак не обойтись, достаточно захотеть прочитать сектор с CD-ROM диска).

Рисунок 9 Kylix в разгаре рабочего дня. для разнообразия – на китайском (япона мать!)

unix.port_image_7.jpg

Рисунок 10 »КИЛИК (греч. Kylix), древнегреческий глиняный, реже металлический сосуд для питья вина: плоская чаша на подставке с двумя горизонтальными ручками» – выписка из энциклопедического словаря

А вот что действительно менявозбуждает, так это Free Pascal (он же FPK Pascal) – бесплатный кросс-платформенный компилятор Паскаля (с исходниками!), поддерживающий Intel x86, Motorola 680×0, PowerPC и работающий практически на любой операционной платформе: Linux, FreeBSD, NetBSD, MacOSX/Darwin, MacOS classic, DOS, Win32, OS/2, BeOS, Solaris, QNX и Amiga. Синтаксически и семантически Free Pascal полностью совместим с TP 7.0 и практически полностью – с DELPHI версий 2 и 3. В дальнейшем планируется поддержка перекрытия функций и операторов. Вы еще не бьетесь в оргазме? Kylix и рядом не валялся. На платформе LINUX он король, а за ее пределами кто?

Единственное, чего недостает Free Pascal'ю – так это нормального IDE. Хотя, на мой мыщъх'ый взгляд, тот IDE который есть – гораздо нормальнее MS VC и DELPHI всех вместе взятых. Одно слово – консоль! При ближайшем рассмотрении выясняется другая замечательная вещь. Free Pascal не совсем компилятор, точнее,совсем не компилятор! Это – транслятор Паскаля в Си. Формально его можно считать компилятором переднего плана (Front-End Compiler), состыкованного с GCC. Отсюда и приличное качество оптимизации и кросс-платформенность.

Рисунок 11 интегрированная среда разработки Free Pascal'я; мой дом, моя нора! «нора», а сказал, а не «дыра», урою этих GUI'шников блин

Смельчакам, отважившимся на самостоятельный перенос Windows-приложений, не обойтись без таблиц соответствий API функций системным вызовам, которые приводятся ниже. Разумеется, это не все функции, а только самые популярные из них (полный список занял бы несколько увесистых томов, для транспортировки которых пришлось бы обзавестись грузовиком):

Win32Linux
CreateProcessfork()/execv()
TerminateProcesskill
ExitProcess()exit()
GetCommandLineargv[]
GetCurrentProcessIdgetpid
KillTimeralarm(0)
SetEnvironmentVariableputenv
GetEnvironmentVariablegetenv
GetExitCodeProcesswaitpid

Таблица 2 функции для работы с процессами

Win32Linux
_beginthreadpthread_attr_init
pthread_attr_setstacksize
pthread_create
_endthreadpthread_exit
TerminateThreadpthread_cancel
GetCurrentThreadIdpthread_self
TerminateThread((HANDLE *) threadId, 0); pthread_cancel(threadId);
WaitForSingleObject ();pthread_join();
_endthread();pthread_exit(0);
Sleep (50) struct timespec timeOut,remains;
timeOut.tv_sec = 0;
timeOut.tv_nsec = 500000000; /* 50 milliseconds */ nanosleep(&timeOut, &remains);
SleepEx (0,0)sched_yield()

Таблица 3 функции для работы с потоками

Win32Linux
CreateFileMaping
OpenFileMapping
mmap
shmget
UnmapViewOfFilemunmap
shmdt
MapViewOfFilemmap
shmat
UnmapViewOfFile(token→location);
CloseHandle(token→hFileMapping);
munmap(token→location, token→nSize);
close(token→nFileDes); remove(token→pFileName); free(token→pFileName);

Таблица 4 функции для работы с файлами, проецируемыми в память

Перенос Windows-приложений на UNIX намного проще, чем это кажется поначалу. К вашим услугам обширный инструментарий и огромное количество библиотек (большей частью бесплатных). Сосредоточьтесь на программном коде и забудьте о пустяках – пусть ими занимается машина (см. эпиграф), но не откладывайте это дело в дальний ящик и прекратите, наконец, игнорировать UNIX-платформу. Ее популярность – свершившийся факт. Так затем терять рынок? Тем более, что конкурировать здесь пока не с кем. В UNIX до сих пор нет множества привычных Windows-приложений и утилит (систем распознавания текста, шестнадцатеричных редакторов и т. д.), поэтому даже плохенькая программа проглатывается публикой с энтузиазмом. Вы все еще ищите во что вонзить свои когти?

  1. WINE
    1. популярный имитатор Windows, поддерживающий большое количество UNIX-платформ. Бесплатен: http://www.winehq.org;__ - WinX, он же Cedega - коммерческий вариант WINE, ориентированный на игры и работающий преимущественно на LINUX-платформе: http://www.transgaming.com____;__
  2. CodeWeavers
    1. коммерческий имитатор Windows, работающий только на LINUX и ориентированный на запуск офисных приложений: http://www.codeweavers.com__; - Visual MainWin - плагин к Microsoft Visual Studio, упрощающий создание переносимого кода и позволяющий компилировать Windows-приложения под различные платформы. Здесь же лежит пара статей по переносу критических бизнес-приложений: http://www.mainsoft.com/products/mainwin.html;__
  3. wxWindows
    1. кросс-платформенная библиотека, более или менее совместимая с MFC, исходные тексты доступны, денег не просит: http://www.wxwindows.org;__ - LIBINT - бесплатная библиотека для работы с INI-файлами на UNIX: http://libini.sourceforge.net__;
  4. Free Pascal
    1. бесплатный кросс-платформенный компилятор Паскаля с ограниченной поддержкой DELPHI: http://www.freepascal.org__; - Porting MFC applications to Linux - толковая статья про перенос MFC-приложений в UNIX при помощи wxWindows: http://www-106.ibm.com/developerworks/library/l-mfc__;
  5. C++ portability guide
    1. шикарная карта рифов и отмелей c отметками все несовместимостей различных компиляторов: http://www.mozilla.org/hacking/portable-cpp.html__; - UNIX Application Migration Guide - шикарное руководство по миграции на Windows от UNIX от Microsoft с многочисленными примерами. Подробно описаны все различия между этими системами, так что этот манускрипт работает в обе стороны: http://www.willydev.net/descargas/prev/unix.pdf__;
  6. The Big Switch: Moving from Windows to Linux with Kylix 3
    1. обзорная статья, описывающая перенос DELPHI/BUILDER приложений на LINUX: http://www-128.ibm.com/developerworks/db2/library/techarticle/0211swart/0211swart2.html__; - Migrating Win32 C/C++ applications to Linux on POWER - замечательная статья, посвященная «ручному» переносу приложений: http://www-128.ibm.com/developerworks/eserver/articles/es-MigratingWin32toLinux.html__;
  7. Using COM technologies on Unix platforms
    1. как перенести COM-приложение на UNIX с минимальной головной болью:
      http://www-128.ibm.com/developerworks/linux/library/l-com.html__; - Реализация Win32 в среде ОС реального времени стандарта POSIX - перенос Windows-приложений на QNX, здесь же находится множество других интересных статей, посвященных этой великолепной, но малоизвестной операционной системе: http://www.rts-ukraine.com/QNXArticles/willows_win32.htm__;
  8. A taste of Wine: Transition from Windows to Linux
    1. WINE как средство переноса приложений из Windows в UNIX:
      http://www-128.ibm.com/developerworks/linux/library/l-wine/index.html__; - OpenNT – путь к «открытому» NT? - обзор UNIX-эмуляторов на Windows NT и Windows NT-эмуляторов на UNIX: http://www.osp.ru/os/1997/03/42.htm__;
  9. Языки программирования через сто лет
    1. Какой язык выбрать для разработки долговременных приложений: http://www.computerra.ru/hitech/35042__; - Портирование кода - подборка ссылок по портированию http://www.opennet.ru/links/sml/50.shtml__;