C/C++ programming: Difference between revisions

From KolibriOS wiki
Jump to navigation Jump to search
(Created page with "== Visual C++ 6/.NET/2005 == * '''License''': command-line version (Visual C++ Toolkit, compiler/linker, standard include files and RTL libraries) is free (http://microsoft.c...")
 
 
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
This section describes C/C++ programming for Kolibri.
'''Warning: The pages below this line require rewriting - copied from Diamond's pages'''
== Visual C++ 6/.NET/2005 ==
== Visual C++ 6/.NET/2005 ==


Line 55: Line 59:


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).
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).
[[File:Hll_vc1.gif]]
[[File:Hll_vc2.gif]]


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
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
Line 71: Line 79:
  /align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj
  /align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj
  pe2kos hello.exe hello
  pe2kos hello.exe hello
[[File:Hll_vc3.gif]]


VS2005 adds new options:
VS2005 adds new options:
Line 78: Line 88:
  /align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj
  /align:16 /nodefaultlib hello.obj kosFile.obj kosSyst.obj mcsmemm.obj
  pe2kos hello.exe hello
  pe2kos hello.exe hello
[[File:Hll_vc4.gif]]
== GCC/G++ ==
* '''License''': free, open-source
* '''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''': dosbox, sdlfire, sdlquake, pig
* '''Generated code format''': 32-bit, probably, 16-bit
* '''Environment/platform''': 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.
To cross-compiling C and C++ programs for KolibriOS was created special toolchain.
Below you can see some manuals on how to install this toolchain on Linux and Windows.
=== Installation on Linux ===
Step-by-step manual here: http://board.kolibrios.org/viewtopic.php?f=33&t=3540
To simplify the process, turbocat wrote a script, which does all the things.
You can download it on this page: http://board.kolibrios.org/viewtopic.php?f=33&t=3540&p=76381#p76381
Example on how to compile Hello world here: https://habr.com/ru/post/527144/
<big>IMPORTANT:</big> warning from author:
  I don't recommend you to run the script from root (only enter the root password when will ask).
  Otherwise toolchain will be installed into root folder, not yours home folder.
=== Installation on Windows ===
Step-by-step manual here: https://habr.com/ru/post/229231/
To make it simpler, Boppan packed toolchain to the archive, available here:
http://board.kolibrios.org/viewtopic.php?f=33&t=1218&p=74401&hilit=kossdk#p74401
== 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).
* '''Example''': life2 (the sources are included to the distributive sources - folders programs\demos\life2)
* '''Generated code format''': 32-bit PE
* '''Environment/platform''': 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
[[File:Hll_bc1.gif]]
== Tiny C Compiler ==
* '''License''': free, OpenSource
* '''Available Kolibri libraries''': big part of RTL (Run-Time Library, standard C library)
* '''Examples''': TinyTextEditor, TinyHashView
* '''Generated code format''': 32-bit COFF, ELF, PE, Kolibri
* '''Environment/platform''': 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, compiled compiler and RTL are available at Kolibri svn-server: [http://websvn.kolibrios.org/listing.php?repname=Kolibri+OS&path=%2Fprograms%2Fdevelop%2Fktcc%2Ftrunk%2F&#aace07482da4e601a5ccc78934b6e811d svn://kolibrios.org/programs/develop/ktcc/trunk].
The code (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;
                }
        }
}
Compilation:
tcc hello.c -lck -o hello.kex
[[Category:Coding]]

Latest revision as of 17:31, 10 June 2021

This section describes C/C++ programming for Kolibri.

Warning: The pages below this line require rewriting - copied from Diamond's pages

Visual C++ 6/.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: LZMA compression library lzmapack.lib; any code, which does not use OS calls and is compiled to object files understandable by the Microsoft linker, can be used (in particular, the many C libraries). Unfortunately, this does not apply to standard RTL (Run-Time Library), so all missing functions must be implemented by hand. However, some of them are already written.
  • Examples: 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 format: 32-bit PE and (for later versions) 64-bit PE64 code depending on used format
  • Environment/platform: Windows, command line or IDE

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).

Hll vc1.gif

Hll vc2.gif

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

Hll vc3.gif

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

Hll vc4.gif

GCC/G++

  • License: free, open-source
  • 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: dosbox, sdlfire, sdlquake, pig
  • Generated code format: 32-bit, probably, 16-bit
  • Environment/platform: 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.

To cross-compiling C and C++ programs for KolibriOS was created special toolchain.

Below you can see some manuals on how to install this toolchain on Linux and Windows.

Installation on Linux

Step-by-step manual here: http://board.kolibrios.org/viewtopic.php?f=33&t=3540 To simplify the process, turbocat wrote a script, which does all the things. You can download it on this page: http://board.kolibrios.org/viewtopic.php?f=33&t=3540&p=76381#p76381

Example on how to compile Hello world here: https://habr.com/ru/post/527144/

IMPORTANT: warning from author:

 I don't recommend you to run the script from root (only enter the root password when will ask).
 Otherwise toolchain will be installed into root folder, not yours home folder.

Installation on Windows

Step-by-step manual here: https://habr.com/ru/post/229231/

To make it simpler, Boppan packed toolchain to the archive, available here:

http://board.kolibrios.org/viewtopic.php?f=33&t=1218&p=74401&hilit=kossdk#p74401

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).
  • Example: life2 (the sources are included to the distributive sources - folders programs\demos\life2)
  • Generated code format: 32-bit PE
  • Environment/platform: 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

Hll bc1.gif

Tiny C Compiler

  • License: free, OpenSource
  • Available Kolibri libraries: big part of RTL (Run-Time Library, standard C library)
  • Examples: TinyTextEditor, TinyHashView
  • Generated code format: 32-bit COFF, ELF, PE, Kolibri
  • Environment/platform: 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, compiled compiler and RTL are available at Kolibri svn-server: svn://kolibrios.org/programs/develop/ktcc/trunk.


The code (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;
                }
        }
}

Compilation:

tcc hello.c -lck -o hello.kex