1f30bcf336
[ChangeLog][Build System] Tools that are called by the build system and are unlikely to be called by the user are now installed to the libexec directory. This is a step towards easier co-installability of different Qt versions. Pick-to: 6.1 Task-number: QTBUG-88791 Change-Id: Id19575b5ba27795f7715e4ea6a09391b26dd4942 Reviewed-by: Kai Koehne <kai.koehne@qt.io>
392 lines
13 KiB
Plaintext
392 lines
13 KiB
Plaintext
|
|
defineReplace(qtPlatformTargetSuffix) {
|
|
suffix =
|
|
android: return($${suffix}_$${QT_ARCH})
|
|
win32 {
|
|
CONFIG(debug, debug|release) {
|
|
mingw {
|
|
qtConfig(debug_and_release):build_pass: \
|
|
return($${suffix}d)
|
|
} else {
|
|
!debug_and_release|build_pass: \
|
|
return($${suffix}d)
|
|
}
|
|
}
|
|
}
|
|
darwin {
|
|
CONFIG(debug, debug|release) {
|
|
!debug_and_release|build_pass: \
|
|
return($${suffix}_debug)
|
|
}
|
|
}
|
|
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) {
|
|
android {
|
|
LIBRARY_NAME_PREFIX = $$2
|
|
LIBRARY_NAME_PREFIX = $$replace(LIBRARY_NAME_PREFIX, "//", "/")
|
|
LIBRARY_NAME_PREFIX = $$replace(LIBRARY_NAME_PREFIX, "/", "_")
|
|
LIBRARY_NAME = $$LIBRARY_NAME_PREFIX$$qtLibraryTarget($$1)
|
|
unset(LIBRARY_NAME_PREFIX)
|
|
} else: 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)
|
|
}
|
|
|
|
# Arguments:
|
|
# variable, default, [suffix for variable for system() use],
|
|
# [prepare primary variable for system() use],
|
|
# [installation location; default: $$[QT_HOST_BINS]]
|
|
defineTest(qtPrepareTool) {
|
|
cmd = $$eval(QT_TOOL.$${2}.binary)
|
|
isEmpty(cmd) {
|
|
isEmpty(5) {
|
|
instloc = $$[QT_HOST_BINS]
|
|
} else {
|
|
instloc = $$5
|
|
}
|
|
cmd = $$instloc/$$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, )
|
|
}
|
|
}
|
|
|
|
# Prepare a tool that's not supposed to be called manually by users but by the build system.
|
|
#
|
|
# Forwards its arguments to qtPrepareTool but defaults the installation location to
|
|
# $$[QT_HOST_LIBEXECS]
|
|
defineTest(qtPrepareLibExecTool) {
|
|
isEmpty(instloc): instloc = "$$[QT_HOST_LIBEXECS]"
|
|
qtPrepareTool($$1, $$2, $$3, $$4, $$instloc)
|
|
}
|
|
|
|
# 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
|
|
equals(QMAKE_HOST.os, Darwin):exists(/bin/bash): \
|
|
shell = /bin/bash
|
|
else: \
|
|
shell = /bin/sh
|
|
batch_cont = \
|
|
"$$LITERAL_HASH!$$shell" \
|
|
$$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}.")
|
|
}
|