diff options
Diffstat (limited to 'qt/org.eclipse.cdt.qt.core/src')
22 files changed, 780 insertions, 543 deletions
diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/Activator.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/Activator.java index 0e719146788..5739000726d 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/Activator.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/Activator.java @@ -12,10 +12,8 @@ import java.io.IOException; import javax.script.ScriptException; import org.eclipse.cdt.core.model.CModelException; -import org.eclipse.cdt.internal.qt.core.build.QtBuildConfigurationFactory; import org.eclipse.cdt.qt.core.IQMLAnalyzer; import org.eclipse.cdt.qt.core.IQtInstallManager; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -47,7 +45,6 @@ public class Activator extends Plugin { public static final QualifiedName QTINDEX_PROP_NAME = new QualifiedName(ID, "qtindex"); //$NON-NLS-1$ private static Activator instance; - private static QtBuildConfigurationFactory.Cleanup configCleanup; public static Activator getDefault() { return instance; @@ -76,18 +73,12 @@ public class Activator extends Plugin { return Status.OK_STATUS; } }.schedule(); - - configCleanup = new QtBuildConfigurationFactory.Cleanup(); - ResourcesPlugin.getWorkspace().addResourceChangeListener(configCleanup); } @Override public void stop(BundleContext context) throws Exception { // QMakeProjectInfoManager.stop(); - ResourcesPlugin.getWorkspace().removeResourceChangeListener(configCleanup); - configCleanup = null; - super.stop(context); } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/LocalQtInstallTargetMapper.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/LocalQtInstallTargetMapper.java deleted file mode 100644 index 45fbcee596e..00000000000 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/LocalQtInstallTargetMapper.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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; - -import org.eclipse.cdt.build.core.IToolChain; -import org.eclipse.cdt.build.gcc.core.GCCToolChainType; -import org.eclipse.cdt.qt.core.IQtInstall; -import org.eclipse.cdt.qt.core.IQtInstallTargetMapper; -import org.eclipse.core.runtime.Platform; -import org.eclipse.launchbar.core.target.ILaunchTarget; - -public class LocalQtInstallTargetMapper implements IQtInstallTargetMapper { - - @Override - public boolean supported(IQtInstall qtInstall, ILaunchTarget launchTarget) { - String os = Platform.getOS(); - String arch = Platform.getOSArch(); - - switch (qtInstall.getSpec()) { - case "macx-clang": //$NON-NLS-1$ - return Platform.OS_MACOSX.equals(os) && Platform.ARCH_X86_64.equals(arch); - case "win32-g++": //$NON-NLS-1$ - return Platform.OS_WIN32.equals(os); - default: - return false; - } - } - - @Override - public boolean supported(IQtInstall qtInstall, IToolChain toolChain) { - if (toolChain.getType().equals(GCCToolChainType.ID)) { - String spec = qtInstall.getSpec(); - return spec.endsWith("-clang") || spec.endsWith("-g++"); //$NON-NLS-1$ //$NON-NLS-2$ - } - return false; - } - -} 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 3cc3d7d92f9..c3e8c423761 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 @@ -16,21 +16,14 @@ import org.eclipse.cdt.qt.core.IQtInstall; public class QtInstall implements IQtInstall { - private final String name; private final Path qmakePath; private String spec; - public QtInstall(String name, Path qmakePath) { - this.name = name; + public QtInstall(Path qmakePath) { this.qmakePath = qmakePath; } @Override - public String getName() { - return name; - } - - @Override public Path getQmakePath() { return qmakePath; } 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 c71cb9afa82..ce8e6cb230c 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 @@ -7,31 +7,29 @@ *******************************************************************************/ package org.eclipse.cdt.internal.qt.core; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import org.eclipse.cdt.build.core.IToolChain; +import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.qt.core.IQtInstall; import org.eclipse.cdt.qt.core.IQtInstallManager; -import org.eclipse.cdt.qt.core.IQtInstallTargetMapper; +import org.eclipse.cdt.qt.core.IQtInstallProvider; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.ConfigurationScope; -import org.eclipse.launchbar.core.target.ILaunchTarget; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; public class QtInstallManager implements IQtInstallManager { - private Map<String, IQtInstall> installs; - private Map<String, IConfigurationElement> mapperElements; - private Map<String, IQtInstallTargetMapper> mappers; + private Map<Path, IQtInstall> installs; + private Map<String, IConfigurationElement> toolChainMap; private Preferences getPreferences() { return ConfigurationScope.INSTANCE.getNode(Activator.ID).node("qtInstalls"); //$NON-NLS-1$ @@ -43,11 +41,25 @@ public class QtInstallManager implements IQtInstallManager { try { Preferences prefs = getPreferences(); for (String key : prefs.keys()) { - installs.put(key, new QtInstall(key, Paths.get(prefs.get(key, "/")))); //$NON-NLS-1$ + QtInstall install = new QtInstall(Paths.get(prefs.get(key, "/"))); //$NON-NLS-1$ + installs.put(install.getQmakePath(), install); } } catch (BackingStoreException e) { Activator.log(e); } + + // Auto installs + IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.ID, "qtInstallProvider"); //$NON-NLS-1$ + for (IConfigurationElement element : point.getConfigurationElements()) { + try { + IQtInstallProvider provider = (IQtInstallProvider) element.createExecutableExtension("class"); //$NON-NLS-1$ + for (IQtInstall install : provider.getInstalls()) { + installs.put(install.getQmakePath(), install); + } + } catch (CoreException e) { + Activator.log(e); + } + } } } @@ -63,7 +75,8 @@ public class QtInstallManager implements IQtInstallManager { } // Add new ones - for (String key : installs.keySet()) { + for (Path path : installs.keySet()) { + String key = path.toString(); if (prefs.get(key, null) == null) { prefs.put(key, installs.get(key).getQmakePath().toString()); } @@ -84,64 +97,49 @@ public class QtInstallManager implements IQtInstallManager { @Override public void addInstall(IQtInstall qt) { initInstalls(); - installs.put(qt.getName(), qt); + installs.put(qt.getQmakePath(), qt); saveInstalls(); } @Override - public IQtInstall getInstall(String name) { + public IQtInstall getInstall(Path qmakePath) { initInstalls(); - return installs.get(name); + return installs.get(qmakePath); } @Override public void removeInstall(IQtInstall install) { - installs.remove(install.getName()); + installs.remove(install.getQmakePath()); saveInstalls(); } @Override - public boolean supports(IQtInstall install, ILaunchTarget target) { - if (mapperElements == null) { - // init the extension point - mapperElements = new HashMap<>(); - mappers = new HashMap<>(); - - IExtensionPoint point = Platform.getExtensionRegistry() - .getExtensionPoint(Activator.ID + ".qtInstallTargetMapper"); //$NON-NLS-1$ - for (IExtension extension : point.getExtensions()) { - for (IConfigurationElement element : extension.getConfigurationElements()) { - String targetTypeId = element.getAttribute("targetTypeId"); //$NON-NLS-1$ - mapperElements.put(targetTypeId, element); + public boolean supports(IQtInstall install, IToolChain toolChain) { + if (toolChainMap == null) { + toolChainMap = new HashMap<>(); + IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.ID, "qtToolChainMapper"); //$NON-NLS-1$ + for (IConfigurationElement element : point.getConfigurationElements()) { + if (element.getName().equals("mapping")) { //$NON-NLS-1$ + String spec = element.getAttribute("spec"); //$NON-NLS-1$ + toolChainMap.put(spec, element); } } } - - String targetTypeId = target.getTypeId(); - IQtInstallTargetMapper mapper = mappers.get(targetTypeId); - if (mapper == null) { - IConfigurationElement element = mapperElements.get(targetTypeId); - if (element != null) { - try { - mapper = (IQtInstallTargetMapper) element.createExecutableExtension("class"); //$NON-NLS-1$ - mappers.put(targetTypeId, mapper); - } catch (CoreException e) { - Activator.log(e); + + IConfigurationElement element = toolChainMap.get(install.getSpec()); + if (element != null) { + for (IConfigurationElement property : element.getChildren("property")) { //$NON-NLS-1$ + String key = property.getAttribute("key"); //$NON-NLS-1$ + String value = property.getAttribute("value"); //$NON-NLS-1$ + if (!value.equals(toolChain.getProperty(key))) { + return false; } } - } - - if (mapper == null) { + return true; + } else { + // Don't know so returning false return false; } - - return mapper.supported(install, target); - } - - @Override - public boolean supports(IQtInstall install, IToolChain toolChain) { - // TODO need another extension point for this - return true; } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java index 881400776ef..93722eb532e 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtBuildConfiguration.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ -package org.eclipse.cdt.qt.core; +package org.eclipse.cdt.internal.qt.core.build; import java.io.BufferedReader; import java.io.File; @@ -19,25 +19,26 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.eclipse.cdt.build.core.CBuildConfiguration; -import org.eclipse.cdt.build.core.IToolChain; -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.model.ILanguage; -import org.eclipse.cdt.core.model.LanguageManager; -import org.eclipse.cdt.core.parser.IExtendedScannerInfo; +import org.eclipse.cdt.core.build.CBuildConfiguration; +import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; 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.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; -public class QtBuildConfiguration extends CBuildConfiguration { +public class QtBuildConfiguration extends CBuildConfiguration implements ICBuildConfiguration, IQtBuildConfiguration { private static final String QTINSTALL_NAME = "cdt.qt.install.name"; //$NON-NLS-1$ private static final String LAUNCH_MODE = "cdt.qt.launchMode"; //$NON-NLS-1$ @@ -53,7 +54,7 @@ public class QtBuildConfiguration extends CBuildConfiguration { String installName = settings.get(QTINSTALL_NAME, ""); //$NON-NLS-1$ if (!installName.isEmpty()) { IQtInstallManager manager = Activator.getService(IQtInstallManager.class); - qtInstall = manager.getInstall(installName); + qtInstall = manager.getInstall(Paths.get(installName)); } else { qtInstall = null; } @@ -61,14 +62,14 @@ public class QtBuildConfiguration extends CBuildConfiguration { launchMode = settings.get(LAUNCH_MODE, ""); //$NON-NLS-1$ } - public QtBuildConfiguration(IBuildConfiguration config, IToolChain toolChain, IQtInstall qtInstall, - String launchMode) { + QtBuildConfiguration(IBuildConfiguration config, IToolChain toolChain, IQtInstall qtInstall, String launchMode) + throws CoreException { super(config, toolChain); this.qtInstall = qtInstall; this.launchMode = launchMode; Preferences settings = getSettings(); - settings.put(QTINSTALL_NAME, qtInstall.getName()); + settings.put(QTINSTALL_NAME, qtInstall.getQmakePath().toString()); settings.put(LAUNCH_MODE, launchMode); try { settings.flush(); @@ -77,18 +78,26 @@ public class QtBuildConfiguration extends CBuildConfiguration { } } + @Override + public <T> T getAdapter(Class<T> adapter) { + return super.getAdapter(adapter); + } + public IQtInstall getQtInstall() { return qtInstall; } + @Override public String getLaunchMode() { return launchMode; } - public String getQmakeCommand() { - return qtInstall.getQmakePath().toString(); + @Override + public Path getQmakeCommand() { + return qtInstall.getQmakePath(); } + @Override public String getQmakeConfig() { switch (launchMode) { case "run": //$NON-NLS-1$ @@ -112,7 +121,8 @@ public class QtBuildConfiguration extends CBuildConfiguration { } } - public Path getProgramPath() throws CoreException { + @Override + public Path getProgramPath() { String projectName = getProject().getName(); switch (Platform.getOS()) { case Platform.OS_MACOSX: @@ -120,45 +130,24 @@ public class QtBuildConfiguration extends CBuildConfiguration { // in the config // TODO also need to pull the app name out of the pro // file name - Path appFolder = getBuildDirectory().resolve(projectName + ".app"); - Path contentsFolder = appFolder.resolve("Contents"); - Path macosFolder = contentsFolder.resolve("MacOS"); + 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: - Path releaseFolder = getBuildDirectory().resolve("release"); - return releaseFolder.resolve(projectName + ".exe"); - default: - throw new CoreException( - new Status(IStatus.ERROR, Activator.ID, "platform not supported: " + Platform.getOS())); + 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$ } - } - - public void setProgramEnvironment(Map<String, String> env) { - Path libPath = getQtInstall().getLibPath(); - switch (Platform.getOS()) { - case Platform.OS_MACOSX: - String libPathEnv = env.get("DYLD_LIBRARY_PATH"); - if (libPathEnv == null) { - libPathEnv = libPath.toString(); - } else { - libPathEnv = libPath.toString() + File.pathSeparator + libPathEnv; - } - env.put("DYLD_LIBRARY_PATH", libPathEnv); - break; - case Platform.OS_WIN32: - String path = env.get("PATH"); - // TODO really need a bin path - // and resolve doesn't work properly on Windows - path = "C:/Qt/5.5/mingw492_32/bin;" + path; - env.put("PATH", path); - break; + default: + Path releaseFolder = getBuildDirectory().resolve("release"); //$NON-NLS-1$ + return releaseFolder.resolve(projectName); } } public String getProperty(String key) { if (properties == null) { List<String> cmd = new ArrayList<>(); - cmd.add(getQmakeCommand()); + cmd.add(getQmakeCommand().toString()); cmd.add("-E"); //$NON-NLS-1$ String config = getQmakeConfig(); @@ -170,7 +159,6 @@ public class QtBuildConfiguration extends CBuildConfiguration { try { ProcessBuilder procBuilder = new ProcessBuilder(cmd).directory(getProjectFile().getParent().toFile()); - getToolChain().setEnvironment(procBuilder.environment()); Process proc = procBuilder.start(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) { properties = new HashMap<>(); @@ -192,58 +180,67 @@ public class QtBuildConfiguration extends CBuildConfiguration { } @Override - public IScannerInfo getScannerInfo(IResource resource) throws IOException { - IScannerInfo info = getCachedScannerInfo(resource); - if (info == null) { - String cxx = getProperty("QMAKE_CXX"); //$NON-NLS-1$ - if (cxx == null) { - Activator.log("No QMAKE_CXX for " + qtInstall.getSpec()); //$NON-NLS-1$ - return null; - } - String[] cxxSplit = cxx.split(" "); //$NON-NLS-1$ - String command = cxxSplit[0]; + public IEnvironmentVariable getVariable(String name) { + // TODO Auto-generated method stub + return null; + } - List<String> args = new ArrayList<>(); - for (int i = 1; i < cxxSplit.length; ++i) { - args.add(cxxSplit[i]); - } - args.addAll(Arrays.asList(getProperty("QMAKE_CXXFLAGS").split(" "))); //$NON-NLS-1$ //$NON-NLS-2$ - args.add("-o"); //$NON-NLS-1$ - args.add("-"); //$NON-NLS-1$ - - String srcFile; - if (resource instanceof IFile) { - srcFile = resource.getLocation().toOSString(); - // Only add file if it's an IFile - args.add(srcFile); - } else { - // Doesn't matter, the toolchain will create a tmp file for this - srcFile = "scannerInfo.cpp"; //$NON-NLS-1$ - } + @Override + public IEnvironmentVariable[] getVariables() { + // TODO + return new IEnvironmentVariable[0]; + } - String[] includePaths = getProperty("INCLUDEPATH").split(" "); //$NON-NLS-1$ //$NON-NLS-2$ - for (int i = 0; i < includePaths.length; ++i) { - Path path = Paths.get(includePaths[i]); - if (!path.isAbsolute()) { - includePaths[i] = getBuildDirectory().resolve(path).toString(); - } - } + @Override + public IScannerInfo getScannerInformation(IResource resource) { + IProject project = resource.getProject(); + IQtInstall qtInstall = getQtInstall(); - ILanguage language = LanguageManager.getInstance() - .getLanguage(CCorePlugin.getContentType(getProject(), srcFile), getProject()); // $NON-NLS-1$ - Path dir = Paths.get(getProject().getLocationURI()); - IExtendedScannerInfo extendedInfo = getToolChain().getScannerInfo(command, args, - Arrays.asList(includePaths), resource, dir); - putScannerInfo(language, extendedInfo); - info = extendedInfo; + String cxx = getProperty("QMAKE_CXX"); //$NON-NLS-1$ + if (cxx == null) { + Activator.log("No QMAKE_CXX for " + qtInstall.getSpec()); //$NON-NLS-1$ + return null; + } + String[] cxxSplit = cxx.split(" "); //$NON-NLS-1$ + Path command = Paths.get(cxxSplit[0]); + + List<String> args = new ArrayList<>(); + for (int i = 1; i < cxxSplit.length; ++i) { + args.add(cxxSplit[i]); } - return info; + args.addAll(Arrays.asList(getProperty("QMAKE_CXXFLAGS").split(" "))); //$NON-NLS-1$ //$NON-NLS-2$ + args.add("-o"); //$NON-NLS-1$ + args.add("-"); //$NON-NLS-1$ + + String srcFile; + if (resource instanceof IFile) { + srcFile = resource.getLocation().toOSString(); + // Only add file if it's an IFile + args.add(srcFile); + } else { + // Doesn't matter, the toolchain will create a tmp file for this + srcFile = "scannerInfo.cpp"; //$NON-NLS-1$ + } + + String[] includePaths = getProperty("INCLUDEPATH").split(" "); //$NON-NLS-1$ //$NON-NLS-2$ + for (int i = 0; i < includePaths.length; ++i) { + Path path = Paths.get(includePaths[i]); + if (!path.isAbsolute()) { + includePaths[i] = getBuildDirectory().resolve(path).toString(); + } + } + + Path dir = Paths.get(project.getLocationURI()); + return getToolChain().getScannerInfo(getBuildConfiguration(), command, args, Arrays.asList(includePaths), + resource, dir); + } + + @Override + public void subscribe(IResource resource, IScannerInfoChangeListener listener) { } @Override - public void clearScannerInfoCache() throws CoreException { - super.clearScannerInfoCache(); - properties = null; + public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationFactory.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationFactory.java deleted file mode 100644 index 0faab232710..00000000000 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationFactory.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.build; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.eclipse.cdt.build.core.IToolChain; -import org.eclipse.cdt.build.core.IToolChainManager; -import org.eclipse.cdt.internal.qt.core.Activator; -import org.eclipse.cdt.internal.qt.core.QtNature; -import org.eclipse.cdt.qt.core.IQtInstall; -import org.eclipse.cdt.qt.core.IQtInstallManager; -import org.eclipse.cdt.qt.core.QtBuildConfiguration; -import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdapterFactory; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.launchbar.core.target.ILaunchTarget; -import org.eclipse.launchbar.core.target.ILaunchTargetManager; - -public class QtBuildConfigurationFactory implements IAdapterFactory { - - private static IQtInstallManager qtInstallManager = Activator.getService(IQtInstallManager.class); - private static IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - - private static Map<IBuildConfiguration, QtBuildConfiguration> cache = new HashMap<>(); - - @Override - public Class<?>[] getAdapterList() { - return new Class<?>[] { QtBuildConfiguration.class }; - } - - @SuppressWarnings("unchecked") - @Override - public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) { - if (adapterType.equals(QtBuildConfiguration.class) && adaptableObject instanceof IBuildConfiguration) { - IBuildConfiguration config = (IBuildConfiguration) adaptableObject; - synchronized (cache) { - QtBuildConfiguration qtConfig = cache.get(config); - if (qtConfig == null) { - if (!config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - qtConfig = new QtBuildConfiguration(config); - cache.put(config, qtConfig); - return (T) qtConfig; - } else { - // Default to local - ILaunchTargetManager targetManager = Activator.getService(ILaunchTargetManager.class); - ILaunchTarget localTarget = targetManager - .getLaunchTargetsOfType(ILaunchTargetManager.localLaunchTargetTypeId)[0]; - qtConfig = createDefaultConfig(config, localTarget); - if (qtConfig != null) { - cache.put(config, qtConfig); - return (T) qtConfig; - } - - // Just find a combination that works - for (ILaunchTarget target : targetManager.getLaunchTargets()) { - if (!target.equals(localTarget)) { - qtConfig = createDefaultConfig(config, localTarget); - if (qtConfig != null) { - cache.put(config, qtConfig); - return (T) qtConfig; - } - } - } - - // TODO if we don't have a target, need another way to - // match whatever qtInstalls we have with matching - // toolchains - } - } - return (T) qtConfig; - } - } - return null; - } - - private static QtBuildConfiguration createDefaultConfig(IBuildConfiguration config, ILaunchTarget target) { - for (IQtInstall qtInstall : qtInstallManager.getInstalls()) { - if (qtInstallManager.supports(qtInstall, target)) { - // Find the toolchain - for (IToolChain toolChain : toolChainManager.getToolChainsSupporting(target)) { - if (qtInstallManager.supports(qtInstall, toolChain)) { - return new QtBuildConfiguration(config, toolChain, qtInstall, "run"); //$NON-NLS-1$ - } - } - } - } - - return null; - } - - public static QtBuildConfiguration getConfig(IProject project, String launchMode, ILaunchTarget target, - IProgressMonitor monitor) throws CoreException { - // return it if it exists already - for (IBuildConfiguration config : project.getBuildConfigs()) { - QtBuildConfiguration qtConfig = config.getAdapter(QtBuildConfiguration.class); - if (qtConfig != null) { - IQtInstall qtInstall = qtConfig.getQtInstall(); - if (qtInstall != null && qtInstallManager.supports(qtInstall, target) - && launchMode.equals(qtConfig.getLaunchMode())) { - return qtConfig; - } - } - } - - // Nope, create it - for (IQtInstall qtInstall : qtInstallManager.getInstalls()) { - if (qtInstallManager.supports(qtInstall, target)) { - // Create the build config - Set<String> configNames = new HashSet<>(); - for (IBuildConfiguration config : project.getBuildConfigs()) { - configNames.add(config.getName()); - } - String baseName = qtInstall.getSpec() + "." + launchMode; //$NON-NLS-1$ - String newName = baseName; - int n = 0; - while (configNames.contains(newName)) { - newName = baseName + (++n); - } - configNames.add(newName); - IProjectDescription projectDesc = project.getDescription(); - projectDesc.setBuildConfigs(configNames.toArray(new String[configNames.size()])); - project.setDescription(projectDesc, monitor); - - // Find the toolchain - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - for (IToolChain toolChain : toolChainManager.getToolChainsSupporting(target)) { - if (qtInstallManager.supports(qtInstall, toolChain)) { - QtBuildConfiguration qtConfig = new QtBuildConfiguration(project.getBuildConfig(newName), - toolChain, qtInstall, launchMode); - return qtConfig; - // TODO what if there's more than toolChain supported? - } - } - } - } - - // No appropriate Qt Install - throw new CoreException( - new Status(IStatus.ERROR, Activator.ID, "No appropriate Qt SDK found for target " + target.getId())); - } - - public static class Cleanup implements IResourceChangeListener { - @Override - public void resourceChanged(IResourceChangeEvent event) { - if (event.getType() == IResourceChangeEvent.PRE_CLOSE - || event.getType() == IResourceChangeEvent.PRE_DELETE) { - if (event.getResource().getType() == IResource.PROJECT) { - IProject project = event.getResource().getProject(); - if (project.isOpen() && project.exists() && QtNature.hasNature(project)) { - try { - for (IBuildConfiguration config : project.getBuildConfigs()) { - cache.remove(config); - } - } catch (CoreException e) { - Activator.log(e); - } - } - } - } - } - } - -}
\ No newline at end of file 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 new file mode 100644 index 00000000000..f0bbed84e37 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * 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.build; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager; +import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; +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.QtNature; +import org.eclipse.cdt.qt.core.IQtBuildConfiguration; +import org.eclipse.cdt.qt.core.IQtInstall; +import org.eclipse.cdt.qt.core.IQtInstallManager; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.launchbar.core.target.ILaunchTarget; + +public class QtBuildConfigurationProvider implements ICBuildConfigurationProvider { + + public static final String ID = "org.eclipse.cdt.qt.core.qtBuildConfigProvider"; //$NON-NLS-1$ + + private IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); + private IQtInstallManager qtInstallManager = Activator.getService(IQtInstallManager.class); + private ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class); + + @Override + public String getId() { + return ID; + } + + @Override + public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config) { + try { + // Double check to make sure this config is ours + if (!config.getName().startsWith(getId() + '/')) { + return null; + } + + if (!config.getProject().hasNature(QtNature.ID)) { + return null; + } + + return new QtBuildConfiguration(config); + } catch (CoreException e) { + Activator.log(e); + } + return null; + } + + @Override + public ICBuildConfiguration getDefaultCBuildConfiguration(IProject project) { + try { + if (!project.hasNature(QtNature.ID)) { + return null; + } + + // try the local target as the default + Map<String, String> properties = new HashMap<>(); + properties.put(IToolChain.ATTR_OS, Platform.getOS()); + properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); + for (IToolChain toolChain : toolChainManager.getToolChainsMatching(properties)) { + IQtBuildConfiguration qtConfig = getConfiguration(project, toolChain, "run", new NullProgressMonitor()); //$NON-NLS-1$ + if (qtConfig == null) { + qtConfig = createConfiguration(project, toolChain, "run", new NullProgressMonitor()); //$NON-NLS-1$ + if (qtConfig != null) { + return qtConfig; + } + } + } + + // local didn't work, try and find one that does + for (IToolChain toolChain : toolChainManager.getToolChainsMatching(new HashMap<>())) { + IQtBuildConfiguration qtConfig = getConfiguration(project, toolChain, "run", new NullProgressMonitor()); //$NON-NLS-1$ + if (qtConfig == null) { + qtConfig = createConfiguration(project, toolChain, "run", new NullProgressMonitor()); //$NON-NLS-1$ + if (qtConfig != null) { + return qtConfig; + } + } + } + } catch (CoreException e) { + Activator.log(e); + } + return null; + } + + public IQtBuildConfiguration getConfiguration(IProject project, IToolChain toolChain, String launchMode, + IProgressMonitor monitor) throws CoreException { + for (IBuildConfiguration config : project.getBuildConfigs()) { + ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + if (cconfig != null) { + IQtBuildConfiguration qtConfig = cconfig.getAdapter(IQtBuildConfiguration.class); + if (qtConfig != null && qtConfig.getLaunchMode().equals(launchMode) + && 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, toolChain, qtInstall, + launchMode); + configManager.addBuildConfiguration(config, qtConfig); + return qtConfig; + } + } + + return null; + } + + public QtBuildConfiguration createConfiguration(IProject project, ILaunchTarget target, String launchMode, + IProgressMonitor monitor) throws CoreException { + // Find the toolchains + Map<String, String> properties = new HashMap<>(); + String os = target.getAttribute(ILaunchTarget.ATTR_OS, null); + if (os != null) { + properties.put(IToolChain.ATTR_OS, os); + } + String arch = target.getAttribute(ILaunchTarget.ATTR_ARCH, null); + if (arch != null) { + properties.put(IToolChain.ATTR_ARCH, arch); + } + + for (IToolChain toolChain : toolChainManager.getToolChainsMatching(properties)) { + 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, toolChain, qtInstall, + launchMode); + configManager.addBuildConfiguration(config, qtConfig); + return qtConfig; + } + } + } + + return null; + } + +} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java index 688b0309a03..2689c43a74b 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java @@ -7,28 +7,38 @@ *******************************************************************************/ package org.eclipse.cdt.internal.qt.core.build; +import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import org.eclipse.cdt.build.core.IConsoleService; -import org.eclipse.cdt.build.core.IToolChain; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ConsoleOutputStream; +import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.build.BuildCommandRunner; +import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.resources.ACBuilder; +import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.internal.qt.core.Activator; import org.eclipse.cdt.internal.qt.core.Messages; -import org.eclipse.cdt.qt.core.QtBuildConfiguration; +import org.eclipse.cdt.qt.core.IQtBuildConfiguration; +import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; -public class QtBuilder extends IncrementalProjectBuilder { +public class QtBuilder extends ACBuilder { public static final String ID = Activator.ID + ".qtBuilder"; //$NON-NLS-1$ @@ -36,70 +46,162 @@ public class QtBuilder extends IncrementalProjectBuilder { protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException { IProject project = getProject(); try { - IConsoleService console = Activator.getService(IConsoleService.class); - QtBuildConfiguration qtConfig = getBuildConfig().getAdapter(QtBuildConfiguration.class); + project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(project); + ConsoleOutputStream errStream = console.getErrorStream(); + ConsoleOutputStream outStream = console.getOutputStream(); + + ICBuildConfiguration cconfig = getBuildConfig().getAdapter(ICBuildConfiguration.class); + IQtBuildConfiguration qtConfig = cconfig.getAdapter(QtBuildConfiguration.class); if (qtConfig == null) { // Qt hasn't been configured yet print a message and bale - console.writeError(Messages.QtBuilder_0); + errStream.write(Messages.QtBuilder_0); return null; } - IToolChain toolChain = qtConfig.getToolChain(); - Path buildDir = qtConfig.getBuildDirectory(); - if (!buildDir.resolve("Makefile").toFile().exists()) { //$NON-NLS-1$ - // Need to run qmake - List<String> command = new ArrayList<>(); - command.add(qtConfig.getQmakeCommand()); - - String config = qtConfig.getQmakeConfig(); - if (config != null) { - command.add(config); - } + Path makeCommand = getMakeCommand(getBuildConfig()); + if (makeCommand == null) { + errStream.write("'make' not found.\n"); + return null; + } - IFile projectFile = qtConfig.getProject().getFile(project.getName() + ".pro"); //$NON-NLS-1$ - command.add(projectFile.getLocation().toOSString()); + try (ErrorParserManager epm = new ErrorParserManager(project, qtConfig.getBuildDirectory().toUri(), this, + qtConfig.getToolChain().getErrorParserIds())) { + BuildCommandRunner runner = new BuildCommandRunner(project, console, epm); - ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); - toolChain.setEnvironment(processBuilder.environment()); - Process process = processBuilder.start(); - StringBuffer msg = new StringBuffer(); - for (String arg : command) { - msg.append(arg).append(' '); + Path buildDir = qtConfig.getBuildDirectory(); + if (!buildDir.resolve("Makefile").toFile().exists()) { //$NON-NLS-1$ + // Need to run qmake + List<String> command = new ArrayList<>(); + command.add(qtConfig.getQmakeCommand().toString()); + + String config = qtConfig.getQmakeConfig(); + if (config != null) { + command.add(config); + } + + IFile projectFile = qtConfig.getBuildConfiguration().getProject() + .getFile(project.getName() + ".pro"); //$NON-NLS-1$ + command.add(projectFile.getLocation().toOSString()); + + ProcessBuilder processBuilder = new ProcessBuilder(command) + .directory(qtConfig.getBuildDirectory().toFile()); + CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(processBuilder.environment(), + getBuildConfig(), true); + Process process = processBuilder.start(); + + StringBuffer msg = new StringBuffer(); + for (String arg : command) { + msg.append(arg).append(' '); + } + msg.append('\n'); + outStream.write(msg.toString()); + + runner.monitor(process); } - msg.append('\n'); - console.writeOutput(msg.toString()); - console.monitor(process, null, buildDir); - } - // run make - // TODO obviously hardcoding here - boolean isWin = Platform.getOS().equals(Platform.OS_WIN32); - String make = isWin ? "C:/Qt/Tools/mingw492_32/bin/mingw32-make" : "make"; //$NON-NLS-1$ //$NON-NLS-2$ - ProcessBuilder procBuilder = new ProcessBuilder(make).directory(buildDir.toFile()); - if (isWin) { - // Need to put the toolchain into env - Map<String, String> env = procBuilder.environment(); - String path = env.get("PATH"); //$NON-NLS-1$ - path = "C:/Qt/Tools/mingw492_32/bin;" + path; //$NON-NLS-1$ - env.put("PATH", path); //$NON-NLS-1$ + // run make + ProcessBuilder procBuilder = new ProcessBuilder(makeCommand.toString()).directory(buildDir.toFile()); + CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(procBuilder.environment(), + getBuildConfig(), true); + Process process = procBuilder.start(); + outStream.write(makeCommand.toString() + '\n'); + runner.monitor(process); } - toolChain.setEnvironment(procBuilder.environment()); - Process process = procBuilder.start(); - console.writeOutput("make\n"); //$NON-NLS-1$ - console.monitor(process, null, buildDir); project.refreshLocal(IResource.DEPTH_INFINITE, monitor); // clear the scanner info cache // TODO be more surgical about what to clear based on what was // built. - qtConfig.clearScannerInfoCache(); + // qtConfig.clearScannerInfoCache(); - console.writeOutput("Complete.\n"); + outStream.write("Complete.\n"); return new IProject[] { project }; } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Building " + project.getName(), e)); //$NON-NLS-1$ } } + @Override + protected void clean(IProgressMonitor monitor) throws CoreException { + IProject project = getProject(); + try { + project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(getProject()); + ConsoleOutputStream errStream = console.getErrorStream(); + ConsoleOutputStream outStream = console.getOutputStream(); + + ICBuildConfiguration cconfig = getBuildConfig().getAdapter(ICBuildConfiguration.class); + IQtBuildConfiguration qtConfig = cconfig.getAdapter(QtBuildConfiguration.class); + if (qtConfig == null) { + // Qt hasn't been configured yet print a message and bale + errStream.write(Messages.QtBuilder_0); + return; + } + + Path makeCommand = getMakeCommand(getBuildConfig()); + if (makeCommand == null) { + errStream.write("'make' not found.\n"); + return; + } + + Path buildDir = qtConfig.getBuildDirectory(); + + try (ErrorParserManager epm = new ErrorParserManager(project, qtConfig.getBuildDirectory().toUri(), this, + qtConfig.getToolChain().getErrorParserIds())) { + BuildCommandRunner runner = new BuildCommandRunner(project, console, epm); + // run make + ProcessBuilder procBuilder = new ProcessBuilder(makeCommand.toString(), "clean") //$NON-NLS-1$ + .directory(buildDir.toFile()); + CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(procBuilder.environment(), + getBuildConfig(), true); + Process process = procBuilder.start(); + outStream.write(makeCommand.toString() + "clean\n"); //$NON-NLS-1$ + runner.monitor(process); + } + + project.refreshLocal(IResource.DEPTH_INFINITE, monitor); + + // clear the scanner info cache + // TODO be more surgical about what to clear based on what was + // built. + // qtConfig.clearScannerInfoCache(); + + outStream.write("Complete.\n"); + // TODO Auto-generated method stub + super.clean(monitor); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Cleaning " + project.getName(), e)); //$NON-NLS-1$ + } + } + + public Path getMakeCommand(IBuildConfiguration config) { + Path makeCommand = findCommand(getBuildConfig(), "make"); //$NON-NLS-1$ + if (makeCommand == null) { + makeCommand = findCommand(getBuildConfig(), "mingw32-make"); //$NON-NLS-1$ + } + return makeCommand; + } + + public Path findCommand(IBuildConfiguration config, String command) { + if (Platform.getOS().equals(Platform.OS_WIN32)) { + command += ".exe"; //$NON-NLS-1$ + } + Map<String, String> env = new HashMap<>(System.getenv()); + CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(env, config, true); + String[] path = env.get("PATH").split(File.pathSeparator); //$NON-NLS-1$ + for (String dir : path) { + Path commandPath = Paths.get(dir, command); + if (Files.exists(commandPath)) { + return commandPath; + } + } + return null; + } + } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtScannerInfoProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtScannerInfoProvider.java deleted file mode 100644 index b2b8eacfe27..00000000000 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtScannerInfoProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.build; - -import java.io.IOException; - -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; -import org.eclipse.cdt.core.parser.IScannerInfoProvider; -import org.eclipse.cdt.internal.qt.core.Activator; -import org.eclipse.cdt.qt.core.QtBuildConfiguration; -import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; - -public class QtScannerInfoProvider implements IScannerInfoProvider { - - @Override - public IScannerInfo getScannerInformation(IResource resource) { - try { - IProject project = resource.getProject(); - IBuildConfiguration config = project.getActiveBuildConfig(); - QtBuildConfiguration qtConfig = config.getAdapter(QtBuildConfiguration.class); - if (qtConfig != null) { - return qtConfig.getScannerInfo(resource); - } - } catch (CoreException | IOException e) { - Activator.log(e); - } - return null; - } - - @Override - public void subscribe(IResource resource, IScannerInfoChangeListener listener) { - } - - @Override - public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { - } - -} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalDebugLaunchConfigDelegate.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalDebugLaunchConfigDelegate.java index 2bf05390d69..9f02551480d 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalDebugLaunchConfigDelegate.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalDebugLaunchConfigDelegate.java @@ -10,6 +10,7 @@ package org.eclipse.cdt.internal.qt.core.launch; import java.nio.file.Path; import java.util.concurrent.ExecutionException; +import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; import org.eclipse.cdt.dsf.concurrent.Query; @@ -22,7 +23,7 @@ import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.internal.qt.core.Activator; -import org.eclipse.cdt.qt.core.QtBuildConfiguration; +import org.eclipse.cdt.qt.core.IQtBuildConfiguration; import org.eclipse.cdt.qt.core.QtLaunchConfigurationDelegate; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -60,10 +61,10 @@ public class QtLocalDebugLaunchConfigDelegate extends QtLaunchConfigurationDeleg throws CoreException { GdbLaunch gdbLaunch = (GdbLaunch) launch; ILaunchTarget target = ((ITargetedLaunch) launch).getLaunchTarget(); - QtBuildConfiguration qtBuildConfig = getQtBuildConfiguration(configuration, mode, target, monitor); + IQtBuildConfiguration qtBuildConfig = getQtBuildConfiguration(configuration, mode, target, monitor); - // TODO get it from the toolchain - gdbLaunch.setGDBPath("/usr/local/bin/gdb"); + IToolChain toolChain = qtBuildConfig.getToolChain(); + gdbLaunch.setGDBPath(toolChain.getCommandPath("gdb").toString()); //$NON-NLS-1$ String gdbVersion = gdbLaunch.getGDBVersion(); Path exeFile = qtBuildConfig.getProgramPath(); diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalRunLaunchConfigDelegate.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalRunLaunchConfigDelegate.java index e0c5e0fdb36..c300c209f8d 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalRunLaunchConfigDelegate.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/launch/QtLocalRunLaunchConfigDelegate.java @@ -8,12 +8,14 @@ package org.eclipse.cdt.internal.qt.core.launch; import java.io.IOException; -import java.nio.file.Path; import java.util.Map; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.internal.qt.core.Activator; -import org.eclipse.cdt.qt.core.QtBuildConfiguration; +import org.eclipse.cdt.qt.core.IQtBuildConfiguration; import org.eclipse.cdt.qt.core.QtLaunchConfigurationDelegate; +import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -33,17 +35,17 @@ public class QtLocalRunLaunchConfigDelegate extends QtLaunchConfigurationDelegat public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { ILaunchTarget target = ((ITargetedLaunch) launch).getLaunchTarget(); - QtBuildConfiguration qtBuildConfig = getQtBuildConfiguration(configuration, mode, target, monitor); + IQtBuildConfiguration qtBuildConfig = getQtBuildConfiguration(configuration, mode, target, monitor); - // get the executable - Path exeFile = qtBuildConfig.getProgramPath(); - - ProcessBuilder builder = new ProcessBuilder(exeFile.toString()) - .directory(qtBuildConfig.getProject().getLocation().toFile()); - - // set up the environment - Map<String, String> env = builder.environment(); - qtBuildConfig.setProgramEnvironment(env); + IBuildConfiguration buildConfig = qtBuildConfig.getBuildConfiguration(); + ProcessBuilder processBuilder = new ProcessBuilder(qtBuildConfig.getProgramPath().toString()) + .directory(buildConfig.getProject().getLocation().toFile()); + + Map<String, String> env = processBuilder.environment(); + for (IEnvironmentVariable var : CCorePlugin.getDefault().getBuildEnvironmentManager() + .getVariables(qtBuildConfig.getBuildConfiguration(), true)) { + env.put(var.getName(), var.getValue()); + } Map<String, String> configEnv = configuration.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<String, String>) null); @@ -54,10 +56,10 @@ public class QtLocalRunLaunchConfigDelegate extends QtLaunchConfigurationDelegat } try { - Process process = builder.start(); - DebugPlugin.newProcess(launch, process, "main"); + Process process = processBuilder.start(); + DebugPlugin.newProcess(launch, process, qtBuildConfig.getProgramPath().toString()); } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Failed to start", e)); + throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Launching", e)); } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/HomebrewQtInstallProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/HomebrewQtInstallProvider.java new file mode 100644 index 00000000000..d9614222cd8 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/HomebrewQtInstallProvider.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.internal.qt.core.QtInstall; +import org.eclipse.cdt.qt.core.IQtInstall; +import org.eclipse.cdt.qt.core.IQtInstallProvider; +import org.eclipse.core.runtime.Platform; + +/** + * QtInstall provider for qt out of Homebrew. Unfortunately they don't put it on the path so we have + * to look where they put it. + */ +public class HomebrewQtInstallProvider implements IQtInstallProvider { + + @Override + public Collection<IQtInstall> getInstalls() { + if (Platform.getOS().equals(Platform.OS_MACOSX)) { + Path qmakePath = Paths.get("/usr/local/opt/qt5/bin/qmake"); //$NON-NLS-1$ + if (Files.exists(qmakePath)) { + return Arrays.asList(new QtInstall(qmakePath)); + } + } + 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 new file mode 100644 index 00000000000..7f0b1a5b037 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/Msys2QtInstallProvider.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +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.cdt.utils.WindowsRegistry; +import org.eclipse.core.runtime.Platform; + +/** + * QtInstall provider for Qt in MSYS2. Use the registry to find out where MSYS2 is installed. + */ +public class Msys2QtInstallProvider implements IQtInstallProvider { + + @Override + public Collection<IQtInstall> getInstalls() { + if (Platform.getOS().equals(Platform.OS_WIN32)) { + List<IQtInstall> installs = new ArrayList<>(); + // Look in the current user Uninstall key to look for the uninstaller + 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 ("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)); + } + } + return installs; + } else { + return Collections.emptyList(); + } + } + +} 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 new file mode 100644 index 00000000000..1ebfe465d0e --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/provider/QtInstallProvider.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; + +import org.eclipse.cdt.codan.core.cxx.Activator; +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.cdt.utils.WindowsRegistry; +import org.eclipse.core.runtime.Platform; + +/** + * Qt Install provider that attempts to find the Qt package as installed using Qt's own installer. + */ +public class QtInstallProvider implements IQtInstallProvider { + + @Override + public Collection<IQtInstall> 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) { + try { + return Files.walk(root, 2).filter((path) -> Files.exists(path.resolve(qmake))) + .map((path) -> new QtInstall(path.resolve(qmake))).collect(Collectors.toList()); + } catch (IOException e) { + Activator.log(e); + } + } + return Collections.emptyList(); + } + + private Path getQtRoot() { + if (Platform.getOS().equals(Platform.OS_WIN32)) { + 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); + } + } + } else { + Path qtDir = Paths.get(System.getProperty("user.home"), "Qt"); //$NON-NLS-1$ //$NON-NLS-2$ + if (Files.exists(qtDir)) { + return qtDir; + } + } + return null; + } + + // gcc is in C:\Qt\Tools\mingw492_32\bin +} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtBuildConfiguration.java new file mode 100644 index 00000000000..08abf17b83f --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtBuildConfiguration.java @@ -0,0 +1,26 @@ +/*******************************************************************************
+ * 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.qt.core;
+
+import java.nio.file.Path;
+
+import org.eclipse.cdt.core.build.ICBuildConfiguration;
+
+public interface IQtBuildConfiguration extends ICBuildConfiguration {
+
+ Path getBuildDirectory();
+
+ Path getQmakeCommand();
+
+ String getQmakeConfig();
+
+ Path getProgramPath();
+
+ String getLaunchMode();
+
+}
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 b3014cbc51b..c55fd1a5f02 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 @@ -17,8 +17,6 @@ import java.nio.file.Path; */ public interface IQtInstall { - String getName(); - Path getQmakePath(); String getSpec(); diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java index 424c5cfd475..ee65f0dc517 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallManager.java @@ -7,10 +7,10 @@ *******************************************************************************/ package org.eclipse.cdt.qt.core; +import java.nio.file.Path; import java.util.Collection; -import org.eclipse.cdt.build.core.IToolChain; -import org.eclipse.launchbar.core.target.ILaunchTarget; +import org.eclipse.cdt.core.build.IToolChain; /** * The manager for Qt installs. @@ -23,12 +23,10 @@ public interface IQtInstallManager { public void addInstall(IQtInstall install); - public IQtInstall getInstall(String name); + public IQtInstall getInstall(Path qmakePath); public void removeInstall(IQtInstall install); - public boolean supports(IQtInstall install, ILaunchTarget target); - public boolean supports(IQtInstall install, IToolChain toolChain); } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallProvider.java new file mode 100644 index 00000000000..174a8db53c1 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallProvider.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * 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.qt.core; + +import java.util.Collection; + +public interface IQtInstallProvider { + + Collection<IQtInstall> getInstalls(); + +} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallTargetMapper.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallTargetMapper.java deleted file mode 100644 index 9e61e12b255..00000000000 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtInstallTargetMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.qt.core; - -import org.eclipse.cdt.build.core.IToolChain; -import org.eclipse.launchbar.core.target.ILaunchTarget; - -public interface IQtInstallTargetMapper { - - /** - * Does the Qt install support the given target. - * - * @param qtInstall - * Qt install - * @param launchTarget - * launch target - * @return does the Qt install support the target - */ - public boolean supported(IQtInstall qtInstall, ILaunchTarget launchTarget); - - /** - * Does the Qt install build using the given toolchain? - * - * @param qtInstall - * Qt install - * @param toolChain - * ToolChain - * @return does the Qt install build with the toolchain - */ - public boolean supported(IQtInstall qtInstall, IToolChain toolChain); - -} 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 0001dd62c27..dc3862bccca 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 @@ -7,7 +7,14 @@ *******************************************************************************/ package org.eclipse.cdt.qt.core; -import org.eclipse.cdt.internal.qt.core.build.QtBuildConfigurationFactory; +import java.util.HashMap; +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; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.runtime.CoreException; @@ -21,11 +28,11 @@ public abstract class QtLaunchConfigurationDelegate extends LaunchConfigurationT @Override public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target, IProgressMonitor monitor) throws CoreException { - QtBuildConfiguration qtBuildConfig = getQtBuildConfiguration(configuration, mode, target, monitor); + IQtBuildConfiguration qtBuildConfig = getQtBuildConfiguration(configuration, mode, target, monitor); // Set it as active if (qtBuildConfig != null) { - IProject project = qtBuildConfig.getProject(); + IProject project = qtBuildConfig.getBuildConfiguration().getProject(); IProjectDescription desc = project.getDescription(); desc.setActiveBuildConfig(qtBuildConfig.getBuildConfiguration().getName()); project.setDescription(desc, monitor); @@ -43,11 +50,39 @@ public abstract class QtLaunchConfigurationDelegate extends LaunchConfigurationT return new IProject[] { project }; } - protected QtBuildConfiguration getQtBuildConfiguration(ILaunchConfiguration configuration, String mode, + protected void populateToolChainProperties(ILaunchTarget target, Map<String, String> properties) { + String os = target.getAttribute(ILaunchTarget.ATTR_OS, null); + if (os != null) { + properties.put(IToolChain.ATTR_OS, os); + } + String arch = target.getAttribute(ILaunchTarget.ATTR_ARCH, null); + if (arch != null) { + properties.put(IToolChain.ATTR_ARCH, arch); + } + } + + protected IQtBuildConfiguration getQtBuildConfiguration(ILaunchConfiguration configuration, String mode, ILaunchTarget target, IProgressMonitor monitor) throws CoreException { // Find the Qt build config + ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class); + QtBuildConfigurationProvider provider = (QtBuildConfigurationProvider) configManager + .getProvider(QtBuildConfigurationProvider.ID); IProject project = configuration.getMappedResources()[0].getProject(); - return QtBuildConfigurationFactory.getConfig(project, mode, target, monitor); + + // Find the toolchains that support this target + Map<String, String> properties = new HashMap<>(); + populateToolChainProperties(target, properties); + + IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); + for (IToolChain toolChain : toolChainManager.getToolChainsMatching(properties)) { + IQtBuildConfiguration qtConfig = provider.createConfiguration(project, toolChain, mode, monitor); + if (qtConfig != null) { + return qtConfig; + } + } + + // Couldn't find any + return null; } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationProvider.java index b325ccf6b90..0ef7ef98c1a 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationProvider.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.internal.qt.core.launch.QtLaunchDescriptor; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -45,6 +46,9 @@ public abstract class QtLaunchConfigurationProvider extends AbstractLaunchConfig protected void populateLaunchConfiguration(ILaunchDescriptor descriptor, ILaunchTarget target, ILaunchConfigurationWorkingCopy workingCopy) throws CoreException { super.populateLaunchConfiguration(descriptor, target, workingCopy); + + // Main is actually in the library. Don't stop there + workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false); // Set the project and the connection QtLaunchDescriptor qtDesc = (QtLaunchDescriptor) descriptor; 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 new file mode 100644 index 00000000000..a484f8dedb5 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.qt.core; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; + +import org.eclipse.cdt.build.gcc.core.GCCToolChain; +import org.eclipse.cdt.build.gcc.core.GCCToolChainType; +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.core.build.IToolChainType; +import org.eclipse.cdt.internal.qt.core.Activator; +import org.eclipse.cdt.utils.WindowsRegistry; +import org.eclipse.core.runtime.Platform; + +public class QtMinGWToolChainProvider implements IToolChainProvider { + + @Override + public Collection<IToolChain> getToolChains() { + if (Platform.getOS().equals(Platform.OS_WIN32)) { + WindowsRegistry registry = WindowsRegistry.getRegistry(); + String uninstallKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; //$NON-NLS-1$ + String subkey; + IToolChainType type = Activator.getService(IToolChainManager.class).getToolChainType(GCCToolChainType.ID); + for (int i = 0; (subkey = registry.getCurrentUserKeyName(uninstallKey, i)) != null; i++) { + 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 { + return Files.walk(Paths.get(installLocation).resolve("Tools"), 1) //$NON-NLS-1$ + .filter((path) -> Files.exists(path.resolve(gcc))) + .map((path) -> new GCCToolChain(type, path.resolve("bin"), "gcc.exe")) //$NON-NLS-1$ //$NON-NLS-2$ + .collect(Collectors.toList()); + } catch (IOException e) { + Activator.log(e); + } + } + } + } + // default + return Collections.emptyList(); + } + +} |