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 8354d8651bb..99c169e941a 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 @@ -378,7 +378,8 @@ public class GCCToolChain extends PlatformObject implements IToolChain { } // Look for it in the path environment var - String path = System.getenv("PATH"); //$NON-NLS-1$ + IEnvironmentVariable myPath = getVariable("PATH"); //$NON-NLS-1$ + String path = myPath != null ? myPath.getValue() : System.getenv("PATH"); //$NON-NLS-1$ for (String entry : path.split(File.pathSeparator)) { Path entryPath = Paths.get(entry); Path cmdPath = entryPath.resolve(command); diff --git a/build/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF index 2cf8671247f..3a0eb13fc66 100644 --- a/build/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.cmake.core/META-INF/MANIFEST.MF @@ -11,7 +11,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.launchbar.core;bundle-version="2.0.0", org.eclipse.cdt.core;bundle-version="5.12.0", org.eclipse.tools.templates.freemarker;bundle-version="1.0.0";visibility:=reexport, - com.google.gson + com.google.gson, + org.eclipse.remote.core;bundle-version="2.1.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.cmake.core diff --git a/build/org.eclipse.cdt.cmake.core/plugin.xml b/build/org.eclipse.cdt.cmake.core/plugin.xml index 32a9f20cc16..14b2864eb46 100644 --- a/build/org.eclipse.cdt.cmake.core/plugin.xml +++ b/build/org.eclipse.cdt.cmake.core/plugin.xml @@ -28,7 +28,7 @@ @@ -36,10 +36,10 @@ diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeToolChainFile.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeToolChainFile.java new file mode 100644 index 00000000000..e10371a469f --- /dev/null +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeToolChainFile.java @@ -0,0 +1,13 @@ +package org.eclipse.cdt.cmake.core; + +import java.nio.file.Path; + +public interface ICMakeToolChainFile { + + Path getPath(); + + String getProperty(String key); + + void setProperty(String key, String value); + +} diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeToolChainManager.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeToolChainManager.java new file mode 100644 index 00000000000..d7879a932c3 --- /dev/null +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/ICMakeToolChainManager.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.cmake.core; + +import java.nio.file.Path; +import java.util.Collection; +import java.util.Map; + +/** + * Manages toolchain files for CMake. + * + * @noimplement + */ +public interface ICMakeToolChainManager { + + ICMakeToolChainFile newToolChainFile(Path path); + + void addToolChainFile(ICMakeToolChainFile file); + + void removeToolChainFile(ICMakeToolChainFile file); + + ICMakeToolChainFile getToolChainFile(Path path); + + Collection getToolChainsFileMatching(Map properties); + + Collection getToolChainFiles(); + +} diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/Activator.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/Activator.java index 0f78429c888..cbd7032ac80 100644 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/Activator.java +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/Activator.java @@ -7,6 +7,7 @@ *******************************************************************************/ package org.eclipse.cdt.cmake.core.internal; +import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Plugin; @@ -18,11 +19,14 @@ public class Activator extends Plugin { private static Activator plugin; + @Override public void start(BundleContext bundleContext) throws Exception { super.start(bundleContext); Activator.plugin = this; + bundleContext.registerService(ICMakeToolChainManager.class, new CMakeToolChainManager(), null); } + @Override public void stop(BundleContext bundleContext) throws Exception { super.stop(bundleContext); Activator.plugin = null; diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java index a1a4f7b2e92..6efa8bf43ae 100644 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015, 2016 QNX Software Systems and others. +// * Copyright (c) 2015, 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 @@ -12,10 +12,14 @@ import java.io.FileReader; 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.Arrays; import java.util.List; import java.util.Map; +import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; +import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; import org.eclipse.cdt.core.ConsoleOutputStream; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.IConsoleParser; @@ -28,17 +32,52 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; import com.google.gson.Gson; public class CMakeBuildConfiguration extends CBuildConfiguration { + private static final String TOOLCHAIN_FILE = "cdt.cmake.toolchainfile"; //$NON-NLS-1$ + + private ICMakeToolChainFile toolChainFile; + public CMakeBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { super(config, name); + + Preferences settings = getSettings(); + String pathStr = settings.get(TOOLCHAIN_FILE, ""); //$NON-NLS-1$ + if (!pathStr.isEmpty()) { + Path path = Paths.get(pathStr); + ICMakeToolChainManager manager = Activator.getService(ICMakeToolChainManager.class); + toolChainFile = manager.getToolChainFile(path); + } } public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) { + this(config, name, toolChain, null); + } + + public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain, + ICMakeToolChainFile toolChainFile) { super(config, name, toolChain); + this.toolChainFile = toolChainFile; + + if (toolChainFile != null) { + Preferences settings = getSettings(); + settings.put(TOOLCHAIN_FILE, toolChainFile.getPath().toString()); + try { + settings.flush(); + } catch (BackingStoreException e) { + Activator.log(e); + } + } + } + + public ICMakeToolChainFile getToolChainFile() { + return toolChainFile; } @Override @@ -52,12 +91,35 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { Path buildDir = getBuildDirectory(); + outStream.write(String.format("Building in: %s\n", buildDir.toString())); + if (!Files.exists(buildDir.resolve("Makefile"))) { //$NON-NLS-1$ - // TODO assuming cmake is in the path here, probably need a - // preference in case it isn't. - List command = Arrays.asList("/usr/local/bin/cmake", //$NON-NLS-1$ - "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", new File(project.getLocationURI()).getAbsolutePath()); //$NON-NLS-1$ + List command = new ArrayList<>(); + + // TODO assuming cmake is in the path here, probably need a preference in case it isn't. + Path cmakePath = CBuildConfiguration.getCommandFromPath(Paths.get("cmake")); //$NON-NLS-1$ + if (cmakePath == null) { + if (!Platform.getOS().equals(Platform.OS_WIN32)) { + cmakePath = Paths.get("/usr/local/bin/cmake"); //$NON-NLS-1$ + } else { + cmakePath = Paths.get("cmake"); //$NON-NLS-1$ + } + } + command.add(cmakePath.toString()); + + command.add("-G"); //$NON-NLS-1$ + // TODO ninja? + command.add("Unix Makefiles"); //$NON-NLS-1$ + + if (toolChainFile != null) { + command.add("-DCMAKE_TOOLCHAIN_FILE=" + toolChainFile.getPath().toString()); //$NON-NLS-1$ + } + + command.add("-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"); //$NON-NLS-1$ + command.add(new File(project.getLocationURI()).getAbsolutePath()); + ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); + setBuildEnvironment(processBuilder.environment()); Process process = processBuilder.start(); outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ watchProcess(process, new IConsoleParser[0], console); @@ -68,6 +130,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { // TODO need to figure out which builder to call. Hardcoding to make for now. List command = Arrays.asList("make"); //$NON-NLS-1$ ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); + setBuildEnvironment(processBuilder.environment()); Process process = processBuilder.start(); outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ watchProcess(process, new IConsoleParser[] { epm }, console); diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationProvider.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationProvider.java index 51f6d313f22..9a2dcfe82c2 100644 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationProvider.java +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationProvider.java @@ -7,21 +7,31 @@ *******************************************************************************/ package org.eclipse.cdt.cmake.core.internal; +import java.util.Collection; import java.util.HashMap; import java.util.Map; +import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; +import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; 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.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.Platform; public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProvider { public static final String ID = "org.eclipse.cdt.cmake.core.provider"; //$NON-NLS-1$ + private ICMakeToolChainManager manager = Activator.getService(ICMakeToolChainManager.class); + private IToolChainManager tcManager = Activator.getService(IToolChainManager.class); + private ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class); + @Override public String getId() { return ID; @@ -61,4 +71,35 @@ public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProv } } + public CMakeBuildConfiguration getCBuildConfiguration(IProject project, Map properties, + String launchMode, IProgressMonitor monitor) throws CoreException { + for (IBuildConfiguration config : project.getBuildConfigs()) { + ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + if (cconfig != null) { + CMakeBuildConfiguration cmakeConfig = cconfig.getAdapter(CMakeBuildConfiguration.class); + if (cmakeConfig != null && cmakeConfig.getToolChain().matches(properties)) { + return cmakeConfig; + } + } + } + + Collection tcs = tcManager.getToolChainsMatching(properties); + if (tcs.isEmpty()) { + return null; + } + IToolChain toolChain = tcs.iterator().next(); + + ICMakeToolChainFile file = null; + Collection files = manager.getToolChainsFileMatching(properties); + if (!files.isEmpty()) { + file = files.iterator().next(); + } + + String configName = "cmake." + toolChain.getId(); //$NON-NLS-1$ + IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, monitor); + CMakeBuildConfiguration cmakeConfig = new CMakeBuildConfiguration(config, configName, toolChain, file); + configManager.addBuildConfiguration(config, cmakeConfig); + return cmakeConfig; + } + } diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchConfigurationDelegate.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchConfigurationDelegate.java new file mode 100644 index 00000000000..f698335c046 --- /dev/null +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchConfigurationDelegate.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * 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.cmake.core.internal; + +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.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.ILaunchConfigurationDelegate; +import org.eclipse.launchbar.core.target.ILaunchTarget; +import org.eclipse.launchbar.core.target.launch.LaunchConfigurationTargetedDelegate; + +public class CMakeLaunchConfigurationDelegate extends LaunchConfigurationTargetedDelegate + implements ILaunchConfigurationDelegate { + + public static final String TYPE_ID = "org.eclipse.cdt.cmake.core.launchConfigurationType"; //$NON-NLS-1$ + + private ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class); + + private IProject getProject(ILaunchConfiguration configuration) throws CoreException { + return configuration.getMappedResources()[0].getProject(); + } + + @Override + public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target, + IProgressMonitor monitor) throws CoreException { + // Set active build config based on target + CMakeBuildConfigurationProvider provider = (CMakeBuildConfigurationProvider) configManager + .getProvider(CMakeBuildConfigurationProvider.ID); + + Map properties = new HashMap<>(); + String os = target.getAttribute(ILaunchTarget.ATTR_OS, ""); //$NON-NLS-1$ + if (!os.isEmpty()) { + properties.put(IToolChain.ATTR_OS, os); + } + String arch = target.getAttribute(ILaunchTarget.ATTR_ARCH, ""); //$NON-NLS-1$ + if (!arch.isEmpty()) { + properties.put(IToolChain.ATTR_ARCH, arch); + } + + IProject project = getProject(configuration); + CMakeBuildConfiguration config = provider.getCBuildConfiguration(project, properties, mode, monitor); + if (config != null) { + IProjectDescription desc = project.getDescription(); + desc.setActiveBuildConfig(config.getBuildConfiguration().getName()); + project.setDescription(desc, monitor); + } + + return superBuildForLaunch(configuration, mode, monitor); + } + + @Override + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) + throws CoreException { + // TODO need to find the binary and launch it. + // Though, more likely, need to have launch configs per binary. + } + + @Override + protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException { + // 1. Extract project from configuration + // TODO dependencies too. + IProject project = getProject(configuration); + return new IProject[] { project }; + } + +} diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLocalLaunchConfigurationProvider.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchConfigurationProvider.java similarity index 76% rename from build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLocalLaunchConfigurationProvider.java rename to build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchConfigurationProvider.java index 55d40734a0c..ffc81526676 100644 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLocalLaunchConfigurationProvider.java +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchConfigurationProvider.java @@ -11,6 +11,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; @@ -23,25 +26,46 @@ import org.eclipse.launchbar.core.ILaunchDescriptor; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.launchbar.core.target.ILaunchTargetManager; -public class CMakeLocalLaunchConfigurationProvider extends AbstractLaunchConfigProvider { +public class CMakeLaunchConfigurationProvider extends AbstractLaunchConfigProvider { + + private final ICMakeToolChainManager manager = Activator.getService(ICMakeToolChainManager.class); + private final IToolChainManager tcManager = Activator.getService(IToolChainManager.class); private Map configs = new HashMap<>(); @Override public boolean supports(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException { - return ILaunchTargetManager.localLaunchTargetTypeId.equals(target.getTypeId()); + if (ILaunchTargetManager.localLaunchTargetTypeId.equals(target.getTypeId())) { + return true; + } + + String os = target.getAttribute(ILaunchTarget.ATTR_OS, ""); //$NON-NLS-1$ + if (os.isEmpty()) { + return false; + } + + String arch = target.getAttribute(ILaunchTarget.ATTR_ARCH, ""); //$NON-NLS-1$ + if (arch.isEmpty()) { + return false; + } + + Map properties = new HashMap<>(); + properties.put(IToolChain.ATTR_OS, os); + properties.put(IToolChain.ATTR_ARCH, arch); + if (manager.getToolChainsFileMatching(properties).isEmpty()) { + return false; + } + + return !tcManager.getToolChainsMatching(properties).isEmpty(); } @Override public ILaunchConfigurationType getLaunchConfigurationType(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException { return DebugPlugin.getDefault().getLaunchManager() - .getLaunchConfigurationType(CMakeLocalRunLaunchConfigDelegate.TYPE_ID); + .getLaunchConfigurationType(CMakeLaunchConfigurationDelegate.TYPE_ID); } - // TODO the rest here is the same as the Qt provider. Opportunity to create - // a common super class - @Override public ILaunchConfiguration getLaunchConfiguration(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException { diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLocalRunLaunchConfigDelegate.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLocalRunLaunchConfigDelegate.java deleted file mode 100644 index 2bb8db73679..00000000000 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLocalRunLaunchConfigDelegate.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.cmake.core.internal; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.model.ILaunchConfigurationDelegate; -import org.eclipse.launchbar.core.target.launch.LaunchConfigurationTargetedDelegate; - -public class CMakeLocalRunLaunchConfigDelegate extends LaunchConfigurationTargetedDelegate - implements ILaunchConfigurationDelegate { - - public static final String TYPE_ID = "org.eclipse.cdt.cmake.core.localLunchConfigurationType"; //$NON-NLS-1$ - - @Override - public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) - throws CoreException { - // TODO need to find the binary and launch it. - } - - @Override - protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException { - // 1. Extract project from configuration - // TODO dependencies too. - IProject project = configuration.getMappedResources()[0].getProject(); - return new IProject[] { project }; - } - -} diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeToolChainFile.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeToolChainFile.java new file mode 100644 index 00000000000..5e97996a5c2 --- /dev/null +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeToolChainFile.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.cmake.core.internal; + +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; + +public class CMakeToolChainFile implements ICMakeToolChainFile { + + String n; + private final Path path; + + final Map properties = new HashMap<>(); + + public CMakeToolChainFile(String n, Path path) { + this.n = n; + this.path = path; + } + + @Override + public Path getPath() { + return path; + } + + @Override + public String getProperty(String key) { + return properties.get(key); + } + + @Override + public void setProperty(String key, String value) { + properties.put(key, value); + } + + boolean matches(Map properties) { + for (Map.Entry property : properties.entrySet()) { + if (!property.getValue().equals(getProperty(property.getKey()))) { + return false; + } + } + return true; + } + +} diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeToolChainManager.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeToolChainManager.java new file mode 100644 index 00000000000..4ac5b957d12 --- /dev/null +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeToolChainManager.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * 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.cmake.core.internal; + +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.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; +import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +public class CMakeToolChainManager implements ICMakeToolChainManager { + + private Map files; + + private static final String N = "n"; //$NON-NLS-1$ + private static final String PATH = "__path"; //$NON-NLS-1$ + + private Preferences getPreferences() { + return InstanceScope.INSTANCE.getNode(Activator.getId()).node("cmakeToolchains"); //$NON-NLS-1$ + } + + private void init() { + if (files == null) { + files = new HashMap<>(); + + Preferences prefs = getPreferences(); + try { + for (String childName : prefs.childrenNames()) { + Preferences tcNode = prefs.node(childName); + String path = tcNode.get(PATH, "/"); //$NON-NLS-1$ + ICMakeToolChainFile file = new CMakeToolChainFile(childName, Paths.get(path)); + for (String key : tcNode.keys()) { + String value = tcNode.get(key, ""); //$NON-NLS-1$ + if (!value.isEmpty()) { + file.setProperty(key, value); + } + } + files.put(file.getPath(), file); + } + } catch (BackingStoreException e) { + Activator.log(e); + } + + // TODO discovery + } + } + + @Override + public ICMakeToolChainFile newToolChainFile(Path path) { + return new CMakeToolChainFile(null, path); + } + + @Override + public void addToolChainFile(ICMakeToolChainFile file) { + init(); + files.put(file.getPath(), file); + + // save it + + CMakeToolChainFile realFile = (CMakeToolChainFile) file; + Preferences prefs = getPreferences(); + String n = realFile.n; + if (n == null) { + n = prefs.get(N, "0"); //$NON-NLS-1$ + realFile.n = n; + } + prefs.put(N, Integer.toString(Integer.parseInt(n) + 1)); + + Preferences tcNode = prefs.node(n); + tcNode.put(PATH, file.getPath().toString()); + for (Entry entry : realFile.properties.entrySet()) { + tcNode.put(entry.getKey(), entry.getValue()); + } + + try { + prefs.flush(); + } catch (BackingStoreException e) { + Activator.log(e); + } + } + + @Override + public void removeToolChainFile(ICMakeToolChainFile file) { + init(); + files.remove(file.getPath()); + + String n = ((CMakeToolChainFile) file).n; + if (n != null) { + Preferences prefs = getPreferences(); + Preferences tcNode = prefs.node(n); + try { + tcNode.removeNode(); + prefs.flush(); + } catch (BackingStoreException e) { + Activator.log(e); + } + } + } + + @Override + public ICMakeToolChainFile getToolChainFile(Path path) { + init(); + return files.get(path); + } + + @Override + public Collection getToolChainFiles() { + init(); + return Collections.unmodifiableCollection(files.values()); + } + + @Override + public Collection getToolChainsFileMatching(Map properties) { + List matches = new ArrayList<>(); + for (ICMakeToolChainFile file : getToolChainFiles()) { + boolean match = true; + for (Entry entry : properties.entrySet()) { + if (!entry.getValue().equals(file.getProperty(entry.getKey()))) { + match = false; + break; + } + } + + if (match) { + matches.add(file); + } + } + return matches; + } + +} diff --git a/build/org.eclipse.cdt.cmake.ui/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.cmake.ui/META-INF/MANIFEST.MF index a3b64a155fd..d57e9c50e80 100644 --- a/build/org.eclipse.cdt.cmake.ui/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.cmake.ui/META-INF/MANIFEST.MF @@ -10,6 +10,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.ui, org.eclipse.ui.ide, org.eclipse.cdt.cmake.core, - org.eclipse.tools.templates.ui;bundle-version="1.1.0" + org.eclipse.tools.templates.ui;bundle-version="1.1.0", + org.eclipse.cdt.core;bundle-version="6.1.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin diff --git a/build/org.eclipse.cdt.cmake.ui/plugin.properties b/build/org.eclipse.cdt.cmake.ui/plugin.properties new file mode 100644 index 00000000000..e4c6c7270fa --- /dev/null +++ b/build/org.eclipse.cdt.cmake.ui/plugin.properties @@ -0,0 +1,9 @@ +############################################################################### +# 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 +############################################################################### + +cmake.preferences.name = CMake diff --git a/build/org.eclipse.cdt.cmake.ui/plugin.xml b/build/org.eclipse.cdt.cmake.ui/plugin.xml index 3edcc339bcd..c76595197c8 100644 --- a/build/org.eclipse.cdt.cmake.ui/plugin.xml +++ b/build/org.eclipse.cdt.cmake.ui/plugin.xml @@ -20,6 +20,14 @@ + + + + T getService(Class service) { + BundleContext context = plugin.getBundle().getBundleContext(); + ServiceReference ref = context.getServiceReference(service); + return ref != null ? context.getService(ref) : null; + } + } diff --git a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakePreferencePage.java b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakePreferencePage.java new file mode 100644 index 00000000000..e6cae98fb80 --- /dev/null +++ b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/CMakePreferencePage.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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.cmake.ui.internal; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; +import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +public class CMakePreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + private ICMakeToolChainManager manager; + private Table filesTable; + private Button removeButton; + + private Map filesToAdd = new HashMap<>(); + private Map filesToRemove = new HashMap<>(); + + @Override + public void init(IWorkbench workbench) { + manager = Activator.getService(ICMakeToolChainManager.class); + } + + @Override + protected Control createContents(Composite parent) { + Composite control = new Composite(parent, SWT.NONE); + control.setLayout(new GridLayout()); + + Group filesGroup = new Group(control, SWT.NONE); + filesGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + filesGroup.setText("ToolChain Files"); + filesGroup.setLayout(new GridLayout(2, false)); + + Composite filesComp = new Composite(filesGroup, SWT.NONE); + filesComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + filesTable = new Table(filesComp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + filesTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + filesTable.setHeaderVisible(true); + filesTable.setLinesVisible(true); + filesTable.addListener(SWT.Selection, e -> { + TableItem[] items = filesTable.getSelection(); + removeButton.setEnabled(items.length > 0); + }); + + TableColumn pathColumn = new TableColumn(filesTable, SWT.NONE); + pathColumn.setText("ToolChain File"); + + TableColumn osColumn = new TableColumn(filesTable, SWT.NONE); + osColumn.setText("OS"); + + TableColumn archColumn = new TableColumn(filesTable, SWT.NONE); + archColumn.setText("CPU"); + + TableColumnLayout tableLayout = new TableColumnLayout(); + tableLayout.setColumnData(pathColumn, new ColumnWeightData(75, 350, true)); + tableLayout.setColumnData(osColumn, new ColumnWeightData(25, 100, true)); + tableLayout.setColumnData(archColumn, new ColumnWeightData(25, 100, true)); + filesComp.setLayout(tableLayout); + + Composite buttonsComp = new Composite(filesGroup, SWT.NONE); + buttonsComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); + buttonsComp.setLayout(new GridLayout()); + + Button addButton = new Button(buttonsComp, SWT.PUSH); + addButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + addButton.setText("Add..."); + addButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + NewCMakeToolChainFileWizard wizard = new NewCMakeToolChainFileWizard(getFiles()); + WizardDialog dialog = new WizardDialog(getShell(), wizard); + if (dialog.open() == Window.OK) { + ICMakeToolChainFile file = wizard.getNewFile(); + if (filesToRemove.containsKey(file.getPath())) { + filesToRemove.remove(file.getPath()); + } else { + filesToAdd.put(file.getPath(), file); + } + updateTable(); + } + } + }); + + removeButton = new Button(buttonsComp, SWT.PUSH); + removeButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + removeButton.setText("Remove"); + removeButton.setEnabled(false); + removeButton.addListener(SWT.Selection, e -> { + if (MessageDialog.openConfirm(getShell(), "Deregister CMake ToolChain File", + "Do you wish to deregister the selected files?")) { + for (TableItem item : filesTable.getSelection()) { + ICMakeToolChainFile file = (ICMakeToolChainFile) item.getData(); + if (filesToAdd.containsKey(file.getPath())) { + filesToAdd.remove(file.getPath()); + } else { + filesToRemove.put(file.getPath(), file); + } + updateTable(); + } + } + }); + + updateTable(); + + return control; + } + + private void updateTable() { + List sorted = new ArrayList<>(getFiles().values()); + Collections.sort(sorted, (o1, o2) -> o1.getPath().toString().compareToIgnoreCase(o2.getPath().toString())); + + filesTable.removeAll(); + for (ICMakeToolChainFile file : sorted) { + TableItem item = new TableItem(filesTable, SWT.NONE); + item.setText(0, file.getPath().toString()); + String os = file.getProperty(IToolChain.ATTR_OS); + if (os != null) { + item.setText(1, os); + } + String arch = file.getProperty(IToolChain.ATTR_ARCH); + if (arch != null) { + item.setText(2, arch); + } + item.setData(file); + } + } + + private Map getFiles() { + Map files = new HashMap<>(); + for (ICMakeToolChainFile file : manager.getToolChainFiles()) { + files.put(file.getPath(), file); + } + + for (ICMakeToolChainFile file : filesToAdd.values()) { + files.put(file.getPath(), file); + } + + for (ICMakeToolChainFile file : filesToRemove.values()) { + files.remove(file.getPath()); + } + + return files; + } + + @Override + public boolean performOk() { + for (ICMakeToolChainFile file : filesToAdd.values()) { + manager.addToolChainFile(file); + } + + for (ICMakeToolChainFile file : filesToRemove.values()) { + manager.removeToolChainFile(file); + } + + return true; + } + +} diff --git a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/Messages.java b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java similarity index 91% rename from build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/Messages.java rename to build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java index 33caa15ce4f..172957a1a42 100644 --- a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/Messages.java +++ b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/Messages.java @@ -1,4 +1,4 @@ -package org.eclipse.cdt.cmake.ui.properties; +package org.eclipse.cdt.cmake.ui.internal; import org.eclipse.osgi.util.NLS; diff --git a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeProjectWizard.java b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeProjectWizard.java index 0e4e431da92..ba0e59ba7f2 100644 --- a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeProjectWizard.java +++ b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeProjectWizard.java @@ -1,3 +1,10 @@ +/******************************************************************************* + * 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.cmake.ui.internal; import org.eclipse.cdt.cmake.core.CMakeProjectGenerator; diff --git a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeToolChainFilePage.java b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeToolChainFilePage.java new file mode 100644 index 00000000000..9317a9316b6 --- /dev/null +++ b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeToolChainFilePage.java @@ -0,0 +1,129 @@ +package org.eclipse.cdt.cmake.ui.internal; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; +import org.eclipse.cdt.cmake.core.ICMakeToolChainManager; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +public class NewCMakeToolChainFilePage extends WizardPage { + + private final Map existing; + private Text pathText; + private Text osText; + private Text archText; + + public NewCMakeToolChainFilePage(Map existing) { + super("NewCMakeToolChainFilePage", "New CMake ToolChain File", null); //$NON-NLS-1$ + this.existing = existing; + } + + @Override + public void createControl(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + comp.setLayout(new GridLayout(2, false)); + + Label pathLabel = new Label(comp, SWT.NONE); + pathLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + pathLabel.setText("Path:"); + + Composite pathComp = new Composite(comp, SWT.NONE); + pathComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = layout.marginWidth = 0; + pathComp.setLayout(layout); + + pathText = new Text(pathComp, SWT.BORDER); + pathText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + pathText.addModifyListener(e -> validate()); + + Button pathButton = new Button(pathComp, SWT.PUSH); + pathButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + pathButton.setText("Browse..."); + pathButton.addListener(SWT.Selection, e -> { + FileDialog dialog = new FileDialog(getShell(), SWT.OPEN); + dialog.setText("Select location for CMake toolchain file"); + String path = dialog.open(); + if (path != null) { + pathText.setText(path); + } + }); + + Label osLabel = new Label(comp, SWT.NONE); + osLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + osLabel.setText("Target OS:"); + + osText = new Text(comp, SWT.BORDER); + osText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + osText.addModifyListener(e -> validate()); + + Label archLabel = new Label(comp, SWT.NONE); + archLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + archLabel.setText("Target CPU:"); + + archText = new Text(comp, SWT.BORDER); + archText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + archText.addModifyListener(e -> validate()); + + setControl(comp); + validate(); + } + + private void validate() { + setPageComplete(false); + + String path = pathText.getText(); + if (path.isEmpty()) { + setErrorMessage("Please set the path to the CMake toolchain file."); + return; + } + + if (existing.containsKey(Paths.get(path))) { + setErrorMessage("CMake toolchain file entry already exists."); + return; + } + + if (osText.getText().isEmpty()) { + setErrorMessage("Please set the target operating system."); + return; + } + + if (archText.getText().isEmpty()) { + setErrorMessage("Please set the target CPU architecture."); + return; + } + + setPageComplete(true); + setErrorMessage(null); + } + + public ICMakeToolChainFile getNewFile() { + ICMakeToolChainManager manager = Activator.getService(ICMakeToolChainManager.class); + ICMakeToolChainFile file = manager.newToolChainFile(Paths.get(pathText.getText())); + + String os = osText.getText(); + if (!os.isEmpty()) { + file.setProperty(IToolChain.ATTR_OS, os); + } + + String arch = archText.getText(); + if (!arch.isEmpty()) { + file.setProperty(IToolChain.ATTR_ARCH, arch); + } + + return file; + } + +} diff --git a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeToolChainFileWizard.java b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeToolChainFileWizard.java new file mode 100644 index 00000000000..f5be2f3e642 --- /dev/null +++ b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/NewCMakeToolChainFileWizard.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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.cmake.ui.internal; + +import java.nio.file.Path; +import java.util.Map; + +import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; +import org.eclipse.jface.wizard.Wizard; + +public class NewCMakeToolChainFileWizard extends Wizard { + + private ICMakeToolChainFile newFile; + private NewCMakeToolChainFilePage page; + + public NewCMakeToolChainFileWizard(Map existing) { + page = new NewCMakeToolChainFilePage(existing); + } + + @Override + public void addPages() { + addPage(page); + } + + @Override + public boolean performFinish() { + newFile = page.getNewFile(); + return true; + } + + public ICMakeToolChainFile getNewFile() { + return newFile; + } + +} diff --git a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/messages.properties b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/messages.properties similarity index 100% rename from build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/messages.properties rename to build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/internal/messages.properties diff --git a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/CMakePropertyPage.java b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/CMakePropertyPage.java index 65052826fcc..7699a3c82d4 100644 --- a/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/CMakePropertyPage.java +++ b/build/org.eclipse.cdt.cmake.ui/src/org/eclipse/cdt/cmake/ui/properties/CMakePropertyPage.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.cmake.ui.properties; import java.io.IOException; +import org.eclipse.cdt.cmake.ui.internal.Messages; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.dialogs.MessageDialog; @@ -35,13 +36,11 @@ import org.eclipse.ui.dialogs.PropertyPage; */ public class CMakePropertyPage extends PropertyPage { + @Override protected Control createContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - composite.setLayout(layout); - GridData data = new GridData(GridData.FILL); - data.grabExcessHorizontalSpace = true; - composite.setLayoutData(data); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + composite.setLayout(new GridLayout()); Button b = new Button(composite, SWT.NONE); b.setText(Messages.CMakePropertyPage_LaunchCMakeGui); diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java index aa52d7812e8..9f056db9cd1 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java @@ -620,4 +620,35 @@ public abstract class CBuildConfiguration extends PlatformObject } } + /** + * Takes a command path and returns either the command path itself if it is + * absolute or the path to the command as it appears in the PATH environment + * variable. Also adjusts the command for Windows's .exe extension. + * + * @since 6.1 + */ + public static Path getCommandFromPath(Path command) { + if (command.isAbsolute()) { + return command; + } + + if (Platform.getOS().equals(Platform.OS_WIN32)) { + if (!command.toString().endsWith(".exe")) { //$NON-NLS-1$ + command = Paths.get(command.toString() + ".exe"); //$NON-NLS-1$ + } + } + + // Look for it in the path environment var + String path = System.getenv("PATH"); //$NON-NLS-1$ + for (String entry : path.split(File.pathSeparator)) { + Path entryPath = Paths.get(entry); + Path cmdPath = entryPath.resolve(command); + if (Files.isExecutable(cmdPath)) { + return cmdPath; + } + } + + return null; + } + } 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 22e90093fce..3d3cb0dda58 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 @@ -12,6 +12,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.model.ILanguage; @@ -244,4 +245,16 @@ public interface IToolChain extends IAdaptable { return command; } + /** + * @since 6.1 + */ + default boolean matches(Map properties) { + for (Map.Entry property : properties.entrySet()) { + if (!property.getValue().equals(getProperty(property.getKey()))) { + return false; + } + } + return true; + } + } 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 c8cbcd0ac89..b4988a486da 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 @@ -28,7 +28,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; @@ -39,7 +39,7 @@ public class QtInstallManager implements IQtInstallManager { private List listeners = new LinkedList<>(); private Preferences getPreferences() { - return ConfigurationScope.INSTANCE.getNode(Activator.ID).node("qtInstalls"); //$NON-NLS-1$ + return InstanceScope.INSTANCE.getNode(Activator.ID).node("qtInstalls"); //$NON-NLS-1$ } private void initInstalls() { diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/Messages.java b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/Messages.java index 70ca439e7e7..4d5c663e07b 100644 --- a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/Messages.java +++ b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/Messages.java @@ -19,8 +19,6 @@ public class Messages extends NLS { public static String NewQtInstallWizardPage_3; public static String NewQtInstallWizardPage_4; public static String NewQtInstallWizardPage_5; - public static String NewQtInstallWizardPage_6; - public static String NewQtInstallWizardPage_7; public static String NewQtInstallWizardPage_8; public static String NewQtInstallWizardPage_9; public static String QtPreferencePage_0; diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/messages.properties b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/messages.properties index 5654d25abc8..2f96228e735 100644 --- a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/messages.properties +++ b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/messages.properties @@ -6,14 +6,12 @@ NewQtInstallWizardPage_2=Name: NewQtInstallWizardPage_3=Location: NewQtInstallWizardPage_4=Browse... NewQtInstallWizardPage_5=Select location of qmake -NewQtInstallWizardPage_6=qmake.exe -NewQtInstallWizardPage_7=qmake NewQtInstallWizardPage_8=Get Qt Spec NewQtInstallWizardPage_9=mkspec: QtPreferencePage_0=Qt Installs QtPreferencePage_1=Location QtPreferencePage_2=mkspec -QtPreferencePage_3=Add +QtPreferencePage_3=Add... QtPreferencePage_4=Remove QtPreferencePage_5=Remove Qt Install QtPreferencePage_6=Are you sure you want to remove the selected Qt installs? 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 bb7d113d173..fc3ee5de8f3 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 @@ -69,7 +69,7 @@ public class NewQtInstallWizardPage extends WizardPage { FileDialog dialog = new FileDialog(getShell(), SWT.OPEN); dialog.setText(Messages.NewQtInstallWizardPage_5); dialog.setFilterExtensions( - new String[] { Platform.getOS().equals(Platform.OS_WIN32) ? Messages.NewQtInstallWizardPage_6 : Messages.NewQtInstallWizardPage_7 }); + new String[] { Platform.getOS().equals(Platform.OS_WIN32) ? "qmake.exe" : "qmake" }); //$NON-NLS-1$ //$NON-NLS-2$ String selected = dialog.open(); if (selected != null) { locationText.setText(selected); diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/QtPreferencePage.java b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/QtPreferencePage.java index 142e87a5b0d..82c8217bddb 100644 --- a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/QtPreferencePage.java +++ b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/preferences/QtPreferencePage.java @@ -103,7 +103,11 @@ public class QtPreferencePage extends PreferencePage implements IWorkbenchPrefer WizardDialog dialog = new WizardDialog(getShell(), wizard); if (dialog.open() == Window.OK) { IQtInstall install = wizard.getInstall(); - installsToAdd.put(install.getQmakePath(), install); + if (installsToRemove.containsKey(install.getQmakePath())) { + installsToRemove.remove(install.getQmakePath()); + } else { + installsToAdd.put(install.getQmakePath(), install); + } updateTable(); } } @@ -117,7 +121,11 @@ public class QtPreferencePage extends PreferencePage implements IWorkbenchPrefer if (MessageDialog.openConfirm(getShell(), Messages.QtPreferencePage_5, Messages.QtPreferencePage_6)) { for (TableItem item : installTable.getSelection()) { IQtInstall install = (IQtInstall) item.getData(); - installsToRemove.put(install.getQmakePath(), install); + if (installsToAdd.containsKey(install.getQmakePath())) { + installsToAdd.remove(install.getQmakePath()); + } else { + installsToRemove.put(install.getQmakePath(), install); + } updateTable(); } } @@ -153,7 +161,10 @@ public class QtPreferencePage extends PreferencePage implements IWorkbenchPrefer for (IQtInstall install : sorted) { TableItem item = new TableItem(installTable, SWT.NONE); item.setText(0, install.getQmakePath().toString()); - item.setText(1, install.getSpec()); + String spec = install.getSpec(); + if (spec != null) { + item.setText(1, install.getSpec()); + } item.setData(install); } }