From dd53919fb3b6f3a8b1765c64ddc5c30161f52d7b Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Wed, 1 Jun 2016 14:17:41 -0400 Subject: [PATCH] Fix up mixing of MSYS2 and Qt MinGW and 64/32-bit toolchains. And fix up autodiscovery and launching on Linux. And disable debug_and_release in all platforms. win32 adds it automatically. Change-Id: If079f83645893d5132b6a459132123f33e5b28f2 --- .../cdt/build/gcc/core/GCCToolChain.java | 14 ++++++- .../internal/GCCPathToolChainProvider.java | 30 ++++++++++++- .../core/internal/Msys2ToolChainProvider.java | 13 ++++-- .../eclipse/cdt/core/build/IToolChain.java | 7 +++- .../internal/core/build/ToolChainManager.java | 9 ++++ qt/org.eclipse.cdt.qt.core/plugin.xml | 14 +++++++ .../cdt/internal/qt/core/QtInstall.java | 23 ++++++++-- .../internal/qt/core/QtInstallManager.java | 8 ++++ .../qt/core/build/QtBuildConfiguration.java | 19 ++++----- .../build/QtBuildConfigurationProvider.java | 42 +++++++++++-------- .../core/provider/LinuxQtInstallProvider.java | 41 ++++++++++++++++++ .../core/provider/Msys2QtInstallProvider.java | 5 ++- .../qt/core/provider/QtInstallProvider.java | 18 +++++--- .../org/eclipse/cdt/qt/core/IQtInstall.java | 5 +++ .../core/QtLaunchConfigurationDelegate.java | 14 ++----- .../cdt/qt/core/QtMinGWToolChainProvider.java | 27 +++++++----- .../preferences/NewQtInstallWizardPage.java | 2 +- 17 files changed, 222 insertions(+), 69 deletions(-) create mode 100644 qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/LinuxQtInstallProvider.java diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java index f2117a113f8..9ffdc420673 100644 --- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java +++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java @@ -55,6 +55,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain { private final String prefix; private final IEnvironmentVariable pathVar; private final IEnvironmentVariable[] envVars; + private final Map properties = new HashMap<>(); protected String[] compileCommands; @@ -113,16 +114,27 @@ public class GCCToolChain extends PlatformObject implements IToolChain { @Override public String getProperty(String key) { - // this class represents a local toolchain + String value = properties.get(key); + if (value != null) { + return value; + } + + // By default, we're a local GCC switch (key) { case ATTR_OS: return Platform.getOS(); case ATTR_ARCH: return Platform.getOSArch(); } + return null; } + @Override + public void setProperty(String key, String value) { + properties.put(key, value); + } + @Override public String getBinaryParserId() { // Assume local builds diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java index 28905b02c97..61a0b69f307 100644 --- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java +++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java @@ -18,8 +18,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.cdt.build.gcc.core.GCCToolChain; +import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.core.build.IToolChainProvider; +import org.eclipse.core.runtime.Platform; /** * Finds gcc and clang on the path. @@ -74,8 +76,32 @@ public class GCCPathToolChainProvider implements IToolChainProvider { String name = target + " - " + version; //$NON-NLS-1$ if (!names.contains(name)) { names.add(name); - manager.addToolChain(new GCCToolChain(this, target, version, - new Path[] { dir.toPath() }, prefix)); + GCCToolChain toolChain = new GCCToolChain(this, target, version, + new Path[] { dir.toPath() }, prefix); + String[] tuple = target.split("-"); //$NON-NLS-1$ + if (tuple.length > 2) { + // Arch + if ("x86_64".equals(tuple[0])) { + toolChain.setProperty(IToolChain.ATTR_ARCH, tuple[0]); + } else { + toolChain.setProperty(IToolChain.ATTR_ARCH, "x86"); // default + } + + // OS + switch (tuple[1]) { + case "w64": + toolChain.setProperty(IToolChain.ATTR_OS, Platform.OS_WIN32); + break; + case "linux": + toolChain.setProperty(IToolChain.ATTR_OS, Platform.OS_LINUX); + break; + case "apple": + toolChain.setProperty(IToolChain.ATTR_OS, Platform.OS_MACOSX); + break; + } + } + toolChain.setProperty(IToolChain.ATTR_PACKAGE, "system"); + manager.addToolChain(toolChain); } } } catch (IOException e) { diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java index aa22cd01409..7e62455a92a 100644 --- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java +++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java @@ -11,6 +11,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import org.eclipse.cdt.build.gcc.core.GCCToolChain; +import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.core.build.IToolChainProvider; import org.eclipse.cdt.utils.WindowsRegistry; @@ -65,8 +66,10 @@ public class Msys2ToolChainProvider implements IToolChainProvider { Path msysPath = Paths.get(installLocation); Path gccPath = msysPath.resolve("mingw64\\bin\\gcc.exe"); //$NON-NLS-1$ if (Files.exists(gccPath)) { - manager.addToolChain(new GCCToolChain(this, "x86_64-w64-mingw32", "msys2.x86_64", new Path[] { //$NON-NLS-1$ //$NON-NLS-2$ - gccPath.getParent(), msysPath.resolve("bin"), msysPath.resolve("usr\\bin") })); //$NON-NLS-1$ //$NON-NLS-2$ + GCCToolChain toolChain = new GCCToolChain(this, "x86_64-w64-mingw32", "msys2.x86_64", new Path[] { //$NON-NLS-1$ //$NON-NLS-2$ + gccPath.getParent(), msysPath.resolve("bin"), msysPath.resolve("usr\\bin") }); //$NON-NLS-1$ //$NON-NLS-2$ + toolChain.setProperty(IToolChain.ATTR_PACKAGE, "msys2"); //$NON-NLS-1$ + manager.addToolChain(toolChain); return true; } else { return addToolChain32(manager, registry, key); @@ -78,8 +81,10 @@ public class Msys2ToolChainProvider implements IToolChainProvider { Path msysPath = Paths.get(installLocation); Path gccPath = msysPath.resolve("mingw32\\bin\\gcc.exe"); //$NON-NLS-1$ if (Files.exists(gccPath)) { - manager.addToolChain(new GCCToolChain(this, "i686-w64-mingw32", "msys2.i686", new Path[] { //$NON-NLS-1$ //$NON-NLS-2$ - gccPath.getParent(), msysPath.resolve("bin"), msysPath.resolve("usr\\bin") })); //$NON-NLS-1$ //$NON-NLS-2$ + GCCToolChain toolChain = new GCCToolChain(this, "i686-w64-mingw32", "msys2.i686", new Path[] { //$NON-NLS-1$ //$NON-NLS-2$ + gccPath.getParent(), msysPath.resolve("bin"), msysPath.resolve("usr\\bin") }); //$NON-NLS-1$ //$NON-NLS-2$ + toolChain.setProperty(IToolChain.ATTR_PACKAGE, "msys2"); //$NON-NLS-1$ + manager.addToolChain(toolChain); return true; } else { return false; diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java index 2d341e28866..c783000cae3 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java @@ -27,11 +27,12 @@ public interface IToolChain extends IAdaptable { // Standard attributes static final String ATTR_OS = "os"; //$NON-NLS-1$ static final String ATTR_ARCH = "arch"; //$NON-NLS-1$ + static final String ATTR_PACKAGE = "package"; // $NON-NLS-2$ IToolChainProvider getProvider(); String getId(); - + String getVersion(); String getName(); @@ -47,6 +48,8 @@ public interface IToolChain extends IAdaptable { */ String getProperty(String key); + void setProperty(String key, String value); + IEnvironmentVariable getVariable(String name); IEnvironmentVariable[] getVariables(); @@ -63,5 +66,5 @@ public interface IToolChain extends IAdaptable { IResource[] getResourcesFromCommand(String[] command, URI buildDirectoryURI); String getBinaryParserId(); - + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java index ed83798bccf..b6fa1aae781 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java @@ -133,6 +133,15 @@ public class ToolChainManager implements IToolChainManager { tcs.add(toolChain); } } + + // Allow 32-bit compilers on 64-bit machines + // TODO is there a cleaner way to do this? + if ("x86_64".equals(properties.get(IToolChain.ATTR_ARCH))) { //$NON-NLS-1$ + Map properties32 = new HashMap<>(properties); + properties32.put(IToolChain.ATTR_ARCH, "x86"); //$NON-NLS-1$ + tcs.addAll(getToolChainsMatching(properties32)); + } + return tcs; } diff --git a/qt/org.eclipse.cdt.qt.core/plugin.xml b/qt/org.eclipse.cdt.qt.core/plugin.xml index 56757c60dc8..56a4eb9ca0c 100644 --- a/qt/org.eclipse.cdt.qt.core/plugin.xml +++ b/qt/org.eclipse.cdt.qt.core/plugin.xml @@ -185,6 +185,9 @@ + + @@ -210,5 +213,16 @@ value="x86_64"> + + + + + + diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstall.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstall.java index c3e8c423761..47ab4d44a06 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstall.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstall.java @@ -10,7 +10,11 @@ package org.eclipse.cdt.internal.qt.core; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.eclipse.cdt.qt.core.IQtInstall; @@ -18,6 +22,7 @@ public class QtInstall implements IQtInstall { private final Path qmakePath; private String spec; + private Map properties = new HashMap<>(); public QtInstall(Path qmakePath) { this.qmakePath = qmakePath; @@ -38,14 +43,16 @@ public class QtInstall implements IQtInstall { return qmakePath.resolve("../../qml"); //$NON-NLS-1$ } - public static String getSpec(String qmakePath) throws IOException { - Process proc = new ProcessBuilder(qmakePath, "-query", "QMAKE_XSPEC").start(); //$NON-NLS-1$ //$NON-NLS-2$ + public static String getSpec(Path qmakePath) throws IOException { + if (Files.exists(qmakePath)) { + Process proc = new ProcessBuilder(qmakePath.toString(), "-query", "QMAKE_XSPEC").start(); //$NON-NLS-1$ //$NON-NLS-2$ try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) { String line = reader.readLine(); if (line != null) { return line.trim(); } } + } return null; } @@ -53,7 +60,7 @@ public class QtInstall implements IQtInstall { public String getSpec() { if (spec == null) { try { - spec = getSpec(getQmakePath().toString()); + spec = getSpec(getQmakePath()); } catch (IOException e) { Activator.log(e); } @@ -61,4 +68,14 @@ public class QtInstall implements IQtInstall { return spec; } + @Override + public void setProperty(String key, String value) { + properties.put(key, value); + } + + @Override + public Map getProperties() { + return Collections.unmodifiableMap(properties); + } + } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java index ce8e6cb230c..73371f51a2d 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtInstallManager.java @@ -13,6 +13,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.qt.core.IQtInstall; @@ -135,6 +136,13 @@ public class QtInstallManager implements IQtInstallManager { return false; } } + + for (Entry property : install.getProperties().entrySet()) { + if (!property.getValue().equals(toolChain.getProperty(property.getKey()))) { + return false; + } + } + return true; } else { // Don't know so returning false diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java index 5617c398be1..f66e451b6f1 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java @@ -113,11 +113,11 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild if (launchMode != null) { switch (launchMode) { case "run": //$NON-NLS-1$ - return new String[] { "CONFIG+=release" }; //$NON-NLS-1$ + return new String[] { "CONFIG-=debug_and_release", "CONFIG+=release" }; //$NON-NLS-1$ //$NON-NLS-2$ case "debug": //$NON-NLS-1$ - return new String[] { "CONFIG+=debug" }; //$NON-NLS-1$ + return new String[] { "CONFIG-=debug_and_release", "CONFIG+=debug" }; //$NON-NLS-1$ //$NON-NLS-2$ default: - return new String[] { "CONFIG+=launch_mode_" + launchMode }; //$NON-NLS-1$ + return new String[] { "CONFIG-=debug_and_release", "CONFIG+=launch_mode_" + launchMode }; //$NON-NLS-1$ //$NON-NLS-2$ } } return new String[] { "CONFIG+=debug_and_release", "CONFIG+=launch_modeall" }; //$NON-NLS-1$ //$NON-NLS-2$ @@ -136,21 +136,18 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild @Override public Path getProgramPath() throws CoreException { + // TODO get the app name from the .pro file. String projectName = getProject().getName(); switch (Platform.getOS()) { case Platform.OS_MACOSX: - // TODO this is mac local specific and really should be - // in the config - // TODO also need to pull the app name out of the pro - // file name Path appFolder = getBuildDirectory().resolve(projectName + ".app"); //$NON-NLS-1$ Path contentsFolder = appFolder.resolve("Contents"); //$NON-NLS-1$ Path macosFolder = contentsFolder.resolve("MacOS"); //$NON-NLS-1$ return macosFolder.resolve(projectName); - case Platform.OS_WIN32: { - String subdir = "run".equals(launchMode) ? "release" : "debug"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - return getBuildDirectory().resolve(subdir).resolve(projectName + ".exe"); //$NON-NLS-1$ - } + case Platform.OS_WIN32: + return getBuildDirectory().resolve(projectName + ".exe"); //$NON-NLS-1$ + case Platform.OS_LINUX: + return getBuildDirectory().resolve(projectName); //$NON-NLS-1$ default: Path releaseFolder = getBuildDirectory().resolve("release"); //$NON-NLS-1$ return releaseFolder.resolve(projectName); diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java index fea1910643e..019c1c29eb5 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java @@ -7,6 +7,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.qt.core.build; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -19,6 +20,7 @@ import org.eclipse.cdt.internal.qt.core.Activator; import org.eclipse.cdt.qt.core.IQtBuildConfiguration; import org.eclipse.cdt.qt.core.IQtInstall; import org.eclipse.cdt.qt.core.IQtInstallManager; +import org.eclipse.cdt.qt.core.QtMinGWToolChainProvider; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -42,7 +44,7 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) { try { if (config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - // try the local target as the default + // try the toolchain for the local target Map properties = new HashMap<>(); properties.put(IToolChain.ATTR_OS, Platform.getOS()); properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); @@ -76,32 +78,36 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide } } - public IQtBuildConfiguration getConfiguration(IProject project, IToolChain toolChain, String launchMode, + public IQtBuildConfiguration getConfiguration(IProject project, Map properties, String launchMode, IProgressMonitor monitor) throws CoreException { + Collection toolChains = toolChainManager.getToolChainsMatching(properties); for (IBuildConfiguration config : project.getBuildConfigs()) { ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); if (cconfig != null) { IQtBuildConfiguration qtConfig = cconfig.getAdapter(IQtBuildConfiguration.class); - if (qtConfig != null && launchMode.equals(qtConfig.getLaunchMode()) - && qtConfig.getToolChain().equals(toolChain)) { - return qtConfig; + if (qtConfig != null && launchMode.equals(qtConfig.getLaunchMode())) { + for (IToolChain toolChain : toolChains) { + if (qtConfig.getToolChain().equals(toolChain)) { + return qtConfig; + } + } } } } - return null; - } - public QtBuildConfiguration createConfiguration(IProject project, IToolChain toolChain, String launchMode, - IProgressMonitor monitor) throws CoreException { - for (IQtInstall qtInstall : qtInstallManager.getInstalls()) { - if (qtInstallManager.supports(qtInstall, toolChain)) { - // TODO what if multiple matches - String configName = "qt." + qtInstall.getSpec() + "." + launchMode; //$NON-NLS-1$ //$NON-NLS-2$ - IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, monitor); - QtBuildConfiguration qtConfig = new QtBuildConfiguration(config, configName, toolChain, qtInstall, - launchMode); - configManager.addBuildConfiguration(config, qtConfig); - return qtConfig; + // Not found, create one + for (IToolChain toolChain : toolChains) { + for (IQtInstall qtInstall : qtInstallManager.getInstalls()) { + if (qtInstallManager.supports(qtInstall, toolChain)) { + // TODO what if multiple matches, this returns first match + String configName = "qt." + qtInstall.getSpec() + "." + launchMode; //$NON-NLS-1$ //$NON-NLS-2$ + IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, + monitor); + QtBuildConfiguration qtConfig = new QtBuildConfiguration(config, configName, toolChain, qtInstall, + launchMode); + configManager.addBuildConfiguration(config, qtConfig); + return qtConfig; + } } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/LinuxQtInstallProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/LinuxQtInstallProvider.java new file mode 100644 index 00000000000..afd6a546eb4 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/LinuxQtInstallProvider.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.internal.qt.core.provider; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.internal.qt.core.QtInstall; +import org.eclipse.cdt.qt.core.IQtInstall; +import org.eclipse.cdt.qt.core.IQtInstallProvider; +import org.eclipse.core.runtime.Platform; + +/** + * Qt install provider that looks for qmake on /usr/bin + */ +public class LinuxQtInstallProvider implements IQtInstallProvider { + + @Override + public Collection getInstalls() { + if (Platform.getOS().equals(Platform.OS_LINUX)) { + Path qmakePath = Paths.get("/usr/bin/qmake"); //$NON-NLS-1$ + if (Files.exists(qmakePath)) { + QtInstall install = new QtInstall(qmakePath); + install.setProperty(IToolChain.ATTR_PACKAGE, "system"); + return Arrays.asList(install); + } + } + return Collections.emptyList(); + } + +} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/Msys2QtInstallProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/Msys2QtInstallProvider.java index 7f0b1a5b037..d3270a25907 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/Msys2QtInstallProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/Msys2QtInstallProvider.java @@ -14,6 +14,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.internal.qt.core.QtInstall; import org.eclipse.cdt.qt.core.IQtInstall; import org.eclipse.cdt.qt.core.IQtInstallProvider; @@ -40,7 +41,9 @@ public class Msys2QtInstallProvider implements IQtInstallProvider { if ("MSYS2 64bit".equals(displayName)) { //$NON-NLS-1$ String installLocation = registry.getCurrentUserValue(compKey, "InstallLocation"); //$NON-NLS-1$ Path qmakePath = Paths.get(installLocation + "\\mingw64\\bin\\qmake.exe"); //$NON-NLS-1$ - installs.add(new QtInstall(qmakePath)); + QtInstall install = new QtInstall(qmakePath); + install.setProperty(IToolChain.ATTR_PACKAGE, "msys2"); //$NON-NLS-1$ + installs.add(install); } } return installs; diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/QtInstallProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/QtInstallProvider.java index 1ebfe465d0e..144eb8959dc 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/QtInstallProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/QtInstallProvider.java @@ -16,6 +16,7 @@ import java.util.Collections; import java.util.stream.Collectors; import org.eclipse.cdt.codan.core.cxx.Activator; +import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.internal.qt.core.QtInstall; import org.eclipse.cdt.qt.core.IQtInstall; import org.eclipse.cdt.qt.core.IQtInstallProvider; @@ -27,14 +28,22 @@ import org.eclipse.core.runtime.Platform; */ public class QtInstallProvider implements IQtInstallProvider { + private static boolean isWin32 = Platform.getOS().equals(Platform.OS_WIN32); + @Override public Collection getInstalls() { Path root = getQtRoot(); - Path qmake = Paths.get(Platform.getOS().equals(Platform.OS_WIN32) ? "bin/qmake.exe" : "bin/qmake"); //$NON-NLS-1$ //$NON-NLS-2$ - if (root != null) { + Path qmake = Paths.get(isWin32 ? "bin/qmake.exe" : "bin/qmake"); //$NON-NLS-1$ //$NON-NLS-2$ + if (root != null && Files.exists(root)) { try { return Files.walk(root, 2).filter((path) -> Files.exists(path.resolve(qmake))) - .map((path) -> new QtInstall(path.resolve(qmake))).collect(Collectors.toList()); + .map((path) -> { + QtInstall install = new QtInstall(path.resolve(qmake)); + if (isWin32 && "win32-g++".equals(install.getSpec())) { //$NON-NLS-1$ + install.setProperty(IToolChain.ATTR_PACKAGE, "qt"); //$NON-NLS-1$ //$NON-NLS-2$ + } + return install; + }).collect(Collectors.toList()); } catch (IOException e) { Activator.log(e); } @@ -43,14 +52,13 @@ public class QtInstallProvider implements IQtInstallProvider { } private Path getQtRoot() { - if (Platform.getOS().equals(Platform.OS_WIN32)) { + if (isWin32) { WindowsRegistry registry = WindowsRegistry.getRegistry(); String uninstallKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; //$NON-NLS-1$ String subkey; for (int i = 0; (subkey = registry.getCurrentUserKeyName(uninstallKey, i)) != null; i++) { String compKey = uninstallKey + '\\' + subkey; String displayName = registry.getCurrentUserValue(compKey, "DisplayName"); //$NON-NLS-1$ - // On Windows, look for MSYS2, MinGW 64/32 locations if ("Qt".equals(displayName)) { //$NON-NLS-1$ String installLocation = registry.getCurrentUserValue(compKey, "InstallLocation"); //$NON-NLS-1$ return Paths.get(installLocation); diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstall.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstall.java index c55fd1a5f02..03cefb83c01 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstall.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstall.java @@ -8,6 +8,7 @@ package org.eclipse.cdt.qt.core; import java.nio.file.Path; +import java.util.Map; /** * Represents an installation of the Qt SDK. Qt installs are defined by the path @@ -25,4 +26,8 @@ public interface IQtInstall { Path getQmlPath(); + void setProperty(String key, String value); + + Map getProperties(); + } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java index d3e952c2740..998546284d7 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java @@ -12,7 +12,6 @@ import java.util.Map; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.internal.qt.core.Activator; import org.eclipse.cdt.internal.qt.core.build.QtBuildConfigurationProvider; import org.eclipse.core.resources.IProject; @@ -71,19 +70,12 @@ public abstract class QtLaunchConfigurationDelegate extends LaunchConfigurationT .getProvider(QtBuildConfigurationProvider.ID); IProject project = configuration.getMappedResources()[0].getProject(); - // Find the toolchains that support this target Map properties = new HashMap<>(); populateToolChainProperties(target, properties); - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - for (IToolChain toolChain : toolChainManager.getToolChainsMatching(properties)) { - IQtBuildConfiguration qtConfig = provider.getConfiguration(project, toolChain, mode, monitor); - if (qtConfig == null) { - qtConfig = provider.createConfiguration(project, toolChain, mode, monitor); - } - if (qtConfig != null) { - return qtConfig; - } + IQtBuildConfiguration qtConfig = provider.getConfiguration(project, properties, mode, monitor); + if (qtConfig != null) { + return qtConfig; } // Couldn't find any diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java index d6918cccde7..c50572f41dd 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java @@ -13,6 +13,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import org.eclipse.cdt.build.gcc.core.GCCToolChain; +import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.core.build.IToolChainProvider; import org.eclipse.cdt.internal.qt.core.Activator; @@ -22,7 +23,8 @@ import org.eclipse.core.runtime.Platform; public class QtMinGWToolChainProvider implements IToolChainProvider { - private static final String ID = "org.eclipse.cdt.qt.core.qtMinGWProvider"; //$NON-NLS-1$ + public static final String ID = "org.eclipse.cdt.qt.core.qtMinGWProvider"; //$NON-NLS-1$ + public static final String TOOLCHAIN_ID = "qt.mingw"; //$NON-NLS-1$ @Override public String getId() { @@ -39,15 +41,20 @@ public class QtMinGWToolChainProvider implements IToolChainProvider { String compKey = uninstallKey + '\\' + subkey; String displayName = registry.getCurrentUserValue(compKey, "DisplayName"); //$NON-NLS-1$ if ("Qt".equals(displayName)) { //$NON-NLS-1$ - String installLocation = registry.getCurrentUserValue(compKey, "InstallLocation"); //$NON-NLS-1$ - Path gcc = Paths.get("\\bin\\gcc.exe"); //$NON-NLS-1$ - try { - Files.walk(Paths.get(installLocation).resolve("Tools"), 1) //$NON-NLS-1$ - .filter((path) -> Files.exists(path.resolve(gcc))) - .map((path) -> new GCCToolChain(this, "qt.mingw", "", new Path[] { path.resolve("bin") })) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - .forEach(toolChain -> manager.addToolChain(toolChain)); - } catch (IOException e) { - Activator.log(e); + Path installLocation = Paths.get(registry.getCurrentUserValue(compKey, "InstallLocation")); //$NON-NLS-1$ + if (Files.exists(installLocation)) { + Path gcc = Paths.get("bin\\gcc.exe"); //$NON-NLS-1$ + try { + Files.walk(installLocation.resolve("Tools"), 1) //$NON-NLS-1$ + .filter(path -> Files.exists(path.resolve(gcc))).map(path -> { + GCCToolChain toolChain = new GCCToolChain(this, TOOLCHAIN_ID, "", //$NON-NLS-1$ + new Path[] { path.resolve("bin") }); //$NON-NLS-1$ + toolChain.setProperty(IToolChain.ATTR_PACKAGE, "qt"); //$NON-NLS-1$ + return toolChain; + }).forEach(toolChain -> manager.addToolChain(toolChain)); + } catch (IOException e) { + Activator.log(e); + } } } } diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/NewQtInstallWizardPage.java b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/NewQtInstallWizardPage.java index a870cafddeb..10965837736 100644 --- a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/NewQtInstallWizardPage.java +++ b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/NewQtInstallWizardPage.java @@ -81,7 +81,7 @@ public class NewQtInstallWizardPage extends WizardPage { @Override protected IStatus run(IProgressMonitor monitor) { try { - String spec = QtInstall.getSpec(selected); + String spec = QtInstall.getSpec(Paths.get(selected)); getControl().getDisplay().asyncExec(() -> { specText.setText(spec); });