.. 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 and Mobile devices .. 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 -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 -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; 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 cards.ringo cards.jpg 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 weighthistory.ringo weighthistory.db 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/applications/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 formdesigner.ringo image/allevents.png image/checkbox.png image/close.png image/combobox.bmp image/datepicker.bmp image/dial.png image/formdesigner.png image/frame.png image/grid.bmp image/hyperlink.png image/image.png image/label.png image/layout.png image/lcdnumber.png image/listview.png image/lock.png image/new.png image/open.png image/progressbar.png image/project.png image/pushbutton.png image/radiobutton.png image/save.png image/saveas.png image/select.png image/slider.png image/spinner.bmp image/statusbar.png image/tab.png image/textarea.png image/textfield.png image/timer.png image/toolbar.png image/tree.bmp image/videowidget.png image/webview.png 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/applications/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/ring2exe/ring2exe.ring * The libraries information are stored in a separated file, So this file can be updated in the future automatically to support new libraries https://github.com/ring-lang/ring/blob/master/ring2exe/ring2exe.data