qt5base-lts/mkspecs/features/qt_functions.prf
Oswald Buddenhagen 4c34b418b8 fix lack of rpath-link when using modules from final location
if the libraries are in a non-standard location, but no rpath is used,
rpath-link is needed. this is often the case for non-prefix builds
(which have no forwarding pris any more).

as we cannot store absolute paths in the final pris, we need to store the
module names, and resolve them only at use time.

Change-Id: I1538b5d531611c76a2d7058a3b2ff683bdcbe427
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
2013-02-04 15:10:22 +01:00

342 lines
11 KiB
Plaintext

defineReplace(qtPlatformTargetSuffix) {
CONFIG(debug, debug|release) {
!debug_and_release|build_pass {
mac:return(_debug)
win32:return(d)
}
}
return()
}
defineReplace(qtLibraryTarget) {
unset(LIBRARY_NAME)
LIBRARY_NAME = $$1
mac:!static:contains(QT_CONFIG, qt_framework) {
QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME
export(QMAKE_FRAMEWORK_BUNDLE_NAME)
} else {
# insert the major version in the library name
# unless it's a framework build
MAJOR_VERSION = $$section(VERSION, ., 0, 0)
LIBRARY_NAME ~= s,^Qt,Qt$$MAJOR_VERSION,
}
unset(LIBRARY_SUFFIX)
contains(TEMPLATE, .*lib):LIBRARY_SUFFIX = $$qtPlatformTargetSuffix()
isEmpty(LIBRARY_SUFFIX):return($$LIBRARY_NAME)
else:return($$member(LIBRARY_NAME, 0)$$LIBRARY_SUFFIX)
}
defineTest(qtAddLibrary) {
warning("qtAddLibrary() is deprecated. Use qtAddModule() or QT+= instead.")
# Reverse-engineer the module name from the library name.
for(var, $$list($$find($$list($$enumerate_vars()), ^QT\\.[^.]+\\.name$))) {
isEqual($$var, $$1) {
var ~= s,^QT\\.([^.]+)\\.name$,\\1,
qtAddModule($$var, , LIBS):return(true):break()
return(false):break() # Yes, the break is insanity. But necessary.
}
}
error("No module matching library '$$1' found.")
}
# target variable, flag source variable
defineTest(qtProcessModuleFlags) {
for(flag, $$2) {
contains(flag, ^-.*): \
$$1 -= $$replace(flag, ^-, )
else: \
$$1 += $$flag
}
export($$1)
}
# qt module
defineTest(qtHaveModule) {
!isEmpty(QT.$${1}.name): \
return(true)
return(false)
}
# qt module, UsePrivate flag, libs variable
defineTest(qtAddModule) {
MODULE_NAME = $$eval(QT.$${1}.name)
MODULE_INCLUDES = $$eval(QT.$${1}.includes)
MODULE_LIBS = $$eval(QT.$${1}.libs)
MODULE_CONFIG = $$eval(QT.$${1}.module_config)
MODULE_MAJOR_VERSION = $$eval(QT.$${1}.MAJOR_VERSION)
qtProcessModuleFlags(CONFIG, QT.$${1}.CONFIG)
qtProcessModuleFlags(DEFINES, QT.$${1}.DEFINES)
MODULE_INCLUDES -= $$QMAKE_DEFAULT_INCDIRS
MODULE_LIBS_ADD = $$MODULE_LIBS
MODULE_LIBS_ADD -= $$QMAKE_DEFAULT_LIBDIRS
INCLUDEPATH *= $$MODULE_INCLUDES
auto_use_privates|isEqual(2, UsePrivate) { # Tests function parameter 2 ($$2) being equal to 'UsePrivate'
INCLUDEPATH += $$eval(QT.$${1}.private_includes)
}
unset(LINKAGE)
mac {
contains(MODULE_CONFIG, lib_bundle) {
FRAMEWORK_INCLUDE = $${MODULE_LIBS}/$${MODULE_NAME}.framework/Headers
!qt_no_framework_direct_includes:exists($$FRAMEWORK_INCLUDE) {
INCLUDEPATH *= $$FRAMEWORK_INCLUDE
LINKAGE = -F$${MODULE_LIBS}
} else {
QMAKE_FRAMEWORKPATH *= $${MODULE_LIBS}
}
LINKAGE += -framework $${MODULE_NAME}$${QT_LIBINFIX}
}
}
# Re-insert the major version in the library name (cf qtLibraryTarget above)
# unless it's a framework build
!mac|!contains(MODULE_CONFIG, lib_bundle): \
MODULE_NAME ~= s,^Qt,Qt$$MODULE_MAJOR_VERSION,
win32 {
# Make sure the version number isn't appended again to the lib name
ver_var = QMAKE_$${upper($$MODULE_NAME$$QT_LIBINFIX)}_VERSION_OVERRIDE
dver_var = QMAKE_$${upper($$MODULE_NAME$$QT_LIBINFIX)}D_VERSION_OVERRIDE
$$ver_var = 0
$$dver_var = 0
export($$ver_var)
export($$dver_var)
}
isEmpty(LINKAGE) {
!isEmpty(MODULE_LIBS_ADD): LINKAGE = -L$$MODULE_LIBS_ADD
lib =
if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
win32: lib = $${MODULE_NAME}$${QT_LIBINFIX}d
mac: lib = $${MODULE_NAME}$${QT_LIBINFIX}_debug
}
isEmpty(lib): lib = $${MODULE_NAME}$${QT_LIBINFIX}
LINKAGE += -l$$lib
contains(QT_CONFIG, rpath): QMAKE_RPATHDIR *= $$eval(QT.$${1}.rpath)
contains(MODULE_CONFIG, staticlib): \
PRE_TARGETDEPS *= $$MODULE_LIBS/$${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
}
# Only link to this module if a libs directory is set, else this is just a module
# to give access to sources or include files, and not for linking.
!isEmpty(MODULE_LIBS) {
!isEmpty(QMAKE_LSB) {
!isEmpty(MODULE_LIBS_ADD): QMAKE_LFLAGS *= --lsb-libpath=$$MODULE_LIBS_ADD
QMAKE_LIBDIR *= /opt/lsb/lib
QMAKE_LFLAGS *= --lsb-shared-libs=$${MODULE_NAME}$${QT_LIBINFIX}
}
$$3 += $$LINKAGE
}
export($$3)
export(INCLUDEPATH)
export(QMAKE_FRAMEWORKPATH)
export(QMAKE_LFLAGS)
export(QMAKE_LIBDIR)
export(QMAKE_RPATHDIR)
export(QMAKE_RPATHLINKDIR)
export(PRE_TARGETDEPS)
return(true)
}
# qt variable, libs variable
defineTest(qtAddModules) {
# Figure out from which modules we're wanting to use the private headers
NEWQT =
for(QTLIB, $$1) {
QTLIBRAW = $$replace(QTLIB, -private$, )
!isEqual(QTLIBRAW, $$QTLIB) {
want_var = QT.$${QTLIBRAW}.want_private
$$want_var = UsePrivate
using_privates = true
NEWQT += $$eval(QT.$${QTLIBRAW}.private_depends)
}
NEWQT += $$QTLIBRAW
contains(QT.$${QTLIBRAW}.CONFIG, auto_use_privates): CONFIG += auto_use_privates
}
# Topological resolution of modules based on their QT.<module>.depends variable
$$1 = $$resolve_depends(NEWQT, "QT.")
# Finally actually add the modules
unset(BAD_QT)
for(QTLIB, $$1) {
QTLIBNAME = $$eval(QT.$${QTLIB}.name)
isEmpty(QTLIBNAME) {
BAD_QT += $$QTLIB
next()
}
target_qt:isEqual(TARGET, $$QTLIBNAME) {
warning("$$TARGET cannot have a $$1 of $$QTLIB")
next()
}
qtAddModule($$QTLIB, $$eval(QT.$${QTLIB}.want_private), $$2)
}
!isEmpty(BAD_QT):error("Unknown module(s) in $$1: $$BAD_QT")
export(using_privates)
}
defineTest(qtAddRpathLink) {
# -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 appear here. However, their private dependencies'
# paths OTOH need to be put there.
pubqt = $$replace(1, -private$, )
pubdep = $$resolve_depends(pubqt, "QT.")
privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".private_depends" ".run_depends")
privdep -= $$pubdep
rpaths =
for(dep, privdep): \
rpaths += $$eval(QT.$${dep}.libs)
QMAKE_RPATHLINKDIR *= $$unique(rpaths)
QMAKE_RPATHLINKDIR -= $$QMAKE_RPATHDIR # -rpath implies -rpath-link
export(QMAKE_RPATHLINKDIR)
}
# variable, default
defineTest(qtPrepareTool) {
$$1 = $$eval(QT_TOOL.$${2}.command)
isEmpty($$1) {
$$1 = $$[QT_HOST_BINS/get]/$$2
contains(QMAKE_HOST.os, Windows):!contains($$1, .*\\.(exe|bat)$) {
exists($$eval($$1).bat) {
$$1 = $$eval($$1).bat
} else {
$$1 = $$eval($$1).exe
}
} else:contains(QMAKE_HOST.os, Darwin) {
BUNDLENAME = $$eval($$1).app/Contents/MacOS/$$2
exists($$BUNDLENAME) {
$$1 = $$BUNDLENAME
}
}
$$1 = $$shell_path($$eval($$1))
}
export($$1)
}
defineTest(qtAddToolEnv) {
for(env, 2) {
value = $$eval($${env}.value)
!isEmpty(value) {
name = $$eval($${env}.name)
equals(QMAKE_DIR_SEP, /) {
contains($${env}.CONFIG, prepend): infix = \${$$name:+:\$$$name}
else: infix =
val = "$$name=$$join(value, :)$$infix"
} else {
# Escape closing parens when expanding the variable, otherwise cmd confuses itself.
contains($${env}.CONFIG, prepend): infix = ;%$$name:)=^)%
else: infix =
val = "(set $$name=$$join(value, ;)$$infix) &"
}
contains(MAKEFILE_GENERATOR, MS.*): val ~= s,%,%%,g
else: val ~= s,\\\$,\$\$,g
$$1 = "$$val $$eval($$1)"
}
}
export($$1)
}
defineTest(qtAddTargetEnv) {
deps = $$replace(QT, -private$, )
deps = $$resolve_depends(deps, "QT.")
!isEmpty(deps) {
for(dep, deps) {
deppath += $$shell_path($$eval(QT.$${dep}.libs))
for(rpath, QT.$${dep}.rpath_link): \
deppath += $$shell_path($$rpath)
}
equals(QMAKE_HOST.os, Windows) {
deppath.name = PATH
} else:contains(QMAKE_HOST.os, Linux|FreeBSD) {
deppath.name = LD_LIBRARY_PATH
} else:equals(QMAKE_HOST.os, Darwin) {
contains(QT_CONFIG, qt_framework): \
deppath.name = DYLD_FRAMEWORK_PATH
else: \
deppath.name = DYLD_LIBRARY_PATH
} else {
error("Operating system not supported.")
}
deppath.value = $$unique(deppath)
deppath.CONFIG = prepend
pluginpath.value =
for(qmod, QMAKEMODULES) {
qmod = $$section(qmod, /, 0, -3)/plugins
exists($$qmod): pluginpath.value += $$shell_path($$qmod)
}
pluginpath.name = QT_PLUGIN_PATH
QT_TOOL_ENV += deppath pluginpath
}
qtAddToolEnv($$1, $$QT_TOOL_ENV)
}
defineReplace(pkgConfigExecutable) {
isEmpty(PKG_CONFIG) {
PKG_CONFIG = pkg-config
!isEmpty(PKG_CONFIG_SYSROOT_DIR) {
win32:isEmpty(MINGW_IN_SHELL):PKG_CONFIG = set PKG_CONFIG_SYSROOT_DIR=$$PKG_CONFIG_SYSROOT_DIR& $$PKG_CONFIG
else:PKG_CONFIG = PKG_CONFIG_SYSROOT_DIR=\"$$PKG_CONFIG_SYSROOT_DIR\" $$PKG_CONFIG
}
!isEmpty(PKG_CONFIG_LIBDIR) {
win32:isEmpty(MINGW_IN_SHELL):PKG_CONFIG = set PKG_CONFIG_LIBDIR=$$PKG_CONFIG_LIBDIR& $$PKG_CONFIG
else:PKG_CONFIG = PKG_CONFIG_LIBDIR=\"$$PKG_CONFIG_LIBDIR\" $$PKG_CONFIG
}
}
return($$PKG_CONFIG)
}
defineTest(packagesExist) {
contains(QT_CONFIG, no-pkg-config):return(false)
# 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)
}