From ae5eeef85c9a818bfa6a3e03511e3935e9abe01f Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 4 Apr 2014 13:53:15 +0400 Subject: 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 --- src/qtchooser/main.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'src/qtchooser/main.cpp') 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 # 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 &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 &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 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 paths = searchPaths(); set 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()); } -- cgit v1.2.3