summaryrefslogtreecommitdiff
path: root/doc/src/cmake/cmake-manual.qdoc
blob: f3ffbe76ae8a26ac0bc5dcbe95012e48f15846d4 (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
// Copyright (C) 2020 The Qt Company Ltd
// Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \page cmake-manual.html
    \target CMake Manual
    \title Build with CMake
    \brief Describes how to use CMake in your development projects.
    \nextpage Getting started with CMake

    \c{CMake} is a tool to simplify the build process for development projects across different
    platforms. \c CMake automatically generates build systems, such as Makefiles and Ninja
    files.

    \c{CMake} is a third-party tool with its own \l{CMake Documentation}{documentation}.
    This manual focuses on how to use \c{CMake} to build Qt applications and libraries.


    \section1 Table of Contents

    \list
        \li \l{Getting started with CMake}
        \list
            \li \l{Building a C++ console application}
            \li \l{Building a C++ GUI application}
            \li \l{Structuring projects}
            \li \l{Building libraries}
            \li \l{Using libraries}
            \li \l{Adding resources}
            \li \l{Adding translations}
            \li \l{Further reading}
        \endlist
        \li \l {Building a QML application}
        \li \l {Building a reusable QML module}
        \li \l{Building projects on the command line}
        \list
            \li \l{CMake generators}
            \li \l{qt-cmake}
            \li \l{Cross-compiling}
            \li \l{Specifying a custom toolchain file}
        \endlist
        \li \l{Imported targets}
        \li \l{Qt CMake policies}
        \li \l{Qt 5 and Qt 6 compatibility}
        \list
            \li \l{Versionless targets}
            \li \l{Versionless commands}
            \li \l{Supporting older Qt 5 versions}
            \li \l{Recommended practices}
        \endlist
        \li \l{CMake Command Reference}
        \list
            \li \l{cmake-commands-qtcore}{Qt6::Core}
            \li \l{cmake-commands-qtdbus}{Qt6::DBus}
            \li \l{cmake-commands-qtinterfaceframework}{Qt6::InterfaceFramework}
            \li \l{cmake-commands-qtlinguisttools}{Qt6::LinguistTools}
            \li \l{cmake-commands-qtprotobuf}{Qt6::Protobuf}
            \li \l{cmake-commands-qtgrpc}{Qt6::Grpc}
            \li \l{cmake-commands-qtqml}{Qt6::Qml}
            \li \l{cmake-macros-qtremoteobjects}{Qt6::RemoteObjects}
            \li \l{cmake-macros-qtscxml}{Qt6::Scxml}
            \li \l{cmake-macros-qtwidgets}{Qt6::Widgets}
            \li \l{cmake-commands-qtwebenginecore}{Qt6::WebEngineCore}
        \endlist
        \li \l{CMake Variable Reference}
        \list
            \li \l{Module variables}
            \li \l{Installation variables}
            \li \l{Project variables}
        \endlist
        \li \l{CMake Property Reference}
        \list
            \li \l{cmake-properties-qtcore}{Qt6::Core}
            \li \l{cmake-properties-qtdbus}{Qt6::DBus}
            \li \l{cmake-properties-qtqml}{Qt6::Qml}
        \endlist
    \endlist
*/

/*!
    \page cmake-get-started.html
    \title Getting started with CMake
    \previouspage Build with CMake
    \nextpage Building projects on the command line

    \c{CMake} is a group of tools that allow to build, test, and package
    applications. Just like Qt, it is available on all major development
    platforms. It is also supported by various IDE's, including
    \l{Qt Creator Manual}{Qt Creator}.

    In this section we will show the most basic way to use Qt in a CMake
    project. First, we create a basic console application. Then, we extend the
    project into a GUI application that uses \l{Qt Widgets}.

    If you want to know how to build an existing CMake project with Qt, see the
    documentation on \l{Building projects on the command line}{how to build
    projects with CMake on the command line}.

    \section2 Building a C++ console application

    A \c{CMake} project is defined by files written in the CMake language.
    The main file is called \c{CMakeLists.txt}, and is usually placed in the
    same directory as the actual program sources.

    Here is a typical \c{CMakeLists.txt} file for a console application written
    in C++ using Qt:

    \quotefromfile snippets/cmake/helloworld_qtcore.cmake
    \skipto cmake_minimum_required
    \printuntil

    Let's go through the content.

    \quotefromfile snippets/cmake/helloworld_qtcore.cmake
    \skipto cmake_minimum_required
    \printuntil cmake_minimum_required

    \c cmake_minimum_required() specifies the minimum CMake version that the
    application requires. Qt itself requires at least CMake version 3.16.
    If you use a Qt that was built statically - the default in \l{Qt for iOS} and
    \l{Qt for WebAssembly} - you need CMake 3.21.1 or newer.

    \printuntil project(

    \c project() sets a project name and the default project version. The
    \c{LANGUAGES} argument tells CMake that the program is written in C++.

    \printuntil CMAKE_CXX_STANDARD_REQUIRED

    Qt 6 requires a compiler supporting C++ version 17 or newer.
    Enforcing this by setting the \c{CMAKE_CXX_STANDARD},
    \c{CMAKE_CXX_STANDARD_REQUIRED} variables will let CMake print an error if
    the compiler is too old.

    \printuntil find_package(

    This tells CMake to look up Qt 6, and import the \c {Core} module. There
    is no point in continuing if \c{CMake} cannot locate the module, so we do
    set the \c{REQUIRED} flag to let CMake abort in this case.

    If successful, the module will set some CMake variables documented in
    \l{Module variables}. It furthermore imports the \c{Qt6::Core} target
    that we use below.

    For \c{find_package} to be successful, \c CMake must find the Qt
    installation. There are different ways you can tell \c CMake about Qt,
    but the most common and recommended approach is to set the CMake cache
    variable \c{CMAKE_PREFIX_PATH} to include the Qt 6 installation prefix.
    Note that \l{Qt Creator Manual}{Qt Creator} will handle this transparently
    for you.

    \printuntil qt_standard_project_setup(

    The \l{qt6_standard_project_setup}{qt_standard_project_setup} command sets
    project-wide defaults for a typical Qt application.

    Among other things, this command sets the \c{CMAKE_AUTOMOC} variable to
    \c{ON}, which instructs CMake to automatically set up rules so that Qt's
    \l{Using the Meta-Object Compiler (moc)}{Meta-Object Compiler (moc)} is
    called transparently, when required.

    See \l{qt6_standard_project_setup}{qt_standard_project_setup}'s reference
    for details.

    \printuntil )

    \l{qt6_add_executable}{qt_add_executable()} tells CMake that we want to
    build an executable (so not a library) called \c{helloworld} as a target.
    It is a  wrapper around the built-in \c add_executable() command, and
    provides additional logic to automatically handle things like linking of
    Qt plugins in static Qt builds, platform-specific customization of library
    names, and so on.

    The target should be built from the C++ source file \c{main.cpp}.

    Typically, you do not list header files here. This is different
    from \l{qmake}, where header files need to be explicitly listed so that
    they are processed by the
    \l{Using the Meta-Object Compiler (moc)} {Meta-Object Compiler (moc)}.

    For creating libraries, see \l{qt6_add_library}{qt_add_library}.

    \printuntil

    Finally, \c{target_link_libraries} tells CMake that the \c{helloworld}
    executable makes use of \l{Qt Core} by referencing the \c{Qt6::Core}
    target imported by the \c{find_package()} call above. This will not only add
    the right arguments to the linker, but also makes sure that the right
    include directories, compiler definitions are passed to the C++ compiler.
    The \c{PRIVATE} keyword is not strictly necessary for an executable target,
    but it is good practice to specify it. If \c{helloworld} was a library
    rather than an executable, then either \c{PRIVATE} or \c{PUBLIC} should be
    specified (\c{PUBLIC} if the library mentions anything from \c{Qt6::Core}
    in its headers, \c{PRIVATE} otherwise).

    \section2 Building a C++ GUI application

    In the \l{Building a C++ console application}{last section} we showed the
    CMakeLists.txt file for a simple console application. We will now extend it
    to create a GUI application that uses the \l{Qt Widgets} module.

    This is the full project file:

    \quotefromfile snippets/cmake/helloworld_qtwidgets.cmake
    \skipto cmake_minimum_required
    \printuntil

    Let's walk through the changes we have made.

    \quotefromfile snippets/cmake/helloworld_qtwidgets.cmake
    \skipto find_package(
    \printuntil find_package(

    In the \c{find_package} call, we replace \c{Core} with \c{Widgets}. This
    will locate the \c{Qt6Widgets} module and provide the \c{Qt6::Widgets}
    targets we later link against.

    Note that the application will still link against \c{Qt6::Core}, because
    \c{Qt6::Widgets} depends on it.

    \printuntil qt_standard_project_setup(

    In addition to \c{CMAKE_AUTOMOC},
    \l{qt6_standard_project_setup}{qt_standard_project_setup} sets the
    \c{CMAKE_AUTOUIC} variable to \c{ON}. This will automatically create rules
    to invoke Qt's \l{User Interface Compiler (uic)} on \c{.ui} source files.

    \printuntil )

    We add a \l{Qt Designer} file (\c{mainwindow.ui}) and its corresponding C++
    source file (\c{mainwindow.cpp}) to the application target's sources.

    \printuntil target_link_libraries

    In the \c{target_link_libraries} command, we link against \c{Qt6::Widgets}
    instead of \c{Qt6::Core}.

    \printuntil

    Finally, we set properties on our application target with the following
    effects:

    \list
        \li Prevent the creation of a console window on Windows.
        \li Create an application bundle on macOS.
    \endlist

    See the \l{CMake Documentation} for more information about these target
    properties.

    \section2 Structuring projects

    Projects that contain more than just one target will benefit from a clear
    project file structure. We will use CMake's \l{CMake add_subdirectory
    documentation}{subdirectory feature}.

    As we plan to extend the project with more targets, we move the source files
    of the application into a subdirectory and create a new \c{CMakeLists.txt}
    in there.

    \badcode
    <project root>
    ├── CMakeLists.txt
    └── src
        └── app
            ├── CMakeLists.txt
            ├── main.cpp
            ├── mainwindow.cpp
            ├── mainwindow.h
            └── mainwindow.ui
    \endcode

    The top-level \c{CMakeLists.txt} contains the overall project setup,
    \c{find_package} and \c{add_subdirectory} calls:

    \code
    cmake_minimum_required(VERSION 3.16)

    project(helloworld VERSION 1.0.0 LANGUAGES CXX)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(Qt6 REQUIRED COMPONENTS Widgets)
    qt_standard_project_setup()

    add_subdirectory(src/app)
    \endcode

    Variables that are set in this file are visible in subdirectory project
    files.

    The application's project file \c{src/app/CMakeLists.txt} contains the
    executable target:

    \code
    qt_add_executable(helloworld
        mainwindow.ui
        mainwindow.cpp
        main.cpp
    )

    target_link_libraries(helloworld PRIVATE Qt6::Widgets)

    set_target_properties(helloworld PROPERTIES
        WIN32_EXECUTABLE ON
        MACOSX_BUNDLE ON
    )
    \endcode

    Such a structure will make it easy to add more targets to the project such
    as libraries or unit tests.

    \section2 Building libraries

    As the project grows, you may want to turn parts of your application code
    into a library that is used by the application and possibly unit tests. This
    section shows how to create such a library.

    Our application currently contains business logic directly in \c{main.cpp}.
    We extract the code into a new static library called \c{businesslogic} in
    the subdirectory \c{"src/businesslogic"} as explained in the \l{Structuring
    projects}{previous section}.

    For the sake of simplicity, the library consists of just one C++ source file
    and its corresponding header file that is included by the application's
    \c{main.cpp}:

    \badcode
    <project root>
    ├── CMakeLists.txt
    └── src
        ├── app
        │   ├── ...
        │   └── main.cpp
        └── businesslogic
            ├── CMakeLists.txt
            ├── businesslogic.cpp
            └── businesslogic.h
    \endcode

    Let's have a look at the library's project file (\c{src/businesslogic/CMakeLists.txt}).

    \quotefromfile snippets/cmake/helloworld_src_businesslogic.cmake
    \skipto add_library
    \printuntil

    Let's go through the content.

    \quotefromfile snippets/cmake/helloworld_src_businesslogic.cmake
    \skipto add_library
    \printto target_link_libraries

    The
    \l{https://cmake.org/cmake/help/latest/command/add_library.html}{add_library}
    command creates the library \c{businesslogic}. Later, we will let the
    application link against this target.

    The \c STATIC keyword denotes a static library. If we wanted to create a
    shared or dynamic library, we would use the \c SHARED keyword.

    \printuntil target_link_libraries

    We have a static library and don't actually have to link other libraries.
    But as our library uses classes from \c{QtCore}, we add a link dependency to
    \c{Qt6::Core}. This pulls in the necessary \c QtCore include paths and
    preprocessor defines.

    \printuntil target_include_directories

    The library API is defined in the header file
    \c{businesslogic/businesslogic.h}. By calling \l{CMake
    target_include_directories documentation}{target_include_directories}, we
    make sure that the absolute path to the \c businesslogic directory is
    automatically added as an include path to all targets using our library.

    This frees us in \c{main.cpp} from using relative paths to locate
    \c{businesslogic.h}. Instead, we can just write

    \badcode
    #include <businesslogic.h>
    \endcode

    Last, we must add the library's subdirectory to the top-level project file:

    \code
    add_subdirectory(src/app)
    add_subdirectory(src/businesslogic)
    \endcode

    \section2 Using libraries

    To use the library we created in the \l{Building libraries}{previous
    section}, we instruct CMake to link against it:

    \code
    target_link_libraries(helloworld PRIVATE
        businesslogic
        Qt6::Widgets
    )
    \endcode

    This ensures that \c{businesslogic.h} is found when main.cpp is compiled.
    Furthermore, the businesslogic static library will become a part of the \c
    helloworld executable.

    In CMake terms, the library \c businesslogic specifies \e{usage
    requirements} (the include path) that every consumer of our library (the
    application) has to satisfy. The \c{target_link_libraries} command takes
    care of that.

    \section2 Adding resources

    We want to display some images in our application, so we add them using the
    \l{The Qt Resource System}{Qt Resource System}.

    \code
    qt_add_resources(helloworld imageresources
        PREFIX "/images"
        FILES logo.png splashscreen.png
    )
    \endcode

    The \l{qt_add_resources} command automatically creates a Qt resource
    containing the referenced images. From the C++ source code, you can access
    the images by prepending the specified resource prefix:

    \code
    logoLabel->setPixmap(QPixmap(":/images/logo.png"));
    \endcode

    The \l{qt_add_resources} command takes as the first argument either a
    variable name or a target name. We recommend to use the target-based variant
    of this command as shown in the example above.

    \section2 Adding translations

    Translations of strings in a Qt project are encoded in \c{.ts} files. See
    \l{Internationalization with Qt} for details.

    To add \c{.ts} files to your project, use the
    \l{qt6_add_translations}{qt_add_translations} command.

    The following example adds a German and a French translation file to the
    \c{helloworld} target:

    \code
    qt_add_translations(helloworld
        TS_FILES helloworld_de.ts helloworld_fr.ts)
    \endcode

    This creates build system rules to automatically generate \c{.qm} files from
    the \c{.ts} files. By default, the \c{.qm} files are embedded into a
    resource and are accessible under the \c{"/i18n"} resource prefix.

    To update the entries in the \c{.ts} file, build the \c{update_translations}
    target:

    \badcode
    $ cmake --build . --target update_translations
    \endcode

    To trigger the generation of the \c{.qm} files manually, build the
    \c{release_translations} target:

    \badcode
    $ cmake --build . --target release_translations
    \endcode

    For more information about how to influence the handling of \c{.ts} files and
    the embedding into a resource, see the
    \l{qt6_add_translations}{qt_add_translations documentation}.

    The \l{qt6_add_translations}{qt_add_translations} command is a convenience
    wrapper. For more fine-grained control of how \c{.ts} files and \c{.qm}
    files are handled, use the underlying commands
    \l{qt6_add_lupdate}{qt_add_lupdate} and
    \l{qt6_add_lrelease}{qt_add_lrelease}.

    \section2 Further reading

    The official \l{CMake Documentation} is an invaluable source for working
    with CMake.

    The official \l{CMake Tutorial} covers common build system tasks.

    The book \l{Professional CMake: A Practical Guide} provides a great
    introduction to the most relevant CMake features.
*/

/*!
    \page cmake-build-qml-application.html
    \title Building a QML application
    \previouspage Getting started with CMake
    \nextpage Building a reusable QML module

    In \l{Building a C++ console application} we showed the
    CMakeLists.txt file for a simple console application. We will now extend it
    to create a QML application that uses the \l{Qt Quick} module.

    This is the full project file:
    \quotefromfile snippets/cmake/helloworld_qtqml.cmake
    \skipto cmake_minimum_required
    \printuntil

    Let's walk through the changes we have made.
    In the \c{find_package} call, we replace \c{Core} with \c{Quick}. This
    will locate the \c{Qt6Quick} module and provide the \c{Qt6::Quick}
    targets we later link against.

    \quotefromfile snippets/cmake/helloworld_qtqml.cmake
    \skipto find_package(
    \printuntil find_package(

    We call \l {qt6_standard_project_setup}{qt_standard_project_setup},
    and specify \l{Building a C++ console application}{CMAKE_CXX_STANDARD},
    and \c{CMAKE_CXX_STANDARD_REQUIRED}.
    By passing \c {REQUIRES 6.5} to \c {qt_standard_project_setup}, we opt-in
    to useful defaults for \l{qt6_add_qml_module}{qt_add_qml_module}.

    \printuntil CMAKE_CXX_STANDARD_REQUIRED


    Note that the application will still link against \c{Qt6::Core}, because
    \c{Qt6::Quick} depends on it.

    \l {qt_add_executable} creates and finalizes an application target:

    \printuntil )

    \l {qt_add_qml_module} passes the target of the executable, a URI, module
    version, and a list of QML files to ensure that myapp becomes a
    QML module. This places the QML files into
    \c { qrc:/qt/qml/${URI} } in the resource file system.
    Moreover, \c qt_add_qml_module ensures that \c qmlcachegen runs.
    Additionally, it creates a \c myapp_qmllint target, which runs \c qmllint on
    the files in QML_FILES.

    \printuntil )

    By adding the referenced resources, they get automatically added to
    the application under the same root path as the QML files – also in the
    resource file system. By keeping the path in the resource system
    consistent with the one in the source and build directory, we ensure that
    the image is always found, as it is resolved relative to FramedImage.qml.
    It refers to the image in the resource file system if we load main.qml from
    there, or to the one in the actual file system if we review it with
    the \c qml tool.

    In the \c{target_link_libraries} command, we link against \c{Qt6::Quick}
    instead of \c{Qt6::Core}.

    \printuntil target_link_libraries
*/

/*!
    \page cmake-build-reusable-qml-module.html
    \title Building a reusable QML module
    \previouspage Building a QML application
    \nextpage Building projects on the command line

    The example below demonstrates how to create a library which exposes C++ to QML.
    The directory structure for the example looks like this:

    \badcode
    ├── CMakeLists.txt
    └── example
        └── mylib
            ├── CMakeLists.txt
            ├── mytype.cpp
            ├── mytype.h
    \endcode

    The toplevel \c CMakeLists.txt file does some basic setup using
    \l{qt6_standard_project_setup}{qt_standard_project_setup}, and then uses
    \c add_subdirectory to include the one in mylib:

    \code
    cmake_minimum_required(VERSION 3.16)

    project(qmlmodule VERSION 1.0.0 LANGUAGES CXX)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)

    find_package(Qt6 REQUIRED COMPONENTS Qml)
    qt_standard_project_setup(REQUIRES 6.5)

    add_subdirectory(example/mylib)
    \endcode

    The subdirectories are structured to
    correspond to the QML module’s URI, but with the dots replaced by
    slashes. That’s the same logic the engine uses when it searches for a
    module in the \l{Import Statements}{import paths}. Following this
    subdirectory structure helps tooling.

    \c mytype.h declares a class and uses the
    \l{Registering C++ Types with the QML Type System}{declarative registration macros}
    to expose it to the engine.

    In the subdirectory’s \c CMakeLists.txt we call \l{qt6_add_qml_module}{qt_add_qml_module}.
    Compared to \l {Building a QML application}, the invocation is slightly
    different:

    \code
    qt_add_qml_module(mylib
        URI example.mylib
        VERSION 1.0
        SOURCES
            mytype.h mytype.cpp
        QML_FILES
            MyQmlType.qml
    )
    \endcode

    The target for \c{mylib} has not been created before. When the target passed
    to \c qt6_add_qml_module does not exist, it automatically creates a library
    target. This avoids a separate
    call to \l {qt6_add_library}{qt_add_library}.
    To register QML types defined in C++, add their header and source files
    as arguments to the SOURCES parameter.

    When the project is built, in addition to the library, a QML plugin is also
    built. The plugin's auto-generated class extends from
    \l {QQmlEngineExtensionPlugin}.
    The mylib library itself already contains the code to register the types
    with the engine.  However, that is only useful in cases where we can link
    against the library. To make the module usable in a QML file loaded by \c qml,
    the \l{qml_runtime_tool}{QML Runtime Tool}, a plugin is needed that can be loaded.
    The plugin is then responsible for actually linking against the library, and
    ensuring that the types get registered.

    Note that the automatic plugin generation is only possible if the module
    does not do anything besides registering the types. If it needs to do
    something more advanced like registering an image provider in
    \c initializeEngine, you still need to manually write the plugin.
    \l{qt6_add_qml_module} has support for this with \c NO_GENERATE_PLUGIN_SOURCE.

    Also, following the directory layout convention helps tooling. That layout
    is mirrored in the build directory. Which means that you can pass the path to
    your build directory to the QML tool (via the \c{-I} flag), and it will find the
    plugin.
*/

/*!
    \page cmake-build-on-cmdline.html
    \title Building projects on the command line
    \previouspage Getting started with CMake
    \nextpage Imported targets

    This page explains how to configure and build existing projects. If you want
    to know how to create a Qt-based CMake project, see the documentation on
    \l{Getting started with CMake}{how to get started with CMake}.

    To build a Qt project, CMake needs to know where the Qt installation is
    located. Usually this is done by setting the CMake variable \l{CMake
    CMAKE_PREFIX_PATH documentation}{CMAKE_PREFIX_PATH} to Qt's installation
    prefix. If you are cross-compiling, see \l{Cross-compiling} for details on
    additional variables you will need to set.

    If Qt is installed using the online installer, choose a Qt version within
    the top-level installation directory. For example, the following command
    shows how this is done on Windows:

    \badcode \QtVersion
    cmake -DCMAKE_PREFIX_PATH=C:\Qt\\1\msvc2019_64 -S <source-dir> -B <build-dir>
    \endcode

    The \c{<source-dir>} and \c{<build-dir>} placeholders represent the source
    and build directories of your project.

    \section1 CMake generators

    CMake generates the necessary build system files that enable build tools
    such as GNU Make or Ninja to build your project.

    CMake's default generator depends on the platform and build environment. For
    example on Windows, CMake generates Visual Studio project files if a Visual
    Studio environment is detected.

    For a consistent developer experience on all platforms, use the \c{Ninja} or
    \c{Ninja Multi-Config} generator.

    You can select the CMake generator either by setting the \c{CMAKE_GENERATOR}
    environment variable or using the \c{-G} argument:

    \badcode
    cmake -G Ninja ...
    \endcode

    \section1 qt-cmake

    The \c{qt-cmake} script is a convenient alternative to configure your
    project. It eliminates the need for you to specify the
    \c{CMAKE_PREFIX_PATH}. You can find it located in the \c{bin} directory of
    your Qt installation prefix. The script passes all parameters to CMake, so
    you can use it just like you would \c{cmake\}:

    \badcode \QtVersion
    C:\Qt\\1\msvc2019_64\bin\qt-cmake -G Ninja -S <source-dir> -B <build-dir>
    \endcode

    After the build system files are generated, your project is ready to be
    built:

    \badcode
    cd <build-dir>
    ninja
    \endcode

    You can also use the generator-independent CMake command:

    \badcode
    cmake --build <build-dir>
    \endcode

    \section1 Cross-compiling

    Building your project for a platform that is different from your development
    machine is called cross-compiling. An example is building for Android (the
    target platform) on a Windows machine (the host platform).

    Cross-compiling with CMake requires a \l{CMake CMAKE_TOOLCHAIN_FILE
    documentation}{toolchain file} for most platforms. It also requires a Qt
    version for the development host, in addition to a Qt version for the target
    platform. For example, you need Qt for Windows and Qt for Android installed
    to cross-compile for Android on Windows.

    Use \c qt-cmake from the Qt installation for the target platform, to
    cross-compile your project for that platform:

    \badcode
    <target-qt>/bin/qt-cmake -S <source-dir> -B <build-dir>
    \endcode

    This will configure your project for the target platform. The toolchain file
    is automatically passed, and possibly other platform-specific variables are
    set up.

    \section1 Specifying a custom toolchain file

    The \c{qt-cmake} script passes a Qt-internal \l{CMake CMAKE_TOOLCHAIN_FILE
    documentation}{toolchain file} to CMake. This toolchain file sets several
    variables that are specific to Qt's target platform.

    If you are using a Qt installation that has not been built on your machine,
    \c{qt-cmake} needs to know the location of the CMake toolchain file for the
    target platform.

    In such a case, you can instruct \c{qt-cmake} to chainload a custom
    toolchain file by setting the \c{QT_CHAINLOAD_TOOLCHAIN_FILE} variable:

    \badcode \QtVersion
    ~/Qt/\1/android_armv7/bin/qt-cmake -DQT_CHAINLOAD_TOOLCHAIN_FILE=<file-path> -S <source-dir> -B <build-dir>
    \endcode

    This instructs Qt's internal toolchain file to load your custom toolchain
    file as well.
*/

/*!
    \page cmake-imported-targets.html
    \title Imported targets
    \brief Provides an overview of the CMake targets imported by Qt.
    \nextpage Qt CMake policies
    \previouspage Building projects on the command line

    Each Qt module that is loaded defines a CMake library target. The target names
    start with \c{Qt6::}, followed by the module name. For example: \c{Qt6::Core}, \c{Qt6::Gui}.
    Pass the name of the library target to \c target_link_libraries to use the respective library.

    \note The targets are also available with a \c{Qt::} prefix:
    \c Qt::Core, \c Qt::Gui, and so on. See also \l{Qt 5 and Qt 6 compatibility}.

    Imported targets are created with the same configurations as when Qt was configured. That is:
    \list
        \li If Qt was configured with the \c -debug switch, an imported target with the DEBUG
            configuration is created.
        \li If Qt was configured with the \c -release switch, an imported target with the RELEASE
            configuration is created.
        \li If Qt was configured with the \c -debug-and-release switch, then imported targets are
            created with both RELEASE and DEBUG configurations.
    \endlist

    If your project has custom \c{CMake} build configurations, you have to map your custom
    configuration to either the debug or the release Qt configuration.

    \snippet snippets/cmake/examples.cmake 2
*/

/*!
    \page qt-cmake-policies.html
    \title Qt CMake policies
    \target qt_cmake_policies
    \brief Provides a list of available Qt CMake policies.
    \previouspage Imported targets
    \nextpage Qt 5 and Qt 6 compatibility

    Qt CMake policies maintain the backward compatibility
    across multiple releases. Every new policy starts by warning you about a
    deprecated feature or behavior; followed by a warning message that briefly
    describes the change. To disable a policy's warning, explicitly
    request the \c NEW or non-backward compatible behavior of a policy
    using the \l{qt_policy}{qt_policy()} command.

    \section1 Policies

    \annotatedlist qt-cmake-policies
*/

/*!
    \page cmake-qt5-and-qt6-compatibility.html
    \title Qt 5 and Qt 6 compatibility
    \previouspage Qt CMake policies
    \nextpage CMake Command Reference

    The semantics of the CMake API in Qt 5 and Qt 6 are largely compatible. However, up to Qt 5.14,
    all imported Qt library targets and commands contained the version number as part of the name.
    This makes writing CMake code that should work with both Qt 5 and Qt 6 somewhat cumbersome.
    Qt 5.15 therefore introduced \e versionless targets and commands to enable writing CMake code
    that is largely agnostic to the different Qt versions.

    \section2 Versionless targets

    In addition to the existing imported targets, Qt 5.15 introduced \e versionless targets. That
    is, to link against \l{Qt Core} one can both reference \c Qt6::Core, or \c Qt::Core:

    \snippet snippets/cmake/qt5_qt6_compatible.cmake versionless_targets

    Above snippet first tries to find a Qt 6 installation. If that fails, it tries to find a
    Qt 5.15 package. Independent of whether Qt 6 or Qt 5 is used, we can use the imported
    \c{Qt::Core} target.

    The versionless targets are defined by default. Set \l{QT_NO_CREATE_VERSIONLESS_TARGETS}
    before the first \c{find_package()} call to disable them.

    \note The imported Qt::Core target will not feature the target properties that are available
    in the Qt6::Core target.

    \section2 Versionless commands

    Since Qt 5.15, the Qt modules also provide versionless variants of their
    \l{CMake Command Reference}{commands}. You can for instance now use \l{qt_add_translation}
    to compile translation files, independent of whether you use Qt 5 or Qt 6.

    Set \l{QT_NO_CREATE_VERSIONLESS_FUNCTIONS} before the first \c{find_package()} call to
    prevent the creation of versionless commands.

    \section2 Mixing Qt 5 and Qt 6

    There might be projects that need to load both Qt 5 and Qt 6 in one CMake context
    (though mixing Qt versions in one library or executable is not supported, so be careful there).

    In such a setup the versionless targets and commands will be implicitly referring to the first
    Qt version that was found via \c{find_package}. Set the \l{QT_DEFAULT_MAJOR_VERSION} CMake
    variable before the first \c{find_package} call to make the version explicit.

    \section2 Supporting older Qt 5 versions

    If you need to support also Qt 5 versions older than Qt 5.15, you can do so by storing the
    current version in an CMake variable:

    \snippet snippets/cmake/qt5_qt6_compatible.cmake older_qt_versions

    Here we let \c{find_package(<PackageName>...)} try to find first Qt 6, and if
    that fails Qt 5, under the name \c{QT}. If either of them is found, \c find_package will
    succeed, and the CMake variable \c{QT_VERSION_MAJOR} will be defined to either \c{5} or \c{6}.

    We then do load the package for the determined Qt version again by creating the name
    \c{Qt${QT_VERSION_MAJOR}} on the fly. This is needed because \c{CMAKE_AUTOMOC}
    expects the package name to be either \c{Qt5} or \c{Qt6}, and will print an error otherwise.

    We can use the same pattern to also specify the name of the imported library.
    Before calling \c{target_link_libraries}, CMake will resolve \c{Qt${QT_VERSION_MAJOR}::Widgets}
    to either \c{Qt5::Widgets} or \c{Qt6::Widgets}.

    \section2 Recommended practices

    Use the versionless variants of the CMake commands where possible.

    Versionless imported targets are mostly useful for projects that need to compile with both
    Qt 5 and Qt 6. Because of the missing target properties, we do not recommend using
    them by default.

    Use the versioned versions of the CMake commands and targets if you need to support Qt 5
    versions older than Qt 5.15, or if you cannot control whether your CMake code is
    loaded in a context where \l{QT_NO_CREATE_VERSIONLESS_FUNCTIONS} or
    \l{QT_NO_CREATE_VERSIONLESS_TARGETS} might be defined. In this case you can still simplify
    your code by determining the actual command or target name through a variable.

    \section2 Unicode support in Windows

    In Qt 6, the \c UNICODE and \c{_UNICODE} compiler definitions are set by default for targets that link
    against Qt modules. This is in line with the qmake behavior, but it is a change compared to
    the CMake API behavior in Qt 5.

    Call \l{qt6_disable_unicode_defines}{qt_disable_unicode_defines()} on the target to not set the definitions.

    \snippet snippets/cmake/qt5_qt6_compatible.cmake disable_unicode_defines
*/

/*!
    \page cmake-variable-reference.html
    \title CMake Variable Reference
    \brief Provides a complete reference for CMake variables implemented in Qt.
    \nextpage CMake Property Reference
    \previouspage CMake Command Reference

    \section1 Module variables

    Qt modules loaded with \c{find_package} set various variables.

    \note You rarely need to access these variables directly. Common tasks like linking against a
    module should be done through the library targets each module defines.

    For example, \c{find_package(Qt6 COMPONENTS Widgets)}, when successful, makes the following
    variables available:

    \table
        \header
            \li Variable
            \li Description
        \row
            \li \c Qt6Widgets_COMPILE_DEFINITIONS
            \li A list of compile definitions to use when building against the library.
        \row
            \li \c Qt6Widgets_DEFINITIONS
            \li A list of definitions to use when building against the library.
        \row
            \li \c Qt6Widgets_EXECUTABLE_COMPILE_FLAGS
            \li A string of flags to use when building executables against the library.
        \row
            \li \c Qt6Widgets_FOUND
            \li A boolean that describes whether the module was found successfully.
        \row
            \li \c Qt6Widgets_INCLUDE_DIRS
            \li A list of include directories to use when building against the library.
        \row
            \li \c Qt6Widgets_LIBRARIES
            \li The name of the imported target for the module: \c Qt5::Widgets
        \row
            \li \c Qt6Widgets_PRIVATE_INCLUDE_DIRS
            \li A list of private include directories to use when building against the library
                and using private Qt API.
        \row
            \li \c Qt6Widgets_VERSION
            \li A string containing the module's version.
    \endtable

    For all packages found with \c{find_package}, equivalents of these variables are available;
    they are case-sensitive.

    \section1 Installation variables

    Additionally, there are also variables that don't relate to a particular package, but to the
    Qt installation itself.

   \table
        \header
            \li Variable
            \li Description
        \row
            \li \target QT_DEFAULT_MAJOR_VERSION
                \c QT_DEFAULT_MAJOR_VERSION
            \li An integer that controls the Qt version that \c qt_ commands forward to in case of
                mixed Qt 5 and Qt 6 projects. It needs to be set to either \c 5 or \c 6 before the
                respective \c find_package() calls.

                If set to \c 5, commands starting with \c qt_ will call their counterpart starting
                with \c qt5_. If set to \c 6, they will call their counterpart starting with
                \c qt6_.

                If not set, the first \c find_package call defines the default version.
        \row
            \li \c QT_LIBINFIX
            \li A string that holds the infix used in library names, when Qt is configured with
                \c{-libinfix}.
        \row
            \li \target QT_NO_CREATE_VERSIONLESS_FUNCTIONS
                \c QT_NO_CREATE_VERSIONLESS_FUNCTIONS
            \li Hides commands that start with \c{qt_}, leaving only the versioned
                ones starting with \c{qt6_}.
        \row
            \li \target QT_NO_CREATE_VERSIONLESS_TARGETS
                \c QT_NO_CREATE_VERSIONLESS_TARGETS
            \li Hides the imported targets starting with \c{Qt::}. Instead, you need to use the
                targets starting with \c{Qt6::}.
        \row
            \li \c QT_VISIBILITY_AVAILABLE
            \li On Unix, a boolean that describes whether Qt libraries and plugins were compiled
                with \c{-fvisibility=hidden}. This means that only selected symbols are exported.
    \endtable

    \section1 Project variables

    These variables can influence CMake commands provided by Qt. They may be set
    by the project, a toolchain file or other third-party packages.

    \section2 Qt6::Core

    \annotatedlist cmake-variables-qtcore

    \section2 Qt6::Qml

    \annotatedlist cmake-variables-qtqml

    \section2 Qt6::InterfaceFramework

    \annotatedlist cmake-variables-qtinterfaceframework
*/

/*!
    \page cmake-property-reference.html
    \title CMake Property Reference
    \brief Provides a complete reference for CMake properties implemented in Qt.
    \previouspage CMake Variable Reference

    \section1 Qt6::Core
    \target cmake-properties-qtcore

    \section2 Target Properties

    \annotatedlist cmake-target-properties-qtcore

    \section2 Source File Properties

    \annotatedlist cmake-source-file-properties-qtcore

    \section2 Global Properties

    \annotatedlist cmake-global-properties-qtcore

    \section1 Qt6::DBus
    \target cmake-properties-qtdbus

    \section2 Source File Properties

    \annotatedlist cmake-source-file-properties-qtdbus

    \section1 Qt6::Qml
    \target cmake-properties-qtqml

    \section2 Source File Properties

    \annotatedlist cmake-source-file-properties-qtqml

    \section2 Global Properties

    \annotatedlist cmake-global-properties-qtqml
*/

/*!
    \page cmake-command-reference.html
    \title CMake Command Reference
    \brief Provides a complete reference for CMake commands implemented in Qt.
    \previouspage Qt 5 and Qt 6 compatibility
    \nextpage CMake Variable Reference

    \section2 Qt6::Core
    \target cmake-commands-qtcore

    \annotatedlist cmake-commands-qtcore

    \section2 Qt6::DBus
    \target cmake-commands-qtdbus

    \annotatedlist cmake-commands-qtdbus

    \section2 Qt6::InterfaceFramework
    \target cmake-commands-qtinterfaceframework

    \annotatedlist cmake-commands-qtinterfaceframework

    \section2 Qt6::LinguistTools
    \target cmake-commands-qtlinguisttools

    \annotatedlist cmake-commands-qtlinguisttools

    \section2 Qt6::Protobuf
    \target cmake-commands-qtprotobuf

    \annotatedlist cmake-commands-qtprotobuf

    \section2 Qt6::Grpc
    \target cmake-commands-qtgrpc

    \annotatedlist cmake-commands-qtgrpc

    \section2 Qt6::Qml
    \target cmake-commands-qtqml

    \annotatedlist cmake-commands-qtqml

    \section2 Qt6::RemoteObjects
    \target cmake-macros-qtremoteobjects

    \annotatedlist cmake-macros-qtremoteobjects

    \section2 Qt6::Scxml
    \target cmake-macros-qtscxml

    \annotatedlist cmake-macros-qtscxml

    \section2 Qt6::ShaderTools
    \target cmake-commands-qtshadertools

    \annotatedlist cmake-commands-qtshadertools

    \section2 Qt6::Widgets
    \target cmake-macros-qtwidgets

    \annotatedlist cmake-macros-qtwidgets

    \target cmake-commands-qtwebenginecore
    \section2 Qt6::WebEngineCore

    \annotatedlist cmake-commands-qtwebenginecore
*/