aboutsummaryrefslogtreecommitdiffstats
path: root/packaging-tools/README
blob: 92d35edce6149de9dd9a82d2f20b0da8c63231f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1.  Introduction to installer scripts

    The folder packaging-tools of Qt 5's qtsdk module contains
    scripts to generate desktop installers based on the Qt
    Installer-Framework. Example configuration templates are provided
    but actual content that is to be installed needs to be generated
    separately.

    For detailed usage of the Qt Installer-Framework itself please refer to the
    Qt Installer-Framework documentation.

    The scripts can be used to create offline installers or online installers.
    For online installers you need a dedicated server to host the repositories.


2.  General requirements

    Make sure you have the following tools installed:
    - Python 2.6 or 2.7
    - Win: win32api python module
    - 7z

    Build requirements:
    - Linux/macOS: gcc toolchain
    - Windows: MinGW/Visual Studio toolchain

3.  Quick start

    The 'create_installer.py' only generates the installer itself and wraps the
    content inside. The actual installable content must be built separately
    and archived in 7z format for the installer.

    Let's assume that you want to create Qt 5 Beta offline installer that
    contains only Qt5 source and binary package.

    You should have the following packages built separately:
        - qt-everywhere-opensource-src-5.0.0.tar.gz i.e. the source pacakge
        - qt5_all.7z                                i.e. the Qt5 binary package (e.g. msvc2010 64-bit)

    Let's assume that you want to create the installer for Windows. Also let's
    assume that you will put the qt-everywhere-opensource-src-5.0.0.tar.gz and
    qt5_all.7z somewhere on your local file system.
    E.g.
        c:\my_qt5_builds\qt-everywhere-opensource-src-5.0.0.tar.gz
        c:\my_qt5_builds\qt5_all.7z


    Open '/configurations/win_x86_beta' and see the following items:

    (1)

        [src.qt.500_beta]
        archive_uri:         # This is the uri where the script will try to download this package
        package_strip_dirs:  # Strip this many unnecessary directories from the beginning of this package before creating the installer. See detailed explanation later in this document.
        archive_name:        # Needed for online installers. Leave as it is.

        -> So this part should look like this:

        [src.qt.500_beta]
        archive_uri:            c:\my_qt5_builds\qt-everywhere-opensource-src-5.0.0.tar.gz
        package_strip_dirs:     1
        target_install_dir:     /
        rpath_target:
        archive_name:           qt-everywhere-opensource-src-5.0.0.7z

    (2)

        [desktop.500_beta.msvc2010_64]
        archive_uri:            # This is the uri where the script will try to download this package
        package_strip_dirs:     # Strip this many unnecessary directories from the beginning of this package before creating the installer. See detailed explanation later in this document.
        archive_name:           # Needed for online installers. Leave as it is.

        -> So this part should look like this:

        [desktop.500_beta.msvc2010_64]
        archive_uri:            c:\my_qt5_builds\qt5_all.7z
        package_strip_dirs:     5
        archive_name:           msvc2010_64_all.7z


        Note! This example assumes that you don't want to include
        32-bit msvc2012 Qt binaries so delete the whole section:

        [qt.sdk.desktop.500_beta.msvc2010]


        Now you are ready the create the installer with the following command (on windows):

        > python create_installer.py -f win_x86_beta --offline --devmode

        Explanations:

            - win_x86_beta  i.e. the main configuration file you just edited
            - offline       creates offline installer
            - devmode       builds Qt Installer-Framework and static Qt4.8 libraries for it on the fly

        Depending on the speed of your computer the installer executable will
        be generated on the scripts root directory (30-60 minutes).


3.1 Offline installers for different platforms

    To create a standalone offline installer use:

    Linux:      python create_installer.py linux -f linux_x86_32_beta --offline --devmode
                OR
                python create_installer.py linux -f linux_x86_64_beta --offline --devmode

    macOS:      python create_installer.py mac -f mac_x86_64_beta --offline --devmode

    Windows:    python create_installer.py -f win_x86_beta --offline --devmode


    output:
        - SDK installer executable will be generated into the scripts root directory.
        - "repositories" directory will be generated into the scripts root directory



4   Detailed explanations about the internals

    Definitions:

        Component:  One component in install tree. E.g. 'qt.sdk.desktop'. Best
                    example can be found from existing installers (Qt SDK) where
                    you can see the "install-tree" where each 'node' represents
                    one component.

        Package:    In this context the 'package' refers to data content. Usually
                    in 7z format. One 'component' can contain multiple packages.

4.1 Configuration files

    Main configuration files reside in the root of '/Configurations'.
    Example main configuration files are:

        '/Configurations/linux_x86_32_beta'
        '/Configurations/linux_x86_64_beta'
        '/Configurations/mac_x86_32_beta'
        '/Configurations/win_x86_32_beta'

    The main configuration files can include other configuration files.
    This approach can be used if the number of installable components is large
    and you want to modularize the configuration files.

        '/Configurations/all-os'  directory can contain configuration files common for all platforms.
        '/Configurations/linux'   directory contains linux platform specific configuration files
        '/Configurations/mac'     directory contains mac platform specific configuration files
        '/Configurations/windows' directory contains windows platform specific configuration files

    Sub-configuration files contain only installable package releated information.
    Main configuratio file contain all the rest required information required for installer creation.

4.2 Package templates.

    Directory '/Configurations/pkg' contain the package templates.
    Example listing:

        com.qt
        com.qt.desktop
        com.qt.desktop.qt
        com.qt.desktop.qt.500
        com.qt.desktop.qt.500.gcc
        com.qt.src
        com.qt.src.500

    Each template has directory called 'meta'. This directory contains at least
    'package.xml' file that contains metadata about specified component.
    Other file commonly seen in the same directory is 'installscript.qs' yet
    optional. E.g.

    '/Configurations/pkg/com.qt.desktop.qt.500.gcc/meta/package.xml'
    '/Configurations/pkg/com.qt.desktop.qt.500.gcc/meta/installscript.xml'

    Note! For each item in the installer GUI 'install-tree' a template needs to exist.

    package.xml contains metadata and description fields for the specific component.
    installscript.qs can be used if the component installation requires some specific
    steps. E.g. Qt binary patching operation is triggered from here during installation phase.
    Please refer to Installer-Framework documentation for detailed instructions:  http://doc-snapshot.qt-project.org/qtifw-1.2/index.html


4.3 Main configuration file explained

    The syntax complies to Python config file format.
    See http://docs.python.org/library/configparser.html

    Brief explanation about the syntax:

        [Section_name]
        key1: value
        key2: value
        keyx: value

    The build script expects to find the following sections and values from the
    main configuration file:


        [PackageNamespace]
        name:                   qt.sdk                                          # Sections starting with this name are identified as components to be installed. E.g. [qt.sdk.desktop.500_beta.msvc2010]
                                                                                # The script will search through all included configuration files (main and sub) and check if the section starts with
                                                                                # 'qt.sdk' (in this example). If the condition is met then parse the key/value pairs under that section and load the
                                                                                # corresponding template from templates directory, e.g. '/configurations/pkg_beta/qt.sdk.desktop.500_beta.msvc2010'
        [PlatformIdentifier]
        identifier:             linux                                           # Check for sub-configuration files from '/configurations/linux'. E.g. on Windows replace this with 'windows'

        [ArchiveRemoteLocation.some_server_nickname_here]
        base_url:               http://<server_address_here>/packages/          # If you choose to put pre-build contents on some remote location (e.g. you have CI system that builds the
                                                                                # packages regularly) you can define the 'base_url' part here.
        base_path:                                                              # Will be deprecated. Do not use. Leave it empty.

        # for testing purposes
        [PackageIgnoreList]
        packages:               foo.bar, foo.bar2, foo.bar3                     # E.g. if you choose to make test installer build and want to exclude one component put the component name here
                                                                                # e.g. qt.sdk.desktop.500_beta.gcc_64

        [PackageConfigurationFiles]
        file_list:                                                              # if you have sub-configuration files e.g. in '/configurations/linux' directory, put the name of the file here.
                                                                                # multiple files can be included when separated by comma

        [OfflinePackageExcludeList]
        package_list:                                                           # if you create offline installer but still want to drop out some components which should reside in online repository
                                                                                # instead list them here, separated by comma. Only if you have server back end to support online repositories.

        [SdkUpdateRepository]
        repository_url_release: http://../qt5repository/linux/x64/online_qt5sdk_repo    # when creating online installer put the base url here where the installer expects to find the Updates.xml
        repository_url_rnd:     http://../qt5repository/linux/x64/online_qt5sdk_repo    # same as above, use this if you have dedicated RnD server for internal testing. Then the installer script
                                                                                        # must be started with additional 'testclient' command line argument

        [TargetArchitechture]
        instruction_set:        x86_64                                          # Currently used only for installer filename generation

        [ConfigDir]
        template_name:          config_qt5                                      # Script tries to locate config templates from directory '/configurations/config_qt5/'
                                                                                # This directory contains bitmaps and general installer resources.

        [ConfigXml]
        template_name:          config.xml.template.linux.qt5-beta              # Filename for the chosen config.xml template to be used. E.g. if your [PlatformIdentifier] is linux then
                                                                                # the script will try to locate the file from '/configurations/linux/'

        [PackageTemplates]
        template_dirs:          pkg_beta                                        # The script needs the location where to load the templates. Now it points to:
                                                                                # '/configurations/pkg_beta'

        [InstallerFrameworkTools]                                               # If you choose to use pre-build Installer-Framework binaries & tools you can give the full package url here
        name:                   ifwt                                            # but it is preferred to use the command line argument 'devmode' so the script will build the Installer-Framework
        package_url:            http://<server_address_here>/packages/.../installer-framework-build-linux-64bit.7z
        version:                1.2.0



    Note! So far no installable components have been defined yet! In the example
    Qt 5 Beta main configuration files the components are defined in the main
    configuration file as well. This approach can be used but when the amount
    of installable components grow it is recommended to split components in
    specific sub-configuration files which you include in this main configuration
    file. Put the sub-configuration files under directory defined in [PlatformIdentifier],
    e.g '/configurations/linux'


4.4 Defining components to be include in the installer

    Example component 1:

    [qt.sdk.desktop.500_beta.msvc2010_64]                                       # Name must start with 'qt.sdk' as defined in [PackageNamespace]
    archives:               archive_1, archive_2, foobar                        # List of archives to be included in this component
    target_install_base:    /Desktop/Qt/5.0.0-beta/msvc2010_64                  # The archives shall be extracted in this directory on user's computer (under <SDK_ROOT>)
    version:                5.0.0                                               # This version will be put into corresponding package.xml <version> field
    version_tag:            %QT_VERSION%                                        # If the package.xml contains <version>%QT_VERSION%</version> then the version number will get replaced automatically
    package_default:        true                                                # Will make the component shown as 'default' component in installer. Values: 'true', 'false', 'script'
    [archive_1]                                                                 # Defines one archive to be included for this component. This was included in the 'archives' list above
    archive_uri:            c:\my_qt5_builds\qt5_all.7z                         # Where to download the package.
    package_strip_dirs:     5                                                   # If your 'qt5_all.7z' containst dir structure you need to rip out e.g. '\temp\work\build\...' you can rip out
                                                                                # these by telling how many directories to strip from the beginning
    target_install_dir:     /                                                   # Normally leave as '/'. This path is appended into 'target_install_base' and the content is installed in this dir
    rpath_target:                                                               # Only for Unix like systems where RPath needs to be patched. If used (not empty) the script will patch the RPath
                                                                                # in executables and libraries found in the archive. E.g. on Linux the value here would be '/lib' where the
                                                                                # Qt libraries reside. The script will patch the RPath value to use relative paths.
    archive_name:           msvc2010_64_all.7z                                  # Only for online installers. This is the name for the package residing on online repositores (on server).
    [archive_2]                                                                 # Another archive to be included in for the component
    archive_uri:            c:\my_qt5_builds\cats.7z
    package_strip_dirs:     3
    target_install_dir:     /
    rpath_target:
    archive_name:           cats.7z
    [foobar]                                                                    # Yet another archive to be included in for the component
    archive_uri:            c:\my_qt5_builds\dogs.7z
    package_strip_dirs:
    target_install_dir:     /
    rpath_target:
    archive_name:           dogs.7z


    So this arbitrary example described one installable component that included three different archives.
    E.g. you might have component 'profiling tools' denoted as 'qt.sdk.misc.tools.profiling' and that installable
    component could include e.g. two archives 'mem leak analyzer' and 'heap profiler' etc. etc.


    Things to remember and notice!

    1) Each used component [qt.sdk.XXXXXXXXXX] must have corresponding template under
       'template_dirs' that was defined in the main configuration file.
       E.g. for this arbitrary component you should have
            '/configurations/pkg_beta/qt.sdk.XXXXXXXXXX'
            '/configurations/pkg_beta/qt.sdk.XXXXXXXXXX/meta'
            '/configurations/pkg_beta/qt.sdk.XXXXXXXXXX/meta/package.xml'
            '/configurations/pkg_beta/qt.sdk.XXXXXXXXXX/meta/installscript.qs' (optional)

    2) You can define 'empty' components without any data. You can just define
       the section name:
            [qt.sdk.YYYYYYYYYY]
       and the YYYYYYYYYY will be shown as one 'node' in the installer's 'install tree'.
       The corresponding template is always needed!
            '/configurations/pkg_beta/qt.sdk.YYYYYYYYYY'
            '/configurations/pkg_beta/qt.sdk.YYYYYYYYYY/meta'
            '/configurations/pkg_beta/qt.sdk.YYYYYYYYYY/meta/package.xml'

    3) The Qt Installer-Framework expects the packages to be in 7z format.
       However the script can manage source packages in .zip or in .tar.gz format
       (it will repackage those).


4.5 Package look-up order

    There are three possibilities where you can put the archives to be included in
    the installer. The script will try to locate the archive in the following
    order:

    - local file system, absolute path
    - archive under templates 'data' folder
    - remote location

    (1) Absolute file path usage:

        [archive_2]
        archive_uri:            c:\my_qt5_builds\cats.7z

        TODO: In theory the script should be able to fetch packages from mapped
              network drives but this is not tested.

    (2) Put archive under templates directory. E.g.

        '/configurations/pkg_beta/qt.sdk.YYYYYYYYYY/data/icons.7z

        This can be handy if you have some small archive that can reside
        in version controll as well. In this case the 'archive_uri' is:

            [archive_2]
            archive_uri:            icons.7z

    (3) Archives on remote location

        E.g. in win_x86_beta main configuration file first notice the following:

            [ArchiveRemoteLocation.some_server_nickname_here]
            base_url:               http://<server_address_here>/packages/

        Then define the archive uri as follows:

            [archive_2]
            archive_uri:            /qt/5.0.0/cats.7z

        -->

        base_url + archive_uri = http://<server_address_here>/packages/qt/5.0.0/windows_vs2010_64/cats.7z

        In the main configuration file you can define remote location. 'The base_url'
        defines the base address under which it tries to locate packages.


        Advanced:

            You can define multiple remote locations as follows:

                [ArchiveRemoteLocation.helsinki]
                base_url:               http://<server_address_here>/packages/

                [ArchiveRemoteLocation.oslo]
                base_url:               http://<server_address_here>/packages/

                [ArchiveRemoteLocation.berlin]
                base_url:               http://<server_address_here>/packages/

            Now you can define dedicated server for the specified component:

                [qt.sdk.desktop.500_beta.foobar]
                archives:               foobar
                target_install_base:    /foobar
                version:                1.2.3
                version_tag:            %VERSION%
                package_default:        true
                [foobar]
                archive_uri:            /foobar.7z
                package_strip_dirs:     5
                target_install_dir:     /
                rpath_target:
                archive_name:           foobar.7z


5.  Building Installer-Framework itself

    When you launch the 'create_installer.py' with command line argument
    'devmode' the script will build the Qt Installer-Framework and static
    Qt libraries for it on the fly.

    For each platform (Linux, Windows, macOS) there is corresponding
    'installer-framework' configuration file:

        '/configurations/linux/installer-framework'
        '/configurations/windows/installer-framework'
        '/configurations/mac/installer-framework'

    This configuration file describes:

        - Where to download the sources for Installer-Framework and Qt
        - What version of Installer-Framework and Qt
        - How they are built

    When using the 'devmode' the main script 'create_installer.py' uses
    the 'bld_ifw_tools.py' script to build the Installer-Framework.

    'create_installer.py'
            |
            --> 'bld_ifw_tools.py'
                    |
                    --> 'bld_ifw_tools_impl.py'
                                |
                                ==> [Installer-Framework libraries & tools]
            |                                       ᶺ
    (read configuration files)                      |
            |                                       |
    (build/package content for installer)           |
            |                                       |
    <create installer> <----------------------------
            |
            v
    'installer executable'

5.1 Generating pre-built Installer-Framework libraries

    Note! The following information is useful only if you choose to use
          pre-built Installer-Framework libraries. This approach can be
          used if you wish to save installer creation time in the long run.

          Otherwise it is recommended to use the 'devmode' command line option
          to create the installer.

    Usage:

        > python bld_ifw_tools.py linux

        or

        > python bld_ifw_tools.py windows

        or

        > python bld_ifw_tools.py mac


    Explanations:

    'bld_ifw_tools.py' builds the Installer-Framework. It expects to find
    file 'installer-framework' under '/configurations/<platform>' where the
    platform is linux/windows/mac.

    If you open the 'installer-framework' file you can find e.g.:

        installer_framework_archive_name:       installer-framework-build-win.7z

    When the build has completed you should find the above mentioned .7z archive
    from the scripts root dir and that contains the IFW libraries and tools.


    You can put this archive e.g. on server share and then define the following
    in you main configuration file, e.g. in 'win_x86_beta'

        [InstallerFrameworkTools]
        package_url:            http://<server_address_here>/.../installer-framework-build-win.7z


    Now you can run the 'create_installer.py' script without 'devmode' option
    as now the script will download the pre-built libraries from the URL
    you have defined and use them instead of building them from sources.
    This will save installer creation time considerably if you start installer
    creation from scratch every time.


5.2 Windows installer-framework configuration explained

    [make]
    make_cmd:                               nmake                               # make command

    [QtForInstallerFramework]                                                   # Configuration how the Qt for Installer-Framework is built
                                                                                # Notice that the Qt is built statically (libraries for Installer-Framework)

    qt_src_package_url:                     http://releases.qt-project.org/qt5.0/beta2/single/qt-everywhere-opensource-src-5.0.0-beta2.zip
    qt_source_dir:                          qt-src                              # Source checkout directory name
    qt_build_dir:                           qt-bld                              # Shadow build directory name
    qt_installerfw_qt_configure_line:       -static -release -opensource -confirm-license -nomake examples -nomake demos -nomake tests -nomake docs -no-webkit -no-phonon -no-dbus -no-opengl -no-qt3support -no-xmlpatterns -no-multimedia -no-declarative -no-declarative-debug -qt-sql-sqlite -plugin-sql-sqlite -prefix

    [InstallerFramework]                                                        # Configuration how the Installer-Framework is built

    installer_framework_url:                git://gitorious.org/installer-framework/installer-framework.git
    installer_framework_source_dir:         ifw-src                             # Source checkout directory name
    installer_framework_build_dir:          ifw-bld                             # Shadow build directory name
    installer_framework_version_tag:        remotes/origin/qt5                  # Branch or tag
    installer_framework_qmake_args:         -config release -config static -r

    [Output]
    installer_framework_archive_name:       installer-framework-build-win.7z    # The script will archive the generated IFW libraries for later use if needed
                                                                                # if you choose to use pre-built libraries afterwards. Otherwise you can ignore this.
    installerbase_archive_name:             installerbase-win.7z                # The script wil archive generated maintenance tool. For online installer use only if needed.
                                                                                # Otherwise you can ignore this.
    qt_archive_name:                        qt-ifw-4.8.0-win.7z                 # The script will archive the generated Qt libraries as well for later use if needed.
                                                                                # TODO! Is this functionality needed? Archiving Qt libraries functionality was added originally
                                                                                # keep QtCreator builds in mind.


5.  Files

    /create_installer.py
        - main build script
        - creates installer binary based on Qt Installer-Framework
    /bldinstallercommon.py
        - common utility functions
    /bld_ifw_tools.py
    /bld_ifw_tools_impl.py
        - utilities to build static Qt and Installer-Framework
    /configurations
        - contains all configuration files
    /configurations/pkg_beta
        - contains package templates that define the Qt 5 Beta installer structure
    /configurations/config_qt5
        - template files, e.g. icons, xml files
    /configurations/linux
        - contains Linux specific configuration files
    /configurations/linux/common
        - common configuration data for Linux installers
    /configurations/linux/config.xml.template.linux
        - config.xml template
    /configurations/linux/installer-framework
        - configuration file for building Qt Installer-Framework


6.  Examples for creating installers and online repositories

    For a complete online setup the following is needed:

    1) A server hosting the online repositories

       Https protocol support is optional but preferred.

    2) Online installer

       - See 6.1.1 and 6.1.2 how to create online installer

    3) Create online repositories

       - See 6.1.3 and examples below
       - Preferably automatise the online repository upload to testing/production
         environments


6.1 Build online installer and online repositories with given content

6.1.1 Build IFW tool package

      > python bld_ifw_tools.py

      It uses the default options. To customize e.g. used Qt src package or Qt configure options
      run the script with "--help".
      This will create an archive containing all the tools required for the rest of the steps.

        packaging-tools/ifw_build_artifacts/installer-framework-build-linux-x64.7z
        packaging-tools/ifw_build_artifacts/installerbase-linux-x64.7z


6.1.2 Create online installer

      To create customized online installer you need:

      1) Address where your online repository is hosted
      2) Customized graphics (E.g. company logo)

      This is defined in the config.xml file.
      The qtsdk provides some templates which can be used as an example.

      Open: packaging-tools/configurations/linux/config.xml.template.linux-x64.qt5-sdk

        Documentation for all settings there can be found here: https://doc.qt.io/qtinstallerframework/ifw-globalconfig.html

      The important part here is to define the correct remote repository where your online repository resides.
      Flexible approach is the define only one remote root respository here. E.g.

        https://my.company.com/online/qtsdkrepository/linux_x64/root/

      Then under this path Updates.xml should exist. In this Updates.xml you can add the actual payload repositories.
      For example see:

        http://download.qt.io/online/qtsdkrepository/linux_x64/root/qt/Updates.xml

      When all the settings in your config.xml are in place:

        > python create_installer.py <options>

            --online                                                                                                      (will create online installer instance)
            --ifw-tools=/home/foobar/dev/qtsdk/packaging-tools/ifw_build_artifacts/installer-framework-build-linux-x64.7z (this is the one you built in step 6.1.1)
            -c /home/foobar/qtsdk/packaging-tools/configurations                                                          (base path for all configuration files)
            -f /home/foobar/qtsdk/packaging-tools/configurations/online_installer_jobs/unifiedqt/linux_x64_online         (main configuration file)
            --preferred-installer-name=my-installer-name
            --add-substitution=@SRC_ARCHIVE_TYPE@=tar.gz                                                                  (search and substitute this in configuration files)
            --add-substitution=@SOME_VERSION_NUMBER_IN_CONF_FILES@=1.2.3                                                  (search and substitute this in configuration files)
            -u http://<my_network_drive>/some/base/path/                                                                  (base path where the script will look for payload if needed)

      For custom projects you can crete dedicated directory (repository) where you put your own configuration files. Use the same structure as used in qtsdk.git.
      The configuration files in the qtsdk.git point into payload using relative paths. For example see:

        packaging-tools/configurations/linux/x64/56/x86_64-qt56-gcc-conf

      See "archive_uri:" part. The script will first check if that is an absolute path e.g. is the file residing on file system. If not then it will pre-pend the value of "-u" (see above)
      to the path. The configuration files in qtsdk.git mostly use relative paths and by "-u" the installer is able to locate the files from the network disk where all build artifacts
      are saved.

      Note! If you rebuild the IFW meanwhile and want to use the new version, delete "packaging-tools/ifwt" directory, the script unpacks the archive given by "--ifw-tools" into this directory
      and uses it from there if the directory exists.


6.1.3 Create online repository

      Easiest way to start is to open for example: "packaging-tools/configurations/repository_configs/desktop_qt5/linux_x64_repository_56" and edit for your needs.
      The important parts:

        "file_list:"        comma separated list of additional configuration files residing under "-c" (see example above)
        "template_dirs:"    comma separated list where to search for actual installer-framework pkg templates (these contain the package.xml and installscript.qs files)

      When you have the configuration files and pkg templates set:

        > python create_installer.py <options>

            --create-repo
            --ifw-tools=/home/foobar/dev/qtsdk/packaging-tools/ifw_build_artifacts/installer-framework-build-linux-x64.7z (this is the one you built in step 6.1.1)
            -c /home/foobar/qtsdk/packaging-tools/configurations
            -f /home/foobar/qtsdk/packaging-tools/configurations/repository_configs/desktop_qt5/linux_x64_repository_56
            -u http://<my_network_drive>/some/base/path/
            --add-substitution=@SRC_ARCHIVE_TYPE@=tar.gz                                                                  (search and substitute this in configuration files)
            --add-substitution=@SOME_VERSION_NUMBER_IN_CONF_FILES@=1.2.3                                                  (search and substitute this in configuration files)

      The generated online repository will end up into:

        /packaging-tools/repository

      To make this available to online users you need to:

        1) Upload this somewhere under your domain, e.g.: https://my.company.com/online/qtsdkrepository/linux_x64/<my_repo_name>
        2) Add this repo into root Updates.xml, e.g.: https://my.company.com/online/qtsdkrepository/linux_x64/root/Updates.xml  (see http://download.qt.io/online/qtsdkrepository/linux_x64/root/qt/Updates.xml)


6.1.4 Simplified example

      1) Create network drive where to put all binary content (payload for the online repositories)

        http://mycompany.intranet/packaging

      2) Establish public(?) domain for the releasable online content

        http(s)://mycompany.com/online/repository/linux_x64

      3) Create IFW tools

        > python bld_ifw_tools.py

      4) Create root online repository

        > python create_installer.py
            --create-repo
            --ifw-tools=/home/foobar/qtsdk/packaging-tools/ifw_build_artifacts/installer-framework-build-linux-x64.7z
            -c /home/foobar/qtsdk/packaging-tools/configurations
            -f /home/foobar/qtsdk/packaging-tools/configurations/repository_configs/tools_desktop/mycompany_example_root_repository
            -u http://mycompany.intranet/packaging  (Usually theroot component does not require any payload but the script requires this parameter)

        -> Upload the root repository from packaging-tools/repository e.g. into:

            http(s)://mycompany.com/online/repository/linux_x64/root/

      5) Build binary artifacts for product "foobar 1.2.3"

         Upload the binary artifacts into:

            http://mycompany.intranet/packaging/foobar/123/

      6) Create online repository for product "foobar" with version 1.2.3

        > python create_installer.py
            --create-repo
            --ifw-tools=/home/foobar/qtsdk/packaging-tools/ifw_build_artifacts/installer-framework-build-linux-x64.7z
            -c /home/foobar/qtsdk/packaging-tools/configurations
            -f /home/foobar/qtsdk/packaging-tools/configurations/repository_configs/desktop_qt5/linux_x64_repository_mycompany_foobar_123
            -u http://mycompany.intranet/packaging  (Usually theroot component does not require any payload but the script requires this parameter)

          Note! Edit the "linux_x64_repository_mycompany_foobar_123" file so that the relative paths point into correct
          files under: http://mycompany.intranet/packaging/foobar/123/

        -> Upload the online repository into e.g.

            http(s)://mycompany.com/online/repository/linux_x64/foobar_123

        -> Edit http(s)://mycompany.com/online/repository/linux_x64/root/Updates.xml

            <RepositoryUpdate>
                <Repository action="add" url="http(s)://mycompany.com/online/repository/linux_x64/foobar_123" displayname="FooBar 1.2.3 online repository"/>
            </RepositoryUpdate>

      7) Further notes

            - When updating online content make sure the payload (.7z files) is in sync before updating metadata (Updates.xml) files.
              If you upload them both at the same time the metadata may be in sync (visible to users) before the actual payload. This will
              result in an error when using the installer when it verifies the content.

              If you update existing online content the above becomes even more important.


6.2.0 Qt 5.6 Linux examples

      Below an example how to produce all Qt5.6 related online repositories for Linux x64.
      This example assumes that the actual binary content is availbale under $PAYLOAD_SERVER_HTTP_BASE (see below).

      1) Run step 6.1.1 (Build IFW tool package)

      2) Create repositories

        export IFW_TOOLS=/home/qtsdk/packaging-tools/ifw_build_artifacts/installer-framework-build-linux-x64.7z
        export CONF_BASE_DIR=/home/qtsdk/packaging-tools/configurations
        export PAYLOAD_SERVER_HTTP_BASE=http://mycompany.intranet/packaging

        > python --create-repo -u $PAYLOAD_SERVER_HTTP_BASE --ifw-tools=$IFW_TOOLS -c $CONF_BASE_DIR -f $CONF_BASE_DIR/repository_configs/desktop_qt5/linux_x64_repository_56
        > python --create-repo -u $PAYLOAD_SERVER_HTTP_BASE --ifw-tools=$IFW_TOOLS -c $CONF_BASE_DIR -f $CONF_BASE_DIR/repository_configs/desktop_qt5/repository_56_src_doc_examples
        > python --create-repo -u $PAYLOAD_SERVER_HTTP_BASE --ifw-tools=$IFW_TOOLS -c $CONF_BASE_DIR -f $CONF_BASE_DIR/repository_configs/android_qt5/linux_x64_android_repository_56

        After creating each invidual repository one needs to copy it into production or testing environment so that the content is visible under some http(s) address.
        For example:
            http(s)://mycompany.com/online/repository/linux_x64/desktop/qt5_56
            http(s)://mycompany.com/online/repository/linux_x64/desktop/qt5_src_doc_examples
            http(s)://mycompany.com/online/repository/linux_x64/android/qt5_56


7 Building binary packages i.e. payload for the installers/online repositories

7.1 Create qt source package(s)

    1) Check out the qt source code from preferred branch/tag

        /home/builder/work/qt5

    2) Create source packages

        > packaging-tools/mksrc.sh -u /home/builder/work/qt5 -v 5.5.2 -m -N -l opensource -i qtdocgallery -i qtfeedback -i qtjsondb -i qtpim -i qtqa -i qtrepotools -i qtsystems

        (see mksrc.sh -h for details)

        In the online repository example 6.2.0 above it was expected that the src packages reside on the network disk ($PAYLOAD_SERVER_HTTP_BASE).
        So after this step the source packages would be uploaded to the network disk.

    3) Build binary package

        Note! Building the various targets requires to set up the build machine environment properly for each target (RHEL, MinGW, MSVC_XXXX, OSX, Android, IOS, WINRT, ...).

        > python mkqt5bld.py <options>

            --src-url=
            --make_cmd=make                                         # e.g. "jom" or "mingw-make" can be used on windows
            --jobs=<cpu count>
            --ignore=<qt module name which you want to ignore>      # use for each excluded module separately
            --configure=<configure options used for the build>
            --prefix=<prefix for the qt build>
            --module-separate-install-list=<comma separated list>   # E.g. if you want to split qt3d as a separate binary package from the main qt binary package

        Upload the binary archive into network drive.

    4) Example layout of the network disk how binary packages are structured. Note that the installer configuration files refer to this directory/filename structure.

        <network storage base path>/qt/5.5.1/latest
            .
            ├── android_armv5
            │   ├── linux_x64
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   ├── linux_x86
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   ├── mac_x64
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   └── mingw_x86
            │       ├── qt5_addons.7z
            │       ├── qt5_essentials.7z
            │       ├── qt5_qt3d.7z
            │       ├── qt5_qtcanvas3d.7z
            │       ├── qt5_qtlocation.7z
            │       ├── qt5_qtpositioning.7z
            │       ├── qt5_qtquick1.7z
            │       ├── qt5_qtquickcontrols.7z
            │       └── qt5_qtscript.7z
            ├── android_armv7
            │   ├── linux_x64
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   ├── linux_x86
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   ├── mac_x64
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   └── mingw_x86
            │       ├── qt5_addons.7z
            │       ├── qt5_essentials.7z
            │       ├── qt5_qt3d.7z
            │       ├── qt5_qtcanvas3d.7z
            │       ├── qt5_qtlocation.7z
            │       ├── qt5_qtpositioning.7z
            │       ├── qt5_qtquick1.7z
            │       ├── qt5_qtquickcontrols.7z
            │       └── qt5_qtscript.7z
            ├── android_x86
            │   ├── linux_x64
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   ├── linux_x86
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   ├── mac_x64
            │   │   ├── qt5_addons.7z
            │   │   ├── qt5_essentials.7z
            │   │   ├── qt5_qt3d.7z
            │   │   ├── qt5_qtcanvas3d.7z
            │   │   ├── qt5_qtlocation.7z
            │   │   ├── qt5_qtpositioning.7z
            │   │   ├── qt5_qtquick1.7z
            │   │   ├── qt5_qtquickcontrols.7z
            │   │   └── qt5_qtscript.7z
            │   └── mingw_x86
            │       ├── qt5_addons.7z
            │       ├── qt5_essentials.7z
            │       ├── qt5_qt3d.7z
            │       ├── qt5_qtcanvas3d.7z
            │       ├── qt5_qtlocation.7z
            │       ├── qt5_qtpositioning.7z
            │       ├── qt5_qtquick1.7z
            │       ├── qt5_qtquickcontrols.7z
            │       └── qt5_qtscript.7z
            ├── ios
            │   └── mac_x64
            │       ├── qt5_addons.7z
            │       ├── qt5_docs.7z
            │       ├── qt5_essentials.7z
            │       ├── qt5_qt3d.7z
            │       ├── qt5_qtcanvas3d.7z
            │       ├── qt5_qtlocation.7z
            │       ├── qt5_qtpositioning.7z
            │       ├── qt5_qtquick1.7z
            │       ├── qt5_qtquickcontrols.7z
            │       └── qt5_qtscript.7z
            ├── linux_gcc_32_rhel66
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   ├── qt5_qtscript.7z
            │   └── qt5_qtwebengine.7z
            ├── linux_gcc_64_rhel66
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   ├── qt5_qtscript.7z
            │   └── qt5_qtwebengine.7z
            ├── mac_x64
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   ├── qt5_qtscript.7z
            │   └── qt5_qtwebengine.7z
            ├── src
            │   ├── doc
            │   │   └── qt5_docs.7z
            │   ├── examples_injection
            │   │   └── qt5_examples.7z
            │   ├── single
            │   │   ├── qt-everywhere-opensource-src-5.5.1.7z
            │   │   ├── qt-everywhere-opensource-src-5.5.1.tar.gz
            │   │   ├── qt-everywhere-opensource-src-5.5.1.tar.xz
            │   │   └── qt-everywhere-opensource-src-5.5.1.zip
            │   └── submodules
            │       ├── qt3d-opensource-src-5.5.1.7z
            │       ├── qt3d-opensource-src-5.5.1.tar.gz
            │       ├── qt3d-opensource-src-5.5.1.tar.xz
            │       ├── qt3d-opensource-src-5.5.1.zip
            │       ├── qt5-opensource-src-5.5.1.7z
            │       ├── qt5-opensource-src-5.5.1.tar.gz
            │       ├── qt5-opensource-src-5.5.1.tar.xz
            │       ├── qt5-opensource-src-5.5.1.zip
            │       ├── qtactiveqt-opensource-src-5.5.1.7z
            │       ├── qtactiveqt-opensource-src-5.5.1.tar.gz
            │       ├── qtactiveqt-opensource-src-5.5.1.tar.xz
            │       ├── qtactiveqt-opensource-src-5.5.1.zip
            │       ├── qtandroidextras-opensource-src-5.5.1.7z
            │       ├── qtandroidextras-opensource-src-5.5.1.tar.gz
            │       ├── qtandroidextras-opensource-src-5.5.1.tar.xz
            │       ├── qtandroidextras-opensource-src-5.5.1.zip
            │       ├── qtbase-opensource-src-5.5.1.7z
            │       ├── qtbase-opensource-src-5.5.1.tar.gz
            │       ├── qtbase-opensource-src-5.5.1.tar.xz
            │       ├── qtbase-opensource-src-5.5.1.zip
            │       ├── qtcanvas3d-opensource-src-5.5.1.7z
            │       ├── qtcanvas3d-opensource-src-5.5.1.tar.gz
            │       ├── qtcanvas3d-opensource-src-5.5.1.tar.xz
            │       ├── qtcanvas3d-opensource-src-5.5.1.zip
            │       ├── qtconnectivity-opensource-src-5.5.1.7z
            │       ├── qtconnectivity-opensource-src-5.5.1.tar.gz
            │       ├── qtconnectivity-opensource-src-5.5.1.tar.xz
            │       ├── qtconnectivity-opensource-src-5.5.1.zip
            │       ├── qtdeclarative-opensource-src-5.5.1.7z
            │       ├── qtdeclarative-opensource-src-5.5.1.tar.gz
            │       ├── qtdeclarative-opensource-src-5.5.1.tar.xz
            │       ├── qtdeclarative-opensource-src-5.5.1.zip
            │       ├── qtdoc-opensource-src-5.5.1.7z
            │       ├── qtdoc-opensource-src-5.5.1.tar.gz
            │       ├── qtdoc-opensource-src-5.5.1.tar.xz
            │       ├── qtdoc-opensource-src-5.5.1.zip
            │       ├── qtenginio-opensource-src-5.5.1.7z
            │       ├── qtenginio-opensource-src-5.5.1.tar.gz
            │       ├── qtenginio-opensource-src-5.5.1.tar.xz
            │       ├── qtenginio-opensource-src-5.5.1.zip
            │       ├── qtgraphicaleffects-opensource-src-5.5.1.7z
            │       ├── qtgraphicaleffects-opensource-src-5.5.1.tar.gz
            │       ├── qtgraphicaleffects-opensource-src-5.5.1.tar.xz
            │       ├── qtgraphicaleffects-opensource-src-5.5.1.zip
            │       ├── qtimageformats-opensource-src-5.5.1.7z
            │       ├── qtimageformats-opensource-src-5.5.1.tar.gz
            │       ├── qtimageformats-opensource-src-5.5.1.tar.xz
            │       ├── qtimageformats-opensource-src-5.5.1.zip
            │       ├── qtlocation-opensource-src-5.5.1.7z
            │       ├── qtlocation-opensource-src-5.5.1.tar.gz
            │       ├── qtlocation-opensource-src-5.5.1.tar.xz
            │       ├── qtlocation-opensource-src-5.5.1.zip
            │       ├── qtmacextras-opensource-src-5.5.1.7z
            │       ├── qtmacextras-opensource-src-5.5.1.tar.gz
            │       ├── qtmacextras-opensource-src-5.5.1.tar.xz
            │       ├── qtmacextras-opensource-src-5.5.1.zip
            │       ├── qtmultimedia-opensource-src-5.5.1.7z
            │       ├── qtmultimedia-opensource-src-5.5.1.tar.gz
            │       ├── qtmultimedia-opensource-src-5.5.1.tar.xz
            │       ├── qtmultimedia-opensource-src-5.5.1.zip
            │       ├── qtquick1-opensource-src-5.5.1.7z
            │       ├── qtquick1-opensource-src-5.5.1.tar.gz
            │       ├── qtquick1-opensource-src-5.5.1.tar.xz
            │       ├── qtquick1-opensource-src-5.5.1.zip
            │       ├── qtquickcontrols-opensource-src-5.5.1.7z
            │       ├── qtquickcontrols-opensource-src-5.5.1.tar.gz
            │       ├── qtquickcontrols-opensource-src-5.5.1.tar.xz
            │       ├── qtquickcontrols-opensource-src-5.5.1.zip
            │       ├── qtscript-opensource-src-5.5.1.7z
            │       ├── qtscript-opensource-src-5.5.1.tar.gz
            │       ├── qtscript-opensource-src-5.5.1.tar.xz
            │       ├── qtscript-opensource-src-5.5.1.zip
            │       ├── qtsensors-opensource-src-5.5.1.7z
            │       ├── qtsensors-opensource-src-5.5.1.tar.gz
            │       ├── qtsensors-opensource-src-5.5.1.tar.xz
            │       ├── qtsensors-opensource-src-5.5.1.zip
            │       ├── qtserialport-opensource-src-5.5.1.7z
            │       ├── qtserialport-opensource-src-5.5.1.tar.gz
            │       ├── qtserialport-opensource-src-5.5.1.tar.xz
            │       ├── qtserialport-opensource-src-5.5.1.zip
            │       ├── qtsvg-opensource-src-5.5.1.7z
            │       ├── qtsvg-opensource-src-5.5.1.tar.gz
            │       ├── qtsvg-opensource-src-5.5.1.tar.xz
            │       ├── qtsvg-opensource-src-5.5.1.zip
            │       ├── qttools-opensource-src-5.5.1.7z
            │       ├── qttools-opensource-src-5.5.1.tar.gz
            │       ├── qttools-opensource-src-5.5.1.tar.xz
            │       ├── qttools-opensource-src-5.5.1.zip
            │       ├── qttranslations-opensource-src-5.5.1.7z
            │       ├── qttranslations-opensource-src-5.5.1.tar.gz
            │       ├── qttranslations-opensource-src-5.5.1.tar.xz
            │       ├── qttranslations-opensource-src-5.5.1.zip
            │       ├── qtwayland-opensource-src-5.5.1.7z
            │       ├── qtwayland-opensource-src-5.5.1.tar.gz
            │       ├── qtwayland-opensource-src-5.5.1.tar.xz
            │       ├── qtwayland-opensource-src-5.5.1.zip
            │       ├── qtwebchannel-opensource-src-5.5.1.7z
            │       ├── qtwebchannel-opensource-src-5.5.1.tar.gz
            │       ├── qtwebchannel-opensource-src-5.5.1.tar.xz
            │       ├── qtwebchannel-opensource-src-5.5.1.zip
            │       ├── qtwebengine-opensource-src-5.5.1.7z
            │       ├── qtwebengine-opensource-src-5.5.1.tar.gz
            │       ├── qtwebengine-opensource-src-5.5.1.tar.xz
            │       ├── qtwebengine-opensource-src-5.5.1.zip
            │       ├── qtwebkit-examples-opensource-src-5.5.1.7z
            │       ├── qtwebkit-examples-opensource-src-5.5.1.tar.gz
            │       ├── qtwebkit-examples-opensource-src-5.5.1.tar.xz
            │       ├── qtwebkit-examples-opensource-src-5.5.1.zip
            │       ├── qtwebkit-opensource-src-5.5.1.7z
            │       ├── qtwebkit-opensource-src-5.5.1.tar.gz
            │       ├── qtwebkit-opensource-src-5.5.1.tar.xz
            │       ├── qtwebkit-opensource-src-5.5.1.zip
            │       ├── qtwebsockets-opensource-src-5.5.1.7z
            │       ├── qtwebsockets-opensource-src-5.5.1.tar.gz
            │       ├── qtwebsockets-opensource-src-5.5.1.tar.xz
            │       ├── qtwebsockets-opensource-src-5.5.1.zip
            │       ├── qtwinextras-opensource-src-5.5.1.7z
            │       ├── qtwinextras-opensource-src-5.5.1.tar.gz
            │       ├── qtwinextras-opensource-src-5.5.1.tar.xz
            │       ├── qtwinextras-opensource-src-5.5.1.zip
            │       ├── qtx11extras-opensource-src-5.5.1.7z
            │       ├── qtx11extras-opensource-src-5.5.1.tar.gz
            │       ├── qtx11extras-opensource-src-5.5.1.tar.xz
            │       ├── qtx11extras-opensource-src-5.5.1.zip
            │       ├── qtxmlpatterns-opensource-src-5.5.1.7z
            │       ├── qtxmlpatterns-opensource-src-5.5.1.tar.gz
            │       ├── qtxmlpatterns-opensource-src-5.5.1.tar.xz
            │       └── qtxmlpatterns-opensource-src-5.5.1.zip
            ├── windows_mingw492_x86
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   └── qt5_qtscript.7z
            ├── windows_vs2010_32
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   └── qt5_qtscript.7z
            ├── windows_vs2012_32
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   └── qt5_qtscript.7z
            ├── windows_vs2013_32
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   ├── qt5_qtscript.7z
            │   └── qt5_qtwebengine.7z
            ├── windows_vs2013_64
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   ├── qt5_qtquick1.7z
            │   ├── qt5_qtquickcontrols.7z
            │   ├── qt5_qtscript.7z
            │   └── qt5_qtwebengine.7z
            ├── windows_vs2013_winrt_x64
            │   ├── qt5_addons.7z
            │   ├── qt5_docs.7z
            │   ├── qt5_essentials.7z
            │   ├── qt5_qt3d.7z
            │   ├── qt5_qtcanvas3d.7z
            │   ├── qt5_qtlocation.7z
            │   ├── qt5_qtpositioning.7z
            │   └── qt5_qtquickcontrols.7z
            └── winphone81
                ├── arm
                │   ├── qt5_addons.7z
                │   ├── qt5_docs.7z
                │   ├── qt5_essentials.7z
                │   ├── qt5_qt3d.7z
                │   ├── qt5_qtcanvas3d.7z
                │   ├── qt5_qtlocation.7z
                │   ├── qt5_qtpositioning.7z
                │   └── qt5_qtquickcontrols.7z
                └── x86
                    ├── qt5_addons.7z
                    ├── qt5_docs.7z
                    ├── qt5_essentials.7z
                    ├── qt5_qt3d.7z
                    ├── qt5_qtcanvas3d.7z
                    ├── qt5_qtlocation.7z
                    ├── qt5_qtpositioning.7z
                    └── qt5_qtquickcontrols.7z

8 build_wrapper.py

    For more complete build management there exists 'build_wrapper.py' which takes care of most of the build steps.
    Note that this script is used in conjunction with Jenkins (https://jenkins.io/) but should work with other systems as well with minor modifications.

    The 'build_wrapper.py' handles the overall build flow in steps:

        1) Init step
            - Creates directory structure on network disk (or local host if chosen)
        2) Src package creation step
            - Creates src packages and uploads them to the network drive
        3) Binary build step
            - Builds the binary package and uploads them to the network drive
        4) Offline installer build step
            - Creates offline installers and uploads them to the network drive
        5) Online repository build step
            - Creates online repositories and triggers online repository update (usually staging/test server)

    In Jenkins each step is a separate job and after successful execution of the step it triggers the next step.
    Failed step can be re-run without the needs starting from the beginning.
    If building multiple targets then the steps 3-5 can be executed in parallel in Jenkins.

    Simplified example flow:

    1-->2-->3 (Linux gcc_64 binaries) --> 4 (Linux gcc_64 offline installer)
         |                            L-> 5 (Linux gcc_64 online repository)
         |->3 (OSX clang binaries)    --> 4 (OSX clang offline installer)
         |                            L-> 5 (OSX clang online repository)
         |->3 (Win 7 binaries)        --> 4 (Win 7 offline installer)
         |                            L-> 5 (Win 7 online repository)

    8.1 Environment

        Package storage server / network drive where the build artifacts are to be uploaded by the 'build_wrapper.py'

            - ssh access (no passwd prompt) from build slaves to the server
            - http(s) access into network drive for the build artifacts

        Online repository test/staging server

            - ssh access (no passwd prompt) from build slaves to the server
            - http(s) access into network drive -> accessible by the (test) online installers

        Each build agent should have the following environment setup:

            LICENSE                             opensource|enterprise
            PACKAGE_STORAGE_SERVER              Name of the packaging server
            PACKAGE_STORAGE_SERVER_USER         Username for accessing the packaging server
            PACKAGE_STORAGE_SERVER_BASE_DIR     Base path on the package storage under which all build artifacts reside
            PACKAGE_STORAGE_SERVER_PATH_HTTP    E.g. 'http://mycompany.intranet/packaging' which maps to $PACKAGE_STORAGE_SERVER:$PACKAGE_STORAGE_SERVER_BASE_DIR
            PKG_NODE_ROOT                       Base working directory, qtsdk.git and the rest should be under this base directory
SIGNING_SERVER
SIGNING_PASSWORD


        For each Qt version a top level configuration file

            RELEASE_DESCRIPTION_FILE


    8.2 Build

        1) Init step

            export RELEASE_DESCRIPTION_FILE=<your_qtsdk_checkout_dir>/packaging-tools/releases/release-55

            python build_wrapper.py -c init -l $LICENSE -b $BUILD_NUMBER -s $PACKAGE_STORAGE_SERVER_USER@$PACKAGE_STORAGE_SERVER -p $PACKAGE_STORAGE_SERVER_BASE_DIR

            Output:

                $PACKAGE_STORAGE_SERVER:$PACKAGE_STORAGE_SERVER_BASE_DIR/qt/5.5/$BUILD_NUMBER
                $PACKAGE_STORAGE_SERVER:$PACKAGE_STORAGE_SERVER_BASE_DIR/qt/5.5/latest          # symlink to above directory, installer configs always point into "latest" snapshot dir

                mycompany-file-server:/some_base_path_here/qt/5.5/90837356
                mycompany-file-server:/some_base_path_here/qt/5.5/latest


        2) Create Qt src package

            export RELEASE_DESCRIPTION_FILE=<your_qtsdk_checkout_dir>/packaging-tools/releases/release-55
            export QT5_GIT_MIRROR=<where to pull qt5 sources>
            export cfg=linux-g++-Rhel6.6-x64 # Note! See 8.3 about build node labels

            python build_wrapper.py -c build_src -l $LICENSE -b $BUILD_NUMBER -s $PACKAGE_STORAGE_SERVER_USER@$PACKAGE_STORAGE_SERVER -p $PACKAGE_STORAGE_SERVER_BASE_DIR -e $cfg

            Output:

                mycompany-file-server:/some_base_path_here/qt/5.5/90837356/src/single/qt-everywhere-opensource-src-5.5.1.tar.gz   (+ .7z, .tar.gz, .zip)
                mycompany-file-server:/some_base_path_here/qt/5.5/90837356/src/submodules/...


        3) Create Qt binary packages

            export RELEASE_BUILD_QT_CONFIGURE_OPTIONS_FILE=<your_qtsdk_checkout_dir>/packaging-tools/releases/release-55
            export RELEASE_DESCRIPTION_FILE=<your_qtsdk_checkout_dir>/packaging-tools/releases/release-55
            export cfg=linux-g++-Rhel6.6-x64 # Note! See 8.3 about build node labels

            python build_wrapper.py -c build_bin -l $LICENSE -b $BUILD_NUMBER -s $PACKAGE_STORAGE_SERVER_USER@$PACKAGE_STORAGE_SERVER -p $PACKAGE_STORAGE_SERVER_BASE_DIR -e $cfg

            Output:

                mycompany-file-server:/some_base_path_here/qt/5.5/90837356/linux_gcc_64_rhel66/qt5_addons.7z
                                                                                               qt5_docs.7z
                                                                                               qt5_essentials.7z
                                                                                               qt5_qtquick1.7z
                                                                                               qt5_qtscript.7z
                                                                                               qt5_qtwebengine.7z
                                                                                               qt5_qtwebkit.7z

        4) Create Qt offline installer

            export RELEASE_DESCRIPTION_FILE=<your_qtsdk_checkout_dir>/packaging-tools/releases/release-55
            export cfg=linux-g++-Rhel6.6-x64 # Note! See 8.3 about build node labels

            python build_wrapper.py -c offline_installer -l $LICENSE -b $BUILD_NUMBER -s $PACKAGE_STORAGE_SERVER_USER@$PACKAGE_STORAGE_SERVER -p $PACKAGE_STORAGE_SERVER_BASE_DIR -e $cfg

            Output:

                mycompany-file-server:/some_base_path_here/qt/5.5.1/installers/latest_available/qt-opensource-linux-x64-5.6.1_<running_snapshot_number>.run

        5) Create online repositories

            For online repository test server:

                PKG_STAGING_SERVER                          # E.g. "mycompany.online.test.server"
                PKG_STAGING_SERVER_UNAME                    # E.g. "qt-builder"
                STAGING_SRV_ONLINE_REPO_BASE_PATH           # E.g. "/data/online/mycompany_sdk"
                REPO_STAGING_SERVER_HOME                    # Home directory under which it expects to find qtsdk.git clone. To perform online repository
                                                              updates remotely it needs additional scripts
                                                              E.g. "/home/qt-builder/qtsdk"

            For production online server 'pending area'

                PROD_ADDR                                   # E.g. master.mycompany.com
                PROD_USER                                   # E.g. "qt-builder"
                PROD_SRV_REPO_BASE_PATH                     # E.g. /data/production/online/mycompany_qtsdk
                PROD_SRV_REPO_PENDING_AREA_DIR              # E.g. /data/pending_content_for_online_production_updates


            PACKAGE_STORAGE_SERVER_PATH_HTTP                # E.g. "http://mycompany.intranet/packaging" <- under this the Qt binary artifacts are downloaded for the installers
            IFW_TOOLS_BASE_URL                              # E.g. "http://mycompany.intranet/packaging/installer-framework/"  <- expects to find 'installer-framework-build-linux-x64.7z' here
            CONFIGURATIONS_FILE_BASE_DIR                    # "/work/build/qtsdk/packaging-tools/configurations" <- depending where it is cloned on the build slave


            export RELEASE_DESCRIPTION_FILE=<your_qtsdk_checkout_dir>/packaging-tools/releases/release-55
            export cfg=linux-g++-Rhel6.6-x64 # Note! See 8.3 about build node labels

            python build_wrapper.py -c repo_build -l $LICENSE -e $cfg

            Output:

                Staging/test server:

                    http://mycompany.online.test.server/mycompany_sdk/linux_x64/desktop/qt5_55/<REPO CONTENT>
                    http://mycompany.online.test.server/mycompany_sdk/linux_x64/desktop/qt5_55_src_doc_examples/<REPO CONTENT>

                Production server:

                    master.mycompany.com:/data/pending_content_for_online_production_updates/mycompany_sdk/linux_x64/desktop/qt5_55/<REPO CONTENT>
                    master.mycompany.com:/data/pending_content_for_online_production_updates/mycompany_sdk/linux_x64/desktop/qt5_55_src_doc_examples/<REPO CONTENT>


    8.3 Build node labels

        The release description file, e.g. packaging-tools/releases/release-55, has all Qt configure options defined for all targets.
        Let's see an example from the above file:

            [release.qt.configure_options.linux]
            build_node_labels:      linux-g++-Rhel6.6-x86, linux-g++-Rhel6.6-x64
            configure_options:      -opensource -confirm-license -debug-and-release -release -nomake tests -nomake examples -qt-zlib
                                    -qt-libjpeg -qt-libpng -qt-xcb -sysconfdir /etc/xdg -plugin-sql-mysql -plugin-sql-psql -plugin-sql-sqlite
                                    -openssl -no-libudev -icu -no-egl

        The section name 'release.qt.configure_options.linux' can be anything as long it:

            - is unique
            - starts with "release.qt.configure_options" keyword

        The "build_node_labels" matches the the agent labels in Jenkins based build system.
        Each build slave has a label and that label is set into environment variable called "cfg". In the above examples you could see the "$cfg" being used.
        By this we tell the 'build_wrapper.py' to pick correct Qt configure options when it is running on a particular build slave.

        The "configure_options" defines the Qt configure options used when making the particular build on the listed slaves (linux-g++-Rhel6.6-x86 and linux-g++-Rhel6.6-x64
        in the above example)