summaryrefslogtreecommitdiffstats
path: root/qmake
diff options
context:
space:
mode:
Diffstat (limited to 'qmake')
-rw-r--r--qmake/Makefile.win322
-rw-r--r--qmake/doc/src/qmake-manual.qdoc22
-rw-r--r--qmake/library/qmakebuiltins.cpp330
-rw-r--r--qmake/library/qmakeevaluator.h5
4 files changed, 184 insertions, 175 deletions
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 851185f3ff..a1699bd6f8 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -39,7 +39,7 @@ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \
-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS \
-DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
- -DQT_NO_FOREACH -DUNICODE
+ -DQT_NO_FOREACH -DUNICODE -D_ENABLE_EXTENDED_ALIGNED_STORAGE
CFLAGS = $(CFLAGS_PCH) $(CFLAGS_BARE) $(CFLAGS)
CXXFLAGS_BARE = $(CFLAGS_BARE)
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 22c34adccd..409062cf49 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -1046,7 +1046,7 @@
library and header files. The proper include and library paths for the
Qt library will automatically be added to the project. This is defined
by default, and can be fine-tuned with the \c{\l{#qt}{QT}} variable.
- \row \li x11 \li The target is a X11 application or library. The proper
+ \row \li x11 \li The target is an X11 application or library. The proper
include paths and libraries will automatically be added to the
project.
\row \li testcase \li The target is an automated test.
@@ -1282,7 +1282,7 @@
\section1 LEXOBJECTS
Specifies the names of intermediate Lex object
- files.The value of this variable is typically handled by
+ files. The value of this variable is typically handled by
qmake and rarely needs to be modified.
\target LEXSOURCES
@@ -1779,9 +1779,9 @@
\note This variable is used on \macos, iOS, tvOS, and watchOS only.
- For projects where the build target is an \macos, iOS, tvOS, or watchOS framework, this
- variable is used to specify the version number that will be applied to the
- framework that is built.
+ For projects where the build target is a \macos, iOS, tvOS, or watchOS
+ framework, this variable is used to specify the version number that will be
+ applied to the framework that is built.
By default, this variable contains the same value as the \l{#VERSION}{VERSION}
variable.
@@ -1865,7 +1865,7 @@
\note This variable is used on Unix platforms only.
Specifies the location of X11 header file paths to be added
- to \l{INCLUDEPATH} when building a X11 target. The value of this variable
+ to \l{INCLUDEPATH} when building an X11 target. The value of this variable
is typically handled by qmake or
\l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
@@ -2255,7 +2255,7 @@
\section1 QMAKE_QMAKE
- Contains the abosolute path of the qmake executable.
+ Contains the absolute path of the qmake executable.
\note Do not attempt to overwrite the value of this variable.
@@ -2323,7 +2323,7 @@
If defined, the value of this variable is used as a path to be prepended to
the built shared library's \c SONAME identifier. The \c SONAME is the
identifier that the dynamic linker will later use to reference the library.
- In general this reference may be a library name or full library path. On \macos,
+ In general, this reference may be a library name or full library path. On \macos,
iOS, tvOS, and watchOS, the path may be specified relatively using the following
placeholders:
@@ -2629,7 +2629,7 @@
\section1 TARGET_x.y.z
- Specifies the extension of \c TARGET with version number. The
+ Specifies the extension of \c TARGET with a version number. The
value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely
needs to be modified.
@@ -2650,7 +2650,7 @@
The subdirectories are specified using the \l{#SUBDIRS}{SUBDIRS}
variable.
\row \li aux \li Creates a Makefile for not building anything. Use this if no compiler
- needs to be invoked to create the target, for instance because your
+ needs to be invoked to create the target; for instance, because your
project is written in an interpreted language.
\note This template type is only available for Makefile-based
generators. In particular, it will not work with the vcxproj and
@@ -2832,7 +2832,7 @@
Windows Phone.
\row
\li logo_480x800
- \li Splash sceen image file of size 480x800 pixels. This is only supported on
+ \li Splash screen image file of size 480x800 pixels. This is only supported on
Windows Phone.
\row
\li logo_large
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 1181435b18..fda1e1c593 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -1223,6 +1223,171 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
return ReturnTrue;
}
+QMakeEvaluator::VisitReturn QMakeEvaluator::testFunc_cache(const ProStringList &args)
+{
+ bool persist = true;
+ enum { TargetStash, TargetCache, TargetSuper } target = TargetCache;
+ enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet;
+ ProKey srcvar;
+ if (args.count() >= 2) {
+ const auto opts = split_value_list(args.at(1).toQStringRef());
+ for (const ProString &opt : opts) {
+ if (opt == QLatin1String("transient")) {
+ persist = false;
+ } else if (opt == QLatin1String("super")) {
+ target = TargetSuper;
+ } else if (opt == QLatin1String("stash")) {
+ target = TargetStash;
+ } else if (opt == QLatin1String("set")) {
+ mode = CacheSet;
+ } else if (opt == QLatin1String("add")) {
+ mode = CacheAdd;
+ } else if (opt == QLatin1String("sub")) {
+ mode = CacheSub;
+ } else {
+ evalError(fL1S("cache(): invalid flag %1.").arg(opt.toQStringView()));
+ return ReturnFalse;
+ }
+ }
+ if (args.count() >= 3) {
+ srcvar = args.at(2).toKey();
+ } else if (mode != CacheSet) {
+ evalError(fL1S("cache(): modes other than 'set' require a source variable."));
+ return ReturnFalse;
+ }
+ }
+ QString varstr;
+ ProKey dstvar = args.at(0).toKey();
+ if (!dstvar.isEmpty()) {
+ if (srcvar.isEmpty())
+ srcvar = dstvar;
+ ProValueMap::Iterator srcvarIt;
+ if (!findValues(srcvar, &srcvarIt)) {
+ evalError(fL1S("Variable %1 is not defined.").arg(srcvar.toQStringView()));
+ return ReturnFalse;
+ }
+ // The caches for the host and target may differ (e.g., when we are manipulating
+ // CONFIG), so we cannot compute a common new value for both.
+ const ProStringList &diffval = *srcvarIt;
+ ProStringList newval;
+ bool changed = false;
+ for (bool hostBuild = false; ; hostBuild = true) {
+#ifdef PROEVALUATOR_THREAD_SAFE
+ m_option->mutex.lock();
+#endif
+ QMakeBaseEnv *baseEnv =
+ m_option->baseEnvs.value(QMakeBaseKey(m_buildRoot, m_stashfile, hostBuild));
+#ifdef PROEVALUATOR_THREAD_SAFE
+ // It's ok to unlock this before locking baseEnv,
+ // as we have no intention to initialize the env.
+ m_option->mutex.unlock();
+#endif
+ do {
+ if (!baseEnv)
+ break;
+#ifdef PROEVALUATOR_THREAD_SAFE
+ QMutexLocker locker(&baseEnv->mutex);
+ if (baseEnv->inProgress && baseEnv->evaluator != this) {
+ // The env is still in the works, but it may be already past the cache
+ // loading. So we need to wait for completion and amend it as usual.
+ QThreadPool::globalInstance()->releaseThread();
+ baseEnv->cond.wait(&baseEnv->mutex);
+ QThreadPool::globalInstance()->reserveThread();
+ }
+ if (!baseEnv->isOk)
+ break;
+#endif
+ QMakeEvaluator *baseEval = baseEnv->evaluator;
+ const ProStringList &oldval = baseEval->values(dstvar);
+ if (mode == CacheSet) {
+ newval = diffval;
+ } else {
+ newval = oldval;
+ if (mode == CacheAdd)
+ newval += diffval;
+ else
+ newval.removeEach(diffval);
+ }
+ if (oldval != newval) {
+ if (target != TargetStash || !m_stashfile.isEmpty()) {
+ baseEval->valuesRef(dstvar) = newval;
+ if (target == TargetSuper) {
+ do {
+ if (dstvar == QLatin1String("QMAKEPATH")) {
+ baseEval->m_qmakepath = newval.toQStringList();
+ baseEval->updateMkspecPaths();
+ } else if (dstvar == QLatin1String("QMAKEFEATURES")) {
+ baseEval->m_qmakefeatures = newval.toQStringList();
+ } else {
+ break;
+ }
+ baseEval->updateFeaturePaths();
+ if (hostBuild == m_hostBuild)
+ m_featureRoots = baseEval->m_featureRoots;
+ } while (false);
+ }
+ }
+ changed = true;
+ }
+ } while (false);
+ if (hostBuild)
+ break;
+ }
+ // We assume that whatever got the cached value to be what it is now will do so
+ // the next time as well, so we just skip the persisting if nothing changed.
+ if (!persist || !changed)
+ return ReturnTrue;
+ varstr = dstvar.toQString();
+ if (mode == CacheAdd)
+ varstr += QLatin1String(" +=");
+ else if (mode == CacheSub)
+ varstr += QLatin1String(" -=");
+ else
+ varstr += QLatin1String(" =");
+ if (diffval.count() == 1) {
+ varstr += QLatin1Char(' ');
+ varstr += quoteValue(diffval.at(0));
+ } else if (!diffval.isEmpty()) {
+ for (const ProString &vval : diffval) {
+ varstr += QLatin1String(" \\\n ");
+ varstr += quoteValue(vval);
+ }
+ }
+ varstr += QLatin1Char('\n');
+ }
+ QString fn;
+ QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
+ if (target == TargetSuper) {
+ if (m_superfile.isEmpty()) {
+ m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
+ printf("Info: creating super cache file %s\n", qPrintable(QDir::toNativeSeparators(m_superfile)));
+ valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
+ }
+ fn = m_superfile;
+ } else if (target == TargetCache) {
+ if (m_cachefile.isEmpty()) {
+ m_cachefile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.cache"));
+ printf("Info: creating cache file %s\n", qPrintable(QDir::toNativeSeparators(m_cachefile)));
+ valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
+ // We could update m_{source,build}Root and m_featureRoots here, or even
+ // "re-home" our rootEnv, but this doesn't sound too useful - if somebody
+ // wanted qmake to find something in the build directory, he could have
+ // done so "from the outside".
+ // The sub-projects will find the new cache all by themselves.
+ }
+ fn = m_cachefile;
+ } else {
+ fn = m_stashfile;
+ if (fn.isEmpty())
+ fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
+ if (!m_vfs->exists(fn, flags)) {
+ printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
+ valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
+ }
+ }
+ return writeFile(fL1S("cache "), fn, QIODevice::Append, flags, varstr);
+}
+
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
const QMakeInternal::QMakeBuiltin &adef, const ProKey &function, const ProStringList &args)
{
@@ -1687,169 +1852,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
#endif
return ReturnTrue;
}
- case T_CACHE: {
- bool persist = true;
- enum { TargetStash, TargetCache, TargetSuper } target = TargetCache;
- enum { CacheSet, CacheAdd, CacheSub } mode = CacheSet;
- ProKey srcvar;
- if (args.count() >= 2) {
- const auto opts = split_value_list(args.at(1).toQStringRef());
- for (const ProString &opt : opts) {
- if (opt == QLatin1String("transient")) {
- persist = false;
- } else if (opt == QLatin1String("super")) {
- target = TargetSuper;
- } else if (opt == QLatin1String("stash")) {
- target = TargetStash;
- } else if (opt == QLatin1String("set")) {
- mode = CacheSet;
- } else if (opt == QLatin1String("add")) {
- mode = CacheAdd;
- } else if (opt == QLatin1String("sub")) {
- mode = CacheSub;
- } else {
- evalError(fL1S("cache(): invalid flag %1.").arg(opt.toQStringView()));
- return ReturnFalse;
- }
- }
- if (args.count() >= 3) {
- srcvar = args.at(2).toKey();
- } else if (mode != CacheSet) {
- evalError(fL1S("cache(): modes other than 'set' require a source variable."));
- return ReturnFalse;
- }
- }
- QString varstr;
- ProKey dstvar = args.at(0).toKey();
- if (!dstvar.isEmpty()) {
- if (srcvar.isEmpty())
- srcvar = dstvar;
- ProValueMap::Iterator srcvarIt;
- if (!findValues(srcvar, &srcvarIt)) {
- evalError(fL1S("Variable %1 is not defined.").arg(srcvar.toQStringView()));
- return ReturnFalse;
- }
- // The caches for the host and target may differ (e.g., when we are manipulating
- // CONFIG), so we cannot compute a common new value for both.
- const ProStringList &diffval = *srcvarIt;
- ProStringList newval;
- bool changed = false;
- for (bool hostBuild = false; ; hostBuild = true) {
-#ifdef PROEVALUATOR_THREAD_SAFE
- m_option->mutex.lock();
-#endif
- QMakeBaseEnv *baseEnv =
- m_option->baseEnvs.value(QMakeBaseKey(m_buildRoot, m_stashfile, hostBuild));
-#ifdef PROEVALUATOR_THREAD_SAFE
- // It's ok to unlock this before locking baseEnv,
- // as we have no intention to initialize the env.
- m_option->mutex.unlock();
-#endif
- do {
- if (!baseEnv)
- break;
-#ifdef PROEVALUATOR_THREAD_SAFE
- QMutexLocker locker(&baseEnv->mutex);
- if (baseEnv->inProgress && baseEnv->evaluator != this) {
- // The env is still in the works, but it may be already past the cache
- // loading. So we need to wait for completion and amend it as usual.
- QThreadPool::globalInstance()->releaseThread();
- baseEnv->cond.wait(&baseEnv->mutex);
- QThreadPool::globalInstance()->reserveThread();
- }
- if (!baseEnv->isOk)
- break;
-#endif
- QMakeEvaluator *baseEval = baseEnv->evaluator;
- const ProStringList &oldval = baseEval->values(dstvar);
- if (mode == CacheSet) {
- newval = diffval;
- } else {
- newval = oldval;
- if (mode == CacheAdd)
- newval += diffval;
- else
- newval.removeEach(diffval);
- }
- if (oldval != newval) {
- if (target != TargetStash || !m_stashfile.isEmpty()) {
- baseEval->valuesRef(dstvar) = newval;
- if (target == TargetSuper) {
- do {
- if (dstvar == QLatin1String("QMAKEPATH")) {
- baseEval->m_qmakepath = newval.toQStringList();
- baseEval->updateMkspecPaths();
- } else if (dstvar == QLatin1String("QMAKEFEATURES")) {
- baseEval->m_qmakefeatures = newval.toQStringList();
- } else {
- break;
- }
- baseEval->updateFeaturePaths();
- if (hostBuild == m_hostBuild)
- m_featureRoots = baseEval->m_featureRoots;
- } while (false);
- }
- }
- changed = true;
- }
- } while (false);
- if (hostBuild)
- break;
- }
- // We assume that whatever got the cached value to be what it is now will do so
- // the next time as well, so we just skip the persisting if nothing changed.
- if (!persist || !changed)
- return ReturnTrue;
- varstr = dstvar.toQString();
- if (mode == CacheAdd)
- varstr += QLatin1String(" +=");
- else if (mode == CacheSub)
- varstr += QLatin1String(" -=");
- else
- varstr += QLatin1String(" =");
- if (diffval.count() == 1) {
- varstr += QLatin1Char(' ');
- varstr += quoteValue(diffval.at(0));
- } else if (!diffval.isEmpty()) {
- for (const ProString &vval : diffval) {
- varstr += QLatin1String(" \\\n ");
- varstr += quoteValue(vval);
- }
- }
- varstr += QLatin1Char('\n');
- }
- QString fn;
- QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
- if (target == TargetSuper) {
- if (m_superfile.isEmpty()) {
- m_superfile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.super"));
- printf("Info: creating super cache file %s\n", qPrintable(QDir::toNativeSeparators(m_superfile)));
- valuesRef(ProKey("_QMAKE_SUPER_CACHE_")) << ProString(m_superfile);
- }
- fn = m_superfile;
- } else if (target == TargetCache) {
- if (m_cachefile.isEmpty()) {
- m_cachefile = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.cache"));
- printf("Info: creating cache file %s\n", qPrintable(QDir::toNativeSeparators(m_cachefile)));
- valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
- // We could update m_{source,build}Root and m_featureRoots here, or even
- // "re-home" our rootEnv, but this doesn't sound too useful - if somebody
- // wanted qmake to find something in the build directory, he could have
- // done so "from the outside".
- // The sub-projects will find the new cache all by themselves.
- }
- fn = m_cachefile;
- } else {
- fn = m_stashfile;
- if (fn.isEmpty())
- fn = QDir::cleanPath(m_outputDir + QLatin1String("/.qmake.stash"));
- if (!m_vfs->exists(fn, flags)) {
- printf("Info: creating stash file %s\n", qPrintable(QDir::toNativeSeparators(fn)));
- valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn);
- }
- }
- return writeFile(fL1S("cache "), fn, QIODevice::Append, flags, varstr);
- }
+ case T_CACHE:
+ return testFunc_cache(args);
case T_RELOAD_PROPERTIES:
#ifdef QT_BUILD_QMAKE
m_option->reloadProperties();
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index 303a23064c..b87aaa0eec 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -250,6 +250,11 @@ public:
#endif
QByteArray getCommandOutput(const QString &args, int *exitCode) const;
+private:
+ // Implementation detail of evaluateBuiltinConditional():
+ VisitReturn testFunc_cache(const ProStringList &args);
+
+public:
QMakeEvaluator *m_caller;
#ifdef PROEVALUATOR_CUMULATIVE
bool m_cumulative;