summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@petroules.com>2013-11-20 17:09:41 -0500
committerJake Petroules <jake.petroules@petroules.com>2013-11-26 16:13:35 +0100
commitdbb39fc1fce3686a5161d68e89e96086fc664556 (patch)
tree7651a5a1e885805eaec99105abcaf61bd865667f
parentd7656eef2decad018759cae7f18c4e66c3a688bf (diff)
downloadqbs-dbb39fc1fce3686a5161d68e89e96086fc664556.tar.gz
Support specifying the Qbs build directory as a command line option.
Also supports changing the default build directory ('.') using the 'preferences.defaultBuildDirectory' property. Task-number: QBS-462 Change-Id: Id3d05d2f5b14197bd3af2e7f9d55bdd263809716 Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
-rw-r--r--src/app/qbs/commandlinefrontend.cpp2
-rw-r--r--src/app/qbs/parser/command.cpp4
-rw-r--r--src/app/qbs/parser/commandlineoption.cpp33
-rw-r--r--src/app/qbs/parser/commandlineoption.h17
-rw-r--r--src/app/qbs/parser/commandlineoptionpool.cpp8
-rw-r--r--src/app/qbs/parser/commandlineoptionpool.h1
-rw-r--r--src/app/qbs/parser/commandlineparser.cpp29
-rw-r--r--src/app/qbs/parser/commandlineparser.h1
-rw-r--r--src/lib/tools/preferences.cpp8
-rw-r--r--src/lib/tools/preferences.h1
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp44
-rw-r--r--tests/auto/blackbox/tst_blackbox.h7
12 files changed, 136 insertions, 19 deletions
diff --git a/src/app/qbs/commandlinefrontend.cpp b/src/app/qbs/commandlinefrontend.cpp
index a2264c497..2cbd087d0 100644
--- a/src/app/qbs/commandlinefrontend.cpp
+++ b/src/app/qbs/commandlinefrontend.cpp
@@ -121,7 +121,7 @@ void CommandLineFrontend::start()
+ QLatin1String("/../"));
SetupProjectParameters params;
params.setProjectFilePath(m_parser.projectFilePath());
- params.setBuildRoot(QDir::currentPath());
+ params.setBuildRoot(m_parser.projectBuildDirectory());
params.setSearchPaths(Preferences(m_settings).searchPaths(qbsRootPath));
params.setPluginPaths(Preferences(m_settings).pluginPaths(qbsRootPath));
params.setIgnoreDifferentProjectFilePath(m_parser.force());
diff --git a/src/app/qbs/parser/command.cpp b/src/app/qbs/parser/command.cpp
index c9f24a36a..f20eedf35 100644
--- a/src/app/qbs/parser/command.cpp
+++ b/src/app/qbs/parser/command.cpp
@@ -169,6 +169,7 @@ static QList<CommandLineOption::Type> resolveOptions()
{
return QList<CommandLineOption::Type>()
<< CommandLineOption::FileOptionType
+ << CommandLineOption::BuildDirectoryOptionType
<< CommandLineOption::LogLevelOptionType
<< CommandLineOption::VerboseOptionType
<< CommandLineOption::QuietOptionType
@@ -345,6 +346,7 @@ QList<CommandLineOption::Type> ShellCommand::supportedOptions() const
{
return QList<CommandLineOption::Type>()
<< CommandLineOption::FileOptionType
+ << CommandLineOption::BuildDirectoryOptionType
<< CommandLineOption::LogLevelOptionType
<< CommandLineOption::VerboseOptionType
<< CommandLineOption::QuietOptionType
@@ -375,6 +377,7 @@ QList<CommandLineOption::Type> StatusCommand::supportedOptions() const
{
return QList<CommandLineOption::Type>()
<< CommandLineOption::FileOptionType
+ << CommandLineOption::BuildDirectoryOptionType
<< CommandLineOption::LogLevelOptionType
<< CommandLineOption::VerboseOptionType
<< CommandLineOption::QuietOptionType
@@ -408,6 +411,7 @@ QList<CommandLineOption::Type> UpdateTimestampsCommand::supportedOptions() const
{
return QList<CommandLineOption::Type>()
<< CommandLineOption::FileOptionType
+ << CommandLineOption::BuildDirectoryOptionType
<< CommandLineOption::LogLevelOptionType
<< CommandLineOption::VerboseOptionType
<< CommandLineOption::QuietOptionType
diff --git a/src/app/qbs/parser/commandlineoption.cpp b/src/app/qbs/parser/commandlineoption.cpp
index c9d21c405..21fe05b41 100644
--- a/src/app/qbs/parser/commandlineoption.cpp
+++ b/src/app/qbs/parser/commandlineoption.cpp
@@ -81,6 +81,39 @@ void FileOption::doParse(const QString &representation, QStringList &input)
m_projectFilePath = getArgument(representation, input);
}
+QString BuildDirectoryOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1|%2 <directory>\n"
+ "\tBuild in the given directory. The default value is the current directory\n"
+ "\tunless preferences.defaultBuildDirectory is set.\n"
+ "\tRelative paths will be interpreted relative to the current directory.\n"
+ "\tIf the directory does not exist, it will be created. Use the special\n"
+ "\tvalue '%3' as a placeholder for the name of the directory\n"
+ "\tcontaining the project file.\n")
+ .arg(longRepresentation(), shortRepresentation(), magicProjectString());
+}
+
+QString BuildDirectoryOption::shortRepresentation() const
+{
+ return QLatin1String("-d");
+}
+
+QString BuildDirectoryOption::longRepresentation() const
+{
+ return QLatin1String("--build-directory");
+}
+
+QString BuildDirectoryOption::magicProjectString()
+{
+ return QLatin1String("@project");
+}
+
+void BuildDirectoryOption::doParse(const QString &representation, QStringList &input)
+{
+ m_projectBuildDirectory = getArgument(representation, input);
+}
+
static QString loglevelLongRepresentation() { return QLatin1String("--log-level"); }
QString VerboseOption::description(CommandType command) const
diff --git a/src/app/qbs/parser/commandlineoption.h b/src/app/qbs/parser/commandlineoption.h
index 8457ef4cb..585128d7a 100644
--- a/src/app/qbs/parser/commandlineoption.h
+++ b/src/app/qbs/parser/commandlineoption.h
@@ -40,6 +40,7 @@ class CommandLineOption
public:
enum Type {
FileOptionType,
+ BuildDirectoryOptionType,
LogLevelOptionType, VerboseOptionType, QuietOptionType,
JobsOptionType,
KeepGoingOptionType,
@@ -87,6 +88,22 @@ private:
QString m_projectFilePath;
};
+class BuildDirectoryOption : public CommandLineOption
+{
+public:
+ QString projectBuildDirectory() const { return m_projectBuildDirectory; }
+ static QString magicProjectString();
+
+private:
+ QString description(CommandType command) const;
+ QString shortRepresentation() const;
+ QString longRepresentation() const;
+ void doParse(const QString &representation, QStringList &input);
+
+private:
+ QString m_projectBuildDirectory;
+};
+
class CountingOption : public CommandLineOption
{
public:
diff --git a/src/app/qbs/parser/commandlineoptionpool.cpp b/src/app/qbs/parser/commandlineoptionpool.cpp
index a7a0d7ab7..d675700d8 100644
--- a/src/app/qbs/parser/commandlineoptionpool.cpp
+++ b/src/app/qbs/parser/commandlineoptionpool.cpp
@@ -43,6 +43,9 @@ CommandLineOption *CommandLineOptionPool::getOption(CommandLineOption::Type type
case CommandLineOption::FileOptionType:
option = new FileOption;
break;
+ case CommandLineOption::BuildDirectoryOptionType:
+ option = new BuildDirectoryOption;
+ break;
case CommandLineOption::LogLevelOptionType:
option = new LogLevelOption;
break;
@@ -101,6 +104,11 @@ FileOption *CommandLineOptionPool::fileOption() const
return static_cast<FileOption *>(getOption(CommandLineOption::FileOptionType));
}
+BuildDirectoryOption *CommandLineOptionPool::buildDirectoryOption() const
+{
+ return static_cast<BuildDirectoryOption *>(getOption(CommandLineOption::BuildDirectoryOptionType));
+}
+
LogLevelOption *CommandLineOptionPool::logLevelOption() const
{
return static_cast<LogLevelOption *>(getOption(CommandLineOption::LogLevelOptionType));
diff --git a/src/app/qbs/parser/commandlineoptionpool.h b/src/app/qbs/parser/commandlineoptionpool.h
index 46c36a9d9..ccb5b0421 100644
--- a/src/app/qbs/parser/commandlineoptionpool.h
+++ b/src/app/qbs/parser/commandlineoptionpool.h
@@ -42,6 +42,7 @@ public:
CommandLineOption *getOption(CommandLineOption::Type type) const;
FileOption *fileOption() const;
+ BuildDirectoryOption *buildDirectoryOption() const;
LogLevelOption *logLevelOption() const;
VerboseOption *verboseOption() const;
QuietOption *quietOption() const;
diff --git a/src/app/qbs/parser/commandlineparser.cpp b/src/app/qbs/parser/commandlineparser.cpp
index 40c0fa3e2..46d1e6173 100644
--- a/src/app/qbs/parser/commandlineparser.cpp
+++ b/src/app/qbs/parser/commandlineparser.cpp
@@ -69,6 +69,7 @@ public:
QString generalHelp() const;
void setupProjectFile();
+ void setupBuildDirectory();
void setupProgress();
void setupLogLevel();
void setupBuildOptions();
@@ -81,6 +82,7 @@ public:
Settings *settings;
Command *command;
QString projectFilePath;
+ QString projectBuildDirectory;
BuildOptions buildOptions;
CommandLineOptionPool optionPool;
CommandPool commandPool;
@@ -129,6 +131,11 @@ QString CommandLineParser::projectFilePath() const
return d->projectFilePath;
}
+QString CommandLineParser::projectBuildDirectory() const
+{
+ return d->projectBuildDirectory;
+}
+
BuildOptions CommandLineParser::buildOptions() const
{
return d->buildOptions;
@@ -351,6 +358,7 @@ void CommandLineParser::CommandLineParserPrivate::doParse()
return;
setupProjectFile();
+ setupBuildDirectory();
setupProgress();
setupLogLevel();
setupBuildOptions();
@@ -464,6 +472,27 @@ void CommandLineParser::CommandLineParserPrivate::setupProjectFile()
qbsDebug() << "Using project file '" << QDir::toNativeSeparators(projectFilePath) << "'.";
}
+void CommandLineParser::CommandLineParserPrivate::setupBuildDirectory()
+{
+ projectBuildDirectory = optionPool.buildDirectoryOption()->projectBuildDirectory();
+ if (projectBuildDirectory.isEmpty()) {
+ projectBuildDirectory = Preferences(settings).defaultBuildDirectory();
+ if (projectBuildDirectory.isEmpty()) {
+ qbsDebug() << "No project build directory given; using current directory.";
+ projectBuildDirectory = QDir::currentPath();
+ } else {
+ qbsDebug() << "No project build directory given; using directory from preferences.";
+ }
+ }
+
+ QDir dir(QFileInfo(projectFilePath).path());
+ projectBuildDirectory.replace(optionPool.buildDirectoryOption()->magicProjectString(),
+ dir.dirName());
+
+ if (!QFileInfo(projectBuildDirectory).isAbsolute())
+ projectBuildDirectory = QDir::currentPath() + QLatin1Char('/') + projectBuildDirectory;
+}
+
void CommandLineParser::CommandLineParserPrivate::setupBuildOptions()
{
buildOptions.setDryRun(dryRun());
diff --git a/src/app/qbs/parser/commandlineparser.h b/src/app/qbs/parser/commandlineparser.h
index 16994437c..e6a0dded7 100644
--- a/src/app/qbs/parser/commandlineparser.h
+++ b/src/app/qbs/parser/commandlineparser.h
@@ -54,6 +54,7 @@ public:
QString commandName() const;
QString commandDescription() const;
QString projectFilePath() const;
+ QString projectBuildDirectory() const;
BuildOptions buildOptions() const;
CleanOptions cleanOptions() const;
InstallOptions installOptions() const;
diff --git a/src/lib/tools/preferences.cpp b/src/lib/tools/preferences.cpp
index f8ed01740..18552807f 100644
--- a/src/lib/tools/preferences.cpp
+++ b/src/lib/tools/preferences.cpp
@@ -72,6 +72,14 @@ QString Preferences::shell() const
}
/*!
+ * \brief Returns the default build directory used by Qbs if none is specified.
+ */
+QString Preferences::defaultBuildDirectory() const
+{
+ return getPreference(QLatin1String("defaultBuildDirectory")).toString();
+}
+
+/*!
* \brief Returns the list of paths where qbs looks for module definitions and such.
* If there is no such setting, \c qbsRootPath will be used to look up a fallback location.
*/
diff --git a/src/lib/tools/preferences.h b/src/lib/tools/preferences.h
index d79ee8aa5..1d6f9dbad 100644
--- a/src/lib/tools/preferences.h
+++ b/src/lib/tools/preferences.h
@@ -45,6 +45,7 @@ public:
bool useColoredOutput() const;
int jobs() const;
QString shell() const;
+ QString defaultBuildDirectory() const;
QStringList searchPaths(const QString &qbsRootPath = QString()) const;
QStringList pluginPaths(const QString &qbsRootPath = QString()) const;
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index cc817242c..503ae8560 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -71,7 +71,15 @@ TestBlackbox::TestBlackbox()
int TestBlackbox::runQbs(const QbsRunParameters &params)
{
- QStringList args = params.arguments;
+ QStringList args;
+ args << params.command;
+ if ((QStringList() << QLatin1String("") << QLatin1String("build") << QLatin1String("clean")
+ << QLatin1String("install") << QLatin1String("resolve") << QLatin1String("run")
+ << QLatin1String("shell") << QLatin1String("status") << QLatin1String("update-timestamps"))
+ .contains(params.command)) {
+ args.append(QStringList(QLatin1String("-d")) << QLatin1String("."));
+ }
+ args << params.arguments;
if (params.useProfile)
args.append(QLatin1String("profile:") + buildProfileName);
QString cmdLine = qbsExecutableFilePath;
@@ -272,7 +280,7 @@ void TestBlackbox::build_project_dry_run()
QDir::setCurrent(testDataDir + projectSubDir);
rmDirR(buildDir);
- QCOMPARE(runQbs(QbsRunParameters("-n")), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QStringList("-n"))), 0);
const QStringList &buildDirContents
= QDir(buildDir).entryList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
QVERIFY2(buildDirContents.isEmpty(), qPrintable(buildDirContents.join(" ")));
@@ -358,7 +366,7 @@ void TestBlackbox::resolve_project_dry_run()
QDir::setCurrent(testDataDir + projectSubDir);
rmDirR(buildDir);
- QCOMPARE(runQbs(QbsRunParameters(QStringList("resolve") << "-n")), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("resolve"), QStringList("-n"))), 0);
QVERIFY2(!QFile::exists(productFileName), qPrintable(productFileName));
QVERIFY2(!QFile::exists(buildGraphPath), qPrintable(buildGraphPath));
}
@@ -388,7 +396,7 @@ void TestBlackbox::clean()
QCOMPARE(runQbs(), 0);
QVERIFY(QFile(appObjectFilePath).exists());
QVERIFY(QFile(appExeFilePath).exists());
- QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts")), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), QStringList("--all-artifacts"))), 0);
QVERIFY(!QFile(appObjectFilePath).exists());
QVERIFY(!QFile(appExeFilePath).exists());
QVERIFY(!QFile(depObjectFilePath).exists());
@@ -398,7 +406,8 @@ void TestBlackbox::clean()
QCOMPARE(runQbs(), 0);
QVERIFY(QFile(appObjectFilePath).exists());
QVERIFY(QFile(appExeFilePath).exists());
- QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts" << "-n")), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"),
+ QStringList("--all-artifacts") << "-n")), 0);
QVERIFY(QFile(appObjectFilePath).exists());
QVERIFY(QFile(appExeFilePath).exists());
QVERIFY(QFile(depObjectFilePath).exists());
@@ -410,7 +419,8 @@ void TestBlackbox::clean()
QVERIFY(QFile(appExeFilePath).exists());
QVERIFY(QFile(depObjectFilePath).exists());
QVERIFY(QFile(depExeFilePath).exists());
- QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts" << "-p" << "dep")),
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"),
+ QStringList("--all-artifacts") << "-p" << "dep")),
0);
QVERIFY(QFile(appObjectFilePath).exists());
QVERIFY(QFile(appExeFilePath).exists());
@@ -423,7 +433,8 @@ void TestBlackbox::clean()
QVERIFY(QFile(appExeFilePath).exists());
QVERIFY(QFile(depObjectFilePath).exists());
QVERIFY(QFile(depExeFilePath).exists());
- QCOMPARE(runQbs(QbsRunParameters(QStringList("clean") << "--all-artifacts" << "-p" << "app")),
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"),
+ QStringList("--all-artifacts") << "-p" << "app")),
0);
QVERIFY(!QFile(appObjectFilePath).exists());
QVERIFY(!QFile(appExeFilePath).exists());
@@ -929,7 +940,7 @@ void TestBlackbox::wildcardRenaming()
QCOMPARE(runQbs(QbsRunParameters("install")), 0);
QVERIFY(QFileInfo(defaultInstallRoot + "/pioniere.txt").exists());
QFile::rename(QDir::currentPath() + "/pioniere.txt", QDir::currentPath() + "/fdj.txt");
- QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--remove-first")), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--remove-first"))), 0);
QVERIFY(!QFileInfo(defaultInstallRoot + "/pioniere.txt").exists());
QVERIFY(QFileInfo(defaultInstallRoot + "/fdj.txt").exists());
}
@@ -942,7 +953,7 @@ void TestBlackbox::recursiveRenaming()
QVERIFY(QFileInfo(defaultInstallRoot + "/dir/subdir/blubb.txt").exists());
waitForNewTimestamp();
QVERIFY(QFile::rename(QDir::currentPath() + "/dir/wasser.txt", QDir::currentPath() + "/dir/wein.txt"));
- QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--remove-first")), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--remove-first"))), 0);
QVERIFY(!QFileInfo(defaultInstallRoot + "/dir/wasser.txt").exists());
QVERIFY(QFileInfo(defaultInstallRoot + "/dir/wein.txt").exists());
QVERIFY(QFileInfo(defaultInstallRoot + "/dir/subdir/blubb.txt").exists());
@@ -1420,7 +1431,7 @@ void TestBlackbox::properQuoting()
{
QDir::setCurrent(testDataDir + "/proper quoting");
QCOMPARE(runQbs(), 0);
- QbsRunParameters params(QStringList() << "run" << "-qp" << "Hello World");
+ QbsRunParameters params(QLatin1String("run"), QStringList() << "-q" << "-p" << "Hello World");
params.expectFailure = true; // Because the exit code is non-zero.
QCOMPARE(runQbs(params), 156);
const char * const expectedOutput = "whitespaceless\ncontains space\ncontains\ttab\n"
@@ -1442,7 +1453,7 @@ void TestBlackbox::installedApp()
QVERIFY(QFile::exists(defaultInstallRoot
+ HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/bin/installedApp"))));
- QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--install-root"
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--install-root")
<< (testDataDir + "/installed-app"))), 0);
QVERIFY(QFile::exists(testDataDir
+ HostOsInfo::appendExecutableSuffix("/installed-app/usr/bin/installedApp")));
@@ -1451,7 +1462,7 @@ void TestBlackbox::installedApp()
QVERIFY(addedFile.open(QIODevice::WriteOnly));
addedFile.close();
QVERIFY(addedFile.exists());
- QCOMPARE(runQbs(QbsRunParameters(QStringList("install") << "--remove-first")), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--remove-first"))), 0);
QVERIFY(QFile::exists(defaultInstallRoot
+ HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/bin/installedApp"))));
QVERIFY(!addedFile.exists());
@@ -1465,7 +1476,7 @@ void TestBlackbox::installedApp()
projectFile.resize(0);
projectFile.write(content);
QVERIFY(projectFile.flush());
- QCOMPARE(runQbs(QbsRunParameters(QStringList("install"))), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"))), 0);
QVERIFY(QFile::exists(defaultInstallRoot
+ HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/local/bin/installedApp"))));
@@ -1475,13 +1486,14 @@ void TestBlackbox::installedApp()
projectFile.resize(0);
projectFile.write(content);
projectFile.close();
- QCOMPARE(runQbs(QbsRunParameters(QStringList("install"))), 0);
+ QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"))), 0);
QVERIFY(QFile::exists(defaultInstallRoot
+ HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/local/custom/installedApp"))));
rmDirR(buildDir);
QbsRunParameters params;
- params.arguments << "install" << "--no-build";
+ params.command = "install";
+ params.arguments << "--no-build";
params.expectFailure = true;
QVERIFY(runQbs(params) != 0);
QVERIFY(m_qbsStderr.contains("No build graph"));
@@ -1489,7 +1501,7 @@ void TestBlackbox::installedApp()
void TestBlackbox::toolLookup()
{
- QbsRunParameters params(QStringList("detect-toolchains") << "--help");
+ QbsRunParameters params(QLatin1String("detect-toolchains"), QStringList("--help"));
params.useProfile = false;
QCOMPARE(runQbs(params), 0);
}
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 43c1d1d12..64ccf84b9 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -45,12 +45,14 @@ public:
init();
}
- QbsRunParameters(const QStringList &args) : arguments(args)
+ QbsRunParameters(const QString &cmd, const QStringList &args = QStringList())
+ : command(cmd), arguments(args)
{
init();
}
- QbsRunParameters(const QString &arg) : arguments(arg)
+ QbsRunParameters(const QStringList &args)
+ : arguments(args)
{
init();
}
@@ -62,6 +64,7 @@ public:
environment = QProcessEnvironment::systemEnvironment();
}
+ QString command;
QStringList arguments;
QProcessEnvironment environment;
bool expectFailure;