aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2018-06-01 11:23:57 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2018-06-01 11:23:57 +0000
commit250e6da6cb06eb7ca82fae0d98be8b4b6123cfcf (patch)
treed06c5d3628b36b4077ce6a05b41150f6a7d00583
parent17059ccd06e56010fa0d44ebcaf0be7b85d69703 (diff)
parent6a3c4dc21c1a5831618e5604df45abe4b0545bba (diff)
Merge "Merge 1.12 into master"
-rw-r--r--doc/howtos.qdoc31
-rw-r--r--doc/qbs.qdoc4
-rw-r--r--doc/reference/cli/builtin/cli-build.qdoc2
-rw-r--r--doc/reference/cli/builtin/cli-install.qdoc2
-rw-r--r--doc/reference/cli/builtin/cli-run.qdoc2
-rw-r--r--doc/reference/cli/cli-options.qdocinc41
-rw-r--r--doc/reference/cli/tools/cli-config-ui.qdoc3
-rw-r--r--doc/reference/cli/tools/cli-config.qdoc24
-rw-r--r--doc/reference/cli/tools/cli-setup-qt.qdoc5
-rw-r--r--doc/reference/cli/tools/cli-setup-toolchains.qdoc5
-rw-r--r--doc/reference/items/convenience/autotestrunner.qdoc2
-rw-r--r--qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs1
-rw-r--r--share/qbs/imports/qbs/base/AutotestRunner.qbs9
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs2
-rw-r--r--src/app/config-ui/commandlineparser.cpp9
-rw-r--r--src/app/config-ui/commandlineparser.h4
-rw-r--r--src/app/config-ui/main.cpp2
-rw-r--r--src/app/config-ui/mainwindow.cpp4
-rw-r--r--src/app/config-ui/mainwindow.h5
-rw-r--r--src/app/config/configcommandexecutor.cpp20
-rw-r--r--src/app/config/configcommandexecutor.h7
-rw-r--r--src/app/config/configcommandlineparser.cpp33
-rw-r--r--src/app/config/configcommandlineparser.h14
-rw-r--r--src/app/config/configmain.cpp7
-rw-r--r--src/app/qbs-setup-qt/commandlineparser.cpp11
-rw-r--r--src/app/qbs-setup-qt/commandlineparser.h4
-rw-r--r--src/app/qbs-setup-qt/main.cpp7
-rw-r--r--src/app/qbs-setup-qt/setupqt.cpp55
-rw-r--r--src/app/qbs-setup-qt/setupqt.h21
-rw-r--r--src/app/qbs-setup-toolchains/commandlineparser.cpp11
-rw-r--r--src/app/qbs-setup-toolchains/commandlineparser.h4
-rw-r--r--src/app/qbs-setup-toolchains/main.cpp1
-rw-r--r--src/app/qbs-setup-toolchains/msvcprobe.cpp9
-rw-r--r--src/lib/corelib/corelib.qbs3
-rw-r--r--src/lib/corelib/tools/preferences.cpp28
-rw-r--r--src/lib/corelib/tools/preferences.h4
-rw-r--r--src/lib/corelib/tools/profile.cpp6
-rw-r--r--src/lib/corelib/tools/settings.cpp149
-rw-r--r--src/lib/corelib/tools/settings.h24
-rw-r--r--src/lib/corelib/tools/settingsmodel.cpp13
-rw-r--r--src/lib/corelib/tools/settingsmodel.h3
-rw-r--r--src/lib/corelib/tools/tools.pri5
-rw-r--r--src/lib/qtprofilesetup/qtenvironment.h1
-rw-r--r--src/lib/qtprofilesetup/qtmsvctools.cpp79
-rw-r--r--src/lib/qtprofilesetup/qtmsvctools.h49
-rw-r--r--src/lib/qtprofilesetup/qtprofilesetup.cpp6
-rw-r--r--src/lib/qtprofilesetup/qtprofilesetup.pro7
-rw-r--r--src/lib/qtprofilesetup/qtprofilesetup.qbs2
-rw-r--r--src/plugins/scanner/cpp/cppscanner.cpp10
-rw-r--r--tests/auto/blackbox/blackbox.pro1
-rw-r--r--tests/auto/blackbox/blackbox.qbs1
-rw-r--r--tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs6
-rw-r--r--tests/auto/blackbox/testdata/bom-sources/main.cpp3
-rw-r--r--tests/auto/blackbox/testdata/bom-sources/theheader.h0
-rw-r--r--tests/auto/blackbox/testdata/maximum-c-language-version/main.c1
-rw-r--r--tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs22
-rw-r--r--tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs6
-rw-r--r--tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs6
-rw-r--r--tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs6
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp119
-rw-r--r--tests/auto/blackbox/tst_blackbox.h3
-rw-r--r--tests/auto/tools/tst_tools.cpp4
62 files changed, 772 insertions, 156 deletions
diff --git a/doc/howtos.qdoc b/doc/howtos.qdoc
index 714996e34..6039a23fb 100644
--- a/doc/howtos.qdoc
+++ b/doc/howtos.qdoc
@@ -38,6 +38,7 @@
\li \l{How do I build a Qt-based project?}
\li \l{How do I make my app build against my library?}
\li \l{How do I use precompiled headers?}
+ \li \l{How do I run my autotests?}
\li \l{How do I create a module for a third-party library?}
\li \l{How do I create application bundles and frameworks on iOS, macOS, tvOS, and watchOS?}
\li \l{How do I apply C/C++ preprocessor macros to only a subset of the files in my product?}
@@ -132,6 +133,36 @@
}
\endcode
+ \section1 How do I run my autotests?
+
+ There are two simple things you need to do in your project. Firstly, you
+ mark your test executables as such. This is done by adding the tag \c{"autotest"}
+ to the product type:
+ \code
+ CppApplication {
+ name: "test1"
+ type: base.concat("autotest")
+ // ...
+ }
+ \endcode
+ The second step is to instantiate an \l AutotestRunner product in your project:
+ \code
+ Project {
+ // ...
+ AutotestRunner { name: "run_my_tests" }
+ }
+ \endcode
+ Building an AutotestRunner product does not produce artifacts, but triggers execution of all
+ applications whose products are tagged as autotests:
+ \code
+ $ qbs -p run_my_tests
+ test1: PASS
+ test2: PASS
+ test3: FAIL
+ ...
+ \endcode
+ See the \l{AutotestRunner}{AutotestRunner documentation} for how to fine-tune the behavior.
+
\section1 How do I create a module for a third-party library?
If you have pre-built binary files in your source tree, you can create
diff --git a/doc/qbs.qdoc b/doc/qbs.qdoc
index b37ef4b95..bfeda503a 100644
--- a/doc/qbs.qdoc
+++ b/doc/qbs.qdoc
@@ -509,6 +509,10 @@
\row \li qbs_use_bundled_qtscript \li Use the bundled QtScript library.
\endtable
+ In addition, you can set the \c QBS_SYSTEM_SETTINGS_DIR environment variable
+ before running qmake to specify a custom location for \QBS to look for its
+ system-level settings.
+
\section1 Using Docker
A set of Docker images for developing \QBS (which are maintained by the \QBS team) is available
diff --git a/doc/reference/cli/builtin/cli-build.qdoc b/doc/reference/cli/builtin/cli-build.qdoc
index d2a418d85..cc5f4b27f 100644
--- a/doc/reference/cli/builtin/cli-build.qdoc
+++ b/doc/reference/cli/builtin/cli-build.qdoc
@@ -61,7 +61,7 @@
\include cli-options.qdocinc changed-files
\include cli-options.qdocinc check-outputs
\include cli-options.qdocinc check-timestamps
- \include cli-options.qdocinc clean-install-root
+ \include cli-options.qdocinc clean_install_root
\include cli-options.qdocinc command-echo-mode
\include cli-options.qdocinc dry-run
\include cli-options.qdocinc project-file
diff --git a/doc/reference/cli/builtin/cli-install.qdoc b/doc/reference/cli/builtin/cli-install.qdoc
index d68d4d922..3bddc4fcd 100644
--- a/doc/reference/cli/builtin/cli-install.qdoc
+++ b/doc/reference/cli/builtin/cli-install.qdoc
@@ -54,7 +54,7 @@
\include cli-options.qdocinc changed-files
\include cli-options.qdocinc check-outputs
\include cli-options.qdocinc check-timestamps
- \include cli-options.qdocinc clean-install-root
+ \include cli-options.qdocinc clean_install_root
\include cli-options.qdocinc command-echo-mode
\include cli-options.qdocinc dry-run
\include cli-options.qdocinc project-file
diff --git a/doc/reference/cli/builtin/cli-run.qdoc b/doc/reference/cli/builtin/cli-run.qdoc
index aa5441010..42bc8d4f9 100644
--- a/doc/reference/cli/builtin/cli-run.qdoc
+++ b/doc/reference/cli/builtin/cli-run.qdoc
@@ -58,7 +58,7 @@
\include cli-options.qdocinc changed-files
\include cli-options.qdocinc check-outputs
\include cli-options.qdocinc check-timestamps
- \include cli-options.qdocinc clean-install-root
+ \include cli-options.qdocinc clean_install_root
\include cli-options.qdocinc command-echo-mode
\include cli-options.qdocinc dry-run
\include cli-options.qdocinc project-file
diff --git a/doc/reference/cli/cli-options.qdocinc b/doc/reference/cli/cli-options.qdocinc
index 5316f459d..189a3526a 100644
--- a/doc/reference/cli/cli-options.qdocinc
+++ b/doc/reference/cli/cli-options.qdocinc
@@ -100,13 +100,13 @@
//! [check-timestamps]
-//! [clean-install-root]
+//! [clean_install_root]
\section2 \c --clean-install-root
Removes the installation base directory before installing.
-//! [clean-install-root]
+//! [clean_install_root]
//! [command-echo-mode]
@@ -287,6 +287,33 @@
//! [list-root]
+//! [config-user]
+
+ \section2 \c {--user}
+
+ Causes read operations to display only the user-level settings,
+ while the system-level settings are ignored.
+ Write operations will target the user-level settings, which is also the default.
+
+//! [config-user]
+
+//! [config-system]
+
+ \section2 \c {--system}
+
+ Read and write operations will consider only the system-level settings.
+
+//! [config-system]
+
+//! [config-ui-system]
+
+ \section2 \c {--system}
+
+ Instructs the tool to work on the system-level settings. Otherwise,
+ the user-level settings are presented.
+
+//! [config-ui-system]
+
//! [log-level]
\section2 \c {--log-level <level>}
@@ -418,6 +445,16 @@
//! [show-progress]
+//! [setup-tools-system]
+
+ \section2 \c {--system}
+
+ If this option is given, the profile(s) created by this tool will end up
+ in the system-level settings and thus be available to all users.
+ Otherwise, they go into the user-level settings.
+
+//! [setup-tools-system]
+
//! [type]
\section2 \c {--type <toolchain type>}
diff --git a/doc/reference/cli/tools/cli-config-ui.qdoc b/doc/reference/cli/tools/cli-config-ui.qdoc
index 29c0ed732..66f46e3e1 100644
--- a/doc/reference/cli/tools/cli-config-ui.qdoc
+++ b/doc/reference/cli/tools/cli-config-ui.qdoc
@@ -37,7 +37,7 @@
\section1 Synopsis
\code
- qbs config-ui [--settings-dir <directory>]
+ qbs config-ui [--settings-dir <directory>] [--system]
\endcode
\section1 Description
@@ -54,6 +54,7 @@
\section1 Options
\include cli-options.qdocinc settings-dir
+ \include cli-options.qdocinc config-ui-system
\include cli-options.qdocinc help
\section1 Examples
diff --git a/doc/reference/cli/tools/cli-config.qdoc b/doc/reference/cli/tools/cli-config.qdoc
index 0d2ba9989..e32ffee0e 100644
--- a/doc/reference/cli/tools/cli-config.qdoc
+++ b/doc/reference/cli/tools/cli-config.qdoc
@@ -36,10 +36,10 @@
\section1 Synopsis
\code
- qbs config [--settings-dir <directory>] [--list [<root> ...]]
+ qbs config [--settings-dir <directory>] [--user|--system] [--list [<root> ...]]
[--unset <key>] [--export <file>] [--import <file>]
- qbs config [--settings-dir <directory>] <key>
- qbs config [--settings-dir <directory>] <key> <value>
+ qbs config [--settings-dir <directory>] [--user|--system] <key>
+ qbs config [--settings-dir <directory>] [--user|--system] <key> <value>
\endcode
\section1 Description
@@ -52,6 +52,22 @@
The third form sets the specified \c <key> with the specified \c <value>.
+ There are two sets of settings: The system-level settings affect all users,
+ while the user-level settings are specific to the current user.
+ By default, the read operations consider both sources. If the same key is
+ present in both settings, then for list values, the system value is
+ appended to the user value, while for other types of values the user-level
+ one takes precedence. Write operations go to the user-level settings by default.
+ Use the \c {--user} and \c {--system} options to change this behavior.
+ \note It is conceivable that the default system value of the
+ \c {preferences.qbsSearchPaths} setting could pull in unwanted \QBS modules,
+ in particular when doing cross-builds. In such a case, you can set
+ \c {preferences.ignoreSystemSearchPaths} to exclude the search paths coming
+ from the system settings. You'll typically do this for a specific profile:
+ \code
+ $ qbs config profiles.myprofile.preferences.ignoreSystemSearchPaths true
+ \endcode
+
You can use the \l{config-ui} command to open the Qbs Settings tool for
managing settings in a hierarchical view.
@@ -65,6 +81,8 @@
\include cli-options.qdocinc unset
\include cli-options.qdocinc export
\include cli-options.qdocinc import
+ \include cli-options.qdocinc config-user
+ \include cli-options.qdocinc config-system
\include cli-options.qdocinc help
\section1 Parameters
diff --git a/doc/reference/cli/tools/cli-setup-qt.qdoc b/doc/reference/cli/tools/cli-setup-qt.qdoc
index 9673286b3..1cf961d0d 100644
--- a/doc/reference/cli/tools/cli-setup-qt.qdoc
+++ b/doc/reference/cli/tools/cli-setup-qt.qdoc
@@ -36,8 +36,8 @@
\section1 Synopsis
\code
- qbs setup-qt [--settings-dir <directory>] --detect
- qbs setup-qt [--settings-dir <directory>] <path to qmake> <profile name>
+ qbs setup-qt [--settings-dir <directory>] [--system] --detect
+ qbs setup-qt [--settings-dir <directory>] [--system] <path to qmake> <profile name>
\endcode
\section1 Description
@@ -56,6 +56,7 @@
\include cli-options.qdocinc detect-qt-versions
\include cli-options.qdocinc settings-dir
+ \include cli-options.qdocinc setup-tools-system
\include cli-options.qdocinc help
\section1 Examples
diff --git a/doc/reference/cli/tools/cli-setup-toolchains.qdoc b/doc/reference/cli/tools/cli-setup-toolchains.qdoc
index 15490cc2a..af3b25069 100644
--- a/doc/reference/cli/tools/cli-setup-toolchains.qdoc
+++ b/doc/reference/cli/tools/cli-setup-toolchains.qdoc
@@ -36,8 +36,8 @@
\section1 Synopsis
\code
- qbs setup-toolchains [--settings-dir <directory>] --detect
- qbs setup-toolchains [--settings-dir <directory>] [--type <toolchain type>]
+ qbs setup-toolchains [--settings-dir <directory>] [--system] --detect
+ qbs setup-toolchains [--settings-dir <directory>] [--system] [--type <toolchain type>]
<compiler path> <profile name>
\endcode
@@ -57,6 +57,7 @@
\section1 Options
\include cli-options.qdocinc settings-dir
+ \include cli-options.qdocinc setup-tools-system
\include cli-options.qdocinc detect-toolchains
\include cli-options.qdocinc type
\include cli-options.qdocinc help
diff --git a/doc/reference/items/convenience/autotestrunner.qdoc b/doc/reference/items/convenience/autotestrunner.qdoc
index 3ec58e456..defb2814e 100644
--- a/doc/reference/items/convenience/autotestrunner.qdoc
+++ b/doc/reference/items/convenience/autotestrunner.qdoc
@@ -112,7 +112,7 @@
*/
/*!
- \qmlproperty stringList AutotestRunner::workingDir
+ \qmlproperty string AutotestRunner::workingDir
If this property is set, it will be the working directory for all invoked test executables.
Otherwise, the working directory will the the parent directory of the respective executable.
diff --git a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs
index 7f978d47b..50a5ea79e 100644
--- a/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs
+++ b/qbs-resources/modules/qbsbuildconfig/qbsbuildconfig.qbs
@@ -15,6 +15,7 @@ Module {
property string importLibInstallDir: libDirName
property string libexecInstallDir: qbs.targetOS.contains("windows") ? appInstallDir
: "libexec/qbs"
+ property string systemSettingsDir
property bool installManPage: qbs.targetOS.contains("unix")
property bool installHtml: true
property bool installQch: false
diff --git a/share/qbs/imports/qbs/base/AutotestRunner.qbs b/share/qbs/imports/qbs/base/AutotestRunner.qbs
index f0bd1af78..a1d89da63 100644
--- a/share/qbs/imports/qbs/base/AutotestRunner.qbs
+++ b/share/qbs/imports/qbs/base/AutotestRunner.qbs
@@ -58,6 +58,13 @@ Product {
auxiliaryInputs: product.auxiliaryInputs
outputFileTags: "autotest-result"
prepare: {
+ // TODO: This is hacky. Possible solution: Add autotest tag to application
+ // in autotest module and have that as inputsFromDependencies instead of application.
+ if (!input.product.type.contains("autotest")) {
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ return cmd;
+ }
var commandFilePath;
var installed = input.moduleProperty("qbs", "install");
if (installed)
@@ -65,7 +72,7 @@ Product {
if (!commandFilePath || !File.exists(commandFilePath))
commandFilePath = input.filePath;
var workingDir = product.workingDir ? product.workingDir
- : FileInfo.path(input.filePath);
+ : FileInfo.path(commandFilePath);
var arguments = product.arguments;
var allowFailure = false;
if (input.autotest) {
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index 1c42169d5..0078bb1af 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -276,7 +276,7 @@ Module {
allowedValues: ['default', 'hidden', 'hiddenInlines', 'minimal']
}
- property string cLanguageVersion
+ property stringList cLanguageVersion
PropertyOptions {
name: "cLanguageVersion"
allowedValues: ["c89", "c99", "c11"]
diff --git a/src/app/config-ui/commandlineparser.cpp b/src/app/config-ui/commandlineparser.cpp
index b05d84343..d38c34e55 100644
--- a/src/app/config-ui/commandlineparser.cpp
+++ b/src/app/config-ui/commandlineparser.cpp
@@ -48,6 +48,7 @@ using qbs::Internal::Tr;
static QString helpOptionShort() { return QLatin1String("-h"); }
static QString helpOptionLong() { return QLatin1String("--help"); }
static QString settingsDirOption() { return QLatin1String("--settings-dir"); }
+static QString systemOption() { return QLatin1String("--system"); }
void CommandLineParser::parse(const QStringList &commandLine)
{
@@ -63,6 +64,9 @@ void CommandLineParser::parse(const QStringList &commandLine)
if (arg == helpOptionShort() || arg == helpOptionLong()) {
m_commandLine.removeFirst();
m_helpRequested = true;
+ } else if (arg == systemOption()) {
+ m_commandLine.removeFirst();
+ m_settingsScope = qbs::Settings::SystemScope;
} else if (arg == settingsDirOption()) {
m_commandLine.removeFirst();
assignOptionArgument(settingsDirOption(), m_settingsDir);
@@ -85,8 +89,9 @@ QString CommandLineParser::usageString() const
"If you have more than a few settings, this might be preferable to "
"plain \"qbs config\", as it presents a hierarchical view.\n");
s += Tr::tr("Usage:\n");
- s += Tr::tr(" %1 [%2 <settings directory>] [%3|%4]\n")
- .arg(m_command, settingsDirOption(), helpOptionShort(), helpOptionLong());
+ s += Tr::tr(" %1 [%2 <settings directory>] [%5] [%3|%4]\n")
+ .arg(m_command, settingsDirOption(), helpOptionShort(), helpOptionLong(),
+ systemOption());
return s;
}
diff --git a/src/app/config-ui/commandlineparser.h b/src/app/config-ui/commandlineparser.h
index 1cb6bf2f7..dc43d33b3 100644
--- a/src/app/config-ui/commandlineparser.h
+++ b/src/app/config-ui/commandlineparser.h
@@ -39,6 +39,8 @@
#ifndef QBS_CONFIGUI_COMMANDLINEPARSER_H
#define QBS_CONFIGUI_COMMANDLINEPARSER_H
+#include <tools/settings.h>
+
#include <QtCore/qstringlist.h>
class CommandLineParser
@@ -48,6 +50,7 @@ public:
bool helpRequested() const { return m_helpRequested; }
QString settingsDir() const { return m_settingsDir; }
+ qbs::Settings::Scope settingsScope() const { return m_settingsScope; }
QString usageString() const;
@@ -57,6 +60,7 @@ private:
[[noreturn]] void complainAboutExtraArguments();
bool m_helpRequested;
+ qbs::Settings::Scope m_settingsScope = qbs::Settings::UserScope;
QString m_settingsDir;
QStringList m_commandLine;
QString m_command;
diff --git a/src/app/config-ui/main.cpp b/src/app/config-ui/main.cpp
index ea4c25760..a7c2662e6 100644
--- a/src/app/config-ui/main.cpp
+++ b/src/app/config-ui/main.cpp
@@ -65,7 +65,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- MainWindow mw(clParser.settingsDir());
+ MainWindow mw(clParser.settingsDir(), clParser.settingsScope());
mw.show();
return app.exec();
}
diff --git a/src/app/config-ui/mainwindow.cpp b/src/app/config-ui/mainwindow.cpp
index dda1ed523..13708366a 100644
--- a/src/app/config-ui/mainwindow.cpp
+++ b/src/app/config-ui/mainwindow.cpp
@@ -53,11 +53,11 @@
#include <QtWidgets/qmenubar.h>
#include <QtWidgets/qmessagebox.h>
-MainWindow::MainWindow(const QString &settingsDir, QWidget *parent)
+MainWindow::MainWindow(const QString &settingsDir, qbs::Settings::Scope scope, QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
- m_model = new qbs::SettingsModel(settingsDir, this);
+ m_model = new qbs::SettingsModel(settingsDir, scope, this);
ui->treeView->setModel(m_model);
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->treeView, &QTreeView::expanded, this, &MainWindow::adjustColumns);
diff --git a/src/app/config-ui/mainwindow.h b/src/app/config-ui/mainwindow.h
index 908e447ea..567a183f1 100644
--- a/src/app/config-ui/mainwindow.h
+++ b/src/app/config-ui/mainwindow.h
@@ -39,6 +39,8 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
+#include <tools/settings.h>
+
#include <QtWidgets/qmainwindow.h>
namespace qbs { class SettingsModel; }
@@ -53,7 +55,8 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
- explicit MainWindow(const QString &settingsDir, QWidget *parent = nullptr);
+ explicit MainWindow(const QString &settingsDir, qbs::Settings::Scope scope,
+ QWidget *parent = nullptr);
~MainWindow();
bool eventFilter(QObject *watched, QEvent *event);
diff --git a/src/app/config/configcommandexecutor.cpp b/src/app/config/configcommandexecutor.cpp
index 365997043..1290ba2f0 100644
--- a/src/app/config/configcommandexecutor.cpp
+++ b/src/app/config/configcommandexecutor.cpp
@@ -52,8 +52,11 @@
using namespace qbs;
-ConfigCommandExecutor::ConfigCommandExecutor(Settings *settings) : m_settings(settings)
+ConfigCommandExecutor::ConfigCommandExecutor(Settings *settings, Settings::Scopes scope)
+ : m_settings(settings), m_scope(scope)
{
+ if (m_scope == qbs::Settings::SystemScope)
+ m_settings->setScopeForWriting(qbs::Settings::SystemScope);
}
void ConfigCommandExecutor::execute(const ConfigCommand &command)
@@ -94,15 +97,15 @@ void ConfigCommandExecutor::setValue(const QString &key, const QString &rawInput
void ConfigCommandExecutor::printSettings(const ConfigCommand &command)
{
if (command.varNames.empty()) {
- const auto keys = m_settings->allKeys();
+ const auto keys = m_settings->allKeys(m_scope);
for (const QString &key : keys)
printOneSetting(key);
} else {
for (const QString &parentKey : command.varNames) {
- if (m_settings->value(parentKey).isValid()) { // Key is a leaf.
+ if (m_settings->value(parentKey, m_scope).isValid()) { // Key is a leaf.
printOneSetting(parentKey);
} else { // Key is a node.
- const auto keys = m_settings->allKeysWithPrefix(parentKey);
+ const auto keys = m_settings->allKeysWithPrefix(parentKey, m_scope);
for (const QString &key : keys)
printOneSetting(parentKey + QLatin1Char('.') + key);
}
@@ -113,7 +116,7 @@ void ConfigCommandExecutor::printSettings(const ConfigCommand &command)
void ConfigCommandExecutor::printOneSetting(const QString &key)
{
printf("%s: %s\n", qPrintable(key),
- qPrintable(qbs::settingsValueToRepresentation(m_settings->value(key))));
+ qPrintable(qbs::settingsValueToRepresentation(m_settings->value(key, m_scope))));
}
void ConfigCommandExecutor::exportSettings(const QString &filename)
@@ -125,9 +128,10 @@ void ConfigCommandExecutor::exportSettings(const QString &filename)
}
QTextStream stream(&file);
stream.setCodec("UTF-8");
- const auto keys = m_settings->allKeys();
+ const auto keys = m_settings->allKeys(m_scope);
for (const QString &key : keys)
- stream << key << ": " << qbs::settingsValueToRepresentation(m_settings->value(key)) << endl;
+ stream << key << ": " << qbs::settingsValueToRepresentation(m_settings->value(key, m_scope))
+ << endl;
}
void ConfigCommandExecutor::importSettings(const QString &filename)
@@ -138,7 +142,7 @@ void ConfigCommandExecutor::importSettings(const QString &filename)
.arg(QDir::toNativeSeparators(filename), file.errorString()));
}
// Remove all current settings
- const auto keys = m_settings->allKeys();
+ const auto keys = m_settings->allKeys(m_scope);
for (const QString &key : keys)
m_settings->remove(key);
diff --git a/src/app/config/configcommandexecutor.h b/src/app/config/configcommandexecutor.h
index c0383a436..463818a73 100644
--- a/src/app/config/configcommandexecutor.h
+++ b/src/app/config/configcommandexecutor.h
@@ -39,9 +39,9 @@
#ifndef CONFIGCOMMANDEXECUTOR_H
#define CONFIGCOMMANDEXECUTOR_H
-#include <QtCore/qcoreapplication.h>
+#include <tools/settings.h>
-namespace qbs { class Settings; }
+#include <QtCore/qcoreapplication.h>
class ConfigCommand;
@@ -49,7 +49,7 @@ class ConfigCommandExecutor
{
Q_DECLARE_TR_FUNCTIONS(ConfigCommandExecutor)
public:
- ConfigCommandExecutor(qbs::Settings *settings);
+ ConfigCommandExecutor(qbs::Settings *settings, qbs::Settings::Scopes scope);
void execute(const ConfigCommand &command);
@@ -61,6 +61,7 @@ private:
void importSettings(const QString &filename);
qbs::Settings *m_settings;
+ const qbs::Settings::Scopes m_scope;
};
#endif // CONFIGCOMMANDEXECUTOR_H
diff --git a/src/app/config/configcommandlineparser.cpp b/src/app/config/configcommandlineparser.cpp
index 46a354939..2f2d1610e 100644
--- a/src/app/config/configcommandlineparser.cpp
+++ b/src/app/config/configcommandlineparser.cpp
@@ -54,7 +54,7 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine)
m_commandLine = commandLine;
if (m_commandLine.empty())
- throw ErrorInfo(Tr::tr("No parameters supplied."));
+ throw Error(Tr::tr("No parameters supplied."));
if (m_commandLine.size() == 1 && (m_commandLine.front() == QLatin1String("--help")
|| m_commandLine.front() == QLatin1String("-h"))) {
m_helpRequested = true;
@@ -73,16 +73,20 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine)
setCommand(ConfigCommand::CfgImport);
else if (arg == QLatin1String("settings-dir"))
assignOptionArgument(arg, m_settingsDir);
+ else if (arg == QLatin1String("user"))
+ setScope(qbs::Settings::UserScope);
+ else if (arg == QLatin1String("system"))
+ setScope(qbs::Settings::SystemScope);
else
- throw ErrorInfo(Tr::tr("Unknown option for config command."));
+ throw Error(Tr::tr("Unknown option for config command."));
}
switch (command().command) {
case ConfigCommand::CfgNone:
if (m_commandLine.empty())
- throw ErrorInfo(Tr::tr("No parameters supplied."));
+ throw Error(Tr::tr("No parameters supplied."));
if (m_commandLine.size() > 2)
- throw ErrorInfo(Tr::tr("Too many arguments."));
+ throw Error(Tr::tr("Too many arguments."));
m_command.varNames << m_commandLine.front();
if (m_commandLine.size() == 1) {
setCommand(ConfigCommand::CfgList);
@@ -93,17 +97,17 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine)
break;
case ConfigCommand::CfgUnset:
if (m_commandLine.empty())
- throw ErrorInfo(Tr::tr("Need name of variable to unset."));
+ throw Error(Tr::tr("Need name of variable to unset."));
m_command.varNames = m_commandLine;
break;
case ConfigCommand::CfgExport:
if (m_commandLine.size() != 1)
- throw ErrorInfo(Tr::tr("Need name of file to which to export."));
+ throw Error(Tr::tr("Need name of file to which to export."));
m_command.fileName = m_commandLine.front();
break;
case ConfigCommand::CfgImport:
if (m_commandLine.size() != 1)
- throw ErrorInfo(Tr::tr("Need name of file from which to import."));
+ throw Error(Tr::tr("Need name of file from which to import."));
m_command.fileName = m_commandLine.front();
break;
case ConfigCommand::CfgList:
@@ -117,10 +121,17 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine)
void ConfigCommandLineParser::setCommand(ConfigCommand::Command command)
{
if (m_command.command != ConfigCommand::CfgNone)
- throw ErrorInfo(Tr::tr("You cannot specify more than one command."));
+ throw Error(Tr::tr("You cannot specify more than one command."));
m_command.command = command;
}
+void ConfigCommandLineParser::setScope(Settings::Scope scope)
+{
+ if (m_scope != qbs::Settings::allScopes())
+ throw Error(Tr::tr("The --user and --system options can only appear once."));
+ m_scope = scope;
+}
+
void ConfigCommandLineParser::printUsage() const
{
puts("Usage:\n"
@@ -130,6 +141,8 @@ void ConfigCommandLineParser::printUsage() const
"\n"
"Options:\n"
" --list [<root> ...] list keys under key <root> or all keys\n"
+ " --user consider only user-level settings\n"
+ " --system consider only system-level settings\n"
" --unset <name> remove key with given name\n"
" --import <file> import settings from given file\n"
" --export <file> export settings to given file\n");
@@ -138,8 +151,8 @@ void ConfigCommandLineParser::printUsage() const
void ConfigCommandLineParser::assignOptionArgument(const QString &option, QString &argument)
{
if (m_commandLine.empty())
- throw ErrorInfo(Tr::tr("Option '%1' needs an argument.").arg(option));
+ throw Error(Tr::tr("Option '%1' needs an argument.").arg(option));
argument = m_commandLine.takeFirst();
if (argument.isEmpty())
- throw ErrorInfo(Tr::tr("Argument for option '%1' must not be empty.").arg(option));
+ throw Error(Tr::tr("Argument for option '%1' must not be empty.").arg(option));
}
diff --git a/src/app/config/configcommandlineparser.h b/src/app/config/configcommandlineparser.h
index 5427c9187..22f6906f9 100644
--- a/src/app/config/configcommandlineparser.h
+++ b/src/app/config/configcommandlineparser.h
@@ -41,6 +41,8 @@
#include "configcommand.h"
+#include <tools/settings.h>
+
#include <QtCore/qstringlist.h>
class ConfigCommandLineParser
@@ -50,15 +52,27 @@ public:
ConfigCommand command() const { return m_command; }
+ qbs::Settings::Scopes scope() const { return m_scope; }
QString settingsDir() const { return m_settingsDir; }
bool helpRequested() const { return m_helpRequested; }
void printUsage() const;
+ class Error
+ {
+ public:
+ Error(const QString &message) : m_message(message) { }
+ QString message() const { return m_message; }
+ private:
+ QString m_message;
+ };
+
private:
void assignOptionArgument(const QString &option, QString &argument);
void setCommand(ConfigCommand::Command command);
+ void setScope(qbs::Settings::Scope scope);
ConfigCommand m_command;
+ qbs::Settings::Scopes m_scope = qbs::Settings::allScopes();
bool m_helpRequested;
QString m_settingsDir;
QStringList m_commandLine;
diff --git a/src/app/config/configmain.cpp b/src/app/config/configmain.cpp
index f97369ce5..29cfaf9c6 100644
--- a/src/app/config/configmain.cpp
+++ b/src/app/config/configmain.cpp
@@ -64,10 +64,13 @@ int main(int argc, char *argv[])
return EXIT_SUCCESS;
}
Settings settings(parser.settingsDir());
- ConfigCommandExecutor(&settings).execute(parser.command());
+ ConfigCommandExecutor(&settings, parser.scope()).execute(parser.command());
+ } catch (const ConfigCommandLineParser::Error &e) {
+ std::cerr << qPrintable(e.message()) << std::endl;
+ parser.printUsage();
+ return EXIT_FAILURE;
} catch (const qbs::ErrorInfo &e) {
std::cerr << qPrintable(e.toString()) << std::endl;
- parser.printUsage();
return EXIT_FAILURE;
}
}
diff --git a/src/app/qbs-setup-qt/commandlineparser.cpp b/src/app/qbs-setup-qt/commandlineparser.cpp
index 2559e0c0b..8444faa77 100644
--- a/src/app/qbs-setup-qt/commandlineparser.cpp
+++ b/src/app/qbs-setup-qt/commandlineparser.cpp
@@ -49,6 +49,7 @@ static QString helpOptionShort() { return QLatin1String("-h"); }
static QString helpOptionLong() { return QLatin1String("--help"); }
static QString detectOption() { return QLatin1String("--detect"); }
static QString settingsDirOption() { return QLatin1String("--settings-dir"); }
+static QString systemOption() { return QLatin1String("--system"); }
void CommandLineParser::parse(const QStringList &commandLine)
{
@@ -73,6 +74,8 @@ void CommandLineParser::parse(const QStringList &commandLine)
m_helpRequested = true;
else if (arg == detectOption())
m_autoDetectionMode = true;
+ else if (arg == systemOption())
+ m_settingsScope = qbs::Settings::SystemScope;
else if (arg == settingsDirOption())
assignOptionArgument(settingsDirOption(), m_settingsDir);
}
@@ -107,10 +110,10 @@ QString CommandLineParser::usageString() const
{
QString s = Tr::tr("This tool creates qbs profiles from Qt versions.\n");
s += Tr::tr("Usage:\n");
- s += Tr::tr(" %1 [%2 <settings directory>] %3\n")
- .arg(m_command, settingsDirOption(), detectOption());
- s += Tr::tr(" %1 [%2 <settings directory>] <path to qmake> <profile name>\n")
- .arg(m_command, settingsDirOption());
+ s += Tr::tr(" %1 [%2 <settings directory>] [%4] %3\n")
+ .arg(m_command, settingsDirOption(), detectOption(), systemOption());
+ s += Tr::tr(" %1 [%2 <settings directory>] [%4] <path to qmake> <profile name>\n")
+ .arg(m_command, settingsDirOption(), systemOption());
s += Tr::tr(" %1 %2|%3\n").arg(m_command, helpOptionShort(), helpOptionLong());
s += Tr::tr("The first form tries to auto-detect all known Qt versions, looking them up "
"via the PATH environment variable.\n");
diff --git a/src/app/qbs-setup-qt/commandlineparser.h b/src/app/qbs-setup-qt/commandlineparser.h
index 8ac1ba44d..a9ecb55c8 100644
--- a/src/app/qbs-setup-qt/commandlineparser.h
+++ b/src/app/qbs-setup-qt/commandlineparser.h
@@ -39,6 +39,8 @@
#ifndef QBS_SETUPTOOLCHAINS_COMMANDLINEPARSER_H
#define QBS_SETUPTOOLCHAINS_COMMANDLINEPARSER_H
+#include <tools/settings.h>
+
#include <QtCore/qstringlist.h>
class CommandLineParser
@@ -52,6 +54,7 @@ public:
QString qmakePath() const { return m_qmakePath; }
QString profileName() const { return m_profileName; }
QString settingsDir() const { return m_settingsDir; }
+ qbs::Settings::Scope settingsScope() const { return m_settingsScope; }
QString usageString() const;
@@ -62,6 +65,7 @@ private:
bool m_helpRequested;
bool m_autoDetectionMode;
+ qbs::Settings::Scope m_settingsScope = qbs::Settings::UserScope;
QString m_qmakePath;
QString m_profileName;
QString m_settingsDir;
diff --git a/src/app/qbs-setup-qt/main.cpp b/src/app/qbs-setup-qt/main.cpp
index d0f78cce6..d1bfd9614 100644
--- a/src/app/qbs-setup-qt/main.cpp
+++ b/src/app/qbs-setup-qt/main.cpp
@@ -68,16 +68,17 @@ int main(int argc, char *argv[])
}
Settings settings(clParser.settingsDir());
+ settings.setScopeForWriting(clParser.settingsScope());
if (clParser.autoDetectionMode()) {
// search all Qt's in path and dump their settings
- const QList<QtEnvironment> qtEnvironments = SetupQt::fetchEnvironments();
+ const std::vector<EnhancedQtEnvironment> qtEnvironments = SetupQt::fetchEnvironments();
if (qtEnvironments.empty()) {
std::cout << qPrintable(Tr::tr("No Qt installations detected. "
"No profiles created."))
<< std::endl;
}
- for (const QtEnvironment &qtEnvironment : qtEnvironments) {
+ for (const EnhancedQtEnvironment &qtEnvironment : qtEnvironments) {
QString profileName = QLatin1String("qt-") + qtEnvironment.qtVersion;
if (SetupQt::checkIfMoreThanOneQtWithTheSameVersion(qtEnvironment.qtVersion, qtEnvironments)) {
QStringList prefixPathParts = qtEnvironment.installPrefixPath
@@ -96,7 +97,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- QtEnvironment qtEnvironment = SetupQt::fetchEnvironment(clParser.qmakePath());
+ EnhancedQtEnvironment qtEnvironment = SetupQt::fetchEnvironment(clParser.qmakePath());
QString profileName = clParser.profileName();
profileName.replace(QLatin1Char('.'), QLatin1Char('-'));
SetupQt::saveToQbsSettings(profileName, qtEnvironment, &settings);
diff --git a/src/app/qbs-setup-qt/setupqt.cpp b/src/app/qbs-setup-qt/setupqt.cpp
index 7f9d98d81..a611a8c07 100644
--- a/src/app/qbs-setup-qt/setupqt.cpp
+++ b/src/app/qbs-setup-qt/setupqt.cpp
@@ -40,6 +40,7 @@
#include "setupqt.h"
#include "../shared/logging/consolelogger.h"
+#include <qtmsvctools.h>
#include <qtprofilesetup.h>
#include <logging/translator.h>
#include <tools/architectures.h>
@@ -104,14 +105,14 @@ bool SetupQt::isQMakePathValid(const QString &qmakePath)
return qmakeFileInfo.exists() && qmakeFileInfo.isFile() && qmakeFileInfo.isExecutable();
}
-QList<QtEnvironment> SetupQt::fetchEnvironments()
+std::vector<EnhancedQtEnvironment> SetupQt::fetchEnvironments()
{
- QList<QtEnvironment> qtEnvironments;
+ std::vector<EnhancedQtEnvironment> qtEnvironments;
const auto qmakePaths = collectQmakePaths();
for (const QString &qmakePath : qmakePaths) {
- const QtEnvironment env = fetchEnvironment(qmakePath);
- if (none_of(qtEnvironments, [&env](const QtEnvironment &otherEnv) {
+ const EnhancedQtEnvironment env = fetchEnvironment(qmakePath);
+ if (none_of(qtEnvironments, [&env](const EnhancedQtEnvironment &otherEnv) {
return env.includePath == otherEnv.includePath;
})) {
qtEnvironments.push_back(env);
@@ -188,44 +189,9 @@ static QString pathQueryValue(const QueryMap &queryMap, const QByteArray &key)
return QDir::fromNativeSeparators(QString::fromLocal8Bit(queryMap.value(key)));
}
-static const QString msvcPrefix = QLatin1String("win32-msvc");
-
-static bool isMsvcQt(const QtEnvironment &env)
-{
- return env.mkspecName.startsWith(msvcPrefix);
-}
-
-static Version msvcCompilerVersionForYear(int year)
-{
- switch (year)
- {
- case 2005:
- return Version(14);
- case 2008:
- return Version(15);
- case 2010:
- return Version(16);
- case 2012:
- return Version(17);
- case 2013:
- return Version(18);
- case 2015:
- return Version(19);
- case 2017:
- return Version(19, 1);
- default:
- return Version();
- }
-}
-
-static Version msvcCompilerVersionFromMkspecName(const QString &mkspecName)
-{
- return msvcCompilerVersionForYear(mkspecName.mid(msvcPrefix.size()).toInt());
-}
-
-QtEnvironment SetupQt::fetchEnvironment(const QString &qmakePath)
+EnhancedQtEnvironment SetupQt::fetchEnvironment(const QString &qmakePath)
{
- QtEnvironment qtEnvironment;
+ EnhancedQtEnvironment qtEnvironment;
QueryMap queryOutput = qmakeQueryOutput(qmakePath);
qtEnvironment.installPrefixPath = pathQueryValue(queryOutput, "QT_INSTALL_PREFIX");
@@ -392,7 +358,7 @@ static QStringList qbsToolchainFromQtMkspec(const QString &mkspec)
enum Match { MatchFull, MatchPartial, MatchNone };
-static Match compatibility(const QtEnvironment &env, const Profile &toolchainProfile)
+static Match compatibility(const EnhancedQtEnvironment &env, const Profile &toolchainProfile)
{
Match match = MatchFull;
@@ -464,7 +430,8 @@ static void compressMsvcProfiles(QStringList &profiles)
profiles.erase(it, profiles.end());
}
-void SetupQt::saveToQbsSettings(const QString &qtVersionName, const QtEnvironment &qtEnvironment,
+void SetupQt::saveToQbsSettings(const QString &qtVersionName,
+ const EnhancedQtEnvironment &qtEnvironment,
Settings *settings)
{
const QString cleanQtVersionName = Profile::cleanName(qtVersionName);
@@ -537,7 +504,7 @@ void SetupQt::saveToQbsSettings(const QString &qtVersionName, const QtEnvironmen
}
bool SetupQt::checkIfMoreThanOneQtWithTheSameVersion(const QString &qtVersion,
- const QList<QtEnvironment> &qtEnvironments)
+ const std::vector<EnhancedQtEnvironment> &qtEnvironments)
{
bool foundOneVersion = false;
for (const QtEnvironment &qtEnvironment : qtEnvironments) {
diff --git a/src/app/qbs-setup-qt/setupqt.h b/src/app/qbs-setup-qt/setupqt.h
index f5ac44c9c..73c0afefe 100644
--- a/src/app/qbs-setup-qt/setupqt.h
+++ b/src/app/qbs-setup-qt/setupqt.h
@@ -40,12 +40,22 @@
#ifndef QBS_SETUPQT_H
#define QBS_SETUPQT_H
+#include <qtenvironment.h>
#include <tools/error.h>
+
#include <QtCore/qcoreapplication.h>
#include <QtCore/qstringlist.h>
+#include <vector>
+
namespace qbs {
-class QtEnvironment;
+
+class EnhancedQtEnvironment : public QtEnvironment
+{
+public:
+ Version msvcVersion;
+};
+
class Settings;
class SetupQt
@@ -53,13 +63,14 @@ class SetupQt
Q_DECLARE_TR_FUNCTIONS(SetupQt)
public:
static bool isQMakePathValid(const QString &qmakePath);
- static QList<QtEnvironment> fetchEnvironments();
+ static std::vector<EnhancedQtEnvironment> fetchEnvironments();
static void addQtBuildVariant(QtEnvironment *env, const QString &buildVariantName);
- static QtEnvironment fetchEnvironment(const QString &qmakePath);
- static void saveToQbsSettings(const QString &qtVersionName, const QtEnvironment & qtEnvironment,
+ static EnhancedQtEnvironment fetchEnvironment(const QString &qmakePath);
+ static void saveToQbsSettings(const QString &qtVersionName,
+ const EnhancedQtEnvironment &qtEnvironment,
Settings *settings);
static bool checkIfMoreThanOneQtWithTheSameVersion(const QString &qtVersion,
- const QList<QtEnvironment> &qtEnvironments);
+ const std::vector<EnhancedQtEnvironment> &qtEnvironments);
};
} // namespace qbs
diff --git a/src/app/qbs-setup-toolchains/commandlineparser.cpp b/src/app/qbs-setup-toolchains/commandlineparser.cpp
index 00e605f3f..fd2e0214f 100644
--- a/src/app/qbs-setup-toolchains/commandlineparser.cpp
+++ b/src/app/qbs-setup-toolchains/commandlineparser.cpp
@@ -50,6 +50,7 @@ static QString helpOptionLong() { return QLatin1String("--help"); }
static QString detectOption() { return QLatin1String("--detect"); }
static QString typeOption() { return QLatin1String("--type"); }
static QString settingsDirOption() { return QLatin1String("--settings-dir"); }
+static QString systemOption() { return QLatin1String("--system"); }
void CommandLineParser::parse(const QStringList &commandLine)
{
@@ -75,6 +76,8 @@ void CommandLineParser::parse(const QStringList &commandLine)
m_helpRequested = true;
else if (arg == detectOption())
m_autoDetectionMode = true;
+ else if (arg == systemOption())
+ m_settingsScope = qbs::Settings::SystemScope;
else if (arg == typeOption())
assignOptionArgument(typeOption(), m_toolchainType);
else if (arg == settingsDirOption())
@@ -111,11 +114,11 @@ QString CommandLineParser::usageString() const
{
QString s = Tr::tr("This tool creates qbs profiles from toolchains.\n");
s += Tr::tr("Usage:\n");
- s += Tr::tr(" %1 [%2 <settings directory>] %3\n")
- .arg(m_command, settingsDirOption(), detectOption());
- s += Tr::tr(" %1 [%3 <settings directory>] [%2 <toolchain type>] "
+ s += Tr::tr(" %1 [%2 <settings directory>] [%4] %3\n")
+ .arg(m_command, settingsDirOption(), detectOption(), systemOption());
+ s += Tr::tr(" %1 [%3 <settings directory>] [%4] [%2 <toolchain type>] "
"<compiler path> <profile name>\n")
- .arg(m_command, typeOption(), settingsDirOption());
+ .arg(m_command, typeOption(), settingsDirOption(), systemOption());
s += Tr::tr(" %1 %2|%3\n").arg(m_command, helpOptionShort(), helpOptionLong());
s += Tr::tr("The first form tries to auto-detect all known toolchains, looking them up "
"via the PATH environment variable.\n");
diff --git a/src/app/qbs-setup-toolchains/commandlineparser.h b/src/app/qbs-setup-toolchains/commandlineparser.h
index 94a7a6283..cb0949bf1 100644
--- a/src/app/qbs-setup-toolchains/commandlineparser.h
+++ b/src/app/qbs-setup-toolchains/commandlineparser.h
@@ -39,6 +39,8 @@
#ifndef QBS_SETUPTOOLCHAINS_COMMANDLINEPARSER_H
#define QBS_SETUPTOOLCHAINS_COMMANDLINEPARSER_H
+#include <tools/settings.h>
+
#include <QtCore/qstringlist.h>
class CommandLineParser
@@ -53,6 +55,7 @@ public:
QString toolchainType() const { return m_toolchainType; }
QString profileName() const { return m_profileName; }
QString settingsDir() const { return m_settingsDir; }
+ qbs::Settings::Scope settingsScope() const { return m_settingsScope; }
QString usageString() const;
@@ -63,6 +66,7 @@ private:
bool m_helpRequested;
bool m_autoDetectionMode;
+ qbs::Settings::Scope m_settingsScope = qbs::Settings::UserScope;
QString m_compilerPath;
QString m_toolchainType;
QString m_profileName;
diff --git a/src/app/qbs-setup-toolchains/main.cpp b/src/app/qbs-setup-toolchains/main.cpp
index 546ae3adb..87a2a842a 100644
--- a/src/app/qbs-setup-toolchains/main.cpp
+++ b/src/app/qbs-setup-toolchains/main.cpp
@@ -69,6 +69,7 @@ int main(int argc, char **argv)
return EXIT_SUCCESS;
}
Settings settings(clParser.settingsDir());
+ settings.setScopeForWriting(clParser.settingsScope());
if (clParser.autoDetectionMode()) {
probe(&settings);
return EXIT_SUCCESS;
diff --git a/src/app/qbs-setup-toolchains/msvcprobe.cpp b/src/app/qbs-setup-toolchains/msvcprobe.cpp
index 294523c1c..919f88d12 100644
--- a/src/app/qbs-setup-toolchains/msvcprobe.cpp
+++ b/src/app/qbs-setup-toolchains/msvcprobe.cpp
@@ -103,6 +103,10 @@ struct MSVCArchInfo
static std::vector<MSVCArchInfo> findSupportedArchitectures(const MSVC &msvc)
{
std::vector<MSVCArchInfo> result;
+ auto addResult = [&result](const MSVCArchInfo &ai) {
+ if (QFile::exists(ai.binPath + QLatin1String("/cl.exe")))
+ result.push_back(ai);
+ };
if (msvc.internalVsVersion.majorVersion() < 15) {
static const QStringList knownArchitectures = QStringList()
<< QStringLiteral("x86")
@@ -117,8 +121,7 @@ static std::vector<MSVCArchInfo> findSupportedArchitectures(const MSVC &msvc)
MSVCArchInfo ai;
ai.arch = knownArchitecture;
ai.binPath = msvc.binPathForArchitecture(knownArchitecture);
- if (QFile::exists(ai.binPath + QLatin1String("/cl.exe")))
- result.push_back(ai);
+ addResult(ai);
}
} else {
QDir vcInstallDir(msvc.vcInstallPath);
@@ -136,7 +139,7 @@ static std::vector<MSVCArchInfo> findSupportedArchitectures(const MSVC &msvc)
ai.arch = arch;
else
ai.arch = shortHostArch + QLatin1Char('_') + arch;
- result.push_back(ai);
+ addResult(ai);
}
}
}
diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs
index 900fde759..fd25d30e0 100644
--- a/src/lib/corelib/corelib.qbs
+++ b/src/lib/corelib/corelib.qbs
@@ -25,10 +25,13 @@ QbsLibrary {
qbsbuildconfig.enableProjectFileUpdates ? ["QBS_ENABLE_PROJECT_FILE_UPDATES"] : []
property stringList enableUnitTestsDefines:
qbsbuildconfig.enableUnitTests ? ["QBS_ENABLE_UNIT_TESTS"] : []
+ property stringList systemSettingsDirDefines: qbsbuildconfig.systemSettingsDir
+ ? ['QBS_SYSTEM_SETTINGS_DIR="' + qbsbuildconfig.systemSettingsDir + '"'] : []
cpp.defines: base.concat([
"QBS_RELATIVE_LIBEXEC_PATH=" + Utilities.cStringQuote(qbsbuildconfig.relativeLibexecPath),
"QBS_VERSION=" + Utilities.cStringQuote(version),
]).concat(projectFileUpdateDefines).concat(enableUnitTestsDefines)
+ .concat(systemSettingsDirDefines)
Properties {
condition: qbs.targetOS.contains("windows")
diff --git a/src/lib/corelib/tools/preferences.cpp b/src/lib/corelib/tools/preferences.cpp
index da7639c40..66803a0f5 100644
--- a/src/lib/corelib/tools/preferences.cpp
+++ b/src/lib/corelib/tools/preferences.cpp
@@ -41,7 +41,6 @@
#include "buildoptions.h"
#include "hostosinfo.h"
#include "profile.h"
-#include "settings.h"
#include "stringconstants.h"
namespace qbs {
@@ -129,23 +128,30 @@ QVariant Preferences::getPreference(const QString &key, const QVariant &defaultV
{
static const QString keyPrefix = QLatin1String("preferences");
const QString fullKey = keyPrefix + QLatin1Char('.') + key;
+ const bool isSearchPaths = key == Internal::StringConstants::qbsSearchPathsProperty();
if (!m_profile.isEmpty()) {
QVariant value = Profile(m_profile, m_settings).value(fullKey);
if (value.isValid()) {
- if (key == Internal::StringConstants::qbsSearchPathsProperty()) // Merge with top-level value.
- value = value.toStringList() + m_settings->value(fullKey).toStringList();
+ if (isSearchPaths) { // Merge with top-level value.
+ value = value.toStringList() + m_settings->value(
+ fullKey, scopesForSearchPaths()).toStringList();
+ }
return value;
}
}
QVariant value = m_profileContents.value(keyPrefix).toMap().value(key);
if (value.isValid()) {
- if (key == Internal::StringConstants::qbsSearchPathsProperty()) // Merge with top-level value
- value = value.toStringList() + m_settings->value(fullKey).toStringList();
+ if (isSearchPaths) {// Merge with top-level value
+ value = value.toStringList() + m_settings->value(
+ fullKey, scopesForSearchPaths()).toStringList();
+ }
return value;
}
- return m_settings->value(fullKey, defaultValue);
+ return m_settings->value(fullKey,
+ isSearchPaths ? scopesForSearchPaths() : Settings::allScopes(),
+ defaultValue);
}
QStringList Preferences::pathList(const QString &key, const QString &defaultValue) const
@@ -155,4 +161,14 @@ QStringList Preferences::pathList(const QString &key, const QString &defaultValu
return paths;
}
+bool Preferences::ignoreSystemSearchPaths() const
+{
+ return getPreference(QStringLiteral("ignoreSystemSearchPaths")).toBool();
+}
+
+Settings::Scopes Preferences::scopesForSearchPaths() const
+{
+ return ignoreSystemSearchPaths() ? Settings::UserScope : Settings::allScopes();
+}
+
} // namespace qbs
diff --git a/src/lib/corelib/tools/preferences.h b/src/lib/corelib/tools/preferences.h
index 98468b78c..07f0edcd7 100644
--- a/src/lib/corelib/tools/preferences.h
+++ b/src/lib/corelib/tools/preferences.h
@@ -42,6 +42,7 @@
#include "qbs_export.h"
#include "commandechomode.h"
+#include "settings.h"
#include <QtCore/qstringlist.h>
#include <QtCore/qvariant.h>
@@ -67,6 +68,9 @@ private:
QVariant getPreference(const QString &key, const QVariant &defaultValue = QVariant()) const;
QStringList pathList(const QString &key, const QString &defaultValue) const;
+ bool ignoreSystemSearchPaths() const;
+ Settings::Scopes scopesForSearchPaths() const;
+
Settings *m_settings;
QString m_profile;
QVariantMap m_profileContents;
diff --git a/src/lib/corelib/tools/profile.cpp b/src/lib/corelib/tools/profile.cpp
index c6ec1b9e7..3ace77d4d 100644
--- a/src/lib/corelib/tools/profile.cpp
+++ b/src/lib/corelib/tools/profile.cpp
@@ -75,7 +75,7 @@ Profile::Profile(const QString &name, Settings *settings, const QVariantMap &pro
bool Profile::exists() const
{
return m_name == fallbackName() || !m_values.empty()
- || !m_settings->allKeysWithPrefix(profileKey()).empty();
+ || !m_settings->allKeysWithPrefix(profileKey(), Settings::allScopes()).empty();
}
/*!
@@ -200,7 +200,7 @@ QVariant Profile::localValue(const QString &key) const
{
QVariant val = m_values.value(key);
if (!val.isValid())
- val = m_settings->value(fullyQualifiedKey(key));
+ val = m_settings->value(fullyQualifiedKey(key), Settings::allScopes());
return val;
}
@@ -230,7 +230,7 @@ QStringList Profile::allKeysInternal(Profile::KeySelection selection,
extendAndCheckProfileChain(profileChain);
QStringList keys = m_values.keys();
if (keys.empty())
- keys = m_settings->allKeysWithPrefix(profileKey());
+ keys = m_settings->allKeysWithPrefix(profileKey(), Settings::allScopes());
if (selection == KeySelectionNonRecursive)
return keys;
const QString baseProfileName = baseProfile();
diff --git a/src/lib/corelib/tools/settings.cpp b/src/lib/corelib/tools/settings.cpp
index 44f127993..189c96a6a 100644
--- a/src/lib/corelib/tools/settings.cpp
+++ b/src/lib/corelib/tools/settings.cpp
@@ -44,6 +44,7 @@
#include "settingscreator.h"
#include <logging/translator.h>
+#include <tools/hostosinfo.h>
#include <tools/stringconstants.h>
#include <QtCore/qsettings.h>
@@ -53,8 +54,46 @@
namespace qbs {
using namespace Internal;
-Settings::Settings(const QString &baseDir)
- : m_settings(SettingsCreator(baseDir).getQSettings()), m_baseDir(baseDir)
+static QString defaultSystemSettingsBaseDir()
+{
+ switch (HostOsInfo::hostOs()) {
+ case HostOsInfo::HostOsWindows: {
+ const char key[] = "ALLUSERSAPPDATA";
+ if (qEnvironmentVariableIsSet(key))
+ return QLatin1String(key);
+ return QStringLiteral("C:/ProgramData");
+ }
+ case HostOsInfo::HostOsMacos:
+ return QStringLiteral("/Library/Application Support");
+ case HostOsInfo::HostOsLinux:
+ case HostOsInfo::HostOsOtherUnix:
+ return QStringLiteral("/etc/xdg");
+ default:
+ return QString();
+ }
+}
+
+static QString systemSettingsBaseDir()
+{
+#ifdef QBS_ENABLE_UNIT_TESTS
+ const char key[] = "QBS_AUTOTEST_SYSTEM_SETTINGS_DIR";
+ if (qEnvironmentVariableIsSet(key))
+ return QLatin1String(qgetenv(key));
+#endif
+#ifdef QBS_SYSTEM_SETTINGS_DIR
+ return QLatin1String(QBS_SYSTEM_SETTINGS_DIR);
+#else
+ return defaultSystemSettingsBaseDir() + QStringLiteral("/qbs");
+#endif
+}
+
+Settings::Settings(const QString &baseDir) : Settings(baseDir, systemSettingsBaseDir()) { }
+
+Settings::Settings(const QString &baseDir, const QString &systemBaseDir)
+ : m_settings(SettingsCreator(baseDir).getQSettings()),
+ m_systemSettings(new QSettings(systemBaseDir + QStringLiteral("/qbs.conf"),
+ QSettings::IniFormat)),
+ m_baseDir(baseDir)
{
// Actual qbs settings are stored transparently within a group, because QSettings
// can see non-qbs fallback settings e.g. from QtProject that we're not interested in.
@@ -64,35 +103,66 @@ Settings::Settings(const QString &baseDir)
Settings::~Settings()
{
delete m_settings;
+ delete m_systemSettings;
}
-QVariant Settings::value(const QString &key, const QVariant &defaultValue) const
+QVariant Settings::value(const QString &key, Scopes scopes, const QVariant &defaultValue) const
{
- return m_settings->value(internalRepresentation(key), defaultValue);
+ QVariant userValue;
+ if (scopes & UserScope)
+ userValue = m_settings->value(internalRepresentation(key));
+ QVariant systemValue;
+ if (scopes & SystemScope)
+ systemValue = m_systemSettings->value(internalRepresentation(key));
+ if (!userValue.isValid()) {
+ if (systemValue.isValid())
+ return systemValue;
+ return defaultValue;
+ }
+ if (!systemValue.isValid())
+ return userValue;
+ if (static_cast<QMetaType::Type>(userValue.type()) == QMetaType::QStringList)
+ return userValue.toStringList() + systemValue.toStringList();
+ if (static_cast<QMetaType::Type>(userValue.type()) == QMetaType::QVariantList)
+ return userValue.toList() + systemValue.toList();
+ return userValue;
}
-QStringList Settings::allKeys() const
+QStringList Settings::allKeys(Scopes scopes) const
{
- QStringList keys = m_settings->allKeys();
+ QStringList keys;
+ if (scopes & UserScope)
+ keys = m_settings->allKeys();
+ if (scopes & SystemScope)
+ keys += m_systemSettings->allKeys();
fixupKeys(keys);
return keys;
}
-QStringList Settings::directChildren(const QString &parentGroup)
+QStringList Settings::directChildren(const QString &parentGroup, Scope scope) const
{
- m_settings->beginGroup(internalRepresentation(parentGroup));
- QStringList children = m_settings->childGroups();
- children << m_settings->childKeys();
- m_settings->endGroup();
+ QSettings * const settings = settingsForScope(scope);
+ settings->beginGroup(internalRepresentation(parentGroup));
+ QStringList children = settings->childGroups();
+ children << settings->childKeys();
+ settings->endGroup();
fixupKeys(children);
return children;
}
-QStringList Settings::allKeysWithPrefix(const QString &group) const
+QStringList Settings::allKeysWithPrefix(const QString &group, Scopes scopes) const
{
- m_settings->beginGroup(internalRepresentation(group));
- QStringList keys = m_settings->allKeys();
- m_settings->endGroup();
+ QStringList keys;
+ if (scopes & UserScope) {
+ m_settings->beginGroup(internalRepresentation(group));
+ keys = m_settings->allKeys();
+ m_settings->endGroup();
+ }
+ if (scopes & SystemScope) {
+ m_systemSettings->beginGroup(internalRepresentation(group));
+ keys += m_systemSettings->allKeys();
+ m_systemSettings->endGroup();
+ }
fixupKeys(keys);
return keys;
}
@@ -103,40 +173,50 @@ void Settings::setValue(const QString &key, const QVariant &value)
throw ErrorInfo(Tr::tr("Invalid use of special profile name '%1'.")
.arg(Profile::fallbackName()));
}
- m_settings->setValue(internalRepresentation(key), value);
+ targetForWriting()->setValue(internalRepresentation(key), value);
+ checkForWriteError();
}
void Settings::remove(const QString &key)
{
- m_settings->remove(internalRepresentation(key));
+ targetForWriting()->remove(internalRepresentation(key));
+ checkForWriteError();
}
void Settings::clear()
{
- m_settings->clear();
+ targetForWriting()->clear();
+ checkForWriteError();
}
void Settings::sync()
{
- m_settings->sync();
+ targetForWriting()->sync();
}
QString Settings::defaultProfile() const
{
- return value(QLatin1String("defaultProfile")).toString();
+ return value(QLatin1String("defaultProfile"), allScopes()).toString();
}
QStringList Settings::profiles() const
{
- m_settings->beginGroup(StringConstants::profilesSettingsKey());
- QStringList result = m_settings->childGroups();
- m_settings->endGroup();
+ QStringList result;
+ if (m_scopeForWriting == UserScope) {
+ m_settings->beginGroup(StringConstants::profilesSettingsKey());
+ result = m_settings->childGroups();
+ m_settings->endGroup();
+ }
+ m_systemSettings->beginGroup(StringConstants::profilesSettingsKey());
+ result += m_systemSettings->childGroups();
+ m_systemSettings->endGroup();
+ result.removeDuplicates();
return result;
}
QString Settings::fileName() const
{
- return m_settings->fileName();
+ return targetForWriting()->fileName();
}
QString Settings::internalRepresentation(const QString &externalKey) const
@@ -159,4 +239,25 @@ void Settings::fixupKeys(QStringList &keys) const
key = externalRepresentation(key);
}
+QSettings *Settings::settingsForScope(Settings::Scope scope) const
+{
+ return scope == UserScope ? m_settings : m_systemSettings;
+}
+
+QSettings *Settings::targetForWriting() const
+{
+ return settingsForScope(m_scopeForWriting);
+}
+
+void Settings::checkForWriteError()
+{
+ if (m_scopeForWriting == SystemScope && m_systemSettings->status() == QSettings::NoError) {
+ sync();
+ if (m_systemSettings->status() == QSettings::AccessError)
+ throw ErrorInfo(Tr::tr("Failure writing system settings file '%1': "
+ "You do not have permission to write to that location.")
+ .arg(fileName()));
+ }
+}
+
} // namespace qbs
diff --git a/src/lib/corelib/tools/settings.h b/src/lib/corelib/tools/settings.h
index cd6e664a3..d0676a072 100644
--- a/src/lib/corelib/tools/settings.h
+++ b/src/lib/corelib/tools/settings.h
@@ -57,18 +57,27 @@ class QBS_EXPORT Settings
public:
// The "pure" base directory without any version scope. Empty string means "system default".
Settings(const QString &baseDir);
+ Settings(const QString &baseDir, const QString &systemBaseDir);
~Settings();
- QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
- QStringList allKeys() const;
- QStringList directChildren(const QString &parentGroup); // Keys and groups.
- QStringList allKeysWithPrefix(const QString &group) const;
+ enum Scope { UserScope = 0x1, SystemScope = 0x2 };
+ Q_DECLARE_FLAGS(Scopes, Scope)
+ static Scopes allScopes() { return Scopes{UserScope, SystemScope}; }
+
+ QVariant value(const QString &key, Scopes scopes,
+ const QVariant &defaultValue = QVariant()) const;
+ QStringList allKeys(Scopes scopes) const;
+ QStringList directChildren(const QString &parentGroup, Scope scope) const; // Keys and groups.
+ QStringList allKeysWithPrefix(const QString &group, Scopes scopes) const;
void setValue(const QString &key, const QVariant &value);
void remove(const QString &key);
void clear();
void sync();
+ void setScopeForWriting(Scope scope) { m_scopeForWriting = scope; }
+ Scope scopeForWriting() const { return m_scopeForWriting; }
+
QString defaultProfile() const;
QStringList profiles() const;
@@ -79,11 +88,18 @@ private:
QString internalRepresentation(const QString &externalKey) const;
QString externalRepresentation(const QString &internalKey) const;
void fixupKeys(QStringList &keys) const;
+ QSettings *settingsForScope(Scope scope) const;
+ QSettings *targetForWriting() const;
+ void checkForWriteError();
QSettings * const m_settings;
+ QSettings * const m_systemSettings;
const QString m_baseDir;
+ Scope m_scopeForWriting = UserScope;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(Settings::Scopes)
+
} // namespace qbs
#endif // QBS_SETTINGS_H
diff --git a/src/lib/corelib/tools/settingsmodel.cpp b/src/lib/corelib/tools/settingsmodel.cpp
index 4defb46b9..e908bfe08 100644
--- a/src/lib/corelib/tools/settingsmodel.cpp
+++ b/src/lib/corelib/tools/settingsmodel.cpp
@@ -113,6 +113,8 @@ public:
void doSave(const Node *node, const QString &prefix);
Node *indexToNode(const QModelIndex &index);
+ Settings::Scope scope() const { return settings->scopeForWriting(); }
+
Node rootNode;
std::unique_ptr<qbs::Settings> settings;
QVariantMap additionalProperties;
@@ -120,10 +122,11 @@ public:
bool editable;
};
-SettingsModel::SettingsModel(const QString &settingsDir, QObject *parent)
+SettingsModel::SettingsModel(const QString &settingsDir, Settings::Scope scope, QObject *parent)
: QAbstractItemModel(parent), d(new SettingsModelPrivate)
{
d->settings.reset(new qbs::Settings(settingsDir));
+ d->settings->setScopeForWriting(scope);
d->readSettings();
}
@@ -150,8 +153,10 @@ void SettingsModel::save()
void SettingsModel::updateSettingsDir(const QString &settingsDir)
{
+ const Settings::Scope scope = d->scope();
beginResetModel();
d->settings.reset(new qbs::Settings(settingsDir));
+ d->settings->setScopeForWriting(scope);
d->readSettings();
endResetModel();
}
@@ -322,7 +327,7 @@ void SettingsModel::SettingsModelPrivate::readSettings()
{
qDeleteAll(rootNode.children);
rootNode.children.clear();
- for (const QString &topLevelKey : settings->directChildren(QString()))
+ for (const QString &topLevelKey : settings->directChildren(QString(), scope()))
addNodeFromSettings(&rootNode, topLevelKey);
for (QVariantMap::ConstIterator it = additionalProperties.constBegin();
it != additionalProperties.constEnd(); ++it) {
@@ -347,8 +352,8 @@ void SettingsModel::SettingsModelPrivate::addNodeFromSettings(Node *parentNode,
const QString &nodeName
= fullyQualifiedName.mid(fullyQualifiedName.lastIndexOf(QLatin1Char('.')) + 1);
Node * const node = createNode(parentNode, nodeName);
- node->value = settingsValueToRepresentation(settings->value(fullyQualifiedName));
- for (const QString &childKey : settings->directChildren(fullyQualifiedName))
+ node->value = settingsValueToRepresentation(settings->value(fullyQualifiedName, scope()));
+ for (const QString &childKey : settings->directChildren(fullyQualifiedName, scope()))
addNodeFromSettings(node, fullyQualifiedName + QLatin1Char('.') + childKey);
dirty = true;
}
diff --git a/src/lib/corelib/tools/settingsmodel.h b/src/lib/corelib/tools/settingsmodel.h
index adcc2a826..6f9631585 100644
--- a/src/lib/corelib/tools/settingsmodel.h
+++ b/src/lib/corelib/tools/settingsmodel.h
@@ -41,6 +41,7 @@
#define QBS_SETTINGSMODEL_H
#include <tools/qbs_export.h>
+#include <tools/settings.h>
#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qvariant.h>
@@ -51,7 +52,7 @@ class QBS_EXPORT SettingsModel : public QAbstractItemModel
{
Q_OBJECT
public:
- SettingsModel(const QString &settingsDir, QObject *parent = nullptr);
+ SettingsModel(const QString &settingsDir, Settings::Scope scope, QObject *parent = nullptr);
~SettingsModel();
int keyColumn() const { return 0; }
diff --git a/src/lib/corelib/tools/tools.pri b/src/lib/corelib/tools/tools.pri
index b6dbebc86..9db30664f 100644
--- a/src/lib/corelib/tools/tools.pri
+++ b/src/lib/corelib/tools/tools.pri
@@ -2,6 +2,11 @@ include(../../../install_prefix.pri)
INCLUDEPATH += $$PWD/../.. # for plugins
+QBS_SYSTEM_SETTINGS_DIR = $$(QBS_SYSTEM_SETTINGS_DIR)
+!isEmpty(QBS_SYSTEM_SETTINGS_DIR) {
+ DEFINES += QBS_SYSTEM_SETTINGS_DIR=\\\"$$QBS_SYSTEM_SETTINGS_DIR\\\"
+}
+
HEADERS += \
$$PWD/architectures.h \
$$PWD/buildgraphlocker.h \
diff --git a/src/lib/qtprofilesetup/qtenvironment.h b/src/lib/qtprofilesetup/qtenvironment.h
index 0b6ab8e51..4fb5a03ee 100644
--- a/src/lib/qtprofilesetup/qtenvironment.h
+++ b/src/lib/qtprofilesetup/qtenvironment.h
@@ -78,7 +78,6 @@ public:
int qtMajorVersion;
int qtMinorVersion;
int qtPatchVersion;
- Version msvcVersion;
bool staticBuild = false;
bool frameworkBuild = false;
};
diff --git a/src/lib/qtprofilesetup/qtmsvctools.cpp b/src/lib/qtprofilesetup/qtmsvctools.cpp
new file mode 100644
index 000000000..0c41b928c
--- /dev/null
+++ b/src/lib/qtprofilesetup/qtmsvctools.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtmsvctools.h"
+
+namespace qbs {
+
+static const QString msvcPrefix = QLatin1String("win32-msvc");
+
+bool isMsvcQt(const QtEnvironment &env)
+{
+ return env.mkspecName.startsWith(msvcPrefix);
+}
+
+static Version msvcCompilerVersionForYear(int year)
+{
+ switch (year)
+ {
+ case 2005:
+ return Version(14);
+ case 2008:
+ return Version(15);
+ case 2010:
+ return Version(16);
+ case 2012:
+ return Version(17);
+ case 2013:
+ return Version(18);
+ case 2015:
+ return Version(19);
+ case 2017:
+ return Version(19, 1);
+ default:
+ return Version();
+ }
+}
+
+Version msvcCompilerVersionFromMkspecName(const QString &mkspecName)
+{
+ return msvcCompilerVersionForYear(mkspecName.mid(msvcPrefix.size()).toInt());
+}
+
+} // namespace qbs
diff --git a/src/lib/qtprofilesetup/qtmsvctools.h b/src/lib/qtprofilesetup/qtmsvctools.h
new file mode 100644
index 000000000..195d0e0ec
--- /dev/null
+++ b/src/lib/qtprofilesetup/qtmsvctools.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtenvironment.h"
+#include <tools/qbs_export.h>
+#include <tools/version.h>
+
+namespace qbs {
+
+QBS_EXPORT bool isMsvcQt(const QtEnvironment &env);
+QBS_EXPORT Version msvcCompilerVersionFromMkspecName(const QString &mkspecName);
+
+} // namespace qbs
diff --git a/src/lib/qtprofilesetup/qtprofilesetup.cpp b/src/lib/qtprofilesetup/qtprofilesetup.cpp
index 4ef952985..6d82d50ad 100644
--- a/src/lib/qtprofilesetup/qtprofilesetup.cpp
+++ b/src/lib/qtprofilesetup/qtprofilesetup.cpp
@@ -40,6 +40,7 @@
#include "qtprofilesetup.h"
#include "qtmoduleinfo.h"
+#include "qtmsvctools.h"
#include <logging/translator.h>
#include <tools/architectures.h>
@@ -420,7 +421,7 @@ static QByteArray libraryFileTag(const QtEnvironment &env, const QtModuleInfo &m
if (module.isStaticLibrary)
result = "staticlibrary";
else
- result = env.msvcVersion.isValid() ? "dynamiclibrary_import" : "dynamiclibrary";
+ result = isMsvcQt(env) ? "dynamiclibrary_import" : "dynamiclibrary";
return result;
}
@@ -581,7 +582,8 @@ static void createModules(Profile &profile, Settings *settings,
? allQt4Modules(qtEnvironment)
: allQt5Modules(profile, qtEnvironment);
const QString profileBaseDir = QString::fromLatin1("%1/profiles/%2")
- .arg(QFileInfo(settings->fileName()).dir().absolutePath(), profile.name());
+ .arg(QFileInfo(settings->fileName()).dir().absolutePath(),
+ profile.name());
const QString qbsQtModuleBaseDir = profileBaseDir + QLatin1String("/modules/Qt");
QStringList allFiles;
copyTemplateFile(QLatin1String("QtModule.qbs"), qbsQtModuleBaseDir, profile, qtEnvironment,
diff --git a/src/lib/qtprofilesetup/qtprofilesetup.pro b/src/lib/qtprofilesetup/qtprofilesetup.pro
index cc89001b1..a6284727a 100644
--- a/src/lib/qtprofilesetup/qtprofilesetup.pro
+++ b/src/lib/qtprofilesetup/qtprofilesetup.pro
@@ -5,16 +5,21 @@ include(../corelib/use_corelib.pri)
HEADERS = \
qtenvironment.h \
qtmoduleinfo.h \
+ qtmsvctools.h \
qtprofilesetup.h
SOURCES = \
qtmoduleinfo.cpp \
+ qtmsvctools.cpp \
qtprofilesetup.cpp
RESOURCES = templates.qrc
!qbs_no_dev_install {
- header.files = qtenvironment.h qtprofilesetup.h
+ header.files = \
+ qtenvironment.h \
+ qtmsvctools.h \
+ qtprofilesetup.h
header.path = $${QBS_INSTALL_PREFIX}/include/qbs
use_pri.files = use_installed_qtprofilesetup.pri
use_pri.path = $${header.path}
diff --git a/src/lib/qtprofilesetup/qtprofilesetup.qbs b/src/lib/qtprofilesetup/qtprofilesetup.qbs
index 7f739e10f..8c8b77020 100644
--- a/src/lib/qtprofilesetup/qtprofilesetup.qbs
+++ b/src/lib/qtprofilesetup/qtprofilesetup.qbs
@@ -9,6 +9,7 @@ QbsLibrary {
files: [
"qtenvironment.h",
"qtprofilesetup.h",
+ "qtmsvctools.h",
"use_installed_qtprofilesetup.pri",
]
qbs.install: qbsbuildconfig.installApiHeaders
@@ -19,6 +20,7 @@ QbsLibrary {
"qtprofilesetup.cpp",
"qtmoduleinfo.cpp",
"qtmoduleinfo.h",
+ "qtmsvctools.cpp",
"templates.qrc",
"templates/*"
]
diff --git a/src/plugins/scanner/cpp/cppscanner.cpp b/src/plugins/scanner/cpp/cppscanner.cpp
index 7e5cbe146..1d7fb7c84 100644
--- a/src/plugins/scanner/cpp/cppscanner.cpp
+++ b/src/plugins/scanner/cpp/cppscanner.cpp
@@ -248,6 +248,16 @@ static void *openScanner(const unsigned short *filePath, const char *fileTags, i
return nullptr;
opaque->fileContent = reinterpret_cast<char *>(vmap);
+
+ // Check for UTF-8 Byte Order Mark (BOM). Skip if found.
+ if (mapl >= 3
+ && opaque->fileContent[0] == char(0xef)
+ && opaque->fileContent[1] == char(0xbb)
+ && opaque->fileContent[2] == char(0xbf)) {
+ opaque->fileContent += 3;
+ mapl -= 3;
+ }
+
CPlusPlus::Lexer lex(opaque->fileContent, opaque->fileContent + mapl);
scanCppFile(opaque.get(), lex, flags & ScanForFileTagsFlag, flags & ScanForDependenciesFlag);
return opaque.release();
diff --git a/tests/auto/blackbox/blackbox.pro b/tests/auto/blackbox/blackbox.pro
index 5e58e0e19..42848d077 100644
--- a/tests/auto/blackbox/blackbox.pro
+++ b/tests/auto/blackbox/blackbox.pro
@@ -4,6 +4,7 @@ HEADERS = tst_blackbox.h tst_blackboxbase.h
SOURCES = tst_blackbox.cpp tst_blackboxbase.cpp
OBJECTS_DIR = generic
MOC_DIR = $${OBJECTS_DIR}-moc
+qbs_enable_unit_tests:DEFINES += QBS_ENABLE_UNIT_TESTS
include(../auto.pri)
diff --git a/tests/auto/blackbox/blackbox.qbs b/tests/auto/blackbox/blackbox.qbs
index 55c116480..917e8345b 100644
--- a/tests/auto/blackbox/blackbox.qbs
+++ b/tests/auto/blackbox/blackbox.qbs
@@ -25,4 +25,5 @@ QbsAutotest {
"tst_blackbox.h",
]
cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
+ .concat(qbsbuildconfig.enableUnitTests ? ["QBS_ENABLE_UNIT_TESTS"] : [])
}
diff --git a/tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs b/tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs
new file mode 100644
index 000000000..8b5dbb238
--- /dev/null
+++ b/tests/auto/blackbox/testdata/bom-sources/bom-sources.qbs
@@ -0,0 +1,6 @@
+import qbs
+
+CppApplication {
+ name: "app"
+ files: ["main.cpp", "theheader.h"]
+}
diff --git a/tests/auto/blackbox/testdata/bom-sources/main.cpp b/tests/auto/blackbox/testdata/bom-sources/main.cpp
new file mode 100644
index 000000000..de10a65a2
--- /dev/null
+++ b/tests/auto/blackbox/testdata/bom-sources/main.cpp
@@ -0,0 +1,3 @@
+#include "theheader.h"
+
+int main() {}
diff --git a/tests/auto/blackbox/testdata/bom-sources/theheader.h b/tests/auto/blackbox/testdata/bom-sources/theheader.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/auto/blackbox/testdata/bom-sources/theheader.h
diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/main.c b/tests/auto/blackbox/testdata/maximum-c-language-version/main.c
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/tests/auto/blackbox/testdata/maximum-c-language-version/main.c
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs
new file mode 100644
index 000000000..2ac47b66a
--- /dev/null
+++ b/tests/auto/blackbox/testdata/maximum-c-language-version/maximum-c-language-version.qbs
@@ -0,0 +1,22 @@
+import qbs
+
+CppApplication {
+ name: "app"
+ property bool enableNewestModule: true
+
+ Probe {
+ id: osProbe
+ property stringList toolchain: qbs.toolchain
+ configure: {
+ if (toolchain.contains("msvc"))
+ console.info("is msvc");
+ found = true;
+ }
+ }
+
+ Depends { name: "oldmodule" }
+ Depends { name: "newermodule" }
+ Depends { name: "newestmodule"; condition: enableNewestModule }
+
+ files: "main.c"
+}
diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs
new file mode 100644
index 000000000..4dd343b3b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newermodule/newermodule.qbs
@@ -0,0 +1,6 @@
+import qbs
+
+Module {
+ Depends { name: "cpp" }
+ cpp.cLanguageVersion: "c99"
+}
diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs
new file mode 100644
index 000000000..f8316a35e
--- /dev/null
+++ b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/newestmodule/newestmodule.qbs
@@ -0,0 +1,6 @@
+import qbs
+
+Module {
+ Depends { name: "cpp" }
+ cpp.cLanguageVersion: "c11"
+}
diff --git a/tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs
new file mode 100644
index 000000000..a753b3e3e
--- /dev/null
+++ b/tests/auto/blackbox/testdata/maximum-c-language-version/modules/oldmodule/oldmodule.qbs
@@ -0,0 +1,6 @@
+import qbs
+
+Module {
+ Depends { name: "cpp" }
+ cpp.cLanguageVersion: "c90"
+}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index ef945f8f4..3c03c6b3e 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -33,6 +33,7 @@
#include <api/languageinfo.h>
#include <tools/hostosinfo.h>
#include <tools/installoptions.h>
+#include <tools/preferences.h>
#include <tools/profile.h>
#include <tools/qttools.h>
#include <tools/shellutils.h>
@@ -4664,6 +4665,94 @@ void TestBlackbox::pseudoMultiplexing()
QCOMPARE(runQbs(), 0);
}
+void TestBlackbox::qbsConfig()
+{
+ QbsRunParameters params("config");
+#ifdef QBS_ENABLE_UNIT_TESTS
+ QTemporaryDir tempSystemSettingsDir;
+ params.environment.insert("QBS_AUTOTEST_SYSTEM_SETTINGS_DIR", tempSystemSettingsDir.path());
+ QTemporaryDir tempUserSettingsDir;
+ QVERIFY(tempSystemSettingsDir.isValid());
+ QVERIFY(tempUserSettingsDir.isValid());
+ const QStringList settingsDirArgs = QStringList{"--settings-dir", tempUserSettingsDir.path()};
+
+ // Set values.
+ params.arguments = settingsDirArgs + QStringList{"--system", "key.subkey.scalar", "s"};
+ QCOMPARE(runQbs(params), 0);
+ params.arguments = settingsDirArgs + QStringList{"--system", "key.subkey.list", "['sl']"};
+ QCOMPARE(runQbs(params), 0);
+ params.arguments = settingsDirArgs + QStringList{"--user", "key.subkey.scalar", "u"};
+ QCOMPARE(runQbs(params), 0);
+ params.arguments = settingsDirArgs + QStringList{"key.subkey.list", "[\"u1\",\"u2\"]"};
+ QCOMPARE(runQbs(params), 0);
+
+ // Check outputs.
+ const auto valueExtractor = [this] {
+ const QByteArray trimmed = m_qbsStdout.trimmed();
+ return trimmed.mid(trimmed.lastIndexOf(':') + 2);
+ };
+ params.arguments = settingsDirArgs + QStringList{"--list", "key.subkey.scalar"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("\"u\""));
+ params.arguments = settingsDirArgs + QStringList{"--list", "--user", "key.subkey.scalar"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("\"u\""));
+ params.arguments = settingsDirArgs + QStringList{"--list", "--system", "key.subkey.scalar"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("\"s\""));
+ params.arguments = settingsDirArgs + QStringList{"--list", "key.subkey.list"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("[\"u1\", \"u2\", \"sl\"]"));
+ params.arguments = settingsDirArgs + QStringList{"--list", "--user", "key.subkey.list"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("[\"u1\", \"u2\"]"));
+ params.arguments = settingsDirArgs + QStringList{"--list", "--system", "key.subkey.list"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("[\"sl\"]"));
+
+ // Remove some values and re-check.
+ params.arguments = settingsDirArgs + QStringList{"--unset", "key.subkey.scalar"};
+ QCOMPARE(runQbs(params), 0);
+ params.arguments = settingsDirArgs + QStringList{"--system", "--unset", "key.subkey.list"};
+ QCOMPARE(runQbs(params), 0);
+ params.arguments = settingsDirArgs + QStringList{"--list", "key.subkey.scalar"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("\"s\""));
+ params.arguments = settingsDirArgs + QStringList{"--list", "key.subkey.list"};
+ QCOMPARE(runQbs(params), 0);
+ QCOMPARE(valueExtractor(), QByteArray("[\"u1\", \"u2\"]"));
+
+ // Check preferences.ignoreSystemSearchPaths
+ params.arguments = settingsDirArgs
+ + QStringList{"--system", "preferences.qbsSearchPaths", "['/usr/lib/qbs']"};
+ QCOMPARE(runQbs(params), 0);
+ params.arguments = settingsDirArgs
+ + QStringList{"preferences.qbsSearchPaths", "['/home/user/qbs']"};
+ QCOMPARE(runQbs(params), 0);
+ qbs::Settings settings(tempUserSettingsDir.path(), tempSystemSettingsDir.path());
+ const qbs::Preferences prefs(&settings, "SomeProfile");
+ QVERIFY2(prefs.searchPaths().contains("/usr/lib/qbs")
+ && prefs.searchPaths().contains("/home/user/qbs"),
+ qPrintable(prefs.searchPaths().join(',')));
+ settings.setValue("profiles.SomeProfile.preferences.ignoreSystemSearchPaths", true);
+ QVERIFY2(!prefs.searchPaths().contains("/usr/lib/qbs")
+ && prefs.searchPaths().contains("/home/user/qbs"),
+ qPrintable(prefs.searchPaths().join(',')));
+
+#else
+ qDebug() << "ability to redirect the system settings dir not compiled in, skipping"
+ "most qbs-config tests";
+#endif // QBS_ENABLE_UNIT_TESTS
+
+ // Check that trying to write to actual system settings causes access failure.
+ params.expectFailure = true;
+ params.environment.clear();
+ params.arguments = QStringList{"--system", "key.subkey.scalar", "s"};
+ QVERIFY(runQbs(params) != 0);
+ QVERIFY2(m_qbsStderr.contains("You do not have permission to write to that location."),
+ m_qbsStderr.constData());
+}
+
void TestBlackbox::radAfterIncompleteBuild_data()
{
QTest::addColumn<QString>("projectFileName");
@@ -5672,6 +5761,21 @@ void TestBlackbox::makefileGenerator()
QVERIFY(!QFile::exists(relativeExecutableFilePath("the app")));
}
+void TestBlackbox::maximumCLanguageVersion()
+{
+ QDir::setCurrent(testDataDir + "/maximum-c-language-version");
+ QCOMPARE(runQbs(QbsRunParameters("resolve",
+ QStringList("products.app.enableNewestModule:true"))), 0);
+ if (m_qbsStdout.contains("is msvc"))
+ QSKIP("MSVC has no support for setting the C language version.");
+ QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line", "-n"})), 0);
+ QVERIFY2(m_qbsStdout.contains("c11") || m_qbsStdout.contains("c1x"), m_qbsStdout.constData());
+ QCOMPARE(runQbs(QbsRunParameters("resolve",
+ QStringList("products.app.enableNewestModule:false"))), 0);
+ QCOMPARE(runQbs(QStringList({"--command-echo-mode", "command-line", "-n"})), 0);
+ QVERIFY2(m_qbsStdout.contains("c99"), m_qbsStdout.constData());
+}
+
void TestBlackbox::maximumCxxLanguageVersion()
{
QDir::setCurrent(testDataDir + "/maximum-cxx-language-version");
@@ -5926,6 +6030,21 @@ void TestBlackbox::badInterpreter()
QCOMPARE(runQbs(QbsRunParameters("run", QStringList() << "-p" << "script-ok")), 0);
}
+void TestBlackbox::bomSources()
+{
+ QDir::setCurrent(testDataDir + "/bom-sources");
+ const bool success = runQbs() == 0;
+ if (!success)
+ QSKIP("Assuming compiler cannot deal with byte order mark");
+ QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ WAIT_FOR_NEW_TIMESTAMP();
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(!m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+ touch("theheader.h");
+ QCOMPARE(runQbs(), 0);
+ QVERIFY2(m_qbsStdout.contains("compiling main.cpp"), m_qbsStdout.constData());
+}
+
void TestBlackbox::buildDataOfDisabledProduct()
{
QDir::setCurrent(testDataDir + QLatin1String("/build-data-of-disabled-product"));
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index c5dcdea8f..af95e12a6 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -52,6 +52,7 @@ private slots:
void autotests();
void auxiliaryInputsFromDependencies();
void badInterpreter();
+ void bomSources();
void buildDataOfDisabledProduct();
void buildDirectories();
void buildEnvChange();
@@ -162,6 +163,7 @@ private slots:
void loadableModule();
void localDeployment();
void makefileGenerator();
+ void maximumCLanguageVersion();
void maximumCxxLanguageVersion();
void minimumSystemVersion();
void minimumSystemVersion_data();
@@ -208,6 +210,7 @@ private slots:
void properQuoting();
void propertiesInExportItems();
void pseudoMultiplexing();
+ void qbsConfig();
void qbsVersion();
void qtBug51237();
void radAfterIncompleteBuild();
diff --git a/tests/auto/tools/tst_tools.cpp b/tests/auto/tools/tst_tools.cpp
index cf94553ba..0073f9e68 100644
--- a/tests/auto/tools/tst_tools.cpp
+++ b/tests/auto/tools/tst_tools.cpp
@@ -300,11 +300,11 @@ void TestTools::testSettingsMigration()
if (hasOldSettings) {
QVERIFY(QFileInfo(settings.baseDirectory() + "/qbs/" QBS_VERSION "/profiles/right.txt")
.exists());
- QCOMPARE(settings.value("key").toString(),
+ QCOMPARE(settings.value("key", Settings::UserScope).toString(),
settings.baseDirectory() + "/qbs/" QBS_VERSION "/profilesright");
} else {
QVERIFY(!QFileInfo(settings.baseDirectory() + "/qbs/" QBS_VERSION "/profiles").exists());
- QVERIFY(settings.allKeys().empty());
+ QVERIFY(settings.allKeys(Settings::UserScope).empty());
}
}