| # This avoids spurious errors when a project is explicitly disabled |
| # due to required Qt modules being missing. |
| !isEmpty(QMAKE_FAILED_REQUIREMENTS): return() |
| |
| qtConfig(thread): CONFIG *= thread |
| |
| #handle defines |
| win32 { |
| qtConfig(shared) { |
| # this variable is read by qmake in qmake/generators/win32/msvc_vcproj.cpp |
| # function VcprojGenerator::initDeploymentTool() |
| QMAKE_DLL_PATHS += $$[QT_INSTALL_BINS/get] |
| } |
| } |
| CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG |
| qtConfig(force_asserts): DEFINES += QT_FORCE_ASSERTS |
| no_keywords:DEFINES += QT_NO_KEYWORDS |
| plugin { #Qt plugins |
| static:DEFINES += QT_STATICPLUGIN |
| DEFINES += QT_PLUGIN |
| } |
| |
| qtestlib { |
| warning("CONFIG+=qtestlib is deprecated. Use QT+=testlib instead.") |
| QT += testlib |
| } |
| qdbus { |
| warning("CONFIG+=qdbus is deprecated. Use QT+=dbus instead.") |
| QT += dbus |
| } |
| help { |
| warning("CONFIG+=help is deprecated. Use QT+=help instead.") |
| QT += help-private # sic! |
| } |
| designer { |
| warning("CONFIG+=designer is deprecated. Use QT+=designer instead.") |
| QT += designer |
| } |
| uitools { |
| warning("CONFIG+=uitools is deprecated. Use QT+=uitools instead.") |
| QT += uitools |
| } |
| qaxcontainer { |
| warning("CONFIG+=qaxcontainer is deprecated. Use QT+=axcontainer instead.") |
| QT += axcontainer |
| } |
| qaxserver { |
| warning("CONFIG+=qaxserver is deprecated. Use QT+=axserver instead.") |
| QT += axserver |
| } |
| |
| !import_qpa_plugin { |
| warning("CONFIG-=import_qpa_plugin is deprecated. Use QTPLUGIN.platforms=- instead.") |
| QTPLUGIN.platforms = - |
| } else: qpa_minimal_plugin { |
| warning("CONFIG+=qpa_minimal_plugin is deprecated. Use QTPLUGIN.platforms=qminimal instead.") |
| QTPLUGIN.platforms = qminimal |
| } |
| |
| !force_import_plugins:!contains(TEMPLATE, ".*app"):!if(contains(TEMPLATE, ".*lib"):dll): \ |
| CONFIG -= import_plugins |
| |
| # qmake variables cannot contain dashes, so normalize the names first |
| CLEAN_QT = $$replace(QT, -private$, _private) |
| CLEAN_QT_PRIVATE = $$replace(QT_PRIVATE, -private$, _private) |
| |
| qt_module_deps = $$CLEAN_QT $$CLEAN_QT_PRIVATE |
| all_qt_module_deps = $$resolve_depends(qt_module_deps, "QT.", ".depends" ".run_depends") |
| |
| QTPLUGIN = $$unique($$list($$lower($$QTPLUGIN))) |
| |
| import_plugins:qtConfig(static) { |
| manualplugs = $$QTPLUGIN # User may specify plugins. Mostly legacy. |
| autoplugs = # Auto-added plugins. |
| # First round: explicitly specified modules. |
| plugin_deps = $$all_qt_module_deps |
| for(ever) { |
| # Automatically link the default plugins for the linked Qt modules. |
| for (qtmod, plugin_deps) { |
| for (ptype, QT.$${qtmod}.plugin_types) { |
| nptype = $$replace(ptype, [-/], _) |
| isEmpty(QTPLUGIN.$$nptype) { |
| for (plug, QT_PLUGINS) { |
| equals(QT_PLUGIN.$${plug}.TYPE, $$ptype) { |
| for (dep, QT_PLUGIN.$${plug}.EXTENDS) { |
| !contains(all_qt_module_deps, $$dep) { |
| plug = |
| break() |
| } |
| } |
| autoplugs += $$plug |
| } |
| } |
| } else { |
| plug = $$eval(QTPLUGIN.$$nptype) |
| !equals(plug, -): \ |
| autoplugs += $$plug |
| } |
| } |
| } |
| QTPLUGIN = $$manualplugs $$autoplugs |
| QTPLUGIN = $$unique(QTPLUGIN) |
| |
| # Obtain the plugins' Qt dependencies ... |
| plugin_deps = |
| for (plug, QTPLUGIN): \ |
| plugin_deps += $$eval(QT_PLUGIN.$${plug}.DEPENDS) |
| plugin_deps = $$resolve_depends(plugin_deps, "QT.", ".depends" ".run_depends") |
| plugin_deps -= $$all_qt_module_deps |
| isEmpty(plugin_deps): \ |
| break() |
| # ... and start over if any new Qt modules appeared, |
| # as these may want to load plugins in turn. |
| all_qt_module_deps += $$plugin_deps |
| } |
| extraplugs = $$manualplugs |
| manualplugs -= $$autoplugs |
| extraplugs -= $$manualplugs |
| !isEmpty(extraplugs): \ |
| warning("Redundant entries in QTPLUGIN: $$extraplugs") |
| |
| !isEmpty(QTPLUGIN) { |
| IMPORT_FILE_CONT = \ |
| "// This file is autogenerated by qmake. It imports static plugin classes for" \ |
| "// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS.<plugin> variables." \ |
| "$${LITERAL_HASH}include <QtPlugin>" |
| for (plug, QTPLUGIN) { |
| plug_class = $$eval(QT_PLUGIN.$${plug}.CLASS_NAME) |
| !isEmpty(plug_class): \ |
| IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$plug_class)" |
| else: \ |
| warning("Plugin class name could not be determined for plugin '$$plug'.") |
| } |
| TARGET_BASENAME = $$lower($$basename(TARGET)) |
| TARGET_BASENAME ~= s/\s/_/g |
| |
| IMPORT_CPP = $$OUT_PWD/$${TARGET_BASENAME}_plugin_import.cpp |
| write_file($$IMPORT_CPP, IMPORT_FILE_CONT)|error() |
| GENERATED_SOURCES += $$IMPORT_CPP |
| QMAKE_DISTCLEAN += $$IMPORT_CPP |
| } |
| } |
| |
| # Only link against plugins in static builds |
| !isEmpty(QTPLUGIN):qtConfig(static) { |
| for (plug, QTPLUGIN) { |
| # Check if the plugin is known to Qt. We can use this to determine |
| # the plugin path. Unknown plugins must rely on the default link path. |
| plug_type = $$eval(QT_PLUGIN.$${plug}.TYPE) |
| !isEmpty(plug_type) { |
| plug_name = $$QMAKE_PREFIX_STATICLIB$${plug}$$qtPlatformTargetSuffix().$$QMAKE_EXTENSION_STATICLIB |
| plug_path = $$eval(QT_PLUGIN.$${plug}.PATH) |
| isEmpty(plug_path): \ |
| plug_path = $$[QT_INSTALL_PLUGINS/get] |
| LIBS += $$plug_path/$$plug_type/$$plug_name |
| } else { |
| LIBS += -l$${plug}$$qtPlatformTargetSuffix() |
| } |
| } |
| } |
| |
| # target variable, flag source variable |
| defineTest(qtProcessModuleFlags) { |
| for(flag, $$2) { |
| contains(flag, ^-.*): \ |
| $$1 -= $$replace(flag, ^-, ) |
| else: \ |
| $$1 += $$flag |
| } |
| export($$1) |
| } |
| |
| unset(using_privates) |
| var_sfx = |
| for(ever) { |
| # Topological resolution of modules based on their QT.<module>.depends variable |
| FULL_QT$$var_sfx = $$resolve_depends(CLEAN_QT$$var_sfx, "QT.") |
| # Finally actually add the modules |
| unset(BAD_QT) |
| for(QTLIB, FULL_QT$$var_sfx) { |
| MODULE_NAME = $$eval(QT.$${QTLIB}.name) |
| MODULE_MODULE = $$eval(QT.$${QTLIB}.module) |
| MODULE_INCLUDES = $$eval(QT.$${QTLIB}.includes) |
| MODULE_LIBS = $$eval(QT.$${QTLIB}.libs) |
| MODULE_FRAMEWORKS = $$eval(QT.$${QTLIB}.frameworks) |
| MODULE_USES = $$eval(QT.$${QTLIB}.uses) |
| MODULE_CONFIG = $$eval(QT.$${QTLIB}.module_config) |
| |
| isEmpty(MODULE_NAME) { |
| BAD_QT += $$QTLIB |
| next() |
| } |
| |
| contains(MODULE_CONFIG, internal_module): \ |
| using_privates = true |
| contains(MODULE_CONFIG, ltcg): \ |
| CONFIG += link_ltcg |
| |
| qtProcessModuleFlags(CONFIG, QT.$${QTLIB}.CONFIG) |
| qtProcessModuleFlags(DEFINES, QT.$${QTLIB}.DEFINES) |
| |
| MODULE_INCLUDES -= $$QMAKE_DEFAULT_INCDIRS |
| |
| # Frameworks shouldn't need include paths, but much code does not use |
| # module-qualified #includes, so by default we add paths which point |
| # directly into the frameworks. Private modules have somewhat convoluted |
| # header paths, so adding them is necessary in every case. |
| !if(contains(MODULE_CONFIG, lib_bundle):qt_no_framework_direct_includes) \ |
| |contains(MODULE_CONFIG, internal_module): \ |
| INCLUDEPATH *= $$MODULE_INCLUDES |
| QMAKE_FRAMEWORKPATH *= $$MODULE_FRAMEWORKS |
| !isEmpty(MODULE_MODULE) { |
| contains(MODULE_CONFIG, lib_bundle) { |
| framework = $$MODULE_MODULE |
| # Linking frameworks by absolute path does not work. |
| LIBS$$var_sfx += -framework $$framework |
| } else { |
| lib = $$MODULE_MODULE$$qtPlatformTargetSuffix() |
| win32|contains(MODULE_CONFIG, staticlib) { |
| lib = $$MODULE_LIBS/$$QMAKE_PREFIX_STATICLIB$${lib}.$$QMAKE_EXTENSION_STATICLIB |
| PRE_TARGETDEPS += $$lib |
| } else { |
| lib = $$MODULE_LIBS/$$QMAKE_PREFIX_SHLIB$${lib}.$$QMAKE_EXTENSION_SHLIB |
| } |
| LIBS$$var_sfx += $$lib |
| } |
| } |
| QMAKE_USE$$var_sfx += $$MODULE_USES |
| # Add capabilities as defined by modules used in the project |
| winrt { |
| MODULE_WINRT_CAPABILITIES = $$eval(QT.$${QTLIB}.winrt_capabilities) |
| !isEmpty(MODULE_WINRT_CAPABILITIES): \ |
| WINRT_MANIFEST.capabilities_default += $$MODULE_WINRT_CAPABILITIES |
| MODULE_WINRT_CAPABILITIES_DEVICE = $$eval(QT.$${QTLIB}.winrt_capabilities_device) |
| !isEmpty(MODULE_WINRT_CAPABILITIES_DEVICE): \ |
| WINRT_MANIFEST.capabilities_device_default += $$MODULE_WINRT_CAPABILITIES_DEVICE |
| } |
| } |
| !isEmpty(BAD_QT):error("Unknown module(s) in QT$$var_sfx: $$replace(BAD_QT, _private$, -private)") |
| |
| !isEmpty(var_sfx): break() |
| var_sfx = _PRIVATE |
| } |
| !isEmpty(using_privates):!no_private_qt_headers_warning:!build_pass { |
| message("This project is using private headers and will therefore be tied to this specific Qt module build version.") |
| message("Running this project against other versions of the Qt modules may crash at any arbitrary point.") |
| message("This is not a bug, but a result of using Qt internals. You have been warned!") |
| } |
| |
| !no_qt_rpath:!static:qtConfig(rpath):!qtConfig(static):\ |
| contains(all_qt_module_deps, core) { |
| relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\ |
| isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) { |
| # NOT the /dev property, as INSTALLS use host paths |
| QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase()) |
| } else { |
| QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev] |
| } |
| } |
| |
| !isEmpty(QMAKE_LFLAGS_RPATHLINK):!qtConfig(static) { |
| # -rpath-link is used by the linker to find dependencies of dynamic |
| # libraries which were NOT specified on the command line. |
| # This means that paths of direct dependencies (QT & QT_PRIVATE) |
| # don't need to be listed, unlike their private dependencies' paths. |
| privdep = $$all_qt_module_deps |
| privdep -= $$resolve_depends(qt_module_deps, "QT.") |
| rpaths = |
| for(dep, privdep): \ |
| rpaths += $$eval(QT.$${dep}.libs) |
| QMAKE_RPATHLINKDIR *= $$unique(rpaths) |
| } |
| |
| # static builds: link qml import plugins into the target. |
| contains(all_qt_module_deps, qml): \ |
| qtConfig(static):import_plugins:!host_build:!no_import_scan { |
| exists($$[QT_INSTALL_QML/get]): \ |
| QMLPATHS *= $$[QT_INSTALL_QML/get] |
| |
| # run qmlimportscanner |
| qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner, , system) |
| for (QMLPATH, QMLPATHS): \ |
| IMPORTPATHS += -importPath $$system_quote($$QMLPATH) |
| |
| # add resources to qmlimportscanner |
| for (RESOURCE, RESOURCES) { |
| defined($${RESOURCE}.files, var) { |
| # in case of a "struct", add the struct's files |
| base = $$RESOURCE.base |
| for (f, $$RESOURCE.files): SCANNERRESOURCES += "$$base/$$f" |
| } else { |
| # if the resource is a file, just add it |
| SCANNERRESOURCES += $$RESOURCE |
| } |
| } |
| |
| !isEmpty(SCANNERRESOURCES) { |
| IMPORTPATHS += -qrcFiles |
| for (RESOURCE, SCANNERRESOURCES): \ |
| IMPORTPATHS += $$absolute_path($$system_quote($$RESOURCE), $$_PRO_FILE_PWD_) |
| } |
| |
| |
| # message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) |
| JSON = $$system($$QMLIMPORTSCANNER $$system_quote($$_PRO_FILE_PWD_) $$IMPORTPATHS) |
| |
| parseJson(JSON, IMPORTS)| error("Failed to parse qmlimportscanner output.") |
| |
| !isEmpty(IMPORTS._KEYS_) { |
| # add import plugins to LIBS line |
| for (key, IMPORTS._KEYS_) { |
| PATH = $$eval(IMPORTS.$${key}.path) |
| PLUGIN = $$eval(IMPORTS.$${key}.plugin) |
| !isEmpty(PATH):!isEmpty(PLUGIN): \ |
| LIBS += $$PATH/$$QMAKE_PREFIX_STATICLIB$${PLUGIN}$$qtPlatformTargetSuffix().$$QMAKE_EXTENSION_STATICLIB |
| } |
| |
| # create qml_plugin_import.cpp |
| IMPORT_FILE_CONT = \ |
| "// This file is autogenerated by qmake. It imports static plugin classes for" \ |
| "// static plugins used by QML imports." \ |
| "$${LITERAL_HASH}include <QtPlugin>" |
| for (key, IMPORTS._KEYS_) { |
| PLUGIN = $$eval(IMPORTS.$${key}.plugin) |
| CLASSNAME = $$eval(IMPORTS.$${key}.classname) |
| !isEmpty(PLUGIN) { |
| !isEmpty(CLASSNAME) { |
| !contains(ADDED_IMPORTS, $$PLUGIN) { |
| ADDED_IMPORTS += $$PLUGIN |
| IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$CLASSNAME)" |
| } |
| } else { |
| error("Plugin $$PLUGIN is missing a classname entry, please add one to the qmldir file.") |
| } |
| } |
| } |
| TARGET_BASENAME = $$lower($$basename(TARGET)) |
| TARGET_BASENAME ~= s/\s/_/g |
| |
| QML_IMPORT_CPP = $$OUT_PWD/$${TARGET_BASENAME}_qml_plugin_import.cpp |
| write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error() |
| GENERATED_SOURCES += $$QML_IMPORT_CPP |
| QMAKE_DISTCLEAN += $$QML_IMPORT_CPP |
| } |
| } |