Программирование на С/C++
Здесь описывается, как использовать разные компиляторы C/C++, чтобы скомпилировать программу под KolibriOS
Visual C++ 6/.NET/2005
- Лицензия: команднострочная версия (Visual C++ Toolkit, компилятор/линковщик, стандартные включаемые файлы и RTL-библиотеки) бесплатна (http://microsoft.com, поиск по сайту), полная версия (IDE, исходники RTL) коммерческая
- Доступные библиотеки для Колибри: библиотека LZMA-упаковки lzmapack.lib; можно использовать любой код, не использующий вызовов ОС и компилирующийся в объектные файлы, которые понимает линковщик от Microsoft (в частности, огромное количество Сишных библиотек). К сожалению, к стандартной RTL (Run-Time Library) это не относится, так что все недостающие функции придётся реализовывать "ручками". Реализация некоторых, впрочем, уже есть.
- Примеры программирования для Колибри: ac97snd, fara, xonix
- Генерируемые форматы: 32-bit PE и 64-bit PE64
- Средства разработки: командная строка в Windows; IDE для Windows
Visual C++ - один из лучших оптимизирующих компиляторов C++. Команднострочный компилятор распространяется Microsoft бесплатно, за IDE нужно платить, поэтому здесь рассматриваются оба варианта. Версия VC6, хоть и довольно давно выпущенная, всё ещё популярна, версии VS.NET и VS2005 имеют свойство тормозить.
Пакет VC (точнее, линковщик link.exe) генерирует исключительно PE-файлы, так что с 32-битностью проблем нет, а вот с генерацией двоичного файла придётся повозиться.
При работе в IDE сначала создадим проект: (для VC6) File->New->Projects->Win32 Application, Project name: hello, (для VS) File->New->Project->Visual C++,General->Empty Project, Name: hello, для VC6 появится мастер, ему указываем "An empty project", подтвердим серьёзность намерений нажатием OK в последнем диалоговом окне и получим в полном соответствии с пожеланиями пустой проект с двумя конфигурациями. Конфигурацию Debug рекомендуется сразу удалить (для VC6 Build->Configurations->кнопка Remove, для VS Build->Configuration Manager->(в выпадающем списке)Edit->кнопка Remove), поскольку отладчик VC в данном контексте заведомо бесполезен. Теперь добавляем в проект (для VC6 Project->Add to Project->Files, для VS Project->Add Existing Item) включаемые файлы kosSyst.h, KosFile.h, mcsmemm.h и файлы с исходным кодом kosSyst.cpp, KosFile.cpp, mcsmemm.cpp (входят в прилагаемые к статье примеры - немного модифицированный вариант из исходников дистрибутива для возможности компиляции с VC6). Кстати, возникающий диалог поддерживает выбор нескольких файлов (если удерживать Ctrl). Далее, создаём основной файл hello.cpp (можно и main.cpp, можно взять любое другое имя) (для VC6 File->New->Files->C++ Source File, File name: hello, для VS File->New->File->Visual C++,C++ File, потом File->Save source1.cpp As, потом File->Move hello.cpp into->hello) и далее начинаем писать сам код. Рекомендуется изучить kosSyst.h, там указаны прототипы функций-обёрток системных вызовов.
#include "kosSyst.h" #include "kosFile.h" const char header[] = "HelloWorld test"; const char string[] = "Hello, World!"; void draw_window(void) { // start redraw kos_WindowRedrawStatus(1); // define&draw window kos_DefineAndDrawWindow(10,40,150,50, 0x33,0xFFFFFF,0,0,(Dword)header); // display string kos_WriteTextToWindow(30,10,8,0,(char*)string,0); // end redraw kos_WindowRedrawStatus(2); } void kos_Main() { draw_window(); for (;;) { switch (kos_WaitForEvent()) { case 1: draw_window(); break; case 2: // key pressed, read it and ignore Byte keyCode; kos_GetKey(keyCode); break; case 3: // button pressed; we have only one button, close kos_ExitApp(); } } }
Теперь настраиваем компиляцию. RTL-библиотеку использовать нельзя, она потянет за собой линковку к Windows-библиотекам, так что для VC6 на вкладке Project->Settings->Link в Category: Input очищаем поле Object/library modules и устанавливаем флажок Ignore all default libraries. Выполнение начинается с функции crtStartUp, так что устанавливаем в Category: Output устанавливаем Entry-point symbol:crtStartUp. Кроме того, в поле Project Options рекомендуется добавить опцию /align:16 (это необязательно, но сильно уменьшает размер бинарника). Для VS соответствующий диалог вызывается по Project->hello Properties и вместо вкладок там treeview, те же действия выполняются так: Configuration Properties->Linker->Input-> Ignore All Default Libraries: Yes, Linker->Advanced->Entry Point: crtStartUp, Linker->Command Line->Additional options: /align:16. Кроме того, для VS нужно явно установить подсистему: Linker->System->SubSystem (возьмите любую, она ни на что не влияет) и отключить при компиляции проверки переполнения стековых буферов и RTTI (они ссылаются на RTL): C/C++ ->Code Generation->Buffer Security Check: No, C/C++ ->Language->Enable Run-Time Type Info: No. Также манифест, вставляемый VS, нам ни к чему, так что Linker->Manifest File->Generate Manifest: No. Теперь компилятор уже способен сгенерировать код, но он окажется в формате PE. Основная идея заключается в том, чтобы получаемый PE-файл пропустить через программу pe2kos.exe, которая сменит его формат на используемый в Колибри. pe2kos.exe включена с исходниками в исходники дистрибутива (папка develop\pe2kos), а также без исходников в прилагаемые к статье примеры. (Есть и альтернативный подход, про который можно прочитать в разделе по MASM, описание линковки.) Колибри-бинарники требуется загружать по нулевому адресу, Колибри-заголовок окажется в начале файла вместо PE-заголовка, так что требуется установить базовый адрес (на той же самой вкладке - Output для VC6, Linker->Advanced для VS - поле Base address) в 0, для VS нужно ещё установить Fixed Base Address в "Image must be loaded at a fixed address (/FIXED)" (VC6 по умолчанию и так не генерирует релокейшенов).
Осталось настроить вызов pe2kos. Для VC6: Project->Settings->Custom Build, для VS: Project->hello Properties->Custom Build Step. В поле Commands/Command Line пишем
pe2kos Release\hello.exe hello
(предполагается, что pe2kos либо лежит в одном из PATH-каталогов, либо в каталоге проекта), в поле Outputs записываем имя бинарника - hello, он сгенерируется в каталоге проекта. Ах да, собственно компиляция теперь как обычно - либо F7, либо Build->Build hello.exe(VC)/Build->Build Solution(VS), либо соответствующая кнопка на панели инструментов. Теперь поработаем с командной строкой. Для начала установим необходимые переменные окружения. При установке VC Toolkit, VC6 или VS в соответствующем разделе главного меню появляется пункт "... Command Prompt", который вызывает консоль, устанавливает нужное окружение и ждёт действий пользователя. Можно самостоятельно запустить консоль и выполнить файл vcvars32.bat. После этого требуется перейти в рабочую папку (диск меняется командой X:, папка на диске - командой cd \folder1\folder2). Предполагается, что в эту папку уже скопированы kosFile.cpp,kosSyst.cpp,mcsmemm.cpp,kosFile.h,kosSyst.h,mcsmemm.h и набран hello.cpp. Необходимые опции компиляции точно такие же, как и в IDE, только теперь они задаются не через GUI, а в командной строке. Компиляция до VS2005:
cl /c /O2 /nologo hello.cpp kosFile.cpp kosSyst.cpp mcsmemm.cpp link /nologo /entry:crtStartUp /subsystem:native /base:0 /fixed /align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj pe2kos hello.exe hello
В VS2005 добавляются новые ключи:
cl /c /O2 /nologo /GS- /GR- hello.cpp kosFile.cpp kosSyst.cpp mcsmemm.cpp link /nologo /manifest:no /entry:crtStartUp /subsystem:native /base:0 /fixed /align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj pe2kos hello.exe hello
GCC/G++
- Лицензия: бесплатные, OpenSource
- Доступные библиотеки для Колибри: портированные RTL (Run-Time Library, стандартная Си-библиотека), SDL (Simple DirectMedia Layer, на ней основаны куча программ); можно использовать любой код, не использующий вызовов ОС и компилирующийся в объектные файлы, которые понимает ld (GNU линковщик).
- Примеры программирования для Колибри: dosbox, sdlfire, sdlquake, pig
- Генерируемые форматы: 32-bit, probably, 16-bit
- Средства разработки: MinGW - командная строка в Windows (http://www.mingw.org); GCC/G++ - стандартные компиляторы, входящие во все пакеты Linux и cygwin (http://www.cygwin.com)
GCC/G++ - один из лучших оптимизирующих компиляторов C/C++. Двоичные файлы как специальный формат не поддерживает, однако, линковщик понимает специальные скрипты, с помощью которых можно ему сказать довольно много.
Для кросс-компиляции программ на C и C++ для KolibriOS был создан специальный тулчейн.
Ниже приведены руководства по установке данного тулчейна на Linux и Windows.
Установка на Linux
Подробное руководство по установке тулчейна http://board.kolibrios.org/viewtopic.php?f=33&t=3540 Чтобы сделать установку более удобной, turbocat'ом был написан специальный скрипт, которые сделает все за вас). Скачать скрипт-установщик можно на этой странице http://board.kolibrios.org/viewtopic.php?f=33&t=3540&p=76381#p76381
Пример с компиляцией Hello world здесь https://habr.com/ru/post/527144/
ВАЖНО: замечание от автора скрипта:
Вот написал небольшой скрипт на BASH. Выполняет все действия по установке kos32-gcc и библиотек для Линукса автоматически. Не рекомендую запускать от рута(предоставляйте рут только когда скрипт сам потребует). Иначе тулчейн будет установлен в папку /root а не ваш домашний каталог!
Установка на Windows
Инструкция по установке тулчейна под Windows: https://habr.com/ru/post/229231/
Для удобства Boppan собрал тулчейн в один архив, скачать его можно тут:
http://board.kolibrios.org/viewtopic.php?f=33&t=1218&p=74401&hilit=kossdk#p74401
Borland C++
- Лицензия: утилиты командной строки бесплатны ( www.borland.com/bcppbuilder/freecompiler или поиск "Command-Line tools" по сайту), IDE коммерческая
- Доступные библиотеки для Колибри: базовая, необходимая для работы (включает работу с многопоточностью, обёртки системных вызовов, работу с кучей, работу с файлами, но RTL нет).
- Примеры программирования для Колибри: life2 (programs\demos\life2)
- Генерируемые форматы: 32-bit PE
- Средства разработки: командная строка в Windows; IDE для Windows
Компилятор не позволяет генерировать двоичные файлы. Здесь используется интересный подход: раз создавать Колибри-бинарники с помощью компилятора не получается, не будем его использовать! Будем использовать FASM, он позволяет генерировать всё, что нужно. Вопрос: а причём же здесь тогда C++? Ответ: будем писать на C++, но компилировать в ассемблерный текст! "Мелкие" проблемы с несоответствием TASM-синтаксиса выходных файлов от Borland C++ FASM-синтаксису решаются несложной программой t2fasm.exe. Для компиляции потребуется библиотека базовых функций, она входит в вышеупомянутые исходники life2. Собственно код (window.cpp) bcc32:
#include <kolibri.h> #include <kos_heap.h> #include <kos_file.h> using namespace Kolibri; const char header[] = "Colors"; bool KolibriOnStart(TStartData &kos_start, TThreadData th) { kos_start.Left = 10; kos_start.Top = 40; kos_start.Width = 135; kos_start.Height = 80; kos_start.WinData.WindowColor = 0xFFFFFF; kos_start.WinData.WindowType = 0x34; // 0x34 - fixed, 0x33 - not fixed kos_start.WinData.Title = header; return true; } void KolibriOnPaint(void) { // If button have ID 1, this is close button DrawButton(2,0xff0000, 10,40,50,20); DrawButton(3,0x00ff00, 70,10,50,20); DrawButton(4,0x0000ff, 70,40,50,20); DrawButton(5,0xFFFE00, 10,10,50,20); } void KolibriOnButton(long id, TThreadData th) { switch(id){ case 2: SetWindowCaption("Red"); break; case 3: SetWindowCaption("Green"); break; case 4: SetWindowCaption("Blue"); break; case 5: SetWindowCaption("Yellow"); //break; }; } /* int KolibriOnIdle(TThreadData th) { return -1; } void KolibriOnSize(int window_rect[], TThreadData th) {} void KolibriOnKeyPress(TThreadData th) { GetKey(); } void KolibriOnMouse(TThreadData th) {} */
Что-бы компилировать FASM версией выше 1.64 нужно пропатчить компилятор. Пример файла window_cpp.bat:
Set NAME=window Set BCC_DIR=..\..\..\bcc32 kos32-bcc -S -v- -R- -6 -a4 -O2 -Og -Oi -Ov -OS -k- -D__KOLIBRI__ -I..\..\..\bcc32\include %NAME%.cpp echo STACKSIZE equ 102400> kos_make.inc echo HEAPSIZE equ 102400>> kos_make.inc echo include "%BCC_DIR%\include\kos_start.inc">> kos_make.inc echo include "%BCC_DIR%\include\kos_func.inc">> kos_make.inc echo include "%BCC_DIR%\include\kos_heap.inc">> kos_make.inc echo include "kos_make.inc" > f_%NAME%.asm t2fasm < %NAME%.asm >> f_%NAME%.asm fasm f_%NAME%.asm %NAME%.kex if exist %NAME%.kex kpack %NAME%.kex if exist %NAME%.kex del kos_make.inc pause
Tiny C Compiler
- Лицензия: бесплатный, OpenSource
- Доступные библиотеки для Колибри: солидная часть RTL (Run-Time Library, стандартная Си-библиотека)
- Программы: TinyTextEditor, TinyHashView
- Генерируемые форматы: 32-bit COFF, ELF, PE, Kolibri
- Средства разработки: командная строка в Windows, Kolibri
Компилятор TCC был доработан для генерации Колибри-бинарников. Также написана некоторая часть C RTL на базе функций Колибри. Исходники как самого компилятора, так и RTL доступны на svn-сервере Колибри: svn://kolibrios.org/programs/develop/ktcc/trunk.
Код (hello.c):
#include <kos32sys1.h> #include <stdlib.h> #define WIN_W 640 #define WIN_H 563 char* title = "TinyC Compiler"; int win_bg_color = 0x858585; void draw_window(){ begin_draw(); sys_create_window(215,100,WIN_W,WIN_H,title,win_bg_color,0x34); end_draw(); } int main() { while(1) { switch(get_os_event()) { case 3: if (get_os_button() == 1) exit(0); break; case 2: get_key(); break; case 1: draw_window(); break; } } }
Компиляция:
tcc hello.c -lck -o hello.kex