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 e91fae99e85..6b28435461d 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 @@ -66,21 +66,20 @@ public class CMakeBuildConfigurationProvider implements ICBuildConfigurationProv // No valid combinations return null; } + } + CMakeBuildConfiguration cmakeConfig = new CMakeBuildConfiguration(config, name); + ICMakeToolChainFile tcFile = cmakeConfig.getToolChainFile(); + IToolChain toolChain = cmakeConfig.getToolChain(); + if (toolChain == null) { + // config not complete + return null; + } + if (tcFile != null && !toolChain.equals(tcFile.getToolChain())) { + // toolchain changed + return new CMakeBuildConfiguration(config, name, tcFile.getToolChain(), tcFile, + cmakeConfig.getLaunchMode()); } else { - CMakeBuildConfiguration cmakeConfig = new CMakeBuildConfiguration(config, name); - ICMakeToolChainFile tcFile = cmakeConfig.getToolChainFile(); - IToolChain toolChain = cmakeConfig.getToolChain(); - if (toolChain == null || tcFile == null) { - // config not complete? - return null; - } - if (!toolChain.equals(tcFile.getToolChain())) { - // toolchain changed - return new CMakeBuildConfiguration(config, name, tcFile.getToolChain(), tcFile, - cmakeConfig.getLaunchMode()); - } else { - return cmakeConfig; - } + return cmakeConfig; } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationManager2.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationManager2.java new file mode 100644 index 00000000000..749e2471a8b --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationManager2.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat Inc. 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 + * + * Contributors: + * Red Hat Inc. - initial implementation + *******************************************************************************/ +package org.eclipse.cdt.core.build; + +/** + * @since 6.5 + */ +public interface ICBuildConfigurationManager2 { + + /** + * Re-evaluate disabled configs to see if they should be re-enabled. + */ + public void recheckConfigs(); + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java index babca7dfa57..eaa35c8ec4f 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java @@ -16,6 +16,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -23,6 +24,7 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager2; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.build.IToolChainManager; @@ -46,7 +48,7 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; -public class CBuildConfigurationManager implements ICBuildConfigurationManager, IResourceChangeListener { +public class CBuildConfigurationManager implements ICBuildConfigurationManager, ICBuildConfigurationManager2, IResourceChangeListener { private static class Provider { private String id; @@ -177,6 +179,59 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager, CModelManager.getDefault().resetBinaryParser(buildConfig.getProject()); } + @Override + public void recheckConfigs() { + initProviders(); + ICBuildConfiguration config = null; + Set projects = new HashSet<>(); + synchronized (configs) { + Iterator iterator = noConfigs.iterator(); + while (iterator.hasNext()) { + IBuildConfiguration buildConfig = iterator.next(); + String configName = null; + ICBuildConfigurationProvider provider = null; + if (IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(buildConfig.getName())) { + configName = ICBuildConfiguration.DEFAULT_NAME; + try { + provider = getProvider(buildConfig.getProject()); + } catch (CoreException e) { + continue; + } + } else { + String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$ + if (segments.length == 2) { + String providerId = segments[0]; + configName = segments[1]; + Provider delegate = getProviderDelegate(providerId); + if (delegate != null && delegate.supports(buildConfig.getProject())) { + provider = delegate.getProvider(); + } + } + } + + if (provider != null) { + try { + config = provider.getCBuildConfiguration(buildConfig, configName); + } catch (CoreException e) { + // do nothing + } + if (config != null) { + iterator.remove(); + projects.add(buildConfig.getProject()); + configs.put(buildConfig, config); + } + } + + } + } + + for (IProject project : projects) { + // Do this outside of the synchronized block to avoid deadlock with + // BinaryRunner + CModelManager.getDefault().resetBinaryParser(project); + } + } + @Override public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) throws CoreException { initProviders(); diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java index 516f9396074..73b40a44527 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java @@ -10,10 +10,15 @@ *******************************************************************************/ package org.eclipse.cdt.docker.launcher; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager2; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; @@ -24,7 +29,9 @@ import org.eclipse.launchbar.core.target.ILaunchTargetProvider; import org.eclipse.launchbar.core.target.ILaunchTargetWorkingCopy; import org.eclipse.launchbar.core.target.TargetStatus; import org.eclipse.linuxtools.docker.core.DockerConnectionManager; +import org.eclipse.linuxtools.docker.core.EnumDockerConnectionState; import org.eclipse.linuxtools.docker.core.IDockerConnection; +import org.eclipse.linuxtools.docker.core.IDockerConnectionManagerListener; import org.eclipse.linuxtools.docker.core.IDockerImage; /** @@ -32,13 +39,17 @@ import org.eclipse.linuxtools.docker.core.IDockerImage; * @author jjohnstn * */ -public class ContainerTargetTypeProvider implements ILaunchTargetProvider { +public class ContainerTargetTypeProvider + implements ILaunchTargetProvider, IDockerConnectionManagerListener { public static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.launchTargetType.container"; //$NON-NLS-1$ public static final String CONTAINER_LINUX = "linux-container"; //$NON-NLS-1$ + private ILaunchTargetManager targetManager; + @Override public void init(ILaunchTargetManager targetManager) { + this.targetManager = targetManager; ILaunchBarManager launchbarManager = CDebugCorePlugin .getService(ILaunchBarManager.class); ILaunchTarget defaultTarget = null; @@ -49,8 +60,13 @@ public class ContainerTargetTypeProvider implements ILaunchTargetProvider { } IDockerConnection[] connections = DockerConnectionManager.getInstance() .getConnections(); + Map establishedConnectionMap = new HashMap<>(); Set imageNames = new HashSet<>(); for (IDockerConnection connection : connections) { + if (connection + .getState() == EnumDockerConnectionState.ESTABLISHED) { + establishedConnectionMap.put(connection.getUri(), connection); + } List images = connection.getImages(); for (IDockerImage image : images) { if (!image.isDangling() && !image.isIntermediateImage()) { @@ -79,11 +95,25 @@ public class ContainerTargetTypeProvider implements ILaunchTargetProvider { } } } + + // remove any launch targets for closed/disabled connections + ILaunchTarget[] targets = targetManager.getLaunchTargetsOfType(TYPE_ID); + for (ILaunchTarget target : targets) { + String uri = target.getAttribute( + IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$ + if (!establishedConnectionMap.containsKey(uri)) { + targetManager.removeLaunchTarget(target); + } + } + try { launchbarManager.setActiveLaunchTarget(defaultTarget); } catch (CoreException e) { DockerLaunchUIPlugin.log(e); } + + DockerConnectionManager.getInstance() + .addConnectionManagerListener(this); } @Override @@ -92,4 +122,85 @@ public class ContainerTargetTypeProvider implements ILaunchTargetProvider { return TargetStatus.OK_STATUS; } + @Override + public void changeEvent(IDockerConnection connection, int type) { + ICBuildConfigurationManager mgr = CCorePlugin + .getService(ICBuildConfigurationManager.class); + ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr; + + if (type == IDockerConnectionManagerListener.ADD_EVENT + || type == IDockerConnectionManagerListener.ENABLE_EVENT) { + ILaunchBarManager launchbarManager = CDebugCorePlugin + .getService(ILaunchBarManager.class); + ILaunchTarget defaultTarget = null; + try { + defaultTarget = launchbarManager.getActiveLaunchTarget(); + } catch (CoreException e) { + // ignore + } + + List images = connection.getImages(); + for (IDockerImage image : images) { + if (!image.isDangling() && !image.isIntermediateImage()) { + + String imageName = "[" //$NON-NLS-1$ + + image.repoTags().get(0).replace(':', '_') + "]"; //$NON-NLS-1$ + String imageName2 = imageName + "[" //$NON-NLS-1$ + + connection.getName() + "]"; //$NON-NLS-1$ + ILaunchTarget target = targetManager + .getLaunchTarget(TYPE_ID, imageName2); + if (target != null) { + continue; + } + target = targetManager.getLaunchTarget(TYPE_ID, imageName); + if (target != null) { + if (target.getAttribute( + IContainerLaunchTarget.ATTR_CONNECTION_URI, "") + .equals(connection.getUri())) { + continue; + } + imageName = imageName2; + } + target = targetManager.addLaunchTarget(TYPE_ID, imageName); + ILaunchTargetWorkingCopy wc = target.getWorkingCopy(); + wc.setAttribute(ILaunchTarget.ATTR_OS, CONTAINER_LINUX); + wc.setAttribute(ILaunchTarget.ATTR_ARCH, + Platform.getOSArch()); + wc.setAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI, + connection.getUri()); + wc.setAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, + image.repoTags().get(0)); + + wc.save(); + } + } + + // reset the default target back again + if (defaultTarget != null) { + try { + launchbarManager.setActiveLaunchTarget(defaultTarget); + } catch (CoreException e) { + DockerLaunchUIPlugin.log(e); + } + + } + + // Re-evaluate config list in case a build config was marked + // invalid and is now enabled + manager.recheckConfigs(); + } else if (type == IDockerConnectionManagerListener.REMOVE_EVENT + || type == IDockerConnectionManagerListener.DISABLE_EVENT) { + String connectionURI = connection.getUri(); + ILaunchTarget[] targets = targetManager + .getLaunchTargetsOfType(TYPE_ID); + for (ILaunchTarget target : targets) { + String uri = target.getAttribute( + IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$ + if (connectionURI.equals(uri)) { + targetManager.removeLaunchTarget(target); + } + } + } + } + } diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java index b7392d20e01..aba09ca8f88 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java @@ -10,19 +10,26 @@ *******************************************************************************/ package org.eclipse.cdt.internal.docker.launcher.ui.launchbar; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager2; +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.docker.launcher.ContainerTargetTypeProvider; +import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin; import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.linuxtools.docker.core.DockerConnectionManager; import org.eclipse.linuxtools.docker.core.IDockerConnection; +import org.eclipse.linuxtools.docker.core.IDockerConnectionManagerListener; import org.eclipse.linuxtools.docker.core.IDockerImage; /** @@ -32,11 +39,14 @@ import org.eclipse.linuxtools.docker.core.IDockerImage; * @since 1.2 * */ -public class ContainerGCCToolChainProvider implements IToolChainProvider { +public class ContainerGCCToolChainProvider + implements IToolChainProvider, IDockerConnectionManagerListener { public static final String PROVIDER_ID = "org.eclipse.cdt.docker.launcher.gcc.provider"; //$NON-NLS-1$ public static final String CONTAINER_LINUX_CONFIG_ID = "linux-container-id"; //$NON-NLS-1$ + private IToolChainManager toolChainManager; + @Override public String getId() { return PROVIDER_ID; @@ -44,9 +54,12 @@ public class ContainerGCCToolChainProvider implements IToolChainProvider { @Override public void init(IToolChainManager manager) throws CoreException { + this.toolChainManager = manager; IDockerConnection[] connections = DockerConnectionManager.getInstance() .getConnections(); + Map connectionMap = new HashMap<>(); for (IDockerConnection connection : connections) { + connectionMap.put(connection.getUri(), connection); List images = connection.getImages(); for (IDockerImage image : images) { if (!image.isDangling() && !image.isIntermediateImage()) { @@ -73,6 +86,75 @@ public class ContainerGCCToolChainProvider implements IToolChainProvider { } } } + + DockerConnectionManager.getInstance() + .addConnectionManagerListener(this); + } + + @Override + public void changeEvent(IDockerConnection connection, int type) { + ICBuildConfigurationManager mgr = CCorePlugin + .getService(ICBuildConfigurationManager.class); + ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr; + + if (type == IDockerConnectionManagerListener.ADD_EVENT + || type == IDockerConnectionManagerListener.ENABLE_EVENT) { + List images = connection.getImages(); + for (IDockerImage image : images) { + if (!image.isDangling() && !image.isIntermediateImage()) { + + Map properties = new HashMap<>(); + + properties.put(ILaunchTarget.ATTR_OS, + ContainerTargetTypeProvider.CONTAINER_LINUX); + properties.put(ILaunchTarget.ATTR_ARCH, + Platform.getOSArch()); + properties.put(IContainerLaunchTarget.ATTR_CONNECTION_URI, + connection.getUri()); + properties.put(IContainerLaunchTarget.ATTR_IMAGE_ID, + image.repoTags().get(0)); + // following can be used for naming build configurations + properties.put(CONTAINER_LINUX_CONFIG_ID, + image.repoTags().get(0).replace(':', '_')); + + + Collection toolChains; + try { + toolChains = toolChainManager + .getToolChainsMatching(properties); + if (toolChains.isEmpty()) { + ContainerGCCToolChain toolChain = new ContainerGCCToolChain( + "gcc-img-" + image.id().substring(0, 19), //$NON-NLS-1$ + this, properties, null); + toolChainManager.addToolChain(toolChain); + } + } catch (CoreException e) { + DockerLaunchUIPlugin.log(e); + } + } + } + // Re-evaluate config list in case a build config was marked + // invalid and is now enabled + manager.recheckConfigs(); + } else if (type == IDockerConnectionManagerListener.REMOVE_EVENT + || type == IDockerConnectionManagerListener.DISABLE_EVENT) { + try { + String connectionURI = connection.getUri(); + Collection toolChains = toolChainManager + .getAllToolChains(); + for (IToolChain toolChain : toolChains) { + String uri = toolChain.getProperty( + IContainerLaunchTarget.ATTR_CONNECTION_URI); + if (connectionURI.equals(uri)) { + toolChainManager.removeToolChain(toolChain); + } + } + } catch (CoreException e1) { + // TODO Auto-generated catch block + DockerLaunchUIPlugin.log(e1); + } + } + } }