# Gerrit changes * https://codereview.qt-project.org/q/topic:%22cmake_api_review_6_2%22+(status:open%20OR%20status:merged) # Discussion topics General topics * Should we raise the minimum CMake version for user projects that use a static Qt? Currently we require a bare minimum of 3.14 for any project, and 3.16 for projects that use the new QML API due to AUTOMOC metatype.json extraction. Raising the minimum to 3.17 would allow us to ensure no 'undefined symbol' errors when linking projects on Linux, due to target_link_options workaround implemented for propgataing object libraries. If yes, what behavior do we want if a lower CMake version is used? * FATAL_ERROR if lower * warn if lower * limit min cmake requirement only on Linux and MinGW with a combination of the above two QML topics extracted from notes taken in internal wiki page * figure out if we want to offer a convenience API for copying / installing QML files and non-qml resources on disk to the build and install dir (yes, we do!) * Discussion about a default qml prefix and offering installation helpers for it * Possibly rename QT_RESOURCE_PREFIX property to QT_QML_MODULE_RESOURCE_PREFIX * Offer a qt_get_qml_module_resource_prefix public API, to get the PREFIX so that non-qml files can be passed into qt_internal_add_resource * Should typeinfo plugins.qmltypes be written to the qmldir file if there's no plugins.qmltypes file installed? Currently we always write it * There are certain repos that specify a custom PLUGIN_TARGET with the previously added plugin name, instead of using the automatically generated name. Is there a good reason to keep those? # Meeting Notes # API Review ## qtbase `qt6_add_executable` - existing TP API `qt_add_executable` ```cmake function(qt6_add_executable target) cmake_parse_arguments(PARSE_ARGV 1 arg "MANUAL_FINALIZATION" "" "") ``` `qt6_finalize_target` - new API `qt_finalize_target` ```cmake function(qt6_finalize_target target) ``` `qt_finalize_executable` - existing API kept for QtCreator compatibility ```cmake function(qt_finalize_executable) qt6_finalize_target(${ARGV}) endfunction() ``` `qt6_enable_import_plugins_finalizer_mode` - new API `qt_enable_import_plugins_finalizer_mode` ```cmake function(qt6_enable_import_plugins_finalizer_mode target enabled) ``` `qt6_enable_object_libraries_finalizer_mode` - new API `qt_enable_object_libraries_finalizer_mode` ```cmake function(qt6_enable_object_libraries_finalizer_mode target enabled) ``` `qt6_add_plugin` - existing TP API `qt_add_plugin` ```cmake function(qt6_add_plugin target) set(${option_args} STATIC SHARED ) set(${single_args} TYPE CLASS_NAME OUTPUT_NAME ) ``` `qt6_add_library` - new API `qt_add_library` ```cmake function(qt6_add_library target) cmake_parse_arguments(PARSE_ARGV 1 arg "MANUAL_FINALIZATION" "" "") ``` `qt6_wasm_add_target_helpers` - new API, probably should be internal `qt_wasm_add_target_helpers` ```cmake function(qt6_wasm_add_target_helpers target) ``` ## qtshadertools `qt6_add_shaders` - existing API `qt_add_shaders` ```cmake function(qt6_add_shaders) qt6_add_shaders_impl(${ARGV}) endfunction() ``` `qt6_add_shaders_impl` - new API, probably needs to be `_qt_internal_add_shaders_impl` New options are `INTERNAL`, `SILENT` , `OUTPUTS` ```cmake function(qt6_add_shaders_impl target resourcename) cmake_parse_arguments( arg "BATCHABLE;PRECOMPILE;PERTARGETCOMPILE;NOGLSL;NOHLSL;NOMSL;DEBUGINFO;OPTIMIZED;SILENT;INTERNAL" "PREFIX;GLSL;HLSL;MSL" "FILES;OUTPUTS;DEFINES" ${ARGN} ) ``` `qt6_internal_add_shaders` - new API, probably needs to be removed `qt_internal_add_shaders` - new API, probably needs to be `_qt_internal_add_shaders` ```cmake function(qt6_internal_add_shaders) qt6_add_shaders_impl(${ARGV} INTERNAL) endfunction() ``` ## qtremoteobjects `qt6_add_repc_sources` renamed from `qt6_add_repc_source` Missing versionless API `qt6_add_repc_replicas` renamed from `qt6_add_repc_replica` Missing versionless API ## qtwayland `qt6_generate_wayland_protocol_client_sources` - existing API New option is `WAYLAND_INCLUDE_DIR` ```cmake function(qt6_generate_wayland_protocol_client_sources target) cmake_parse_arguments(arg "" "WAYLAND_INCLUDE_DIR" "FILES" ${ARGN}) ``` `qt6_generate_wayland_protocol_server_sources` - existing API New option is `WAYLAND_INCLUDE_DIR` ```cmake function(qt6_generate_wayland_protocol_server_sources target) cmake_parse_arguments(arg "" "WAYLAND_INCLUDE_DIR" "FILES" ${ARGN}) ``` ## qtscxml `qt6_add_statecharts` - existing API New options are `OUTPUT_DIR`, `NAMESPACE`. Renamed option `OPTIONS` to `QSCXMLC_ARGUMENTS` ```cmake function(qt6_add_statecharts target_or_outfiles) set(options) set(oneValueArgs OUTPUT_DIR NAMESPACE) set(multiValueArgs QSCXMLC_ARGUMENTS) cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) ``` ## qtquick3d `qt6_quick3d_bake_lightprobe_hdri` - new API `qt_quick3d_bake_lightprobe_hdri` ```cmake # .hdr -> .ktx baker. Quite similar to qt6_add_shaders(). # # For example, the following autogenerates the lightprobe map at build time and # includes it in the executable under :/maps/OpenfootageNET_garage-1024.ktx: # # qt6_quick3d_bake_lightprobe_hdri(principledmaterial "ibl_assets" # PREFIX # "/maps" # FILES # "maps/OpenfootageNET_garage-1024.hdr" ) # function(qt6_quick3d_bake_lightprobe_hdri target resource_name) cmake_parse_arguments(arg "" "PREFIX;INTERNAL" "FILES" ${ARGN} ) ``` `qt6_quick3d_internal_bake_lightprobe_hdri` - new API, wraps qt6_quick3d_bake_lightprobe_hdri `qt_quick3d_internal_bake_lightprobe_hdri` ## qttools `qt6_add_lupdate` - new API `qt_add_lupdate` ```cmake function(qt6_add_lupdate target) set(options NO_GLOBAL_TARGET) set(oneValueArgs) set(multiValueArgs TS_FILES SOURCES INCLUDE_DIRECTORIES OPTIONS) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) ``` `qt6_add_lrelease` - new API `qt_add_lrelease` ```cmake function(qt6_add_lrelease target) set(options MANUAL NO_GLOBAL_TARGET) set(oneValueArgs QM_FILES_OUTPUT_VARIABLE) set(multiValueArgs TS_FILES OPTIONS) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) ``` `qt6_add_translations` - new API `qt_add_translations` ```cmake function(qt6_add_translations target) set(options) set(oneValueArgs QM_FILES_OUTPUT_VARIABLE) set(multiValueArgs TS_FILES SOURCES INCLUDE_DIRECTORIES LUPDATE_OPTIONS LRELEASE_OPTIONS) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) ``` ## qtactiveqt `qt6_target_typelibs` - new API in 6.1, we missed reviewing this, was marked with TP `qt_target_typelibs` - missing versionless API ```cmake # Generates a C++ namespace for a type library and adds generated sources to the target. Arguments: # # LIBRARIES: List of type libraries. A type library (.tlb) is a binary file that stores information # about a COM or DCOM object's properties and methods in a form that is accessible to other # applications at runtime. The list may contain either the path to the library or the name # of the library. # If the library name is specified, the function will search for the library according to the # CMake find_file function rules. See https://cmake.org/cmake/help/latest/command/find_file.html # for details. # Note: The library name must include a file suffix, e.g "ieframe.dll". # LIBRARIES also may contain the library UUID in the following format: # <generated_files_basename>:<{00000000-0000-0000-0000-000000000000}> # The 'generated_files_basename' may contain ASCII letters, numbers and underscores and will be # used as the base name for the generated files. # # OUTPUT_DIRECTORY: Custom location of the generated source files. # ${CMAKE_CURRENT_BINARY_DIR} is the default location if not specified. (OPTIONAL) # # COMPAT: Adds compatibility flag to the dumpcpp call, that generates namespace with # dynamicCall-compatible API. (OPTIONAL) function(qt6_target_typelibs target) cmake_parse_arguments(arg "COMPAT" "OUTPUT_DIRECTORY" "LIBRARIES" ${ARGN}) ``` `qt6_add_axserver_executable` - new API `qt_add_axserver_executable` ```cmake Adds an ActiveX server executable, generates an IDL file and links the produced .tbl to the # executable. # Arguments: See qt6_target_idl # function(qt6_add_axserver_executable target) cmake_parse_arguments(arg "SKIP_AX_SERVER_REGISTRATION" "" "" ${ARGN}) ``` `qt6_add_axserver_library` - new API `qt6_add_axserver_library` ```cmake # Adds an ActiveX server library, generates an IDL file and links the produced .tbl to the # dll. # Arguments: See qt6_target_idl # function(qt6_add_axserver_library target) cmake_parse_arguments(arg "SKIP_AX_SERVER_REGISTRATION" "" "" ${ARGN}) ``` `qt6_target_idl` - new API `qt_target_idl` ```cmake function(qt6_add_axserver_executable target) # Adds post-build rules to generate and link IDC/MIDL artifacts to the library or executable. # Arguments: # SKIP_AX_SERVER_REGISTRATION skips the ActiveX server registration. # Note: You may also use the QT_SKIP_AX_SERVER_REGISTRATION variable to globally skip # the ActiveX server registrations. # function(qt6_target_idl target) cmake_parse_arguments(arg "SKIP_AX_SERVER_REGISTRATION" "" "" ${ARGN}) ``` ## qtdeclarative `qt6_add_qml_module` - existing TP API `qt_add_qml_module` ```cmake # Create a Qml Module. # # target: The name of the target to use for the qml module. If it does not # already exist, it will be created. This is referred to as the "backing # target" when a separate plugin is also generated (see PLUGIN_TARGET below). # (REQUIRED) # # URI: Declares the module identifier of the module. The module identifier is # the (dotted URI notation) identifier for the module, which must match the # module's install path. (REQUIRED) # # VERSION: The module's version. (REQUIRED) # # PAST_MAJOR_VERSIONS: List of past major versions this QML module was available # in. Ensures that the module can be imported when using these major versions. # (OPTIONAL) # # TARGET_PATH: Overwrite the generated target path. By default the target path # is generated from the URI by replacing the '.' with a '/'. However, under # certain circumstance this may not be enough. Use this argument to provide # a replacement. (OPTIONAL) # # RESOURCE_PREFIX: Resource Prefix to be used when adding resources to the # target. This may include the qmldir file, compiled/cached *.qml files, etc. # If not specified, a default prefix of "/" is used. (OPTIONAL) # # OUTPUT_DIRECTORY: Overrides the directory where the qmldir, *.qmltypes and # plugin library will be created. Defaults to ${CMAKE_CURRENT_BINARY_DIR} if # not specified. (OPTIONAL) # # STATIC, SHARED: Explicitly specify the type of library to create. At most one # of these two options can be specified. If neither is given, then the type of # library follows CMake's usual rules of creating a static library unless the # BUILD_SHARED_LIBS variable is set to true. (OPTIONAL) # # CLASS_NAME: Provides the class name of the C++ plugin used by the module. This # information is required for all the QML modules that depend on a C++ plugin # for additional functionality. Qt Quick applications built with static # linking cannot resolve the module imports without this information. # If no CLASS_NAME is given, it defaults to the URI with non-alphanumeric # characters converted to underscores, and "Plugin" appended. If an existing # target is passed in as the PLUGIN_TARGET and it has a QT_PLUGIN_CLASS_NAME # target property set, that will be used as the default CLASS_NAME instead. # (OPTIONAL) # # PLUGIN_TARGET: The recommended arrangement is to have separate backing and # plugin libraries. By default, the plugin library will be created as a second # CMake target with the same name as ${target}, but with "plugin" appended. # This name can be overridden with PLUGIN_TARGET. To use a single target # instead of separate backing and plugin targets, set PLUGIN_TARGET to the # same as ${target}. (OPTIONAL) # # NO_CREATE_PLUGIN_TARGET: When given, the plugin target will not be # automatically created. Use this if the qml module will always be used by # linking directly to the backing target and no plugin is needed at runtime. # An executable that is set up as its own qml module is one example where this # option is appropriate. Note also that an existing target can be specified in # PLUGIN_TARGET, in which case it will be modified by this function rather # than created by it. (OPTIONAL) # # NO_GENERATE_PLUGIN_SOURCE: A .cpp file will be created for the plugin class # by default and automatically added to the plugin target. Use this option to # indicate that no such .cpp file should be generated. The caller is then # responsible for providing their own plugin class if a separate plugin will # be created. Note that this option is independent of NO_CREATE_PLUGIN_TARGET. # (OPTIONAL) # # NO_PLUGIN_OPTIONAL: The plugin is marked as optional in the qmldir file by # default. If the plugin contains code other than just the shim plugin loader # class, specify this option to indicate that the plugin must always be loaded # as part of the qml module. (OPTIONAL) # # OUTPUT_TARGETS: In static builds, additional CMake targets can be created # which consumers of the module will need to link to and potentially install. # Supply the name of an output variable, which will be set to a list of these # targets. If installing the main target, you will also need to install these # output targets for static builds. (OPTIONAL) # # DESIGNER_SUPPORTED: Specify this argument if the plugin is supported by Qt # Quick Designer. By default, the plugin will not be supported. (OPTIONAL) # # TYPEINFO: Path to a file which declares a type description file for the module # that can be read by QML tools such as Qt Creator to access information about # the types defined by the module's plugins. You will typically need to also # specify NO_GENERATE_QMLTYPES if using this option. When TYPEINFO is not # specified, it will default to "${target}.qmltypes". (OPTIONAL) # # NO_GENERATE_QMLTYPES: Do not automatically generate the *.qmltypes file. # See also the TYPEINFO option. (OPTIONAL) # # NO_GENERATE_QMLDIR: Do not automatically generate the qmldir file. (OPTIONAL) # # IMPORTS: List of other Qml Modules that this module imports. A version can be # specified by appending it after a slash(/), e.g QtQuick/2.0. The minor # version may be omitted, e.g. QtQuick/2. Alternatively "auto" may be given # as version to forward the version the current module is being imported with, # e.g. QtQuick/auto. (OPTIONAL) # # OPTIONAL_IMPORTS: List of other Qml Modules that this module may import at # run-time. Those are not automatically imported by the QML engine when # importing the current module, but rather serve as hints to tools like # qmllint. Versions can be specified in the same way as for IMPORTS. # (OPTIONAL) # # DEPENDENCIES: List of QML Module dependencies and their versions. The module # and its version must be separated via a slash(/). E.g. QtQuick/2.0 # (OPTIONAL) # # IMPORT_PATH: State that QML modules this one depends on may be found in the # given import paths. (OPTIONAL) # # SOURCES: List of C++ sources. (OPTIONAL) # # QML_FILES: List of Qml files. See qt6_target_qml_sources() for more # information on how to specify additional properties on qml files. (OPTIONAL) # # RESOURCES: Resources used in QML, for example images. (OPTIONAL) # # NO_LINT: By default, this function will create a separate ${target}_qmllint # target if any .qml files are added to ${target} (see qt6_add_qml_sources()). # Provide the NO_LINT option to disable this behavior. (OPTIONAL) # # NO_CACHEGEN: By default, this function will compile each .qml file added to # the target and store that compiled version in the target's resources. # Provide the NO_CACHEGEN option to disable this behavior. # See qt6_add_qml_sources() for further details. (OPTIONAL) # function(qt6_add_qml_module target) ``` `qt6_add_qml_plugin` - new API `qt_add_qml_plugin` ```cmake # Create a Qml plugin. Projects should not normally need to call this function # directly. Rather, it would normally be called by qt6_add_qml_module() to # create or update the plugin associated with its backing target. # # target: The name of the target to use for the qml plugin. If it does not # already exist, it will be created. (REQUIRED) # # STATIC, SHARED: Explicitly specify the type of plugin library to create. # At most one of these two options can be specified. (OPTIONAL) # # BACKING_TARGET: The backing target that the plugin is associated with. This # can be the same as ${target}, in which case there is only the one merged # target. If this option is not provided, then URI must be given. (OPTIONAL) # # URI: Declares the module identifier of the qml module this plugin is # associated with. The module identifier is the (dotted URI notation) # identifier for the qml module. If URI is not given, then a BACKING_TARGET # must be provided (the backing target should have its URI recorded on it by # qt6_add_qml_module()). (OPTIONAL) # # TARGET_PATH: Overwrite the generated target path. By default the target path # is generated from the URI by replacing the '.' with a '/'. However, under # certain circumstances this may not be enough. Use this argument to provide # a replacement. It is only used if targeting Android. (OPTIONAL) # # CLASS_NAME: By default, the class name will be taken from the backing target, # if provided, or falling back to the URI with "Plugin" appended. Any # non-alphanumeric characters in the URI will be replaced with underscores. # (OPTIONAL) # # OUTPUT_DIRECTORY: Overrides the directory where the plugin library will be # created. Defaults to ${CMAKE_CURRENT_BINARY_DIR} if not specified. # (OPTIONAL) # # NO_GENERATE_SOURCE: A .cpp file will be created for the plugin class # by default and automatically added to the plugin target. Use this option to # indicate that no such .cpp file should be generated. The caller is then # responsible for providing their own plugin class. (OPTIONAL) # function(qt6_add_qml_plugin target) ``` `qt6_target_qml_sources` - new API `qt_target_qml_sources` ```cmake # Add Qml files (.qml,.js,.mjs) to a Qml module. # # target: The backing target of the qml module. (REQUIRED) # # FILES: The qml files to add to the backing target. Supported file extensions # are .qml, .js and .mjs. No other file types should be listed. (REQUIRED) # # PREFIX: The resource path under which to add the compiled qml files. If not # specified, the QT_RESOURCE_PREFIX property of the target is used (that # property is normally set by qt6_add_qml_module()). If the default is empty, # this option must be provided. (OPTIONAL) # # OUTPUT_TARGETS: In static builds, additional CMake targets can be created # which consumers of the module will need to link to and potentially install. # Supply the name of an output variable, which will be set to a list of these # targets. If installing the main target, you will also need to install these # output targets for static builds. (OPTIONAL) # # NO_LINT: Do not add the specified files to the ${target}_qmllint target. # If this option is not given, the default will be taken from the target. # # NO_CACHEGEN: Do not compile the qml files. Add the raw qml files to the # target resources instead. If this option is not given, the default will be # taken from the target. # # NO_QMLDIR_TYPES: Do not append type information from the qml files to the # qmldir file associated with the qml module. If this option is not given, # the default will be taken from the target. # # In addition to the above NO_... options, individual files can be explicitly # skipped by setting the relevant source property. These are: # # - QT_QML_SKIP_QMLLINT # - QT_QML_SKIP_QMLDIR_ENTRY # - QT_QML_SKIP_CACHEGEN # # Disabling the qmldir entry for a qml file would normally only be used for a # file that does not expose a public type (e.g. a private JS file). # If appending of type information has not been disabled for a particular qml # file, the following additional source properties can be specified to # customize the file's type details: # # QT_QML_SOURCE_VERSION: Version(s) for this qml file. If not present the module # version will be used. # # QT_QML_SOURCE_TYPENAME: Override the file's type name. If not present, the # type name will be deduced using the file's basename. # # QT_QML_SINGLETON_TYPE: Set to true if this qml file contains a singleton type. # # QT_QML_INTERNAL_TYPE: When set to true, the type specified by # QT_QML_SOURCE_TYPENAME will not be available to users of this module. # # e.g.: # set_source_files_properties(my_qml_file.qml # PROPERTIES # QT_QML_SOURCE_VERSION "2.0;6.0" # QT_QML_SOURCE_TYPENAME MyQmlFile # # qt6_target_qml_sources(my_qml_module # FILES # my_qml_file.qml # ) # # The above will produce the following entry in the qmldir file: # # MyQmlFile 2.0 my_qml_file.qml # function(qt6_target_qml_sources target) ``` `qt6_qml_type_registration` - existing TP API `qt_qml_type_registration` New option compared to 6.1 TP is `OUTPUT_DIRECTORY` ```cmake NOTE: This function does not normally need to be called directly by projects. # It is called automatically by qt6_add_qml_module() unless # NO_GENERATE_QMLTYPES is also given to that function. # # target: Expected to be the backing target for a qml module. Certain target # properties normally set by qt6_add_qml_module() will be retrieved from this # target. (REQUIRED) # # OUTPUT_DIRECTORY: Specifies the directory in which to write the generated # ${target}.qmltypes file. If not given, it defaults to the binary directory # of the target. (OPTIONAL) # # MANUAL_MOC_JSON_FILES: Specifies a list of json files, generated by a manual # moc call, to extract metatypes. (OPTIONAL) # function(qt6_qml_type_registration target) ``` `qt6_import_qml_plugins` - existing API `qt_import_qml_plugins` New properties queried from target are `QT_QML_IMPORT_PATH`, `QT_QML_MODULE_FILES`, `SOURCE_DIR` ```cmake # This function is called as a finalizer in qt6_finalize_executable() for any # target that links against the Qml library for a statically built Qt. function(qt6_import_qml_plugins target) set(options) set(oneValueArgs "PATH_TO_SCAN") set(multiValueArgs) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) ```