4d289edb14
The requirement to separate debug and release DLLs on Windows stems from the Visual Studio C run-time library appearing in two different variants (debug and release) and not mixing well. It's possible to perform builds without optimzations and with debug symbols while linking against the release version of the C run-time, but at the same time the debug version of the run-time brings other developer visible advantages. MinGW on the other hand does not have this distinction, does not ship with separate DLLS and does also not require the VS C runtime library. Therefore we do not need this separation for MinGW, which means that our packages can be reduced in size and application developers wishing to debug their applications do not have to use debug builds of the Qt libraries or run into Qt internal debug code. Task-number: QTBUG-78445 Change-Id: Idf588606091298dc44262c4c89e689df18d34747 Reviewed-by: Cristian Adam <cristian.adam@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
354 lines
12 KiB
Plaintext
354 lines
12 KiB
Plaintext
|
|
defineReplace(qtPlatformTargetSuffix) {
|
|
suffix =
|
|
android: return($${suffix}_$${QT_ARCH})
|
|
else: CONFIG(debug, debug|release) {
|
|
!debug_and_release|build_pass {
|
|
mac: return($${suffix}_debug)
|
|
win32:!gcc: return($${suffix}d)
|
|
}
|
|
}
|
|
return($$suffix)
|
|
}
|
|
|
|
defineReplace(qtLibraryTarget) {
|
|
LIBRARY_NAME = $$1
|
|
CONFIG(shared, static|shared):qtConfig(framework) {
|
|
QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME
|
|
export(QMAKE_FRAMEWORK_BUNDLE_NAME)
|
|
}
|
|
return($$LIBRARY_NAME$$qtPlatformTargetSuffix())
|
|
}
|
|
|
|
defineReplace(qt5LibraryTarget) {
|
|
LIBRARY_NAME = $$qtLibraryTarget($$1)
|
|
isEmpty(QMAKE_FRAMEWORK_BUNDLE_NAME) {
|
|
# Insert the major version of Qt in the library name
|
|
# unless it's a framework build.
|
|
LIBRARY_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
|
|
}
|
|
return($$LIBRARY_NAME)
|
|
}
|
|
|
|
defineReplace(qtRelativeRPathBase) {
|
|
darwin {
|
|
if(equals(TEMPLATE, app):app_bundle)|\
|
|
if(equals(TEMPLATE, lib):plugin:plugin_bundle) {
|
|
shallow_bundle: return($$target.path/$${TARGET}.app)
|
|
return($$target.path/$${TARGET}.app/Contents/MacOS)
|
|
}
|
|
equals(TEMPLATE, lib):!plugin:lib_bundle {
|
|
shallow_bundle: return($$target.path/$${TARGET}.framework)
|
|
return($$target.path/$${TARGET}.framework/Versions/Current)
|
|
}
|
|
}
|
|
return($$target.path)
|
|
}
|
|
|
|
defineTest(qtAddLibrary) {
|
|
warning("qtAddLibrary() is deprecated. Use QT+= instead.")
|
|
|
|
# Reverse-engineer the module name from the library name.
|
|
for(var, QT_MODULES) {
|
|
isEqual(QT.$${var}.name, $$1) {
|
|
QT += $$var
|
|
export(QT)
|
|
return(true)
|
|
}
|
|
}
|
|
error("No module matching library '$$1' found.")
|
|
}
|
|
|
|
# qt module
|
|
defineTest(qtHaveModule) {
|
|
!isEmpty(QT.$$replace(1, -, _).name): \
|
|
return(true)
|
|
return(false)
|
|
}
|
|
|
|
# variable, default, [suffix for variable for system() use], [prepare primary variable for system() use]
|
|
defineTest(qtPrepareTool) {
|
|
cmd = $$eval(QT_TOOL.$${2}.binary)
|
|
isEmpty(cmd) {
|
|
cmd = $$[QT_HOST_BINS]/$$2
|
|
exists($${cmd}.pl) {
|
|
$${1}_EXE = $${cmd}.pl
|
|
cmd = perl -w $$system_path($${cmd}.pl)
|
|
} else: contains(QMAKE_HOST.os, Windows) {
|
|
$${1}_EXE = $${cmd}.exe
|
|
cmd = $$system_path($${cmd}.exe)
|
|
} else:contains(QMAKE_HOST.os, Darwin) {
|
|
BUNDLENAME = $${cmd}.app/Contents/MacOS/$$2
|
|
exists($$BUNDLENAME) {
|
|
cmd = $$BUNDLENAME
|
|
}
|
|
$${1}_EXE = $$cmd
|
|
} else {
|
|
$${1}_EXE = $$cmd
|
|
}
|
|
} else {
|
|
$${1}_EXE = $$last(cmd)
|
|
}
|
|
export($${1}_EXE)
|
|
QT_TOOL_ENV += $$eval(QT_TOOL.$${2}.envvars)
|
|
QT_TOOL_NAME = $$2
|
|
!isEmpty(3)|!isEmpty(4) {
|
|
$$1$$3 =
|
|
for (arg, cmd): \
|
|
$$1$$3 += $$system_quote($$arg)
|
|
qtAddTargetEnv($$1$$3, QT_TOOL.$${2}.depends, system)
|
|
}
|
|
isEmpty(4) {
|
|
$$1 =
|
|
for (arg, cmd): \
|
|
$$1 += $$shell_quote($$arg)
|
|
qtAddTargetEnv($$1, QT_TOOL.$${2}.depends, )
|
|
}
|
|
}
|
|
|
|
# target variable, list of env var names, [non-empty: prepare for system(), not make]
|
|
defineTest(qtAddToolEnv) {
|
|
isEmpty(3): \
|
|
ds = $$QMAKE_DIR_SEP
|
|
else: \
|
|
ds = $$DIR_SEPARATOR
|
|
batch_sets =
|
|
for(env, 2) {
|
|
value = $$eval($${env}.value)
|
|
!isEmpty(value) {
|
|
name = $$eval($${env}.name)
|
|
config = $$eval($${env}.CONFIG)
|
|
equals(ds, /) {
|
|
contains(config, prepend): infix = \${$$name:+:\$$$name}
|
|
else: contains(config, always_prepend): infix = :\$$$name
|
|
else: infix =
|
|
# Under msys, this path is taken only in the non-system()
|
|
# case, so using shell_quote() always works.
|
|
batch_sets += \
|
|
"$$name=$$shell_quote($$join(value, :))$$infix" \
|
|
"export $$name"
|
|
} else {
|
|
value ~= s,\\^,^^^^,g
|
|
value ~= s,!,^^!,g
|
|
value ~= s,\\),^),g
|
|
contains(config, prepend) {
|
|
batch_sets += \
|
|
"if defined $$name (" \
|
|
" set $$name=$$join(value, ;);!$$name!" \
|
|
") else (" \
|
|
" set $$name=$$join(value, ;)" \
|
|
")"
|
|
} else: contains(config, always_prepend) {
|
|
batch_sets += "(set $$name=$$join(value, ;);!$$name!)"
|
|
} else {
|
|
batch_sets += "(set $$name=$$join(value, ;))"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
!isEmpty(batch_sets) {
|
|
batch_name = wrapper
|
|
!isEmpty(QT_TOOL_NAME): batch_name = $${QT_TOOL_NAME}_wrapper
|
|
cmd = $$eval($$1)
|
|
!isEmpty(cmd): cmd = "$$cmd "
|
|
equals(ds, /) {
|
|
batch_name = $${batch_name}.sh
|
|
batch_cont = \
|
|
"$$LITERAL_HASH!/bin/sh" \
|
|
$$batch_sets \
|
|
"exec $$cmd\"$@\""
|
|
# It would be nicer to use the '.' command (without 'exec' above),
|
|
# but that doesn't set the positional arguments under (d)ash.
|
|
$$1 =
|
|
} else {
|
|
batch_name = $${batch_name}.bat
|
|
batch_cont = \
|
|
"@echo off" \
|
|
"SetLocal EnableDelayedExpansion" \
|
|
$$batch_sets \
|
|
"$$cmd%*" \
|
|
"EndLocal"
|
|
$$1 = call
|
|
}
|
|
!build_pass:!write_file($$OUT_PWD/$$batch_name, batch_cont, exe): error()
|
|
isEmpty(3): \
|
|
$$1 += $$shell_quote($$shell_path($$OUT_PWD/$$batch_name))
|
|
else: \
|
|
$$1 += $$system_quote($$system_path($$OUT_PWD/$$batch_name))
|
|
QMAKE_DISTCLEAN += $$OUT_PWD/$$batch_name
|
|
}
|
|
export($$1)
|
|
export(QMAKE_DISTCLEAN)
|
|
}
|
|
|
|
# target variable, dependency var name, [non-empty: prepare for system(), not make]
|
|
defineTest(qtAddTargetEnv) {
|
|
deps = $$replace($$2, -private$, _private)
|
|
deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends")
|
|
!isEmpty(deps) {
|
|
libs = libs
|
|
deppath.CONFIG = prepend
|
|
equals(QMAKE_HOST.os, Windows) {
|
|
libs = bins
|
|
deppath.CONFIG = always_prepend
|
|
deppath.name = PATH
|
|
} else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) {
|
|
deppath.name = LD_LIBRARY_PATH
|
|
} else:contains(QMAKE_HOST.os, Haiku) {
|
|
deppath.name = LIBRARY_PATH
|
|
} else:equals(QMAKE_HOST.os, Darwin) {
|
|
qtConfig(framework): \
|
|
deppath.name = DYLD_FRAMEWORK_PATH
|
|
else: \
|
|
deppath.name = DYLD_LIBRARY_PATH
|
|
} else:equals(QMAKE_HOST.os, AIX) {
|
|
deppath.name = LIBPATH
|
|
} else {
|
|
error("Operating system not supported.")
|
|
}
|
|
ptypes =
|
|
for(dep, deps) {
|
|
isEmpty(3): \
|
|
deppath += $$shell_path($$eval(QT.$${dep}.$$libs))
|
|
else: \
|
|
deppath += $$system_path($$eval(QT.$${dep}.$$libs))
|
|
ptypes += $$eval(QT.$${dep}.plugin_types)
|
|
}
|
|
deppath.value = $$unique(deppath)
|
|
|
|
pluginpath.value =
|
|
ppaths = $$[QT_INSTALL_PLUGINS/get]
|
|
for(qplug, QT_PLUGINS): \
|
|
contains(ptypes, $$eval(QT_PLUGIN.$${qplug}.TYPE)): \
|
|
ppaths += $$eval(QT_PLUGIN.$${qplug}.PATH)
|
|
ppaths = $$unique(ppaths)
|
|
for(qplug, ppaths) {
|
|
isEmpty(3): \
|
|
pluginpath.value += $$shell_path($$qplug)
|
|
else: \
|
|
pluginpath.value += $$system_path($$qplug)
|
|
}
|
|
pluginpath.name = QT_PLUGIN_PATH
|
|
pluginpath.CONFIG = prepend
|
|
|
|
QT_TOOL_ENV += deppath pluginpath
|
|
}
|
|
qtAddToolEnv($$1, $$QT_TOOL_ENV, $$3)
|
|
}
|
|
|
|
defineReplace(pkgConfigExecutable) {
|
|
isEmpty(PKG_CONFIG) {
|
|
!isEmpty(QMAKE_PKG_CONFIG) {
|
|
# Assumed to be properly sysrootified.
|
|
PKG_CONFIG = $$QMAKE_PKG_CONFIG
|
|
export(PKG_CONFIG)
|
|
} else {
|
|
PKG_CONFIG = pkg-config
|
|
!cross_compile {
|
|
export(PKG_CONFIG)
|
|
} else {
|
|
# Cross compiling, ensure that pkg-config is set up sanely.
|
|
sysroot = $$[QT_SYSROOT]
|
|
|
|
pkgConfigLibdir = $$(PKG_CONFIG_LIBDIR)
|
|
isEmpty(pkgConfigLibdir) {
|
|
isEmpty(sysroot) {
|
|
warning("Cross compiling without sysroot. Disabling pkg-config.")
|
|
return()
|
|
}
|
|
!exists("$$sysroot/usr/lib/pkgconfig") {
|
|
warning("Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and the")
|
|
warning("host's .pc files would be used (even if you set PKG_CONFIG_PATH).")
|
|
warning("Set this variable to the directory that contains target .pc files")
|
|
warning("for pkg-config to function correctly when cross-compiling.")
|
|
return()
|
|
}
|
|
|
|
pkgConfigLibdir = $$system_path($$sysroot/usr/lib/pkgconfig)$$QMAKE_DIRLIST_SEP$$system_path($$sysroot/usr/share/pkgconfig)
|
|
!isEmpty(GCC_MACHINE_DUMP): \
|
|
pkgConfigLibdir = "$$pkgConfigLibdir$$QMAKE_DIRLIST_SEP$$system_path($$sysroot/usr/lib/$$GCC_MACHINE_DUMP/pkgconfig)"
|
|
message("PKG_CONFIG_LIBDIR automatically set to $$pkgConfigLibdir")
|
|
}
|
|
pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR)
|
|
isEmpty(pkgConfigSysrootDir) {
|
|
isEmpty(sysroot) {
|
|
warning("Disabling pkg-config since PKG_CONFIG_SYSROOT_DIR is not set.")
|
|
warning("Set this variable to your sysroot for pkg-config to function")
|
|
warning("correctly when cross-compiling.")
|
|
return()
|
|
}
|
|
|
|
pkgConfigSysrootDir = $$sysroot
|
|
message("PKG_CONFIG_SYSROOT_DIR automatically set to $$pkgConfigSysrootDir")
|
|
}
|
|
|
|
sysroot.name = PKG_CONFIG_SYSROOT_DIR
|
|
sysroot.value = $$pkgConfigSysrootDir
|
|
libdir.name = PKG_CONFIG_LIBDIR
|
|
libdir.value = $$pkgConfigLibdir
|
|
QT_TOOL_NAME = pkg-config
|
|
qtAddToolEnv(PKG_CONFIG, sysroot libdir, SYS)
|
|
}
|
|
}
|
|
}
|
|
|
|
PKG_CONFIG += 2> $$QMAKE_SYSTEM_NULL_DEVICE
|
|
|
|
return($$PKG_CONFIG)
|
|
}
|
|
|
|
defineTest(packagesExist) {
|
|
# this can't be done in global scope here because qt_functions is loaded
|
|
# before the .pro is parsed, so if the .pro set PKG_CONFIG, we wouldn't know it
|
|
# yet. oops.
|
|
pkg_config = $$pkgConfigExecutable()
|
|
|
|
for(package, ARGS) {
|
|
!system($$pkg_config --exists $$package):return(false)
|
|
}
|
|
|
|
return(true)
|
|
}
|
|
|
|
# Prepares target that will iterate through all subdirs (except those
|
|
# with no_default_target or no_{name_of_target}_target. The prepared
|
|
# target must still be manually added to QMAKE_EXTRA_TARGETS.
|
|
defineTest(prepareRecursiveTarget) {
|
|
target = $$1
|
|
no_$${target}_target: return()
|
|
|
|
for(subdir, SUBDIRS) {
|
|
subdir_config = $$eval($${subdir}.CONFIG)
|
|
contains(subdir_config, no_default_target): next()
|
|
contains(subdir_config, no_$${target}_target): next()
|
|
|
|
$${target}.recurse += $$subdir
|
|
}
|
|
|
|
# Set up the recurse target only when there
|
|
# is something to recurse into.
|
|
isEmpty($${target}.recurse): return()
|
|
|
|
$${target}.CONFIG = recursive
|
|
$${target}.recurse_target = $${target}
|
|
|
|
export($${target}.recurse)
|
|
export($${target}.CONFIG)
|
|
export($${target}.recurse_target)
|
|
}
|
|
|
|
defineTest(qtConfig) {
|
|
modules = $$QT $$QT_PRIVATE $$QT_FOR_CONFIG
|
|
modules ~= s,-private$,_private,g
|
|
modules = $$resolve_depends(modules, "QT.", ".depends")
|
|
modules += global global_private
|
|
modules = $$reverse(modules)
|
|
for (module, modules) {
|
|
contains(QT.$${module}.enabled_features, $$1): \
|
|
return(true)
|
|
contains(QT.$${module}.disabled_features, $$1): \
|
|
return(false)
|
|
}
|
|
error("Could not find feature $${1}.")
|
|
}
|