diff options
author | Dmitry Shachnev <mitya57@gmail.com> | 2014-04-04 13:53:15 +0400 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-02-10 22:19:20 +0000 |
commit | ae5eeef85c9a818bfa6a3e03511e3935e9abe01f (patch) | |
tree | 332a91ff67ce35376219fa393fe26773e5559d10 | |
parent | 59789eb9ad2468cc6b839dfba4e5a57581effd74 (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.cpp | 60 |
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()); } |