.. index:: 
	single: Distributing Ring Application using Ring2EXE; Introduction

=============================================
Distributing Ring Applications using Ring2EXE
=============================================

In this chapter we will learn about distributing Ring applications.

Starting from Ring 1.6 we have a nice tool called Ring2EXE (Written in Ring itself)

Using Ring2EXE we can distribute applications quickly for Windows, Linux, macOS, WebAssembly and Mobile devices

.. note:: We can use the Distribute Menu in the Ring Notepad application (More Easy)

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Using Ring2EXE

Using Ring2EXE
==============

.. code-block:: none

		ring2exe filename.ring [Options]

This will set filename.ring as input to the program 	

The next files will be generated 

.. code-block:: none

		filename.ringo	  	(The Ring Object File - by Ring Compiler)
		filename.c	  	(The C Source code file
					 Contains the ringo file content
					 Will be generated by this program)
		filename_buildvc.bat 	(Will be executed to build filename.c using Visual C/C++)
		filename_buildgcc.bat 	(Will be executed to build filename.c using GNU C/C++)
		filename_buildclang.bat (Will be executed to build filename.c using CLang C/C++)
		filename.obj	  	(Will be generated by the Visual C/C++ compiler) 
		filename.exe 	  	(Will ge generated by the Visual C/C++ Linker)
		filename	  	(Executable File - On Linux & MacOS X platforms)

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; How Ring2EXE works?

How Ring2EXE works?
===================

At first the Ring compiler will be used to generate the Ring object file (*.ringo)

If we have a C compiler (optional), This object file will be embedded inside a C source code file

Then using the C compiler and the Ring library (Contains the Ring Virtual Machine) the executable file

will be generated!

If we don't have a C compiler, the Ring executable will be copied and renamed to your application name

And your Ring object file (*.ringo) will become ring.ringo to be executed at startup of the executable file.

So it's better and easy to have a C compiler on your machine to be used by Ring2EXE. 

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Example

Example 
=======

We have test.ring contains the next code

.. code-block:: ring

	see "Hello, World!" + nl

To build th executable file for Windows, Linux or macOS

.. code-block:: none
	
		ring2exe test.ring 

To run the program (Windows)

.. code-block:: none

		test 

To run the program (Linux and macOS)

.. code-block:: none

		./test


.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Options

Options
=======

.. code-block:: none

		-keep       	 : Don't delete Temp. Files
		-static     	 : Build Standalone Executable File 
				   (Don't use ring.dll/ring.so/ring.dylib)
		-gui        	 : Build GUI Application (Hide the Console Window)
		-dist	    	 : Prepare application for distribution 
		-allruntime 	 : Include all libraries in distribution
		-mobileqt	 : Prepare Qt Project to distribute Ring Application for Mobile
		-webassemblyqt	 : Prepare Qt Project to distribute Ring Application for the web (WebAssembly)
		-noqt	    	 : Remove RingQt from distribution
		-noallegro 	 : Remove RingAllegro from distribution
		-noopenssl  	 : Remove RingOpenSSL from distribution
		-nolibcurl  	 : Remove RingLibCurl from distribution
		-nomysql    	 : Remove RingMySQL from distribution
		-noodbc     	 : Remove RingODBC from distribution
		-nosqlite   	 : Remove RingSQLite from distribution
		-noopengl   	 : Remove RingOpenGL from distribution
		-nofreeglut 	 : Remove RingFreeGLUT from distribution
		-nolibzip   	 : Remove RingLibZip from distribution
		-noconsolecolors : Remove RingConsoleColors from distribution
		-nomurmuhash	 : Remove RingMurmurHash from distribution
		-nocruntime	 : Remove C Runtime from distribution
		-qt	    	 : Add RingQt to distribution
		-allegro 	 : Add RingAllegro to distribution
		-openssl  	 : Add RingOpenSSL to distribution
		-libcurl  	 : Add RingLibCurl to distribution
		-mysql    	 : Add RingMySQL to distribution
		-odbc     	 : Add RingODBC to distribution
		-sqlite   	 : Add RingSQLite to distribution
		-postgresql	 : Add RingPostgreSQL to distribution
		-opengl   	 : Add RingOpenGL to distribution
		-freeglut 	 : Add RingFreeGLUT to distribution
		-libzip   	 : Add RingLibZip to distribution
		-libuv		 : Add RingLibuv to distribution
		-consolecolors   : Add RingConsoleColors to distribution
		-murmurhash	 : Add RingMurmurHash to distribution
		-cruntime	 : Add C Runtime to distribution

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Building standalone console application

Building standalone console application
=======================================

Using the "-static" option we can build executable console application

So we don't have to use ring.dll, ring.so or ring.dylib 

This avoid only the need to Ring dynamic link library

If you are using another libraries, You will need to include it with your application. 

.. code-block:: none

		ring2exe test.ring -static


.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Distributing RingAllegro Applications

Distributing RingAllegro Applications
=====================================

We have test2.ring contains the next code

.. code-block:: ring


	# Just a simple program to test Ring2EXE Tool!
	# Using RingAllegro

	load "gameengine.ring"  # Give Control to the Game Engine

	func main               # Called by the Game Engine

	        oGame = New Game        # Create the Game Object
        	{
                	title = "My First Game"
        	}     


To build the executable file and prepare for distributing the Game

We use "-dist" option and "-allruntime" to include all libraries

.. code-block:: none

	ring2exe test2.ring -dist -allruntime

After executing the previous command

On Windows we will have : target/windows folder

On Linux we will have   : target/linux folder

On macOS we will have   : target/macos folder

The previous command will add all of the Ring runtime libraries to our distribution

But we may need only RingAllegro, So it's better to use the next command

.. code-block:: none

	ring2exe test2.ring -dist -allegro -cruntime

This will produce smaller size distribution and will avoid the runtime files that we don't need!


Also we could use the "-gui" option to hide the console window

So it's better to use the next command

.. code-block:: none

	ring2exe test2.ring -dist -gui -allegro -cruntime

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Distributing RingAllegro Applications

Distributing RingQt Applications
================================

We have test3.ring contains the next code

.. code-block:: ring

	# Just a simple program to test Ring2EXE Tool!
	# Using RingQt

	load "guilib.ring"

	new qApp {
		new qWidget() {
			setwindowtitle("Hello, World!")
			resize(400,400)
			show()
		}
		exec()
	}


To build the executable file and prepare for distributing the GUI application

We use "-dist" option and "-allruntime" to include all libraries

.. code-block:: none

	ring2exe test3.ring -dist -allruntime

After executing the previous command

On Windows we will have : target/windows folder

On Linux we will have   : target/linux folder

On macOS we will have   : target/macos folder

The previous command will add all of the Ring runtime libraries to our distribution

But we may need only RingQt, So it's better to use the next command

.. code-block:: none

	ring2exe test3.ring -dist -qt -cruntime

This will produce smaller size distribution and will avoid the runtime files that we don't need!

Also we could use the "-gui" option to hide the console window

So it's better to use the next command

.. code-block:: none

	ring2exe test3.ring -dist -gui -qt -cruntime

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Distributing Applications for Mobile using RingQt

Distributing Applications for Mobile using RingQt
=================================================

To prepare a Qt project for your RingQt application (test3.ring) use the "-mobileqt" option

Example :

.. code-block:: none

	ring2exe test3.ring -dist -mobileqt

After executing the previous command, We will have the Qt project in target/mobile/qtproject folder

The main project file will be project.pro which we can open using the Qt Creator IDE.

Also we will have the resource file : project.qrc 

Another important file is our C++ main file : main.cpp


.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Distributing Applications for WebAssembly using RingQt

Distributing Applications for WebAssembly using RingQt
======================================================

To prepare a Qt project (WebAssembly) for your RingQt application (myapp.ring) use the "-webassemblyqt" option

Example :

.. code-block:: none

	ring2exe myapp.ring -dist -webassemblyqt

After executing the previous command, We will have the Qt project in target/webassembly/qtproject folder

The main project file will be project.pro which we can open using the Qt Creator IDE.

Also we will have the resource file : project.qrc 

Another important file is our C++ main file : main.cpp


.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Building the Cards Game for Mobile using RingQt

Building the Cards Game for Mobile using RingQt
===============================================

For a better example, consider building an Android package for the Cards game that comes with the

Ring language in this folder : ring/application/cards

The Cards game folder contains three files

cards.ring : The Game source code

cards.jpg : The image file used by the game

project.qrc : Resource file to be used with the Qt project

The resource file contains the next content

.. code-block:: none

	<RCC>
    		<qresource>
        		<file>cards.ringo</file>
			<file>cards.jpg</file>
    		</qresource>
	</RCC>

We have two files in the resource file

The first file is cards.ringo (The Ring Object File) and the second file is cards.jpg (The image file)

As a start, Ring2EXE will generate this resource file in target/mobile/qtproject/project.qrc

But this file will contains only cards.ringo (That Ring2EXE will generate by calling Ring compiler)

We need to update this resource file to add the image file : cards.jpg 

After this update, we copy the resource file to the main application folder

So when we use Ring2EXE again, Our updated resource file will be used!

Now to build the cards game for Mobile

(1) Run the next command

.. code-block:: none

	ring2exe cards.ring -dist -mobileqt

(2) Open target/mobile/qtproject/project.pro using Qt creator

(3) Build and Run using Qt Creator 


How the Cards game will find the image file ?

RingQt comes with a simple function : AppFile() that we can use to determine the files that we may

access on Desktop or Mobile platforms

The next code from cards.ring

.. code-block:: ring

	mypic = new QPixmap(AppFile("cards.jpg"))

So all what you need is using AppFile() function around your image files!

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Building the Weight History Application for Mobile using RingQt

Building the Weight History Application for Mobile using RingQt
===============================================================

Another example to distribute your application for Mobile Devices using Ring2EXE and Qt

consider building an Android package for the Weight History application that comes with the

Ring language in this folder : ring/application/weighthistory 

The Weight History application folder contains four files

weighthistory.ring : The application source code

weighthistory.db  : The SQLite database

project.qrc : The resource file for the Qt project

main.cpp : The main C++ source file for the Qt project

To build the Weight History application for Mobile

(1) Run the next command

.. code-block:: none

	ring2exe weighthistory.ring -dist -mobileqt

(2) Open target/mobile/qtproject/project.pro using Qt creator

(3) Build and Run using Qt Creator 

The resource file (project.qrc) contains two files

.. code-block:: none

	<RCC>
		<qresource>
			<file>weighthistory.ringo</file>
			<file>weighthistory.db</file>
		</qresource>
	</RCC>

The first file is weighthistory.ringo (Ring Object File - Generated by Ring2EXE by calling Ring compiler)

The database file : weighthistory.db

The main.cpp contains the next little update, To copy the database file from resources to a writable location

on the mobile device

.. code-block:: none

    QString path3 ;
    path3 = path+"/weighthistory.db";
    QFile::copy(":/weighthistory.db",path3);

You will need to do this with database files only!

When we use Ring2EXE, the tool will check for project.qrc and main.cpp, if they exist then your updated

files will be used in target/mobile/qtproject instead of the default version generated by Ring2EXE

So Use Ring2EXE to generate these files, Then copy them to your application folder when you update them.

.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Building the Form Designer for Mobile using RingQt

Building the Form Designer for Mobile using RingQt
==================================================

To build the Form Designer application (ring/tools/formdesigner) for Mobile

(1) Run the next command

.. code-block:: none

	ring2exe formdesigner.ring -dist -mobileqt

(2) Open target/mobile/qtproject/project.pro using Qt creator

(3) Build and Run using Qt Creator 

in the folder ring/application/formdesigner You will find the resource file : project.qrc

It will be used automatically by Ring2EXE 

.. code-block:: none

	<RCC>
		<qresource>
			<file>formdesigner.ringo</file>
			<file>image/allevents.png</file>
			<file>image/checkbox.png</file>
			<file>image/close.png</file>
			<file>image/combobox.bmp</file>
			<file>image/datepicker.bmp</file>
			<file>image/dial.png</file>
			<file>image/formdesigner.png</file>
			<file>image/frame.png</file>
			<file>image/grid.bmp</file>
			<file>image/hyperlink.png</file>
			<file>image/image.png</file>
			<file>image/label.png</file>
			<file>image/layout.png</file>
			<file>image/lcdnumber.png</file>
			<file>image/listview.png</file>
			<file>image/lock.png</file>
			<file>image/new.png</file>
			<file>image/open.png</file>
			<file>image/progressbar.png</file>
			<file>image/project.png</file>
			<file>image/pushbutton.png</file>
			<file>image/radiobutton.png</file>
			<file>image/save.png</file>
			<file>image/saveas.png</file>
			<file>image/select.png</file>
			<file>image/slider.png</file>
			<file>image/spinner.bmp</file>
			<file>image/statusbar.png</file>
			<file>image/tab.png</file>
			<file>image/textarea.png</file>
			<file>image/textfield.png</file>
			<file>image/timer.png</file>
			<file>image/toolbar.png</file>
			<file>image/tree.bmp</file>
			<file>image/videowidget.png</file>
			<file>image/webview.png</file>
		</qresource>
	</RCC>

As we did in the Cards game, The Form Designer will use the AppFile() function to determine the
name of the Image files.

The next code from ring/tools/formdesigner/mainwindow/formdesignerview.ring

.. code-block:: ring

	func CreateToolBar
		aBtns = [
				new qtoolbutton(win) {
					setbtnimage(self,AppFile("image/new.png"))
					setclickevent(Method(:NewAction))
					settooltip("New File")
				} ,
				new qtoolbutton(win) {
					setbtnimage(self,AppFile("image/open.png"))
					setclickevent(Method(:OpenAction))
					settooltip("Open File")
				} ,
				new qtoolbutton(win) {
					setbtnimage(self,AppFile("image/save.png"))
					setclickevent(Method(:SaveAction))
					settooltip("Save")
				 } ,
				new qtoolbutton(win) {
					setbtnimage(self,AppFile("image/saveas.png"))
					setclickevent(Method(:SaveAsAction))
					settooltip("Save As")
				 } ,
				new qtoolbutton(win) {
					setbtnimage(self,AppFile("image/close.png"))
					setclickevent(Method(:ExitAction))
					settooltip("Exit")
				}
			]

		tool1 = win.addtoolbar("files")  {
	  		for x in aBtns { addwidget(x) addseparator() }
		}

From this example, We know that we can use sub folders for images.


.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Creating the Qt resource file using Folder2qrc

Creating the Qt resource file using Folder2qrc
==============================================

When we have large RingQt project that contains a lot of images and files, We need to add these files 
to the resource file ( *.qrc ) when distributing applications for Mobile devices. 

Instead of adding these files one by one, Ring 1.6 comes with a simple tool that save our time, It's
called Folder2qrc.

Example:

.. code-block:: none

	folder2qrc formdesigner.ring

We determine the main source file while we are in the application folder, and Folder2qrc will check all
of the files in the current folder and sub folders, Then add them to the resource file after the
mainfile.ringo (In our example this will be formdesigner.ringo)

The output file will be : project.qrc

You can open it and remove the files that you don't need in the resources!


.. index:: 
	pair: Distributing Ring Application using Ring2EXE; Important Information about Ring2EXE

Important Information about Ring2EXE
====================================

* Using Ring2EXE to prepare distribution will delete all of the files in the old distribution

for example, if you have target/windows folder then used

.. code-block:: none

	ring2exe test3.ring -dist -allruntime

The files in target/windows will be deleted before adding the files again

This is important when you prepare a distribution for Mobile devices

.. code-block:: none

	ring2exe test3.ring -dist -mobileqt

If you modified the resource file : project.qrc or the main file : main.cpp

Don't forget to copy them to the application folder!

So Ring2EXE can use the updated version if you tried the previous command again!

* Ring2EXE is written in Ring, and you can read the source code from

	https://github.com/ring-lang/ring/blob/master/tools/ring2exe/ring2exe.ring

* The libraries information are stored in a separated files, So these files can be updated in the future
automatically to support new libraries

	https://github.com/ring-lang/ring/blob/master/tools/ring2exe/libs

