summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shachnev <mitya57@gmail.com>2014-04-04 13:53:15 +0400
committerThiago Macieira <thiago.macieira@intel.com>2015-02-10 22:19:20 +0000
commitae5eeef85c9a818bfa6a3e03511e3935e9abe01f (patch)
tree332a91ff67ce35376219fa393fe26773e5559d10
parent59789eb9ad2468cc6b839dfba4e5a57581effd74 (diff)
Implement fallback mechanism for some tools
If a tool was requested without specifying the SDK name, and the default SDK does not have that tool, fall back to any installed SDK that contains that tool. Currently this is enabled only for qdbus, qmlscene, and for tools that are new in Qt 5. Change-Id: I19a82a06c75fe9cd624aa51b086d72e75310ba35 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/qtchooser/main.cpp60
1 files changed, 52 insertions, 8 deletions
diff --git a/src/qtchooser/main.cpp b/src/qtchooser/main.cpp
index 8728f56..d028ee6 100644
--- a/src/qtchooser/main.cpp
+++ b/src/qtchooser/main.cpp
@@ -65,6 +65,7 @@
#if defined(_WIN32) || defined(__WIN32__)
# include <process.h>
# define execv _execv
+# define stat _stat
# define PATH_SEP "\\"
# define EXE_SUFFIX ".exe"
#else
@@ -111,8 +112,22 @@ struct Sdk
string librariesPath;
bool isValid() const { return !toolsPath.empty(); }
+ bool hasTool(const string &targetTool) const;
};
+bool Sdk::hasTool(const string &targetTool) const
+{
+ struct stat st;
+ if (toolsPath.empty())
+ return false;
+ if (stat((toolsPath + PATH_SEP + targetTool).c_str(), &st))
+ return false;
+#ifdef S_IEXEC
+ return (st.st_mode & S_IEXEC);
+#endif
+ return true;
+}
+
struct ToolWrapper
{
int printHelp();
@@ -126,8 +141,9 @@ private:
typedef bool (*VisitFunction)(const string &targetSdk, Sdk &item);
typedef void (*FinishFunction)(const set<string> &seenSdks);
- Sdk iterateSdks(const string &targetSdk, VisitFunction visit, FinishFunction finish = 0);
- Sdk selectSdk(const string &targetSdk);
+ Sdk iterateSdks(const string &targetSdk, VisitFunction visit, FinishFunction finish = 0,
+ const string &targetTool = "");
+ Sdk selectSdk(const string &targetSdk, const string &targetTool = "");
static void printSdks(const set<string> &seenNames);
static bool matchSdk(const string &targetSdk, Sdk &sdk);
@@ -266,7 +282,7 @@ static bool mkparentdir(string name)
int ToolWrapper::runTool(const string &targetSdk, const string &targetTool, char **argv)
{
- Sdk sdk = selectSdk(targetSdk);
+ Sdk sdk = selectSdk(targetSdk, targetTool);
if (!sdk.isValid())
return 1;
@@ -454,7 +470,8 @@ vector<string> ToolWrapper::searchPaths() const
return paths;
}
-Sdk ToolWrapper::iterateSdks(const string &targetSdk, VisitFunction visit, FinishFunction finish)
+Sdk ToolWrapper::iterateSdks(const string &targetSdk, VisitFunction visit, FinishFunction finish,
+ const string &targetTool)
{
vector<string> paths = searchPaths();
set<string> seenNames;
@@ -483,11 +500,20 @@ Sdk ToolWrapper::iterateSdks(const string &targetSdk, VisitFunction visit, Finis
continue;
seenNames.insert(d->d_name);
- sdk.name = d->d_name;
- sdk.name.resize(fnamelen + 1 - sizeof confSuffix);
+ if (targetTool.empty()) {
+ sdk.name = d->d_name;
+ sdk.name.resize(fnamelen + 1 - sizeof confSuffix);
+ } else {
+ // To make the check in matchSdk() succeed
+ sdk.name = "default";
+ }
sdk.configFile = path + PATH_SEP + d->d_name;
- if (visit && visit(targetSdk, sdk))
+ if (visit && visit(targetSdk, sdk)) {
+ // If a tool was requested, but not found here, skip this sdk
+ if (!targetTool.empty() && !sdk.hasTool(targetTool))
+ continue;
return sdk;
+ }
}
closedir(dir);
@@ -499,9 +525,27 @@ Sdk ToolWrapper::iterateSdks(const string &targetSdk, VisitFunction visit, Finis
return Sdk();
}
-Sdk ToolWrapper::selectSdk(const string &targetSdk)
+// All tools that exist for only one Qt version should be
+// here. Other tools in this list are qdbus and qmlscene.
+bool fallbackAllowed(const string &tool)
{
+ return tool == "qdbus" ||
+ tool == "qml" ||
+ tool == "qmlimportscanner" ||
+ tool == "qmlscene" ||
+ tool == "qtdiag" ||
+ tool == "qtpaths" ||
+ tool == "qtplugininfo";
+}
+
+Sdk ToolWrapper::selectSdk(const string &targetSdk, const string &targetTool)
+{
+ // First, try the requested SDK
Sdk matchedSdk = iterateSdks(targetSdk, &ToolWrapper::matchSdk);
+ if (targetSdk.empty() && !matchedSdk.hasTool(targetTool) && fallbackAllowed(targetTool)) {
+ // If a tool was requested, fall back to any SDK that has it
+ matchedSdk = iterateSdks(string(), &ToolWrapper::matchSdk, 0, targetTool);
+ }
if (!matchedSdk.isValid()) {
fprintf(stderr, "%s: could not find a Qt installation of '%s'\n", argv0, targetSdk.c_str());
}