OSDN Git Service

【更新内容】
[ring-lang-081/ring.git] / docs / en / source / distribute_ring2exe.txt
1 .. index:: 
2         single: Distributing Ring Application using Ring2EXE; Introduction
3
4 =============================================
5 Distributing Ring Applications using Ring2EXE
6 =============================================
7
8 In this chapter we will learn about distributing Ring applications.
9
10 Starting from Ring 1.6 we have a nice tool called Ring2EXE (Written in Ring itself)
11
12 Using Ring2EXE we can distribute applications quickly for Windows, Linux, macOS and Mobile devices
13
14 .. note:: We can use the Distribute Menu in the Ring Notepad application (More Easy)
15
16 .. index:: 
17         pair: Distributing Ring Application using Ring2EXE; Using Ring2EXE
18
19 Using Ring2EXE
20 ==============
21
22 .. code-block:: none
23
24                 ring2exe filename.ring [Options]
25
26 This will set filename.ring as input to the program     
27
28 The next files will be generated 
29
30 .. code-block:: none
31
32                 filename.ringo          (The Ring Object File - by Ring Compiler)
33                 filename.c              (The C Source code file
34                                          Contains the ringo file content
35                                          Will be generated by this program)
36                 filename_buildvc.bat    (Will be executed to build filename.c using Visual C/C++)
37                 filename_buildgcc.bat   (Will be executed to build filename.c using GNU C/C++)
38                 filename_buildclang.bat (Will be executed to build filename.c using CLang C/C++)
39                 filename.obj            (Will be generated by the Visual C/C++ compiler) 
40                 filename.exe            (Will ge generated by the Visual C/C++ Linker)
41                 filename                (Executable File - On Linux & MacOS X platforms)
42
43 .. index:: 
44         pair: Distributing Ring Application using Ring2EXE; How Ring2EXE works?
45
46 How Ring2EXE works?
47 ===================
48
49 At first the Ring compiler will be used to generate the Ring object file (*.ringo)
50
51 If we have a C compiler (optional), This object file will be embedded inside a C source code file
52
53 Then using the C compiler and the Ring library (Contains the Ring Virtual Machine) the executable file
54
55 will be generated!
56
57 If we don't have a C compiler, the Ring executable will be copied and renamed to your application name
58
59 And your Ring object file (*.ringo) will become ring.ringo to be executed at startup of the executable file.
60
61 So it's better and easy to have a C compiler on your machine to be used by Ring2EXE. 
62
63 .. index:: 
64         pair: Distributing Ring Application using Ring2EXE; Example
65
66 Example 
67 =======
68
69 We have test.ring contains the next code
70
71 .. code-block:: ring
72
73         see "Hello, World!" + nl
74
75 To build th executable file for Windows, Linux or macOS
76
77 .. code-block:: none
78         
79                 ring2exe test.ring 
80
81 To run the program (Windows)
82
83 .. code-block:: none
84
85                 test 
86
87 To run the program (Linux and macOS)
88
89 .. code-block:: none
90
91                 ./test
92
93
94 .. index:: 
95         pair: Distributing Ring Application using Ring2EXE; Options
96
97 Options
98 =======
99
100 .. code-block:: none
101
102                 -keep            : Don't delete Temp. Files
103                 -static          : Build Standalone Executable File 
104                                    (Don't use ring.dll/ring.so/ring.dylib)
105                 -gui             : Build GUI Application (Hide the Console Window)
106                 -dist            : Prepare application for distribution 
107                 -allruntime      : Include all libraries in distribution
108                 -mobileqt        : Prepare Qt Project to distribute Ring Application for Mobile
109                 -noqt            : Remove RingQt from distribution
110                 -noallegro       : Remove RingAllegro from distribution
111                 -noopenssl       : Remove RingOpenSSL from distribution
112                 -nolibcurl       : Remove RingLibCurl from distribution
113                 -nomysql         : Remove RingMySQL from distribution
114                 -noodbc          : Remove RingODBC from distribution
115                 -nosqlite        : Remove RingSQLite from distribution
116                 -noopengl        : Remove RingOpenGL from distribution
117                 -nofreeglut      : Remove RingFreeGLUT from distribution
118                 -nolibzip        : Remove RingLibZip from distribution
119                 -noconsolecolors : Remove RingConsoleColors from distribution
120                 -nomurmuhash     : Remove RingMurmurHash from distribution
121                 -nocruntime      : Remove C Runtime from distribution
122                 -qt              : Add RingQt to distribution
123                 -allegro         : Add RingAllegro to distribution
124                 -openssl         : Add RingOpenSSL to distribution
125                 -libcurl         : Add RingLibCurl to distribution
126                 -mysql           : Add RingMySQL to distribution
127                 -odbc            : Add RingODBC to distribution
128                 -sqlite          : Add RingSQLite to distribution
129                 -postgresql      : Add RingPostgreSQL to distribution
130                 -opengl          : Add RingOpenGL to distribution
131                 -freeglut        : Add RingFreeGLUT to distribution
132                 -libzip          : Add RingLibZip to distribution
133                 -libuv           : Add RingLibuv to distribution
134                 -consolecolors   : Add RingConsoleColors to distribution
135                 -murmurhash      : Add RingMurmurHash to distribution
136                 -cruntime        : Add C Runtime to distribution
137
138 .. index:: 
139         pair: Distributing Ring Application using Ring2EXE; Building standalone console application
140
141 Building standalone console application
142 =======================================
143
144 Using the "-static" option we can build executable console application
145
146 So we don't have to use ring.dll, ring.so or ring.dylib 
147
148 This avoid only the need to Ring dynamic link library
149
150 If you are using another libraries, You will need to include it with your application. 
151
152 .. code-block:: none
153
154                 ring2exe test.ring -static
155
156
157 .. index:: 
158         pair: Distributing Ring Application using Ring2EXE; Distributing RingAllegro Applications
159
160 Distributing RingAllegro Applications
161 =====================================
162
163 We have test2.ring contains the next code
164
165 .. code-block:: ring
166
167
168         # Just a simple program to test Ring2EXE Tool!
169         # Using RingAllegro
170
171         load "gameengine.ring"  # Give Control to the Game Engine
172
173         func main               # Called by the Game Engine
174
175                 oGame = New Game        # Create the Game Object
176                 {
177                         title = "My First Game"
178                 }     
179
180
181 To build the executable file and prepare for distributing the Game
182
183 We use "-dist" option and "-allruntime" to include all libraries
184
185 .. code-block:: none
186
187         ring2exe test2.ring -dist -allruntime
188
189 After executing the previous command
190
191 On Windows we will have : target/windows folder
192
193 On Linux we will have   : target/linux folder
194
195 On macOS we will have   : target/macos folder
196
197 The previous command will add all of the Ring runtime libraries to our distribution
198
199 But we may need only RingAllegro, So it's better to use the next command
200
201 .. code-block:: none
202
203         ring2exe test2.ring -dist -allegro -cruntime
204
205 This will produce smaller size distribution and will avoid the runtime files that we don't need!
206
207
208 Also we could use the "-gui" option to hide the console window
209
210 So it's better to use the next command
211
212 .. code-block:: none
213
214         ring2exe test2.ring -dist -gui -allegro -cruntime
215
216 .. index:: 
217         pair: Distributing Ring Application using Ring2EXE; Distributing RingAllegro Applications
218
219 Distributing RingQt Applications
220 ================================
221
222 We have test3.ring contains the next code
223
224 .. code-block:: ring
225
226         # Just a simple program to test Ring2EXE Tool!
227         # Using RingQt
228
229         load "guilib.ring"
230
231         new qApp {
232                 new qWidget() {
233                         setwindowtitle("Hello, World!")
234                         resize(400,400)
235                         show()
236                 }
237                 exec()
238         }
239
240
241 To build the executable file and prepare for distributing the GUI application
242
243 We use "-dist" option and "-allruntime" to include all libraries
244
245 .. code-block:: none
246
247         ring2exe test3.ring -dist -allruntime
248
249 After executing the previous command
250
251 On Windows we will have : target/windows folder
252
253 On Linux we will have   : target/linux folder
254
255 On macOS we will have   : target/macos folder
256
257 The previous command will add all of the Ring runtime libraries to our distribution
258
259 But we may need only RingQt, So it's better to use the next command
260
261 .. code-block:: none
262
263         ring2exe test3.ring -dist -qt -cruntime
264
265 This will produce smaller size distribution and will avoid the runtime files that we don't need!
266
267 Also we could use the "-gui" option to hide the console window
268
269 So it's better to use the next command
270
271 .. code-block:: none
272
273         ring2exe test3.ring -dist -gui -qt -cruntime
274
275 .. index:: 
276         pair: Distributing Ring Application using Ring2EXE; Distributing Applications for Mobile using RingQt
277
278 Distributing Applications for Mobile using RingQt
279 =================================================
280
281 To prepare a Qt project for your RingQt application (test3.ring) use the "-mobileqt" option
282
283 Example :
284
285 .. code-block:: none
286
287         ring2exe test3.ring -dist -mobileqt
288
289 After executing the previous command, We will have the Qt project in target/mobile/qtproject folder
290
291 The main project file will be project.pro which we can open using the Qt Creator IDE.
292
293 Also we will have the resource file : project.qrc 
294
295 Another important file is our C++ main file : main.cpp
296
297
298 .. index:: 
299         pair: Distributing Ring Application using Ring2EXE; Building the Cards Game for Mobile using RingQt
300
301 Building the Cards Game for Mobile using RingQt
302 ===============================================
303
304 For a better example, consider building an Android package for the Cards game that comes with the
305
306 Ring language in this folder : ring/application/cards
307
308 The Cards game folder contains three files
309
310 cards.ring : The Game source code
311
312 cards.jpg : The image file used by the game
313
314 project.qrc : Resource file to be used with the Qt project
315
316 The resource file contains the next content
317
318 .. code-block:: none
319
320         <RCC>
321                 <qresource>
322                         <file>cards.ringo</file>
323                         <file>cards.jpg</file>
324                 </qresource>
325         </RCC>
326
327 We have two files in the resource file
328
329 The first file is cards.ringo (The Ring Object File) and the second file is cards.jpg (The image file)
330
331 As a start, Ring2EXE will generate this resource file in target/mobile/qtproject/project.qrc
332
333 But this file will contains only cards.ringo (That Ring2EXE will generate by calling Ring compiler)
334
335 We need to update this resource file to add the image file : cards.jpg 
336
337 After this update, we copy the resource file to the main application folder
338
339 So when we use Ring2EXE again, Our updated resource file will be used!
340
341 Now to build the cards game for Mobile
342
343 (1) Run the next command
344
345 .. code-block:: none
346
347         ring2exe cards.ring -dist -mobileqt
348
349 (2) Open target/mobile/qtproject/project.pro using Qt creator
350
351 (3) Build and Run using Qt Creator 
352
353
354 How the Cards game will find the image file ?
355
356 RingQt comes with a simple function : AppFile() that we can use to determine the files that we may
357
358 access on Desktop or Mobile platforms
359
360 The next code from cards.ring
361
362 .. code-block:: ring
363
364         mypic = new QPixmap(AppFile("cards.jpg"))
365
366 So all what you need is using AppFile() function around your image files!
367
368 .. index:: 
369         pair: Distributing Ring Application using Ring2EXE; Building the Weight History Application for Mobile using RingQt
370
371 Building the Weight History Application for Mobile using RingQt
372 ===============================================================
373
374 Another example to distribute your application for Mobile Devices using Ring2EXE and Qt
375
376 consider building an Android package for the Weight History application that comes with the
377
378 Ring language in this folder : ring/application/weighthistory 
379
380 The Weight History application folder contains four files
381
382 weighthistory.ring : The application source code
383
384 weighthistory.db  : The SQLite database
385
386 project.qrc : The resource file for the Qt project
387
388 main.cpp : The main C++ source file for the Qt project
389
390 To build the Weight History application for Mobile
391
392 (1) Run the next command
393
394 .. code-block:: none
395
396         ring2exe weighthistory.ring -dist -mobileqt
397
398 (2) Open target/mobile/qtproject/project.pro using Qt creator
399
400 (3) Build and Run using Qt Creator 
401
402 The resource file (project.qrc) contains two files
403
404 .. code-block:: none
405
406         <RCC>
407                 <qresource>
408                         <file>weighthistory.ringo</file>
409                         <file>weighthistory.db</file>
410                 </qresource>
411         </RCC>
412
413 The first file is weighthistory.ringo (Ring Object File - Generated by Ring2EXE by calling Ring compiler)
414
415 The database file : weighthistory.db
416
417 The main.cpp contains the next little update, To copy the database file from resources to a writable location
418
419 on the mobile device
420
421 .. code-block:: none
422
423     QString path3 ;
424     path3 = path+"/weighthistory.db";
425     QFile::copy(":/weighthistory.db",path3);
426
427 You will need to do this with database files only!
428
429 When we use Ring2EXE, the tool will check for project.qrc and main.cpp, if they exist then your updated
430
431 files will be used in target/mobile/qtproject instead of the default version generated by Ring2EXE
432
433 So Use Ring2EXE to generate these files, Then copy them to your application folder when you update them.
434
435 .. index:: 
436         pair: Distributing Ring Application using Ring2EXE; Building the Form Designer for Mobile using RingQt
437
438 Building the Form Designer for Mobile using RingQt
439 ==================================================
440
441 To build the Form Designer application (ring/applications/formdesigner) for Mobile
442
443 (1) Run the next command
444
445 .. code-block:: none
446
447         ring2exe formdesigner.ring -dist -mobileqt
448
449 (2) Open target/mobile/qtproject/project.pro using Qt creator
450
451 (3) Build and Run using Qt Creator 
452
453 in the folder ring/application/formdesigner You will find the resource file : project.qrc
454
455 It will be used automatically by Ring2EXE 
456
457 .. code-block:: none
458
459         <RCC>
460                 <qresource>
461                         <file>formdesigner.ringo</file>
462                         <file>image/allevents.png</file>
463                         <file>image/checkbox.png</file>
464                         <file>image/close.png</file>
465                         <file>image/combobox.bmp</file>
466                         <file>image/datepicker.bmp</file>
467                         <file>image/dial.png</file>
468                         <file>image/formdesigner.png</file>
469                         <file>image/frame.png</file>
470                         <file>image/grid.bmp</file>
471                         <file>image/hyperlink.png</file>
472                         <file>image/image.png</file>
473                         <file>image/label.png</file>
474                         <file>image/layout.png</file>
475                         <file>image/lcdnumber.png</file>
476                         <file>image/listview.png</file>
477                         <file>image/lock.png</file>
478                         <file>image/new.png</file>
479                         <file>image/open.png</file>
480                         <file>image/progressbar.png</file>
481                         <file>image/project.png</file>
482                         <file>image/pushbutton.png</file>
483                         <file>image/radiobutton.png</file>
484                         <file>image/save.png</file>
485                         <file>image/saveas.png</file>
486                         <file>image/select.png</file>
487                         <file>image/slider.png</file>
488                         <file>image/spinner.bmp</file>
489                         <file>image/statusbar.png</file>
490                         <file>image/tab.png</file>
491                         <file>image/textarea.png</file>
492                         <file>image/textfield.png</file>
493                         <file>image/timer.png</file>
494                         <file>image/toolbar.png</file>
495                         <file>image/tree.bmp</file>
496                         <file>image/videowidget.png</file>
497                         <file>image/webview.png</file>
498                 </qresource>
499         </RCC>
500
501 As we did in the Cards game, The Form Designer will use the AppFile() function to determine the
502 name of the Image files.
503
504 The next code from ring/applications/formdesigner/mainwindow/formdesignerview.ring
505
506 .. code-block:: ring
507
508         func CreateToolBar
509                 aBtns = [
510                                 new qtoolbutton(win) {
511                                         setbtnimage(self,AppFile("image/new.png"))
512                                         setclickevent(Method(:NewAction))
513                                         settooltip("New File")
514                                 } ,
515                                 new qtoolbutton(win) {
516                                         setbtnimage(self,AppFile("image/open.png"))
517                                         setclickevent(Method(:OpenAction))
518                                         settooltip("Open File")
519                                 } ,
520                                 new qtoolbutton(win) {
521                                         setbtnimage(self,AppFile("image/save.png"))
522                                         setclickevent(Method(:SaveAction))
523                                         settooltip("Save")
524                                  } ,
525                                 new qtoolbutton(win) {
526                                         setbtnimage(self,AppFile("image/saveas.png"))
527                                         setclickevent(Method(:SaveAsAction))
528                                         settooltip("Save As")
529                                  } ,
530                                 new qtoolbutton(win) {
531                                         setbtnimage(self,AppFile("image/close.png"))
532                                         setclickevent(Method(:ExitAction))
533                                         settooltip("Exit")
534                                 }
535                         ]
536
537                 tool1 = win.addtoolbar("files")  {
538                         for x in aBtns { addwidget(x) addseparator() }
539                 }
540
541 From this example, We know that we can use sub folders for images.
542
543
544 .. index:: 
545         pair: Distributing Ring Application using Ring2EXE; Creating the Qt resource file using Folder2qrc
546
547 Creating the Qt resource file using Folder2qrc
548 ==============================================
549
550 When we have large RingQt project that contains a lot of images and files, We need to add these files 
551 to the resource file ( *.qrc ) when distributing applications for Mobile devices. 
552
553 Instead of adding these files one by one, Ring 1.6 comes with a simple tool that save our time, It's
554 called Folder2qrc.
555
556 Example:
557
558 .. code-block:: none
559
560         folder2qrc formdesigner.ring
561
562 We determine the main source file while we are in the application folder, and Folder2qrc will check all
563 of the files in the current folder and sub folders, Then add them to the resource file after the
564 mainfile.ringo (In our example this will be formdesigner.ringo)
565
566 The output file will be : project.qrc
567
568 You can open it and remove the files that you don't need in the resources!
569
570
571 .. index:: 
572         pair: Distributing Ring Application using Ring2EXE; Important Information about Ring2EXE
573
574 Important Information about Ring2EXE
575 ====================================
576
577 * Using Ring2EXE to prepare distribution will delete all of the files in the old distribution
578
579 for example, if you have target/windows folder then used
580
581 .. code-block:: none
582
583         ring2exe test3.ring -dist -allruntime
584
585 The files in target/windows will be deleted before adding the files again
586
587 This is important when you prepare a distribution for Mobile devices
588
589 .. code-block:: none
590
591         ring2exe test3.ring -dist -mobileqt
592
593 If you modified the resource file : project.qrc or the main file : main.cpp
594
595 Don't forget to copy them to the application folder!
596
597 So Ring2EXE can use the updated version if you tried the previous command again!
598
599 * Ring2EXE is written in Ring, and you can read the source code from
600
601         https://github.com/ring-lang/ring/blob/master/ring2exe/ring2exe.ring
602
603 * The libraries information are stored in a separated files, So these files can be updated in the future
604 automatically to support new libraries
605
606         https://github.com/ring-lang/ring/blob/master/ring2exe/libs
607