Use of various compilers in KolibriOS.

Introduction

The operating system Kolibri is meant in the first place for programmers on assembler using FASM. But FASM is not sole compiler, there are other assemblers and chiefly high level languages (further - HLL); many programs have been written on HLL, and some of them have been ported to Kolibri. This article describes methods which allow such actions (what ideas are used at that).

This article shows use of various compilers on an example of simple program, which says "Hello, World!". At that the article does not describe, how the code works - the reader is assumed to either know common principles of Kolibri-programs work or be ready to examine the quoted code. Also the article assumes that the reader knows the language, about which he reads (various article parts, which describes various languages, do not depend on each other and may be studied selectively). Nevertheless I want to say base information necessary for understanding the article:

Because the goal of this article is to demonstrate features of compilation in various cases, the main goal of the quoted code is to be understandable. So, for fasm and nasm I have used standard include files and macroses (which is not typical for me). In fact, the resulting files can be made some smaller, but this will result in worsening readability and complication of understanding the code.

The examples to the article is placed here.

Assembler FASM.

  • License: free, OpenSource, available at http://flatassembler.net
  • Available Kolibri libraries: many (are included in the distributive sources in the folder "develop"), because most programmers write it for FASM
  • Examples of programming for Kolibri: many - most programs are written on FASM
  • Generated code: any mixture of 16,32,64-bit code, switched by directives use16/use32/use64
  • Generated formats: binary and DOS-COM/DOS-SYS, DOS-EXE, COFF/COFF64, PE/PE64, ELF/ELF64
  • Engineering environment: command line in DOS, Windows and Linux; IDE for Windows; GUI for Kolibri; in Kolibri compilation from editor TinyPad and file manager KFar

    FASM is main tool of Kolibri developers and the sole compiler ported for Kolibri itself. Supports creation of binary files (for that one must say in the source start "format binary" or do not set format at all) and 16/32/64-bit code (directives use16/use32/use64). In the quoted code the macro MEOS_APP_START is opened to use32, org 0x0 and header.
    The code (hello.asm):
    include "macros.inc"
    
    MEOS_APP_START
    
    CODE
    redraw:
            call    draw_window
    wait_event:
            mcall   10
            dec     eax
            jz      redraw
            dec     eax
            jz      key
    ; button pressed; we have only one button, close
            mcall   -1
    key:
    ; key pressed, read it and ignore
            mcall   2
            jmp     wait_event
    
    draw_window:
            mcall   12, 1           ; start redraw
            mcall   0, <10,150>, <40,50>, 0x33FFFFFF, , header      ; define&draw window
            mcall   4, <30,10>, 0x80000000, string                  ; display string
            mcall   12, 2           ; end redraw
            ret
    
    DATA
    header  db      'HelloWorld test',0
    string  db      'Hello, World!',0
    
    UDATA
    
    MEOS_APP_END
    
    (The file macros.inc is standard include file, is included to the distributive and to sources attached to the article).
    There is command-line version of compiler, there is IDE for Windows, there is Kolibri version. Command-line compilation:
    fasm hello.asm hello
    (console view here)

    Compilation from fasmw - Windows-IDE: Ctrl+F9 or item "Compile" in menu, after this it is recommented to rename hello.bin to hello - this is not necessary, but in Kolibri for executable files by convention the empty extension is used.
    (Windows-IDE here)

    Compilation from Kolibri: enter to according fields names of input and output files and press the button "Compile".
    (Kolibri-FASM here)

    Beacuse FASM is important for Kolibri developers, one can call it also from TinyPad and from KFar:
    (compile from TinyPad)

    (compile from KFar)

    Assembler NASM.

  • License: free, OpenSource, available at http://nasm.sourceforge.net
  • Available Kolibri libraries: include file mos.inc
  • Examples of programming for Kolibri: applications aclock and c4, their sources are included in the distributive sources (folders programs\Thomas_Mathys\aclock, ...\c4)
  • Generated code: any mixture of 16 and 32-bit code, switch with directives bits 16/32
  • Generated formats: binary and DOS-COM/DOS-SYS, a.out, COFF, PE, ELF
  • Engineering environment: command line in DOS, Windows и Linux; IDE for DOS

    Assembler NASM some time ago was enough popular, but now it is not widespread. Binary files creation is done with command-line option "-f bin" (which is default format), 32-bit code is generated with the directive "bits 32". In the quoted code the macro MOS_HEADER01 is opened to org 0x0 and header.
    The code (hello.asm):
    	bits	32
    	%include 'mos.inc'
    	section .text
    
    	MOS_HEADER01 main,image_end,memory_end,stacktop,0,0
    
    main:
    redraw:
    	call	draw_window
    wait_event:
    	MOS_WAITEVENT
    	dec	eax
    	jz	redraw
    	dec	eax
    	jz	key
    ; button pressed; we have only one button, close
    	MOS_EXIT
    key:
    ; key pressed, read it and ignore
    	mov	eax, MOS_SC_GETKEY
    	int	0x40
    	jmp	wait_event
    
    draw_window:
    	MOS_STARTREDRAW
    	xor	eax, eax
    	mov	ebx, 10*65536 + 150
    	mov	ecx, 40*65536 + 50
    	mov	edx, 0x33FFFFFF
    	mov	edi, header
    	int	0x40		; define&draw window
    	mov	eax, MOS_SC_WRITETEXT
    	mov	ebx, 30*65536 + 10
    	mov	ecx, 0x80000000
    	mov	edx, string
    	int	0x40		; display string
    	MOS_ENDREDRAW
    	ret
    
    	section	.data
    header	db	'HelloWorld test',0
    string	db	'Hello, World!',0
    image_end:
    
    	section .bss
    alignb	4
    stack	resb	1024
    stacktop:
    
    memory_end:
    
    (The file mos.inc can be found in the distributive sources - it is placed with nasm-program in the folder programs\Thomas_Mathys\aclock, and also included to the sources attached to the article.)
    Command-line compilation:
    nasm hello.asm
    or
    nasmw hello.asm
    depending on used version. It is allowed to add options "-f bin", "-o hello", but they are default ones.
    NASM works silently

    When using IDE, output file will have the extension .com and it is recommended to rename it, in Kolibri by the convention executable files have the empty extension.
    NASM IDE

    Assembler MASM.

  • License: free, available at http://movsd.com (MASM32 package) and at http://microsoft.com (compiler/linker/tools; use search on site)
  • Available Kolibri libraries: library for LZMA-pack lzmapack.lib; any code, which does not use OS calls and is compiled to object files understandable by Microsoft linker, can be linked; macrolibraries are not present, because the author of this approach does not like them, but include files from MASM32 package (it contains many include files) can be used, of course, those of them who does not use Windows functions
  • Examples of programming for Kolibri: mtappack (the sources are included in the sources of distributive - folder programs\Diamond\mtappack), similar approach is used in kpack and kerpack (the sources are approximately in the same place)
  • Generated code: 32-bit and (for latest versions) 64-bit code depending on used format
  • Generated formats: PE and (for latest versions) PE64
  • Engineering environment: Windows command-line

    MASM32 package enjoys wide popularity around assembler programmers for Windows. In fact, in this environment MASM and FASM are used equally, other assemblers are significantly less widespread. Because MASM (more strictly, the linker link.exe) can generate only PE-files, 32-bitness is not a problem, but creation of binary file must be done specially.
    The code (hello.asm):
            .486
            .model  flat
    
    .data
    ; header
            db      'MENUET01'
            dd      1
            dd      offset _start
            dd      offset bss_start        ; i_end
            dd      offset bss_end          ; memory
            dd      offset stacktop         ; esp
            dd      0, 0                    ; params, icon
    
    header  db      'HelloWorld test',0
    string  db      'Hello, World!',0
    
    .data?
    bss_start label byte
    align 4
            db      1000h dup (?)
    stacktop = $
    bss_end label byte
    
    .code
    _start:
    redraw:
            call    draw_window
    wait_event:
            mov     eax, 10
            int     40h
            dec     eax
            jz      redraw
            dec     eax
            jz      key
    ; button pressed; we have only one button, close
            mov     eax, -1
            int     40h
    key:
    ; key pressed, read it and ignore
            mov     eax, 2
            int     40h
            jmp     wait_event
    
    draw_window:
            mov     eax, 12
            mov     ebx, 1
            int     40h             ; start redraw
            xor     eax, eax
            mov     ebx, 10*65536 + 150
            mov     ecx, 40*65536 + 50
            mov     edx, 33FFFFFFh
            mov     edi, offset header
            int     40h             ; define&draw window
            mov     eax, 4
            mov     ebx, 30*65536 + 10
            mov     ecx, 80000000h
            mov     edx, offset string
            int     40h             ; draw string
            mov     eax, 12
            mov     ebx, 2
            int     40h             ; end redraw
            ret
    
            end     _start
    
    And now the compilation. The general principle: we will create pseudo-PE file with single section, and then will pull out this section to Kolibri-binary with the simple FASM-script. There exists also another way, it is shown in the description of linking for Visual C++.
    The compilation in MASM is carried out in two phases: compilation proper and linking. The advantage of this approach compared to one-phase process used by FASM and NASM, is the ability to use on second phase the code, which can be not on MASM at all, but, for example, on C. To achieve such effect in FASM/NASM, one must compile to object file (since they allow it) and then search for linker (as mentioned packages do not have their own linker) and take troubles with it (using the same plan as described here).
    The compilation of asm-file is absolutely standard:
    \masm32\bin\ml /nologo /c /coff hello.asm
    
    (option /nologo suppress copyright banner, /c means "only compile, do not link", /coff generates COFF-object).
    Link is much more interesting:
    \masm32\bin\link /fixed /subsystem:native /base:-0x10000 /align:0x10000
    		/merge:.data=.text /merge:.rdata=.text /nologo hello.obj
    

    Explanations:

  • /nologo - suppress copyright banner (this option is not necessary)
  • /merge:.data=.text /merge:.rdata=.text - we need that exe-file contains only one section with initialized data, so we merge all such sections
  • /base:-0x10000 /align:0x10000 - we need that this section is placed on zero address; but by default exe-file starts from PE-header with minimum address, followed by sections with greater addresses. Therefore we override base address (equal to header address). The value is choiced according to the fact, that it must be aligned to 0x10000 boundary or link.exe will not run. After setting base address we set sections align so, that the first section gets to zero address. Ooh!
  • /subsystem:native - we must select any subsystem (the linker must fill the according field in PE-header, and we will ignore this field)
  • /fixed - says linker not to generate the section .reloc with fixups, such section will only hinder us

    As the result the file hello.exe must be generated. The last stage: take file doexe.asm containing following code:
    virtual at 0
    file 'hello.exe':3Ch,4
    load pehea dword from 0
    file 'hello.exe':pehea+0F8h,28h
    load physofs dword from 4+14h
    load mem dword from 4+8
    file 'hello.exe':physofs+16,4
    load sz dword from $-4
    end virtual
    file 'hello.exe':physofs,sz
    store dword mem at 14h
    
    and compile:
    fasm doexe.asm hello
    
    command line and MASM

    Environments Visual C++ 6, C++ from Visual Studio .NET/2005.

  • License: command-line version (Visual C++ Toolkit, compiler/linker, standard include files and RTL libraries) is free (http://microsoft.com, search on site), full version (IDE, RTL sources) is commercial
  • Available Kolibri libraries: library for LZMA-pack lzmapack.lib; any code, which does not use OS calls and is compiled to object files understandable by Microsoft linker, can be used (in particular, large quantity C libraries). Unfortunately, this is not applied to standard RTL (Run-Time Library), so all missing functions must be implemented by hand. However, some of them are already written.
  • Examples of programming for Kolibri: ac97snd, fara, xonix (the sources are included in the sources of the distributive in folders programs\Serge\ac97snd, programs\Diamond\fara, programs\Diamond\xonix correspondingly)
  • Generated code: 32-bit and (for latest versions) 64-bit code depending on used format
  • Generated formats: PE and (for latest versions) PE64
  • Engineering environment: command line in Windows; IDE for Windows

    Visual C++ is one from the best optimizing C++ compilers. Command-line compiler is distributed by Microsoft for free, for IDE one must pay (at least for licensed version :-) ), so both variants are examined here. The version VC6, though written enough time ago, is still popular, the versions VS.NET and VS2005 like to brake.
    VC package (more strictly, the linker link.exe) generates only PE-files, so 32-bitness is not a problem, but creation of binary files is tricky.
    Under work in IDE let us at first create project: (for VC6) File->New->Projects->Win32 Application, Project name: hello, (for VS) File->New->Project->Visual C++,General->Empty Project, Name: hello, for VC6 the wizard will appear, say to it "An empty project", accept seriousness of our intensions by pressing OK in the last dialog window and we will get fully according to our wishes the empty project with two configurations. It is recommended to delete the configuration Debug right away (for VC6 Build->Configurations->button Remove, for VS Build->Configuration Manager->(in listbox)Edit->button Remove), as the VC debugger is certainly useless in this context. Now let us add to the project (for VC6 Project->Add to Project->Files, for VS Project->Add Existing Item) include files kosSyst.h, KosFile.h, mcsmemm.h and source files kosSyst.cpp, KosFile.cpp, mcsmemm.cpp (are included to examples attached to the article - slightly modified variant from distributive sources to allow compilation in VC6). Apropos, the appearing dialog supports multiple choice (with holded Ctrl). Next, create main file hello.cpp (or main.cpp, or any other name) (for VC6 File->New->Files->C++ Source File, File name: hello, for VS File->New->File->Visual C++,C++ File, then File->Save source1.cpp As, then File->Move hello.cpp into->hello) and next write the code. It is recommended to learn kosSyst.h, this file contains prototypes of system calls wrappers.
    #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();
    		}
    	}
    }
    
    Now let us tune compilation. We can not use RTL-library, because it will force link to Windows-libraries, so for VC6 on the tab "Project->Settings->Link" in "Category: Input" clear editbox "Object/library modules" and set checkbox "Ignore all default libraries". Entry point is the function crtStartUp, so in "Category: Output" set "Entry-point symbol:" in "crtStartUp". Moreover, in "Project Options" it is recommended to add option "/align:16" (this is not necessary, but greatly decreases binary size). For VS the corresponding dialog is called by "Project->hello Properties" and has treeview instead of tabs, similar actions are executed as follows: Configuration Properties->Linker->Input-> Ignore All Default Libraries: Yes, Linker->Advanced->Entry Point: crtStartUp, Linker->Command Line->Additional options: /align:16. Moreover, VS requires obvious subsystem guideline: Linker->System->SubSystem (select any, it has no influence) and disable at compilation buffer overflow checks and RTTI (they use RTL): C/C++ ->Code Generation->Buffer Security Check: No, C/C++ ->Language->Enable Run-Time Type Info: No. Also manifest inserted by VS has no value for us, so Linker->Manifest File->Generate Manifest: No. Now the compiler can already generate code, but it will be created in PE format. The main idea is to pass generated PE-file through the program pe2kos.exe, which will change its format to used in Kolibri. pe2kos.exe is included with the sources to the distributive sources (the folder "develop\pe2kos"), and also without the sources to examples attached to the article. (There exists also another way, it is shown in MASM chapter, description of linking.) Kolibri-binaries are loaded at zero address, Kolibri-header will be created in the file beginning instead of PE-header, so base address must be set (at the same tab - "Output" for VC6, "Linker->Advanced" for VS - field "Base address") to 0, VS also requires "Fixed Base Address" set to "Image must be loaded at a fixed address (/FIXED)" (VC6 by default does not generate fixups itself).
    опции проекта в VC6

    опции проекта в VS

    The remaining part is to setup call to pe2kos. For VC6: Project->Settings->Custom Build, for VS: Project->hello Properties->Custom Build Step. In the editbox Commands/Command Line write
    pe2kos Release\hello.exe hello
    (pe2kos is assumed to be placed either in one from PATH-folders or in project folder), in the editbox Outputs write binary name - hello, it will be generated in the project folder. The build process is now as usually - either F7, or Build->Build hello.exe(VC)/Build->Build Solution(VS), or corresponding button on toolbar.
    Now let us work with the command line. At first, set required environment variables. When VC Toolkit, VC6 or VS are installing, they create in the corresponding partition of main menu the item "... Command Prompt", which calls console, sets up used environment and waits for user actions. One can also independently run console and execute the file vcvars32.bat. Next, go to work folder (drive is changed by the command "X:", folder on drive - by the command "cd \folder1\folder2"). Following assumes that the folder already contains kosFile.cpp,kosSyst.cpp,mcsmemm.cpp,kosFile.h,kosSyst.h,mcsmemm.h and created hello.cpp.
    Required compilation options are the same as in IDE, but now they are selected not through GUI, but in command line.
    Compilation before 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
    
    command line of VC++ Toolkit 2003

    VS2005 adds new options:
    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
    
    command line of VS2005

    Compilers GCC, G++.

  • License: free, OpenSource
  • Available Kolibri libraries: ported RTL (Run-Time Library, standard C-library), SDL (Simple DirectMedia Layer, it is base for many programs); any code, which does not use OS calls and is compiled to object files understandable by GNU linker, can be used (in particular, many C libraries).
  • Examples of programming for Kolibri: dosbox, sdlfire, sdlquake, pig
  • Generated code: 32-bit, probably, 16-bit
  • Generated code: various
  • Engineering environment: MinGW - command line in Windows (http://www.mingw.org); GCC/G++ are standard compilers included in all Linux and cygwin packages (http://www.cygwin.com)

    GCC/G++ are one from the best optimizing C/C++ compilers. They do not support binary files as special format, but linker understands special scripts, which can give to him enough information.
    Developing requires in addition to MinGW/cygwin/linux (any variant can be used) the library menuetlibc, available at http://diamondz.land.ru/menuetlibc.7z. Download it, allocate some folder for it, unpack the archive there and create environment variable MENUETDEV with the value "full path to the selected folder". (Under cygwin/linux when using standard bash shell environment variables are set by the command of the form "export MENUETDEV=/home/username/menuetlibc", which is reasonable to be placed in .bash_profile to avoid necessity of manually enter each time when loading. Under Win9x the command of the form "SET MENUETDEV=c:\kolibri\menuetlibc" should be placed in autoexec.bat and then one should reboot computer. Under WinNT/2k/XP setting of environment variables is done through GUI: Control Panel->System->Advanced ->Environment variables.)
    After those settings give the command "make" from selected folder. And wait, because compilation of libraries from the beginning is long enough. If all will succeed, the subfolder "lib" will contain 6 libraries, and "programs\binclock" - test Kolibri-program mbinclk.
    And now let us write "helloworld" program. Here prototypes of system calls wrappers are placed in $(MENUETDEV)/include/menuet/os.h. The code (hello.c):
    #include <menuet/os.h>
    
    const char header[] = "HelloWorld test";
    const char string[] = "Hello, World!";
    
    void draw_window(void)
    {
    	// start redraw
    	__menuet__window_redraw(1);
    	// define&draw window
    	__menuet__define_window(10,40,150,50,
    		0x33FFFFFF,0,(__u32)header);
            // display string
            __menuet__write_text(30,10,0x80000000,string,0);
            // end redraw
            __menuet__window_redraw(2);
    }
    
    void app_main(void)
    {
    	draw_window();
    	for (;;)
    	{
    		switch (__menuet__wait_for_event())
    		{
    		case 1:
    			draw_window();
    			break;
    		case 2:
    			// key pressed, read it and ignore
    			__menuet__getkey();
    			break;
    		case 3:
    			// button pressed; we have only one button, close
    			return;
    		}
    	}
    }
    
    The compilation is carried out, as anywhere in the GNU world, by the command
    make
    which requires Makefile with the following contents:
    OUTFILE = hello
    OBJS = hello.o
    include $(MENUETDEV)/makefiles/Makefile_for_program
    
    make. Simply make.

    Some explanation for actions happened off screen.

    Compiler Borland C++.

  • License: command-line tools are free (www.borland.com/bcppbuilder/freecompiler or seatch "Command-Line tools" on site), IDE is commercial
  • Available Kolibri libraries: base library, necessary for work (includes multithreading, system calls wrappers, heap allocation/free, files handling, but does not contain RTL).
  • Examples of programming for Kolibri: checkers, life2 (the sources are included to the distributive sources - folders programs\Diamond\checkers и ...\life2)
  • Generated code: 32-bit
  • Generated formats: PE
  • Engineering environment: command line in Windows; IDE for Windows

    The compiler can not generate binary files. Here the interesting approach is used: since Kolibri-binaries can not be created with the compiler, let us do not use compiler! We will use FASM, it can generate anything needed. But in which connection C++ stays here? The answer is: we will write on C++, but compile in the assembler text! "Minor" problems with inconsistency between TASM-syntax of output files from Borland C++ and FASM-syntax are solved with not complicated program t2fasm.exe, which is included with the sources to the distributive sources (folder "develop"), and also (without sources) to examples attached to the article.
    For compilation the library of base functions is required, it can be found in mentioned sources of checkers and life2, and also in the examples for the article.
    The code (hello.cpp):
    #include <menuet.h>
    #include <me_heap.h>
    #include <me_file.h>
    
    using namespace Menuet;
    
    const char header[] = "HelloWorld test";
    const char string[] = "Hello, World!";
    
    bool MenuetOnStart(TStartData &me_start, TThreadData /*th*/)
    {
    	me_start.Left = 10;
    	me_start.Top = 40;
    	me_start.Width = 150;
    	me_start.Height = 30;
    	me_start.WinData.Title = header;
    	return true;
    }
    
    void MenuetOnDraw(void)
    {
    	DrawString(30,10,0,string);
    }
    
    bool MenuetOnClose(TThreadData /*th*/)
    {return true;}
    int MenuetOnIdle(TThreadData /*th*/)
    {return -1;}
    void MenuetOnSize(int /*window_rect*/[], TThreadData /*th*/)
    {}
    void MenuetOnKeyPress(TThreadData /*th*/)
    {GetKey();}
    void MenuetOnMouse(TThreadData /*th*/)
    {}
    
    The compilation requires FASM with version not above 1.64. On condition that you have got such version:
    bcc32 -S -v- -R- -6 -a4 -O2 -Og -Oi -Ov -OS -k- -D__MENUET__ -Iinclude hello.cpp
    echo include "me_make.inc" > f_hello.asm
    t2fasm < hello.asm >> f_hello.asm
    fasm f_hello.asm hello
    
    Borland C++ & FASM

    The compiler Tiny C.

  • License: free, OpenSource
  • Available Kolibri libraries: big part of RTL (Run-Time Library, standard C library)
  • Examples of programming for Kolibri: spektr
  • Generated code: 32-bit
  • Generated formats: COFF, ELF, PE, Kolibri
  • Engineering environment: command line in Windows

    The compiler TCC was elaborated for generation of Kolibri-binaries. Also some part of C RTL on the base of Kolibri functions has been written. The sources of the compiler and RTL are available at Kolibri svn-server: svn://kolibrios.org/programs/develop/metcc/trunk.
    For a start, one should compile the compiler :) For this one needs anything of MinGW/cygwin/linux, where the compiler GCC is present. In the presence of GCC one should say in the folder "source"
    gcc tcc.c -o tcc.exe
    The library is also compiled with GCC. Under Windows it is enough to run build.bat, for cygwin/linux there is Makefile. In the result GCC must create files melibc.a and start\start.o.
    Now let us copy tcc.exe, melibc.a and start.o to the work folder. Let us also copy to the same folder files from the folder "include".
    The code (hello.c):
    #include "mesys.h"
    
    const char header[] = "HelloWorld test";
    const char string[] = "Hello, World!";
    
    void draw_window(void)
    {
    	// start redraw
    	_msys_window_redraw(1);
    	// define&draw window
    	_msys_draw_window(10,40,150,50,0xFFFFFF,0x33,0,0,(int)header);
    	// display string
    	_msys_write_text(30,10,0x80000000,string,0);
    	// end redraw
    	_msys_window_redraw(2);
    }
    
    int main(int argc, char** argv[])
    {
    	draw_window();
    	for (;;)
    	{
    		switch (_msys_wait_for_event_infinite())
    		{
    		case 1:
    			draw_window();
    			break;
    		case 2:
    			// key pressed, read it and ignore
    			_msys_get_key();
    			break;
    		case 3:
    			// button pressed; we have only one button, close
    			return 0;
    		}
    	}
    }
    
    Compilation:
    tcc hello.c start.o melibc.a -o hello
    
    TCC at work

    Compiler Pascal Pro.

  • License: free
  • Available Kolibri libraries: load of files with PE-format (with some limitations)
  • Examples of programming for Kolibri: none (at moment)
  • Generated code: 16-bit or 32-bit
  • Generated formats: Kolibri and some others
  • Engineering environment: command line in DOS and Windows

    The compiler Pascal Pro was elaborated for generation of Kolibri-binaries, and also the library of system calls wrappers has been created. Links and discussions can be found on our forum http://meos.sysbin.com.
    The code (hello.pas):
    Program hello;
    Uses kolibri;
    
    var k:TKolibri;
    const
    	header:string='HelloWorld test'#0;
    	str:string='Hello, World!';
    
    procedure draw_window;
    begin
    	{start redraw}
    	k.BeginDraw;
    	{define&draw window}
    	k.DefineWindow(10,40,150,50,$33FFFFFF,0,integer(@header[1]));
    	{display string}
    	k.WriteText(30,10,0,0,str);
    	{end redraw}
    	k.EndDraw;
    end;
    
    var key:DWord;
    begin
    	draw_window;
    	while true do
    	begin
    		case k.WaitForEvent of
    		1:draw_window;
    		2:k.GetKey(key);{key pressed, read it and ignore}
    		3:break;	{button pressed; we have only one button, close}
    		end;
    	end;
    end.
    
    The compilation is not a problem:
    ppro hello
    PPro for DOS