Qt6 Build System: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(initial revision)
 
 
(19 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Category:Developing Qt::Qt Build System]]
This is a description of the Qt6 CMake-based build system.
This is a description of the Qt6 CMake-based build system.


For Qt5, see [[Qt5 Build System]].
For Qt5, see [[Qt5 Build System]].


For a description of terms used here, please see the [[Qt Build System Glossary]].  
For a description of terms used here, please see the [[Qt Build System Glossary]].
 
When writing CMake code, beware of the [[CMake Language Pitfalls]].
 
There is some historical information at [[CMake Port]].
 
== Configuration at CMake level ==
Qt6 uses CMake, and you can use plain CMake to configure Qt. For a more convenient way to configure Qt, use the configure script, which internals are described further down on this page.
 
=== The configure.cmake files ===
How Qt can be configure is defined in <tt>configure.cmake</tt> files. There can be multiple configure.cmake files in a repository:
 
* configure.cmake at the top level of the repository
* src/mymodule/configure.cmake in the subdirectory of a Qt module
 
The  <tt>configure.cmake</tt> files typically contain the following things
 
* qt_find_package calls to make 3rdparty libraries available
* compile tests
* feature definitions
* entries for Qt's configure summary
* messages that are conditionally displayed
 
=== Commands in configure.cmake ===
 
==== qt_find_package ====
This is a macro that wraps CMake's <tt>find_package</tt> and adds Qt-specific stuff.
<code>
qt_find_package(<PackageName>
    [PROVIDED_TARGETS target1 target2 ...]]
    [MODULE_NAME name QMAKE_LIB name]
)</code>
 
<tt>PROVIDED_TARGETS</tt> lists targets that are provided by the package. The targets are promoted to global unless that's inhibited.
 
<tt>MODULE_NAME</tt> and <tt>QMAKE_LIB</tt> are meant to be specified together.
<tt>MODULE_NAME</tt> denotes the Qt module name in QMake parlance this package belongs to. <tt>QMAKE_LIB</tt> is the corresponding library name that QMake understands.
 
==== qt_config_compile_test ====
qt_config_compile_test(name
    LABEL text
    [LIBRARIES library1 library2 ...]
    [C_STANDARD version]
    [CXX_STANDARD version]
    [COMPILE_OPTIONS option1 option2 ...]
    [PACKAGES package1 package2 ...]
    [CMAKE_FLAGS flag1 flag2 ...]
    [CODE source_code]
    [PROJECT_PATH path]
)
Builds either a string of source code or a whole project to determine whether the build is successful.
 
Sets a <tt>TEST_${name}_OUTPUT</tt> variable with the build output, to the scope of the calling function. Sets a <tt>TEST_${name}</tt> cache variable to either <tt>TRUE</tt> or <tt>FALSE</tt> if the build is successful or not.
 
One can either specify the source code of the test project with <tt>CODE</tt> or use <tt>PROJECT_PATH</tt> to point to a directory with a full CMake project.
 
==== qt_feature("<feature>" ...) ====
 
Defines a feature called <feature>. Whether a feature is enabled can
be then elsewhere be checked by <tt>QT_FEATURE_foo</tt>. Users are
supposed to control features by setting the <tt>FEATURE_foo</tt>
variable to <tt>ON</tt> or <tt>OFF</tt> (note the absence of the
<tt>QT_</tt> prefix).
 
<code>qt_feature("<feature>" [PUBLIC] [PRIVATE]
    [LABEL "<label>"]
    [PURPOSE "<purpose>"]
    [SECTION "<selection>"]
    [AUTODETECT <condition>]
    [CONDITION <condition>]
    [ENABLE <condition>]
    [DISABLE <condition>]
    [EMIT_IF <condition>]
)</code>
 
<tt>PUBLIC</tt> or <tt>PRIVATE</tt> defines whether the feature is
available within the Qt module, or also in other Qt modules.
 
<tt>PURPOSE</tt> is the help text that's displayed on <tt>configure
-list-features</tt>. A missing <tt>PURPOSE</tt> is the usual reason
for a feature not being displayed on <tt>configure
-list-features</tt>.
 
<tt>LABEL</tt> is a human-readable name that shortly describes the
feature in the configure summary.
 
<tt>AUTODETECT</tt> determines whether the feature is opt-in or
opt-out. The default is <tt>ON</tt>. Features that are supposed to be
enabled explicitly by the user should have <tt>AUTODETECT OFF</tt>.
 
<tt>CONDITION</tt> specifies a condition that needs to be satisfied if
the feature is turned on. If the user enables a feature but the
condition is not satisfied, an error will be yielded. If the feature
is auto-detected and the condition is not satisfied, there will be no
error.
 
<tt>EMIT_IF</tt> If this evaluates to false, skip the feature
completely. No cache variable for this feature will be recorded. This
can be used to enable a feature on certain platforms only.
 
<tt>ENABLE</tt> Evaluates to a condition that will enable the feature.
This is usually set to react on <tt>INPUT_foo</tt> values.
 
<tt>DISABLE</tt> is the complement of <tt>ENABLE</tt>.
 
==== qt_feature_definition("<feature>" "<name>" ...) ====
 
Makes a C++ define <tt><name></tt> available.
 
<code>
qt_feature_definition("<feature>" "<name>" [NEGATE] [VALUE "<value>"])
</code>
 
If <tt>&lt;value&gt;</tt> is set, the define will have this as value.
 
If <tt>NEGATE</tt> is given, the define is set only if the feature is disabled. Otherwise it is set only if it is enabled.
 
==== qt_configure_add_summary_section ====
qt_configure_add_summary_section(NAME "Things")
Adds a new section in the configure summary named "Things".  Summary entries added after this call will be added to that section until qt_configure_end_summary_section() is called.
 
==== qt_configure_end_summary_section ====
qt_configure_end_summary_section()
Ends the currently active summary section.
 
==== qt_configure_add_summary_entry ====
qt_configure_add_summary_entry(
    ARGS <string>
    [TYPE feature|featureList|firstAvailableFeature]
    [MESSAGE <string>]
    [CONDITION <list>]
)
Adds an entry to the configure summary in the currently active summary section.
 
ARGS is a string that contains features, separated by spaces.
 
TYPE defaults to "feature". The different types have the following meaning:
 
* feature: display whether the feature in ARGS is enabled. Display the feature's LABEL. MESSAGE is ignored. If the feature has no LABEL, use the feature's name.
* featureList: display MESSAGE and the LABELs of the enabled features in ARGS.
* firstAvailableFeature: display MESSAGE and the LABEL of the first of the enabled features in ARGS.
 
CONDITION can be used to conditionally suppress the display of the summary entry.
 
==== qt_configure_add_report_entry ====
<code>
qt_configure_process_add_report_entry(
    TYPE NOTE|WARNING|ERROR|FATAL_ERROR
    MESSAGE message
    [CONDITION condition]
)</code>
 
Adds a message, warning or error to the configure summary.
 
<tt>CONDITION</tt> specifies whether to issue the report entry.
 
=== Common tasks ===
 
==== Defining a simple boolean feature ====
TBD
 
==== Calling functions that the configure script doesn't know about ====
TBD
 
== Qt's configure script ==
Qt's configure script is a convenience interface that translates its command line options to CMake arguments.
 
=== Where configure's logic is implemented ===
Most of configure's logic is implemented in qtbase/cmake/QtProcessConfigureArgs.cmake. This is a CMake script that is run via cmake -P by configure/configure.bat.
 
Only very special configure options need to be implemented here. Most should be doable with the qt_cmdline.cmake configuration files.
 
=== qt_cmdline.cmake files ===
Most configure options are defined in <tt>qt_cmdline.cmake</tt> files throughout the repositories. Each Qt repository can have a top-level <tt>qt_cmdline.cmake</tt> file and several lower-level ones. For example, qtbase has the following files (at the time of writing):
qt_cmdline.cmake
src/corelib/qt_cmdline.cmake
src/gui/qt_cmdline.cmake
src/network/qt_cmdline.cmake
src/plugins/sqldrivers/qt_cmdline.cmake
src/printsupport/qt_cmdline.cmake
src/sql/qt_cmdline.cmake
src/testlib/qt_cmdline.cmake
src/widgets/qt_cmdline.cmake
src/xml/qt_cmdline.cmake
The top-level file must reference the lower-level files. This is similar to include statements or CMake's <tt>add_subdirectory</tt> calls.
qt_commandline_subconfig(src/corelib)
qt_commandline_subconfig(src/network)
qt_commandline_subconfig(src/gui)
qt_commandline_subconfig(src/sql)
qt_commandline_subconfig(src/xml)
qt_commandline_subconfig(src/widgets)
...
This is also necessary to let configure pick up the configure.cmake files in the subdirectories. The configure script needs to be aware of the features defined in those configure.cmake files.
 
=== What effect can configure options have? ===
Configure options can affect three things:
 
* -foo could be directly translated to a CMake variable that is passed as -DNAME=value.
* -foo and -no-foo could control the feature "foo".
* --foo bar could set the variable INPUT_foo that can be used in configure.cmake or regular CMake files.
 
=== Commands available in qt_cmdline.cmake ===
 
==== qt_commandline_subconfig ====
qt_commandline_subconfig(path)
As outlined above, this is something like an include statement that pulls further qt_cmdline.cmake files. The parameter path is the path of a subdirectory where another qt_cmdline.cmake is located.
 
==== qt_commandline_option ====
qt_commandline_option(name
    TYPE type_name
    [NAME variable_name]
    [VALUE value]
    [VALUES value1 [value2 ...]]
    [MAPPING from1 to1 [from2 to2 ...]]
    [CONTROLS_FEATURE]
)
 
==== qt_commandline_custom ====
qt_commandline_custom(handler)
Registers a custom handler function. This was once used to handle QMAKE_xxx=yyy assignments. You really must do internal stuff in there.
 
This functionality should probably be removed.
 
==== qt_commandline_prefix ====
qt_commandline_prefix(D defines)
Add a configure option -D that sets the variable INPUT_defines. The user may pass multiple prefix arguments to configure. The values accumulate in INPUT_defines.
 
QtProcessConfigureArgs.cmake has special handling for all prefixes in qtbase.
 
=== Common tasks ===


At the moment, there's not much here. We plan to extend this in the future.
===== How to add a command line option that controls a feature? =====
TBD


Probably, [[CMake_Port/Configure_System]] should be merged into this.
==== How to add a command line option that sets a CMake variable? ====
TBD

Latest revision as of 15:18, 27 March 2024


This is a description of the Qt6 CMake-based build system.

For Qt5, see Qt5 Build System.

For a description of terms used here, please see the Qt Build System Glossary.

When writing CMake code, beware of the CMake Language Pitfalls.

There is some historical information at CMake Port.

Configuration at CMake level

Qt6 uses CMake, and you can use plain CMake to configure Qt. For a more convenient way to configure Qt, use the configure script, which internals are described further down on this page.

The configure.cmake files

How Qt can be configure is defined in configure.cmake files. There can be multiple configure.cmake files in a repository:

  • configure.cmake at the top level of the repository
  • src/mymodule/configure.cmake in the subdirectory of a Qt module

The configure.cmake files typically contain the following things

  • qt_find_package calls to make 3rdparty libraries available
  • compile tests
  • feature definitions
  • entries for Qt's configure summary
  • messages that are conditionally displayed

Commands in configure.cmake

qt_find_package

This is a macro that wraps CMake's find_package and adds Qt-specific stuff.

qt_find_package(<PackageName>
    [PROVIDED_TARGETS target1 target2 ...]]
    [MODULE_NAME name QMAKE_LIB name]
)

PROVIDED_TARGETS lists targets that are provided by the package. The targets are promoted to global unless that's inhibited.

MODULE_NAME and QMAKE_LIB are meant to be specified together. MODULE_NAME denotes the Qt module name in QMake parlance this package belongs to. QMAKE_LIB is the corresponding library name that QMake understands.

qt_config_compile_test

qt_config_compile_test(name
    LABEL text
    [LIBRARIES library1 library2 ...]
    [C_STANDARD version]
    [CXX_STANDARD version]
    [COMPILE_OPTIONS option1 option2 ...]
    [PACKAGES package1 package2 ...]
    [CMAKE_FLAGS flag1 flag2 ...]
    [CODE source_code]
    [PROJECT_PATH path]
)

Builds either a string of source code or a whole project to determine whether the build is successful.

Sets a TEST_${name}_OUTPUT variable with the build output, to the scope of the calling function. Sets a TEST_${name} cache variable to either TRUE or FALSE if the build is successful or not.

One can either specify the source code of the test project with CODE or use PROJECT_PATH to point to a directory with a full CMake project.

qt_feature("<feature>" ...)

Defines a feature called <feature>. Whether a feature is enabled can be then elsewhere be checked by QT_FEATURE_foo. Users are supposed to control features by setting the FEATURE_foo variable to ON or OFF (note the absence of the QT_ prefix).

qt_feature("<feature>" [PUBLIC] [PRIVATE]
    [LABEL "<label>"]
    [PURPOSE "<purpose>"]
    [SECTION "<selection>"]
    [AUTODETECT <condition>]
    [CONDITION <condition>]
    [ENABLE <condition>]
    [DISABLE <condition>]
    [EMIT_IF <condition>]
)

PUBLIC or PRIVATE defines whether the feature is available within the Qt module, or also in other Qt modules.

PURPOSE is the help text that's displayed on configure -list-features. A missing PURPOSE is the usual reason for a feature not being displayed on configure -list-features.

LABEL is a human-readable name that shortly describes the feature in the configure summary.

AUTODETECT determines whether the feature is opt-in or opt-out. The default is ON. Features that are supposed to be enabled explicitly by the user should have AUTODETECT OFF.

CONDITION specifies a condition that needs to be satisfied if the feature is turned on. If the user enables a feature but the condition is not satisfied, an error will be yielded. If the feature is auto-detected and the condition is not satisfied, there will be no error.

EMIT_IF If this evaluates to false, skip the feature completely. No cache variable for this feature will be recorded. This can be used to enable a feature on certain platforms only.

ENABLE Evaluates to a condition that will enable the feature. This is usually set to react on INPUT_foo values.

DISABLE is the complement of ENABLE.

qt_feature_definition("<feature>" "<name>" ...)

Makes a C++ define <name> available.

qt_feature_definition("<feature>" "<name>" [NEGATE] [VALUE "<value>"])

If <value> is set, the define will have this as value.

If NEGATE is given, the define is set only if the feature is disabled. Otherwise it is set only if it is enabled.

qt_configure_add_summary_section

qt_configure_add_summary_section(NAME "Things")

Adds a new section in the configure summary named "Things". Summary entries added after this call will be added to that section until qt_configure_end_summary_section() is called.

qt_configure_end_summary_section

qt_configure_end_summary_section()

Ends the currently active summary section.

qt_configure_add_summary_entry

qt_configure_add_summary_entry(
    ARGS <string>
    [TYPE feature|featureList|firstAvailableFeature]
    [MESSAGE <string>]
    [CONDITION <list>]
)

Adds an entry to the configure summary in the currently active summary section.

ARGS is a string that contains features, separated by spaces.

TYPE defaults to "feature". The different types have the following meaning:

  • feature: display whether the feature in ARGS is enabled. Display the feature's LABEL. MESSAGE is ignored. If the feature has no LABEL, use the feature's name.
  • featureList: display MESSAGE and the LABELs of the enabled features in ARGS.
  • firstAvailableFeature: display MESSAGE and the LABEL of the first of the enabled features in ARGS.

CONDITION can be used to conditionally suppress the display of the summary entry.

qt_configure_add_report_entry

qt_configure_process_add_report_entry(
    TYPE NOTE|WARNING|ERROR|FATAL_ERROR
    MESSAGE message
    [CONDITION condition]
)

Adds a message, warning or error to the configure summary.

CONDITION specifies whether to issue the report entry.

Common tasks

Defining a simple boolean feature

TBD

Calling functions that the configure script doesn't know about

TBD

Qt's configure script

Qt's configure script is a convenience interface that translates its command line options to CMake arguments.

Where configure's logic is implemented

Most of configure's logic is implemented in qtbase/cmake/QtProcessConfigureArgs.cmake. This is a CMake script that is run via cmake -P by configure/configure.bat.

Only very special configure options need to be implemented here. Most should be doable with the qt_cmdline.cmake configuration files.

qt_cmdline.cmake files

Most configure options are defined in qt_cmdline.cmake files throughout the repositories. Each Qt repository can have a top-level qt_cmdline.cmake file and several lower-level ones. For example, qtbase has the following files (at the time of writing):

qt_cmdline.cmake
src/corelib/qt_cmdline.cmake
src/gui/qt_cmdline.cmake
src/network/qt_cmdline.cmake
src/plugins/sqldrivers/qt_cmdline.cmake
src/printsupport/qt_cmdline.cmake
src/sql/qt_cmdline.cmake
src/testlib/qt_cmdline.cmake
src/widgets/qt_cmdline.cmake
src/xml/qt_cmdline.cmake

The top-level file must reference the lower-level files. This is similar to include statements or CMake's add_subdirectory calls.

qt_commandline_subconfig(src/corelib)
qt_commandline_subconfig(src/network)
qt_commandline_subconfig(src/gui)
qt_commandline_subconfig(src/sql)
qt_commandline_subconfig(src/xml)
qt_commandline_subconfig(src/widgets)
...

This is also necessary to let configure pick up the configure.cmake files in the subdirectories. The configure script needs to be aware of the features defined in those configure.cmake files.

What effect can configure options have?

Configure options can affect three things:

  • -foo could be directly translated to a CMake variable that is passed as -DNAME=value.
  • -foo and -no-foo could control the feature "foo".
  • --foo bar could set the variable INPUT_foo that can be used in configure.cmake or regular CMake files.

Commands available in qt_cmdline.cmake

qt_commandline_subconfig

qt_commandline_subconfig(path)

As outlined above, this is something like an include statement that pulls further qt_cmdline.cmake files. The parameter path is the path of a subdirectory where another qt_cmdline.cmake is located.

qt_commandline_option

qt_commandline_option(name
    TYPE type_name
    [NAME variable_name]
    [VALUE value]
    [VALUES value1 [value2 ...]]
    [MAPPING from1 to1 [from2 to2 ...]]
    [CONTROLS_FEATURE]
)

qt_commandline_custom

qt_commandline_custom(handler)

Registers a custom handler function. This was once used to handle QMAKE_xxx=yyy assignments. You really must do internal stuff in there.

This functionality should probably be removed.

qt_commandline_prefix

qt_commandline_prefix(D defines)

Add a configure option -D that sets the variable INPUT_defines. The user may pass multiple prefix arguments to configure. The values accumulate in INPUT_defines.

QtProcessConfigureArgs.cmake has special handling for all prefixes in qtbase.

Common tasks

How to add a command line option that controls a feature?

TBD

How to add a command line option that sets a CMake variable?

TBD