Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Johnston2018-03-04 23:27:51 +0000
committerJeff Johnston2018-03-06 19:48:01 +0000
commitc9822e117e7076aa66246b1c7a5af01800a46118 (patch)
tree3d36be54311c2c80fc5868f375dbc2ebd0b59663 /launch/org.eclipse.cdt.docker.launcher
parentc781ba5c361d9b9b5b4f43b920a111c46e3b928c (diff)
downloadorg.eclipse.cdt-c9822e117e7076aa66246b1c7a5af01800a46118.tar.gz
org.eclipse.cdt-c9822e117e7076aa66246b1c7a5af01800a46118.tar.xz
org.eclipse.cdt-c9822e117e7076aa66246b1c7a5af01800a46118.zip
Bug 531985 - Support Container build with new Core Build
- add new ContainerTargetTypeProvider to create a new target for each usable Docker image from known connections - add new ContainerGCCToolChain class which supports gcc in a Container for projects with Container targets - add new ContainerGCCToolChainProvider which creates a ContainerGCCToolChain for each usable Docker image from known connections - add new CoreBuildContainerLaunchConfigProvider class - add new CoreBuildContainerLaunchDescriptorType class - add new ContainerTargetLabelProvider class to support adding a new Container target - add new NewContainerTargetWizard and NewContainerTargetWizardPage to add/edit a new Container target - add new IContainerLaunchTarget class - add new refreshScannerInfo method to ICBuildConfiguration interface to allow switching ScannerInfo when target is switched - implement default refreshScannerInfo method in CBuildConfiguration which currently does nothing - add new fetchContainerDirs method to CommandLauncherManager to fetch container directories for a project that is using Core Model and CBuildConfigurations - add new verifyIncludePaths method to ICommandLauncherFactory2 that takes an ICBuildConfiguration and implement this for ContainerCommandLauncherFactory - fix ContainerCommandLauncher command handling to use a list of Strings to preserve spaces in arguments and call new runCommand interface in Docker UI...as well do not link any args that are files if they are system directories (e.g. /usr /bin) - fix getCommandLauncher in ContainerCommandLauncherFactory when passing an ICBuildConfiguration so that it uses the configuration's toolchain properties to figure out if a Container build is asked for - fix launch method of ContainerLaunchConfigurationDelegate to check if working directory is null in which case use the project directory - also add buildForLaunch method override and preLaunchCheck to ContainerLaunchConfigurationDelegate so it can be used for Core Build launching as well and ensure that the project name and active configuration is set properly - in CoreBuildLaunchBarTracker, use the lastTarget to set the active target instead of the local field "target" as this will end up setting a random target as the active target. Also call the new refreshScannerInfo method of the build configuration when the active target has changed - add ICBuildConfiguration support to Docker LaunchShortcut such that properties will be set appropriately and acquired from the toolChain - bump up Docker launcher version to 1.2.0 Change-Id: I074b02314f6ac6942fdf230b1dc8e154ced3088e
Diffstat (limited to 'launch/org.eclipse.cdt.docker.launcher')
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/META-INF/MANIFEST.MF6
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/plugin.properties1
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/plugin.xml44
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java51
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java129
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java95
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/IContainerLaunchTarget.java24
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java143
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/LaunchShortcut.java287
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java2
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties2
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java606
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java78
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerTargetLabelProvider.java35
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchConfigProvider.java201
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchDescriptorType.java39
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/Messages.java49
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizard.java117
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizardPage.java309
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/messages.properties28
20 files changed, 2093 insertions, 153 deletions
diff --git a/launch/org.eclipse.cdt.docker.launcher/META-INF/MANIFEST.MF b/launch/org.eclipse.cdt.docker.launcher/META-INF/MANIFEST.MF
index 5570d05b4b3..975d2ff645a 100644
--- a/launch/org.eclipse.cdt.docker.launcher/META-INF/MANIFEST.MF
+++ b/launch/org.eclipse.cdt.docker.launcher/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Plugin.name
Bundle-SymbolicName: org.eclipse.cdt.docker.launcher;singleton:=true
-Bundle-Version: 1.1.1.qualifier
+Bundle-Version: 1.2.0.qualifier
Bundle-Activator: org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin
Bundle-Vendor: %Plugin.vendor
Bundle-Localization: plugin
@@ -27,7 +27,9 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.core.databinding.beans,
org.eclipse.jface.databinding,
org.eclipse.core.databinding;bundle-version="1.6.0",
- org.eclipse.core.databinding.property;bundle-version="1.6.0"
+ org.eclipse.core.databinding.property;bundle-version="1.6.0",
+ org.eclipse.launchbar.ui;bundle-version="2.2.0",
+ com.google.gson
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.docker.launcher,
diff --git a/launch/org.eclipse.cdt.docker.launcher/plugin.properties b/launch/org.eclipse.cdt.docker.launcher/plugin.properties
index 245288bb62e..038134a6414 100644
--- a/launch/org.eclipse.cdt.docker.launcher/plugin.properties
+++ b/launch/org.eclipse.cdt.docker.launcher/plugin.properties
@@ -22,3 +22,4 @@ Container.settings=Container Settings
ContainerBuild.property.enablement=Container Build Enablement
ContainerBuild.property.connection=Container Build Connection
ContainerBuild.property.image=Container Build Image
+ContainerTarget.name=Container Target
diff --git a/launch/org.eclipse.cdt.docker.launcher/plugin.xml b/launch/org.eclipse.cdt.docker.launcher/plugin.xml
index a9c3f67e105..0323cb81380 100644
--- a/launch/org.eclipse.cdt.docker.launcher/plugin.xml
+++ b/launch/org.eclipse.cdt.docker.launcher/plugin.xml
@@ -113,5 +113,47 @@
weight="020">
</tab>
</extension>
-
+ <extension
+ point="org.eclipse.launchbar.core.launchTargetTypes">
+ <launchTargetType
+ id="org.eclipse.cdt.docker.launcher.launchTargetType.container"
+ provider="org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider">
+ </launchTargetType>
+ </extension>
+ <extension
+ point="org.eclipse.launchbar.ui.launchTargetTypeUI">
+ <launchTargetTypeUI
+ id="org.eclipse.cdt.docker.launcher.launchTargetType.container"
+ labelProvider="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.ContainerTargetLabelProvider">
+ </launchTargetTypeUI>
+ <wizard2
+ class="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.NewContainerTargetWizard"
+ icon="icons/repository-middle.gif"
+ id="org.eclipse.cdt.docker.launcher.launchTargetType.container"
+ name="%ContainerTarget.name">
+ </wizard2>
+ </extension>
+ <extension
+ point="org.eclipse.cdt.core.toolChainProvider">
+ <provider
+ class="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.ContainerGCCToolChainProvider"
+ id="org.eclipse.cdt.docker.launcher.gcc.provider">
+ </provider>
+ <type
+ id="org.eclipse.cdt.build.gcc"
+ name="GCC">
+ </type>
+ <type
+ id="org.eclipse.cdt.build.clang"
+ name="clang">
+ </type>
+ </extension>
+ <extension
+ point="org.eclipse.launchbar.core.launchBarContributions">
+ <configProvider
+ class="org.eclipse.cdt.internal.docker.launcher.ui.launchbar.CoreBuildContainerLaunchConfigProvider"
+ descriptorType="org.eclipse.cdt.debug.core.coreBuildDescriptorType"
+ priority="15">
+ </configProvider>
+ </extension>
</plugin>
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java
index 003ae70cbda..53613f74c7d 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java
@@ -13,6 +13,7 @@ import java.util.Properties;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.build.ICBuildCommandLauncher;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
+import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.ProcessClosure;
@@ -88,6 +89,13 @@ public class ContainerCommandLauncher
@Override
public void setBuildConfiguration(ICBuildConfiguration config) {
this.fBuildConfig = config;
+ if (fProject == null) {
+ try {
+ fProject = config.getBuildConfiguration().getProject();
+ } catch (CoreException e) {
+ // ignore
+ }
+ }
}
@Override
@@ -135,6 +143,16 @@ public class ContainerCommandLauncher
return null;
}
+ private boolean isSystemDir(IPath p) {
+ String firstSegment = p.segment(0);
+ if (firstSegment.equals("usr") || firstSegment.equals("opt") //$NON-NLS-1$ //$NON-NLS-2$
+ || firstSegment.equals("bin") || firstSegment.equals("etc") //$NON-NLS-1$ //$NON-NLS-2$
+ || firstSegment.equals("sbin")) { //$NON-NLS-1$
+ return true;
+ }
+ return false;
+ }
+
@Override
public Process execute(IPath commandPath, String[] args, String[] env,
IPath workingDirectory, IProgressMonitor monitor)
@@ -157,21 +175,21 @@ public class ContainerCommandLauncher
ArrayList<String> commandSegments = new ArrayList<>();
- StringBuilder b = new StringBuilder();
+ List<String> cmdList = new ArrayList<>();
+
String commandString = commandPath.toPortableString();
if (commandPath.getDevice() != null) {
commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
}
- b.append(commandString);
+ cmdList.add(commandString);
commandSegments.add(commandString);
for (String arg : args) {
- b.append(" "); //$NON-NLS-1$
String realArg = VariablesPlugin.getDefault()
.getStringVariableManager().performStringSubstitution(arg);
if (Platform.getOS().equals(Platform.OS_WIN32)) {
// check if file exists and if so, add an additional directory
IPath p = new Path(realArg);
- if (p.isValidPath(realArg) && p.getDevice() != null) {
+ if (p.isValidPath(realArg) && p.getDevice() != null && !isSystemDir(p)) {
File f = p.toFile();
String modifiedArg = realArg;
// if the directory of the arg as a file exists, we mount it
@@ -192,7 +210,7 @@ public class ContainerCommandLauncher
// check if file directory exists and if so, add an additional
// directory
IPath p = new Path(realArg);
- if (p.isValidPath(realArg)) {
+ if (p.isValidPath(realArg) && !isSystemDir(p)) {
File f = p.toFile();
if (f.isFile()) {
f = f.getParentFile();
@@ -202,19 +220,12 @@ public class ContainerCommandLauncher
}
}
}
- b.append(realArg);
+ cmdList.add(realArg);
commandSegments.add(realArg);
}
commandArgs = commandSegments.toArray(new String[0]);
- String commandDir = commandPath.removeLastSegments(1).toString();
- if (commandDir.isEmpty()) {
- commandDir = null;
- } else if (commandPath.getDevice() != null) {
- commandDir = "/" + commandDir.replace(':', '/'); //$NON-NLS-1$
- }
-
IProject[] referencedProjects = fProject.getReferencedProjects();
for (IProject referencedProject : referencedProjects) {
String referencedProjectPath = referencedProject.getLocation()
@@ -227,8 +238,6 @@ public class ContainerCommandLauncher
.add(referencedProjectPath);
}
- String command = b.toString();
-
String workingDir = workingDirectory.makeAbsolute().toPortableString();
if (workingDirectory.toPortableString().equals(".")) { //$NON-NLS-1$
workingDir = "/tmp"; //$NON-NLS-1$
@@ -255,9 +264,12 @@ public class ContainerCommandLauncher
String connectionName = null;
String imageName = null;
if (buildCfg != null) {
- selectedVolumeString = buildCfg.getProperty(SELECTED_VOLUMES_ID);
- connectionName = buildCfg.getProperty(CONNECTION_ID);
- imageName = buildCfg.getProperty(IMAGE_ID);
+ IToolChain toolChain = buildCfg.getToolChain();
+ selectedVolumeString = toolChain.getProperty(SELECTED_VOLUMES_ID);
+ connectionName = toolChain
+ .getProperty(IContainerLaunchTarget.ATTR_CONNECTION_URI);
+ imageName = toolChain
+ .getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
} else {
ICConfigurationDescription cfgd = CoreModel.getDefault()
.getProjectDescription(fProject).getActiveConfiguration();
@@ -301,8 +313,7 @@ public class ContainerCommandLauncher
fProcess = launcher.runCommand(connectionName, imageName, fProject,
this,
- command,
- commandDir,
+ cmdList,
workingDir,
additionalDirs,
origEnv, fEnvironment, supportStdin, privilegedMode,
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java
index 3589d6c6467..369460f1588 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java
@@ -16,13 +16,13 @@ import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.ICommandLauncherFactory;
import org.eclipse.cdt.core.ICommandLauncherFactory2;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
+import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
@@ -33,6 +33,7 @@ import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.linuxtools.docker.ui.launch.ContainerLauncher;
@@ -98,20 +99,18 @@ public class ContainerCommandLauncherFactory
@Override
public ICommandLauncher getCommandLauncher(ICBuildConfiguration cfgd) {
- // check if container build enablement has been checked
- Map<String, String> props = cfgd.getProperties();
- if (props != null) {
- String enablementProperty = props
- .get(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
- if (enablementProperty != null) {
- boolean enableContainer = Boolean
- .parseBoolean(enablementProperty);
- // enablement has occurred, we can return a
- // ContainerCommandLauncher
- if (enableContainer) {
+ // check if container linux os is set
+ IToolChain toolchain;
+ try {
+ toolchain = cfgd.getToolChain();
+ if (toolchain != null) {
+ if (ContainerTargetTypeProvider.CONTAINER_LINUX
+ .equals(toolchain.getProperty(IToolChain.ATTR_OS))) {
return new ContainerCommandLauncher();
}
}
+ } catch (CoreException e) {
+ DockerLaunchUIPlugin.log(e);
}
return null;
}
@@ -213,6 +212,112 @@ public class ContainerCommandLauncherFactory
}
+ /**
+ * @since 1.2
+ */
+ @Override
+ public List<String> verifyIncludePaths(ICBuildConfiguration cfgd, List<String> includePaths) {
+ IToolChain toolchain = null;
+ boolean isContainerEnabled = false;
+ try {
+ toolchain = cfgd.getToolChain();
+ if (toolchain != null) {
+ if (ContainerTargetTypeProvider.CONTAINER_LINUX
+ .equals(toolchain.getProperty(IToolChain.ATTR_OS))) {
+ isContainerEnabled = true;
+ }
+ }
+ } catch (CoreException e) {
+ DockerLaunchUIPlugin.log(e);
+ }
+
+ if (isContainerEnabled) {
+ String connectionName = toolchain
+ .getProperty(IContainerLaunchTarget.ATTR_CONNECTION_URI);
+ String imageName = toolchain
+ .getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
+ if (connectionName == null || connectionName.isEmpty()
+ || imageName == null || imageName.isEmpty()) {
+ DockerLaunchUIPlugin.logErrorMessage(
+ Messages.ContainerCommandLauncher_invalid_values);
+ return includePaths;
+ }
+ ContainerLauncher launcher = new ContainerLauncher();
+ if (includePaths.size() > 0) {
+ // Create a directory to put the header files for
+ // the image. Use the connection name to form
+ // the directory name as the connection may be
+ // connected to a different repo using the same
+ // image name.
+ IPath pluginPath = Platform
+ .getStateLocation(Platform
+ .getBundle(DockerLaunchUIPlugin.PLUGIN_ID))
+ .append("HEADERS"); //$NON-NLS-1$
+ pluginPath.toFile().mkdir();
+ pluginPath = pluginPath.append(getCleanName(connectionName));
+ pluginPath.toFile().mkdir();
+ // To allow the user to later manage the headers, store
+ // the
+ // real connection name in a file.
+ IPath connectionNamePath = pluginPath.append(".name"); //$NON-NLS-1$
+ File f = connectionNamePath.toFile();
+ try {
+ f.createNewFile();
+ try (FileWriter writer = new FileWriter(f);
+ BufferedWriter bufferedWriter = new BufferedWriter(
+ writer);) {
+ bufferedWriter.write(connectionName);
+ bufferedWriter.newLine();
+ } catch (IOException e) {
+ DockerLaunchUIPlugin.log(e);
+ return includePaths;
+ }
+ pluginPath = pluginPath.append(getCleanName(imageName));
+ pluginPath.toFile().mkdir();
+ // To allow the user to later manage the headers,
+ // store the
+ // real image name in a file.
+ IPath imageNamePath = pluginPath.append(".name"); //$NON-NLS-1$
+ f = imageNamePath.toFile();
+ f.createNewFile();
+ try (FileWriter writer = new FileWriter(f);
+ BufferedWriter bufferedWriter = new BufferedWriter(
+ writer);) {
+ bufferedWriter.write(imageName);
+ bufferedWriter.newLine();
+ } catch (IOException e) {
+ DockerLaunchUIPlugin.log(e);
+ return includePaths;
+ }
+ } catch (IOException e) {
+ DockerLaunchUIPlugin.log(e);
+ return includePaths;
+ }
+ IPath hostDir = pluginPath;
+ int status = launcher.fetchContainerDirsSync(connectionName,
+ imageName, includePaths, hostDir);
+ if (status == 0) {
+ Set<String> copiedVolumes = launcher
+ .getCopiedVolumes(connectionName, imageName);
+ List<String> newEntries = new ArrayList<>();
+
+ for (String path : includePaths) {
+ if (copiedVolumes.contains(path)) {
+ IPath newPath = hostDir.append(path);
+ String newEntry = newPath.toOSString();
+ newEntries.add(newEntry);
+ } else {
+ newEntries.add(path);
+ }
+ }
+ return newEntries;
+ }
+
+ }
+ }
+ return includePaths;
+ }
+
@Override
public List<ICLanguageSettingEntry> verifyLanguageSettingEntries(
IProject project, List<ICLanguageSettingEntry> entries) {
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
new file mode 100644
index 00000000000..516f9396074
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2017, 2018 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
+ *
+ * Contributors:
+ * Red Hat Inc. - modified for use with Docker Container launching
+ *******************************************************************************/
+package org.eclipse.cdt.docker.launcher;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.launchbar.core.ILaunchBarManager;
+import org.eclipse.launchbar.core.target.ILaunchTarget;
+import org.eclipse.launchbar.core.target.ILaunchTargetManager;
+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.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerImage;
+
+/**
+ * @since 1.2
+ * @author jjohnstn
+ *
+ */
+public class ContainerTargetTypeProvider implements ILaunchTargetProvider {
+
+ 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$
+
+ @Override
+ public void init(ILaunchTargetManager targetManager) {
+ ILaunchBarManager launchbarManager = CDebugCorePlugin
+ .getService(ILaunchBarManager.class);
+ ILaunchTarget defaultTarget = null;
+ try {
+ defaultTarget = launchbarManager.getActiveLaunchTarget();
+ } catch (CoreException e) {
+ // ignore
+ }
+ IDockerConnection[] connections = DockerConnectionManager.getInstance()
+ .getConnections();
+ Set<String> imageNames = new HashSet<>();
+ for (IDockerConnection connection : connections) {
+ List<IDockerImage> 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$
+ if (imageNames.contains(imageName)) {
+ imageName += "[" + connection.getName() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ imageNames.add(imageName);
+ ILaunchTarget target = targetManager
+ .getLaunchTarget(TYPE_ID, imageName);
+ if (target == null) {
+ 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();
+ }
+ }
+ }
+ try {
+ launchbarManager.setActiveLaunchTarget(defaultTarget);
+ } catch (CoreException e) {
+ DockerLaunchUIPlugin.log(e);
+ }
+ }
+
+ @Override
+ public TargetStatus getStatus(ILaunchTarget target) {
+ // Always OK
+ return TargetStatus.OK_STATUS;
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/IContainerLaunchTarget.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/IContainerLaunchTarget.java
new file mode 100644
index 00000000000..9413486c330
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/IContainerLaunchTarget.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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 contribution
+ *******************************************************************************/
+package org.eclipse.cdt.docker.launcher;
+
+/**
+ * @since 1.2
+ * @author jjohnstn
+ *
+ */
+public interface IContainerLaunchTarget {
+
+ // Container attributes
+ public static final String ATTR_CONNECTION_URI = "connection_uri"; //$NON-NLS-1$
+ public static final String ATTR_IMAGE_ID = "image_id"; //$NON-NLS-1$
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java
index 2f600556861..f52cdea7a51 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java
@@ -23,12 +23,22 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.build.ICBuildConfiguration;
+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.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
+import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -42,6 +52,8 @@ import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
+import org.eclipse.launchbar.core.target.ILaunchTarget;
+import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.linuxtools.docker.core.Activator;
import org.eclipse.linuxtools.docker.core.IDockerContainerInfo;
import org.eclipse.linuxtools.docker.core.IDockerNetworkSettings;
@@ -169,6 +181,14 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
.getAttribute(
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null);
+ // if we don't have a working directory, the default is to use
+ // the project
+ if (workingDir == null && projectName != null) {
+ IProject project = ResourcesPlugin.getWorkspace().getRoot()
+ .getProject(projectName);
+ workingDir = project.getLocation().toOSString();
+ }
+
if (workingDir != null) {
IPath workingPath = new Path(workingDir);
if (workingPath.getDevice() != null) {
@@ -258,6 +278,13 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
.getAttribute(
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
(String) null);
+ // if we don't have a working directory, the default is to use
+ // the project
+ if (workingDir == null && projectName != null) {
+ IProject project = ResourcesPlugin.getWorkspace().getRoot()
+ .getProject(projectName);
+ workingDir = project.getLocation().toOSString();
+ }
if (workingDir != null) {
IPath workingPath = new Path(workingDir);
if (workingPath.getDevice() != null) {
@@ -492,6 +519,122 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$
}
+ public static IProject getProject(ILaunchConfiguration configuration)
+ throws CoreException {
+ // TODO - make sure this is really the correct project
+ return configuration.getMappedResources()[0].getProject();
+ }
+
+ /**
+ * @since 1.2
+ */
+ protected ICBuildConfigurationManager configManager = CDebugCorePlugin
+ .getService(ICBuildConfigurationManager.class);
+ /**
+ * @since 1.2
+ */
+ protected IToolChainManager toolChainManager = CDebugCorePlugin
+ .getService(IToolChainManager.class);
+
+ /*
+ * @since 1.2
+ */
+ protected ICBuildConfiguration getBuildConfiguration(
+ ILaunchConfiguration configuration, String mode,
+ ILaunchTarget target, IProgressMonitor monitor)
+ throws CoreException {
+ IProject project = getProject(configuration);
+ String toolchainId = configuration
+ .getAttribute(ICBuildConfiguration.TOOLCHAIN_ID, (String) null);
+ if (toolchainId != null) {
+ String providerId = configuration
+ .getAttribute(ICBuildConfiguration.TOOLCHAIN_TYPE, ""); //$NON-NLS-1$
+ IToolChain toolchain = toolChainManager.getToolChain(providerId,
+ toolchainId);
+ if (toolchain != null) {
+ return configManager.getBuildConfiguration(project, toolchain,
+ mode, monitor);
+ }
+ }
+
+ // Pick the first one that matches
+ Map<String, String> properties = new HashMap<>();
+ properties.putAll(target.getAttributes());
+ for (IToolChain toolChain : toolChainManager
+ .getToolChainsMatching(properties)) {
+ ICBuildConfiguration buildConfig = configManager
+ .getBuildConfiguration(project, toolChain, mode, monitor);
+ if (buildConfig != null) {
+ return buildConfig;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean buildForLaunch(ILaunchConfiguration configuration,
+ String mode, IProgressMonitor monitor) throws CoreException {
+ IProject project = getProject(configuration);
+ String name = configuration.getName();
+ Pattern p = Pattern.compile(".*?\\[([^\\]]+)\\](.*)"); //$NON-NLS-1$
+ Matcher m = p.matcher(name);
+ if (m.matches()) {
+ ILaunchTargetManager targetManager = CCorePlugin
+ .getService(ILaunchTargetManager.class);
+ ILaunchTarget target = null;
+ ILaunchTarget[] targets = targetManager.getLaunchTargetsOfType(
+ ContainerTargetTypeProvider.TYPE_ID);
+ for (ILaunchTarget t : targets) {
+ if (t.getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, "")
+ .replaceAll(":", "_").equals(m.group(1))) {
+ target = t;
+ break;
+ }
+ }
+ if (target != null) {
+ ICBuildConfiguration cconfig = getBuildConfiguration(
+ configuration, mode, target, monitor);
+ if (cconfig != null) {
+ IProjectDescription desc = project.getDescription();
+ desc.setActiveBuildConfig(
+ cconfig.getBuildConfiguration().getName());
+ project.setDescription(desc, monitor);
+ }
+ }
+ }
+
+ return super.buildForLaunch(configuration, mode, monitor);
+ }
+
+ @Override
+ public boolean preLaunchCheck(ILaunchConfiguration config, String mode,
+ IProgressMonitor monitor) throws CoreException {
+ String projectName = config.getAttribute(
+ ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
+ (String) null);
+ IProject project = null;
+ if (projectName == null) {
+ IResource[] resources = config.getMappedResources();
+ if (resources != null && resources.length > 0
+ && resources[0] instanceof IProject) {
+ project = (IProject) resources[0];
+ }
+ ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
+ wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
+ project.getName());
+ wc.doSave();
+ } else {
+ projectName = projectName.trim();
+ if (!projectName.isEmpty()) {
+ project = ResourcesPlugin.getWorkspace().getRoot()
+ .getProject(projectName);
+ }
+ }
+
+ return super.preLaunchCheck(config, mode, monitor);
+ }
+
@Override
protected String getPluginID() {
return DockerLaunchUIPlugin.PLUGIN_ID;
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/LaunchShortcut.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/LaunchShortcut.java
index 255a37258af..2f9eeac0f2e 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/LaunchShortcut.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/LaunchShortcut.java
@@ -15,6 +15,8 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import org.eclipse.cdt.core.build.ICBuildConfiguration;
+import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBinary;
@@ -24,6 +26,7 @@ import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.docker.launcher.ContainerCommandLauncher;
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
+import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
@@ -31,6 +34,7 @@ import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.ui.CElementLabelProvider;
+import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
@@ -260,46 +264,63 @@ public class LaunchShortcut implements ILaunchShortcut {
ILaunchConfigurationType configType = getLaunchConfigType();
List<ILaunchConfiguration> candidateConfigs = Collections.emptyList();
IProject project = bin.getCProject().getProject();
- ICConfigurationDescription cfgd = CoreModel.getDefault()
- .getProjectDescription(project).getActiveConfiguration();
String connectionUri = null;
String imageName = null;
- if (cfgd != null) {
- IConfiguration cfg = ManagedBuildManager
- .getConfigurationForDescription(cfgd);
- if (cfg != null) {
- IOptionalBuildProperties props = cfg
- .getOptionalBuildProperties();
- String containerBuild = props.getProperty(
- ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
- if (containerBuild != null) {
- boolean containerBuildEnabled = Boolean
- .parseBoolean(containerBuild);
- if (containerBuildEnabled) {
- connectionUri = props.getProperty(
- ContainerCommandLauncher.CONNECTION_ID);
- imageName = props
- .getProperty(ContainerCommandLauncher.IMAGE_ID);
- }
- } else {
- IDockerConnection[] connections = DockerConnectionManager
- .getInstance().getConnections();
- if (connections != null && connections.length > 0) {
- connectionUri = connections[0].getUri();
- Preferences prefs = InstanceScope.INSTANCE
- .getNode(DockerLaunchUIPlugin.PLUGIN_ID);
- imageName = prefs.get(PreferenceConstants.DEFAULT_IMAGE,
- null);
- if (imageName == null) {
- List<IDockerImage> images = connections[0]
- .getImages();
- if (images != null && images.size() > 0)
- imageName = images.get(0).repoTags().get(0);
+ ICBuildConfiguration cbcfg = null;
+ try {
+ IBuildConfiguration buildConfig = project.getActiveBuildConfig();
+ cbcfg = buildConfig.getAdapter(ICBuildConfiguration.class);
+ if (cbcfg != null) {
+ IToolChain toolChain = cbcfg.getToolChain();
+ connectionUri = toolChain.getProperty(
+ IContainerLaunchTarget.ATTR_CONNECTION_URI);
+ imageName = toolChain
+ .getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
+ }
+ } catch (CoreException e1) {
+ // do nothing
+ }
+ if (cbcfg == null) {
+ ICConfigurationDescription cfgd = CoreModel.getDefault()
+ .getProjectDescription(project).getActiveConfiguration();
+ if (cfgd != null) {
+ IConfiguration cfg = ManagedBuildManager
+ .getConfigurationForDescription(cfgd);
+ if (cfg != null) {
+ IOptionalBuildProperties props = cfg
+ .getOptionalBuildProperties();
+ String containerBuild = props.getProperty(
+ ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
+ if (containerBuild != null) {
+ boolean containerBuildEnabled = Boolean
+ .parseBoolean(containerBuild);
+ if (containerBuildEnabled) {
+ connectionUri = props.getProperty(
+ ContainerCommandLauncher.CONNECTION_ID);
+ imageName = props.getProperty(
+ ContainerCommandLauncher.IMAGE_ID);
}
}
}
}
}
+
+ if (connectionUri == null) {
+ IDockerConnection[] connections = DockerConnectionManager
+ .getInstance().getConnections();
+ if (connections != null && connections.length > 0) {
+ connectionUri = connections[0].getUri();
+ Preferences prefs = InstanceScope.INSTANCE
+ .getNode(DockerLaunchUIPlugin.PLUGIN_ID);
+ imageName = prefs.get(PreferenceConstants.DEFAULT_IMAGE, null);
+ if (imageName == null) {
+ List<IDockerImage> images = connections[0].getImages();
+ if (images != null && images.size() > 0)
+ imageName = images.get(0).repoTags().get(0);
+ }
+ }
+ }
+
try {
ILaunchConfiguration[] configs = DebugPlugin.getDefault()
.getLaunchManager().getLaunchConfigurations(configType);
@@ -308,23 +329,34 @@ public class LaunchShortcut implements ILaunchShortcut {
IPath programPath = CDebugUtils.getProgramPath(config);
String projectName = CDebugUtils.getProjectName(config);
IPath binPath = bin.getResource().getProjectRelativePath();
- if (programPath != null && programPath.equals(binPath)) {
- if (projectName != null
- && projectName.equals(bin.getCProject()
- .getProject().getName())) {
- // if we have an active configuration with container
- // build properties, make sure they match, otherwise
- // add the launch config as a candidate
- if (connectionUri != null
- && connectionUri.equals(config.getAttribute(
- ILaunchConstants.ATTR_CONNECTION_URI,
- (String) null))) {
- if (imageName != null && imageName.equals(config
- .getAttribute(ILaunchConstants.ATTR_IMAGE,
+ if (projectName != null && projectName
+ .equals(bin.getCProject().getProject().getName())) {
+ if (programPath != null) {
+ if (programPath.equals(binPath)) {
+ // if we have an active configuration with container
+ // build properties, make sure they match, otherwise
+ // add the launch config as a candidate
+ if (connectionUri != null
+ && connectionUri.equals(config.getAttribute(
+ ILaunchConstants.ATTR_CONNECTION_URI,
(String) null))) {
- candidateConfigs.add(config);
+ if (imageName != null
+ && imageName.equals(config.getAttribute(
+ ILaunchConstants.ATTR_IMAGE,
+ (String) null))) {
+ candidateConfigs.add(config);
+ }
}
}
+ } else if (cbcfg != null && candidateConfigs.isEmpty()) {
+ ILaunchConfigurationWorkingCopy wc = config
+ .getWorkingCopy();
+ populateLaunchConfiguration(wc, mode, bin,
+ projectName,
+ connectionUri, imageName);
+ wc.doSave();
+ candidateConfigs.add(config);
+ break;
}
}
}
@@ -353,6 +385,59 @@ public class LaunchShortcut implements ILaunchShortcut {
return configuration;
}
+ private void populateLaunchConfiguration(ILaunchConfigurationWorkingCopy wc,
+ String mode, IBinary bin, String projectName, String connectionUri,
+ String imageName) {
+ // DSF settings...use GdbUIPlugin preference store for defaults
+ IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
+ .getPreferenceStore();
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
+ preferenceStore.getString(
+ IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND));
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
+ preferenceStore.getString(
+ IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT));
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
+ preferenceStore.getBoolean(
+ IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP));
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
+ IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
+ wc.setAttribute(
+ IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND,
+ IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT);
+ wc.setAttribute(
+ IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK,
+ IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT);
+ wc.setAttribute(
+ IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE,
+ IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT);
+
+ wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME,
+ bin.getResource().getProjectRelativePath().toString());
+ wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
+ projectName);
+ wc.setMappedResources(new IResource[] { bin.getResource(),
+ bin.getResource().getProject() });
+ wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
+ (String) null); // default is the project directory
+
+ Preferences prefs = InstanceScope.INSTANCE
+ .getNode(DockerLaunchUIPlugin.PLUGIN_ID);
+
+ Boolean keepPref = prefs.getBoolean(
+ PreferenceConstants.KEEP_CONTAINER_AFTER_LAUNCH, false);
+ wc.setAttribute(ILaunchConstants.ATTR_KEEP_AFTER_LAUNCH, keepPref);
+
+ // For Debug mode we need to set gdbserver info as well
+ if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_COMMAND,
+ "gdbserver"); //$NON-NLS-1$
+ wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_PORT, "2345"); //$NON-NLS-1$
+ }
+ wc.setAttribute(ILaunchConstants.ATTR_CONNECTION_URI, connectionUri);
+ wc.setAttribute(ILaunchConstants.ATTR_IMAGE, imageName);
+ }
+
/**
* Create a launch configuration based on a binary, and optionally save it
* to the underlying resource.
@@ -368,33 +453,45 @@ public class LaunchShortcut implements ILaunchShortcut {
String mode, boolean save) {
ILaunchConfiguration config = null;
try {
- String binaryPath = bin.getResource().getProjectRelativePath()
- .toString();
-
IProject project = bin.getResource().getProject();
- ICConfigurationDescription cfgd = CoreModel.getDefault()
- .getProjectDescription(project).getActiveConfiguration();
- IConfiguration cfg = ManagedBuildManager
- .getConfigurationForDescription(cfgd);
-
- IOptionalBuildProperties options = cfg.getOptionalBuildProperties();
boolean containerBuild = false;
String connectionId = null;
String imageName = null;
+ IBuildConfiguration buildConfig = project.getActiveBuildConfig();
+ ICBuildConfiguration cbuildcfg = buildConfig
+ .getAdapter(ICBuildConfiguration.class);
+ if (cbuildcfg != null) {
+ IToolChain toolChain = cbuildcfg.getToolChain();
+ connectionId = toolChain.getProperty(
+ IContainerLaunchTarget.ATTR_CONNECTION_URI);
+ imageName = toolChain
+ .getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID);
+ } else {
- if (options != null) {
- String containerBuildString = options.getProperty(
- ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
- if (containerBuildString != null) {
- containerBuild = Boolean.parseBoolean(options.getProperty(
- ContainerCommandLauncher.CONTAINER_BUILD_ENABLED));
- }
- if (containerBuild) {
- connectionId = options.getProperty(
- ContainerCommandLauncher.CONNECTION_ID);
- imageName = options
- .getProperty(ContainerCommandLauncher.IMAGE_ID);
+ ICConfigurationDescription cfgd = CoreModel.getDefault()
+ .getProjectDescription(project)
+ .getActiveConfiguration();
+ IConfiguration cfg = ManagedBuildManager
+ .getConfigurationForDescription(cfgd);
+
+ IOptionalBuildProperties options = cfg
+ .getOptionalBuildProperties();
+
+ if (options != null) {
+ String containerBuildString = options.getProperty(
+ ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
+ if (containerBuildString != null) {
+ containerBuild = Boolean
+ .parseBoolean(options.getProperty(
+ ContainerCommandLauncher.CONTAINER_BUILD_ENABLED));
+ }
+ if (containerBuild) {
+ connectionId = options.getProperty(
+ ContainerCommandLauncher.CONNECTION_ID);
+ imageName = options
+ .getProperty(ContainerCommandLauncher.IMAGE_ID);
+ }
}
}
@@ -406,41 +503,7 @@ public class LaunchShortcut implements ILaunchShortcut {
? ("[" + imageName + "]") //$NON-NLS-1$ //$NON-NLS-2$
: ""))); //$NON-NLS-1$
- // DSF settings...use GdbUIPlugin preference store for defaults
- IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
- .getPreferenceStore();
- wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
- preferenceStore.getString(
- IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND));
- wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
- preferenceStore.getString(
- IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT));
- wc.setAttribute(
- IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
- preferenceStore.getBoolean(
- IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP));
- wc.setAttribute(
- IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
- IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
- wc.setAttribute(
- IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND,
- IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT);
- wc.setAttribute(
- IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK,
- IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT);
- wc.setAttribute(
- IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE,
- IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT);
-
- wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME,
- binaryPath);
- wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
- bin.getCProject().getElementName());
- wc.setMappedResources(new IResource[] { bin.getResource(),
- bin.getResource().getProject() });
- wc.setAttribute(
- ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
- (String) null);
+
Preferences prefs = InstanceScope.INSTANCE
.getNode(DockerLaunchUIPlugin.PLUGIN_ID);
@@ -480,8 +543,6 @@ public class LaunchShortcut implements ILaunchShortcut {
return null;
}
- wc.setAttribute(ILaunchConstants.ATTR_CONNECTION_URI,
- connection.getUri());
// use build image if one is specified, otherwise, see if a default
// image is set in preferences, otherwise find first image in image
@@ -513,18 +574,8 @@ public class LaunchShortcut implements ILaunchShortcut {
return null;
}
- wc.setAttribute(ILaunchConstants.ATTR_IMAGE, (String) image);
-
- Boolean keepPref = prefs.getBoolean(
- PreferenceConstants.KEEP_CONTAINER_AFTER_LAUNCH, false);
- wc.setAttribute(ILaunchConstants.ATTR_KEEP_AFTER_LAUNCH, keepPref);
-
- // For Debug mode we need to set gdbserver info as well
- if (mode.equals(ILaunchManager.DEBUG_MODE)) {
- wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_COMMAND,
- "gdbserver"); //$NON-NLS-1$
- wc.setAttribute(ILaunchConstants.ATTR_GDBSERVER_PORT, "2345"); //$NON-NLS-1$
- }
+ populateLaunchConfiguration(wc, mode, bin, project.getName(),
+ connection.getUri(), image);
if (save) {
config = wc.doSave();
@@ -532,7 +583,7 @@ public class LaunchShortcut implements ILaunchShortcut {
config = wc;
}
} catch (CoreException e) {
- e.printStackTrace();
+ DockerLaunchUIPlugin.log(e);
}
return config;
}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java
index bb380e40c65..aa071ed6959 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java
@@ -105,6 +105,8 @@ public class Messages extends NLS {
public static String ContainerCommandLauncher_image_msg;
public static String CommandLauncher_CommandCancelled;
+ public static String ContainerTarget_name;
+
public static String ContainerCommandLauncher_invalid_values;
public static String Gdbserver_Settings_Remotetimeout_label;
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties
index 576419a814e..5b8e30e9590 100644
--- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties
@@ -45,6 +45,8 @@ ContainerPropertyTab_Enable_Msg=Build inside Docker Image
ContainerPropertyTab_Run_Autotools_In_Container_Msg=Run all Autotools in Container
ContainerPropertyTab_Run_Autotools_In_Container_Tooltip=Run Autotool commands in the Docker Container. This may cause inconsistencies between configurations sharing generated files.
+ContainerTarget_name=Docker Container
+
HeaderPreferencePage_Connection_Label=Connection
HeaderPreferencePage_Image_Label=Image
HeaderPreferencePage_Remove_Label=Remove
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java
new file mode 100644
index 00000000000..ae828a9fd0b
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java
@@ -0,0 +1,606 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2017, 2018 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
+ *
+ * Contributors:
+ * Red Hat Inc. - modified for use in Container build
+ *******************************************************************************/
+package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+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 java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CommandLauncherManager;
+import org.eclipse.cdt.core.ICommandLauncher;
+import org.eclipse.cdt.core.build.ICBuildConfiguration;
+import org.eclipse.cdt.core.build.IToolChain;
+import org.eclipse.cdt.core.build.IToolChainProvider;
+import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
+import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
+import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
+import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
+import org.eclipse.cdt.docker.launcher.ContainerCommandLauncher;
+import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
+import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
+import org.eclipse.core.resources.IBuildConfiguration;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.linuxtools.docker.ui.Activator;
+
+/**
+ * The Container GCC toolchain. It represents a GCC that will run in a Docker
+ * Container. It can be overridden to change environment variable settings.
+ *
+ * @since 1.2
+ */
+public class ContainerGCCToolChain extends PlatformObject implements IToolChain {
+
+ public static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.gcc"; //$NON-NLS-1$
+
+ private final IToolChainProvider provider;
+ private final String id;
+ private final Path path;
+ private final IEnvironmentVariable[] envVars;
+ private final Map<String, String> properties = new HashMap<>();
+
+ private String cCommand;
+ private String cppCommand;
+ private String[] commands;
+
+
+ public ContainerGCCToolChain(String id, IToolChainProvider provider,
+ Map<String, String> properties,
+ IEnvironmentVariable[] envVars) {
+ this.provider = provider;
+ this.path = new File("/usr/bin/gcc").toPath(); //$NON-NLS-1$
+
+ // We include arch in the id since a compiler can support multiple arches.
+ StringBuilder idBuilder = new StringBuilder("container-gcc-"); //$NON-NLS-1$
+ idBuilder.append(properties.get(Platform.getOSArch()));
+ idBuilder.append('-');
+ idBuilder.append(path.toString());
+ this.id = id;
+
+ this.properties.putAll(properties);
+ this.envVars = envVars;
+ }
+
+ @Override
+ public String getTypeId() {
+ return TYPE_ID;
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ @Override
+ public IToolChainProvider getProvider() {
+ return provider;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String getVersion() {
+ return ""; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getName() {
+ StringBuilder name = new StringBuilder(); // $NON-NLS-1$
+ String os = getProperty(ATTR_OS);
+ if (os != null) {
+ name.append(os);
+ name.append(' ');
+ }
+
+ String arch = getProperty(ATTR_ARCH);
+ if (arch != null) {
+ name.append(arch);
+ name.append(' ');
+ }
+
+ if (path != null) {
+ name.append(path.toString());
+ }
+
+ return name.toString();
+ }
+
+ @Override
+ public String getProperty(String key) {
+ String value = properties.get(key);
+ if (value != null) {
+ return value;
+ }
+
+ switch (key) {
+ case ATTR_OS:
+ return ContainerTargetTypeProvider.CONTAINER_LINUX;
+ case ATTR_ARCH:
+ return Platform.getOSArch();
+ }
+
+ return null;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public void setProperty(String key, String value) {
+ properties.put(key, value);
+ }
+
+ @Override
+ public String getBinaryParserId() {
+ return CCorePlugin.PLUGIN_ID + ".ELF"; //$NON-NLS-1$
+ }
+
+ protected void addDiscoveryOptions(List<String> command) {
+ command.add("-E"); //$NON-NLS-1$
+ command.add("-P"); //$NON-NLS-1$
+ command.add("-v"); //$NON-NLS-1$
+ command.add("-dD"); //$NON-NLS-1$
+ }
+
+ @Override
+ public IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, List<String> commandStrings,
+ IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI) {
+ try {
+ Path buildDirectory = Paths.get(buildDirectoryURI);
+
+ Path command = Paths.get(commandStrings.get(0));
+ List<String> commandLine = new ArrayList<>();
+ if (command.isAbsolute()) {
+ commandLine.add(command.toString());
+ } else {
+ commandLine.add(getCommandPath(command).toString());
+ }
+
+ if (baseScannerInfo != null) {
+ if (baseScannerInfo.getIncludePaths() != null) {
+ for (String includePath : baseScannerInfo.getIncludePaths()) {
+ commandLine.add("-I" + includePath); //$NON-NLS-1$
+ }
+ }
+
+ if (baseScannerInfo.getDefinedSymbols() != null) {
+ for (Map.Entry<String, String> macro : baseScannerInfo.getDefinedSymbols().entrySet()) {
+ if (macro.getValue() != null && !macro.getValue().isEmpty()) {
+ commandLine.add("-D" + macro.getKey() + "=" + macro.getValue()); //$NON-NLS-1$
+ } else {
+ commandLine.add("-D" + macro.getKey()); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ addDiscoveryOptions(commandLine);
+ commandLine.addAll(commandStrings.subList(1, commandStrings.size()));
+
+ // Strip surrounding quotes from the args on Windows
+ if (Platform.OS_WIN32.equals(Platform.getOS())) {
+ for (int i = 0; i < commandLine.size(); i++) {
+ String arg = commandLine.get(i);
+ if (arg.startsWith("\"") && arg.endsWith("\"")) { //$NON-NLS-1$ //$NON-NLS-2$
+ commandLine.set(i, arg.substring(1, arg.length() - 1));
+ }
+ }
+ }
+
+ // Change output to stdout
+ boolean haveOut = false;
+ for (int i = 0; i < commandLine.size() - 1; ++i) {
+ if (commandLine.get(i).equals("-o")) { //$NON-NLS-1$
+ commandLine.set(i + 1, "-"); //$NON-NLS-1$
+ haveOut = true;
+ break;
+ }
+ }
+ if (!haveOut) {
+ commandLine.add("-o"); //$NON-NLS-1$
+ commandLine.add("-"); //$NON-NLS-1$
+ }
+
+ // Change source file to a tmp file (needs to be empty)
+ Path tmpFile = null;
+ for (int i = 1; i < commandLine.size(); ++i) {
+ String arg = commandLine.get(i);
+ if (!arg.startsWith("-")) { //$NON-NLS-1$
+ Path filePath;
+ try {
+ filePath = buildDirectory.resolve(commandLine.get(i)).normalize();
+ } catch (InvalidPathException e) {
+ continue;
+ }
+ IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(filePath.toUri());
+ if (files.length > 0 && files[0].exists()) {
+ // replace it with a temp file
+ Path parentPath = filePath.getParent();
+ String extension = files[0].getFileExtension();
+ if (extension == null) {
+ // Not sure if this is a reasonable choice when
+ // there's
+ // no extension
+ extension = ".cpp"; //$NON-NLS-1$
+ } else {
+ extension = '.' + extension;
+ }
+ tmpFile = Files.createTempFile(parentPath, ".sc", extension); //$NON-NLS-1$
+ commandLine.set(i, tmpFile.toString());
+ }
+ } else if (arg.equals("-o")) { //$NON-NLS-1$
+ // skip over the next arg
+ // TODO handle other args like this
+ i++;
+ }
+ }
+ if (tmpFile == null) {
+ // Have to assume there wasn't a source file. Add one in the
+ // resource's container
+ // TODO really?
+ IPath parentPath = resource instanceof IFile ? resource.getParent().getLocation()
+ : resource.getLocation();
+ if (parentPath.toFile().exists()) {
+ tmpFile = Files.createTempFile(parentPath.toFile().toPath(), ".sc", ".cpp"); //$NON-NLS-1$ //$NON-NLS-2$
+ commandLine.add(tmpFile.toString());
+ }
+ }
+
+ return getScannerInfo(buildConfig, commandLine, buildDirectory, tmpFile);
+ } catch (IOException e) {
+ Activator.log(e);
+ return null;
+ }
+ }
+
+ @Override
+ public IExtendedScannerInfo getDefaultScannerInfo(IBuildConfiguration buildConfig,
+ IExtendedScannerInfo baseScannerInfo, ILanguage language, URI buildDirectoryURI) {
+ try {
+ String[] commands = getCompileCommands(language);
+ if (commands == null || commands.length == 0) {
+ // no default commands
+ return null;
+ }
+
+ Path buildDirectory = Paths.get(buildDirectoryURI);
+
+ // Pick the first one
+ Path command = Paths.get(commands[0]);
+ List<String> commandLine = new ArrayList<>();
+ if (command.isAbsolute()) {
+ commandLine.add(command.toString());
+ } else {
+ commandLine.add(getCommandPath(command).toString());
+ }
+
+ if (baseScannerInfo != null) {
+ if (baseScannerInfo.getIncludePaths() != null) {
+ for (String includePath : baseScannerInfo.getIncludePaths()) {
+ commandLine.add("-I" + includePath); //$NON-NLS-1$
+ }
+ }
+
+ if (baseScannerInfo.getDefinedSymbols() != null) {
+ for (Map.Entry<String, String> macro : baseScannerInfo.getDefinedSymbols().entrySet()) {
+ if (macro.getValue() != null && !macro.getValue().isEmpty()) {
+ commandLine.add("-D" + macro.getKey() + "=" + macro.getValue()); //$NON-NLS-1$
+ } else {
+ commandLine.add("-D" + macro.getKey()); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ addDiscoveryOptions(commandLine);
+
+ // output to stdout
+ commandLine.add("-o"); //$NON-NLS-1$
+ commandLine.add("-"); //$NON-NLS-1$
+
+ // Source is an empty tmp file
+ String extension;
+ if (GPPLanguage.ID.equals(language.getId())) {
+ extension = ".cpp"; //$NON-NLS-1$
+ } else if (GCCLanguage.ID.equals(language.getId())) {
+ extension = ".c"; //$NON-NLS-1$
+ } else {
+ // In theory we shouldn't get here
+ return null;
+ }
+
+ Path tmpFile = Files.createTempFile(buildDirectory, ".sc", extension); //$NON-NLS-1$
+ commandLine.add(tmpFile.toString());
+
+ return getScannerInfo(buildConfig, commandLine, buildDirectory, tmpFile);
+ } catch (IOException e) {
+ Activator.log(e);
+ return null;
+ }
+ }
+
+ private IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, List<String> commandLine,
+ Path buildDirectory, Path tmpFile) throws IOException {
+ Files.createDirectories(buildDirectory);
+
+ // Startup the command
+ ContainerCommandLauncher commandLauncher = new ContainerCommandLauncher();
+ ICBuildConfiguration cconfig = buildConfig
+ .getAdapter(ICBuildConfiguration.class);
+ commandLauncher.setBuildConfiguration(cconfig);
+ commandLauncher.setProject(buildConfig.getProject());
+ // CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(processBuilder.environment(),
+ // buildConfig, true);
+ org.eclipse.core.runtime.IPath commandPath = new org.eclipse.core.runtime.Path(
+ commandLine.get(0));
+ String[] args = commandLine.subList(1, commandLine.size())
+ .toArray(new String[0]);
+ org.eclipse.core.runtime.IPath workingDirectory = new org.eclipse.core.runtime.Path(
+ buildDirectory.toString());
+
+ Process process;
+ try (ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = new ByteArrayOutputStream()) {
+ process = commandLauncher.execute(commandPath, args, new String[0],
+ workingDirectory, new NullProgressMonitor());
+ if (process != null && commandLauncher.waitAndRead(stdout, stderr,
+ new NullProgressMonitor()) != ICommandLauncher.OK) {
+ String errMsg = commandLauncher.getErrorMessage();
+ DockerLaunchUIPlugin.logErrorMessage(errMsg);
+ return null;
+ }
+
+ // process.waitFor();
+
+ // Scan for the scanner info
+ Map<String, String> symbols = new HashMap<>();
+ List<String> includePath = new ArrayList<>();
+ Pattern definePattern = Pattern.compile("#define ([^\\s]*)\\s(.*)"); //$NON-NLS-1$
+ boolean inIncludePaths = false;
+
+ // concatenate stdout after stderr as stderr has the include paths
+ // and stdout has the defines
+ String[] outlines = stdout.toString(StandardCharsets.UTF_8.name())
+ .split("\\r?\\n"); //$NON-NLS-1$
+ String[] errlines = stderr.toString(StandardCharsets.UTF_8.name())
+ .split("\\r?\\n"); //$NON-NLS-1$
+ String[] lines = new String[errlines.length + outlines.length];
+ System.arraycopy(errlines, 0, lines, 0, errlines.length);
+ System.arraycopy(outlines, 0, lines, errlines.length,
+ outlines.length);
+
+ for (String line : lines) {
+ line = line.trim();
+ if (inIncludePaths) {
+ if (line.equals("End of search list.")) { //$NON-NLS-1$
+ inIncludePaths = false;
+ } else {
+ String include = line.trim();
+ org.eclipse.core.runtime.IPath path = new org.eclipse.core.runtime.Path(
+ include);
+ if (!path.isAbsolute()) {
+ org.eclipse.core.runtime.IPath newPath = workingDirectory
+ .append(path);
+ include = newPath.makeAbsolute().toPortableString();
+ }
+ includePath.add(include);
+ }
+ } else if (line.startsWith("#define ")) { //$NON-NLS-1$
+ Matcher matcher = definePattern.matcher(line);
+ if (matcher.matches()) {
+ symbols.put(matcher.group(1), matcher.group(2));
+ }
+ } else if (line.equals("#include <...> search starts here:")) { //$NON-NLS-1$
+ inIncludePaths = true;
+ }
+ }
+
+ // Process include paths for scanner info and point to any copied
+ // header directories
+ includePath = CommandLauncherManager.getInstance()
+ .processIncludePaths(cconfig, includePath);
+
+ ExtendedScannerInfo info = new ExtendedScannerInfo(symbols,
+ includePath.toArray(new String[includePath.size()]));
+ return info;
+ } catch (CoreException e1) {
+ return null;
+ } finally {
+ Files.delete(tmpFile);
+ }
+
+ }
+
+ @Override
+ public String[] getErrorParserIds() {
+ return new String[] { "org.eclipse.cdt.core.GCCErrorParser", //$NON-NLS-1$
+ "org.eclipse.cdt.core.GASErrorParser", //$NON-NLS-1$
+ "org.eclipse.cdt.core.GLDErrorParser", //$NON-NLS-1$
+ "org.eclipse.cdt.core.GmakeErrorParser", //$NON-NLS-1$
+ "org.eclipse.cdt.core.CWDLocator" //$NON-NLS-1$
+ };
+ }
+
+ @Override
+ public IEnvironmentVariable getVariable(String name) {
+ if (envVars != null) {
+ for (IEnvironmentVariable var : envVars) {
+ if (var.getName().equals(name)) {
+ return var;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public IEnvironmentVariable[] getVariables() {
+ return envVars;
+ }
+
+ @Override
+ public Path getCommandPath(Path command) {
+ if (command.isAbsolute()) {
+ return command;
+ }
+
+ return new File("/usr/bin/" + command).toPath(); //$NON-NLS-1$
+ }
+
+ private void initCompileCommands() {
+ if (commands == null) {
+ cCommand = path.getFileName().toString();
+ cppCommand = null;
+ if (cCommand.contains("gcc")) { //$NON-NLS-1$
+ cppCommand = cCommand.replace("gcc", "g++"); //$NON-NLS-1$ //$NON-NLS-2$
+ // Also recognize c++ as an alias for g++
+ commands = new String[] { cCommand, cppCommand, cCommand.replace("gcc", "cc"), //$NON-NLS-1$ //$NON-NLS-2$
+ cCommand.replace("gcc", "c++") }; //$NON-NLS-1$ //$NON-NLS-2$
+ } else if (cCommand.contains("clang")) { //$NON-NLS-1$
+ cppCommand = cCommand.replace("clang", "clang++"); //$NON-NLS-1$ //$NON-NLS-2$
+ commands = new String[] { cCommand, cppCommand };
+ } else if (cCommand.contains("emcc")) { //$NON-NLS-1$
+ // TODO Hack for emscripten. Can we generalize?
+ cppCommand = cCommand.replace("emcc", "em++"); //$NON-NLS-1$ //$NON-NLS-2$
+ commands = new String[] { cCommand, cppCommand };
+ } else {
+ commands = new String[] { cCommand };
+ }
+ }
+ }
+
+ @Override
+ public String[] getCompileCommands() {
+ initCompileCommands();
+ return commands;
+ }
+
+ @Override
+ public String[] getCompileCommands(ILanguage language) {
+ initCompileCommands();
+ if (GPPLanguage.ID.equals(language.getId())) {
+ return new String[] { cppCommand != null ? cppCommand : cCommand };
+ } else if (GCCLanguage.ID.equals(language.getId())) {
+ return new String[] { cCommand };
+ } else {
+ return new String[0];
+ }
+ }
+
+ @Override
+ public IResource[] getResourcesFromCommand(List<String> cmd, URI buildDirectoryURI) {
+ // Start at the back looking for arguments
+ List<IResource> resources = new ArrayList<>();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ for (int i = cmd.size() - 1; i >= 0; --i) {
+ String arg = cmd.get(i);
+ if (arg.startsWith("-")) { //$NON-NLS-1$
+ // ran into an option, we're done.
+ break;
+ }
+ if (i > 1 && cmd.get(i - 1).equals("-o")) { //$NON-NLS-1$
+ // this is an output file
+ --i;
+ continue;
+ }
+ try {
+ Path srcPath = Paths.get(arg);
+ URI uri;
+ if (srcPath.isAbsolute()) {
+ uri = srcPath.toUri();
+ } else {
+ if (arg.startsWith("/") && Platform.getOS().equals(Platform.OS_WIN32)) { //$NON-NLS-1$
+ String drive = srcPath.getName(0).toString();
+ if (drive.length() == 1) {
+ srcPath = Paths.get(drive + ":\\").resolve(srcPath.subpath(1, srcPath.getNameCount())); //$NON-NLS-1$
+ }
+ }
+ uri = Paths.get(buildDirectoryURI).resolve(srcPath).toUri().normalize();
+ }
+
+ for (IFile resource : root.findFilesForLocationURI(uri)) {
+ resources.add(resource);
+ }
+ } catch (IllegalArgumentException e) {
+ // Bad URI
+ continue;
+ }
+ }
+
+ return resources.toArray(new IResource[resources.size()]);
+ }
+
+ @Override
+ public List<String> stripCommand(List<String> command, IResource[] resources) {
+ List<String> newCommand = new ArrayList<>();
+
+ for (int i = 0; i < command.size() - resources.length; ++i) {
+ String arg = command.get(i);
+ if (arg.startsWith("-o")) { //$NON-NLS-1$
+ if (arg.equals("-o")) { //$NON-NLS-1$
+ i++;
+ }
+ continue;
+ }
+ newCommand.add(arg);
+ }
+
+ return newCommand;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ContainerGCCToolChain tc = (ContainerGCCToolChain) obj;
+ if (tc.id != this.id)
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+}
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
new file mode 100644
index 00000000000..b7392d20e01
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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 contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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.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.IDockerImage;
+
+/**
+ *
+ * @author jjohnstn
+ *
+ * @since 1.2
+ *
+ */
+public class ContainerGCCToolChainProvider implements IToolChainProvider {
+
+ 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$
+
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ @Override
+ public void init(IToolChainManager manager) throws CoreException {
+ IDockerConnection[] connections = DockerConnectionManager.getInstance()
+ .getConnections();
+ for (IDockerConnection connection : connections) {
+ List<IDockerImage> images = connection.getImages();
+ for (IDockerImage image : images) {
+ if (!image.isDangling() && !image.isIntermediateImage()) {
+
+ Map<String, String> 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(':', '_'));
+
+ ContainerGCCToolChain toolChain = new ContainerGCCToolChain(
+ "gcc-img-" + image.id().substring(0, 19), //$NON-NLS-1$
+ this, properties, null);
+
+ manager.addToolChain(toolChain);
+ }
+ }
+ }
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerTargetLabelProvider.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerTargetLabelProvider.java
new file mode 100644
index 00000000000..82c846e08d6
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerTargetLabelProvider.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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.docker.launcher.ui.launchbar;
+
+import org.eclipse.cdt.debug.internal.ui.CDebugImages;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.launchbar.core.target.ILaunchTarget;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author jjohnstn
+ * @since 1.2
+ *
+ */
+public class ContainerTargetLabelProvider extends LabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof ILaunchTarget) {
+ return ((ILaunchTarget) element).getId();
+ }
+ return super.getText(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return CDebugImages.get(CDebugImages.IMG_OBJS_CDT_LOGO);
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchConfigProvider.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchConfigProvider.java
new file mode 100644
index 00000000000..6b51587372a
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchConfigProvider.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * 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.docker.launcher.ui.launchbar;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
+import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
+import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
+import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
+import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.launchbar.core.AbstractLaunchConfigProvider;
+import org.eclipse.launchbar.core.ILaunchDescriptor;
+import org.eclipse.launchbar.core.target.ILaunchTarget;
+
+/**
+ * @since 1.2
+ * @author jjohnstn
+ *
+ */
+public class CoreBuildContainerLaunchConfigProvider extends AbstractLaunchConfigProvider {
+
+ private static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.launchConfigurationType"; //$NON-NLS-1$
+
+ private Map<IProject, Map<String, ILaunchConfiguration>> configs = new HashMap<>();
+
+ @Override
+ public boolean supports(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
+ return target != null && ContainerTargetTypeProvider.TYPE_ID
+ .equals(target.getTypeId());
+ }
+
+ @Override
+ public ILaunchConfigurationType getLaunchConfigurationType(ILaunchDescriptor descriptor, ILaunchTarget target)
+ throws CoreException {
+ return DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(TYPE_ID);
+ }
+
+ @Override
+ public ILaunchConfiguration getLaunchConfiguration(ILaunchDescriptor descriptor, ILaunchTarget target)
+ throws CoreException {
+ ILaunchConfiguration config = null;
+ IProject project = descriptor.getAdapter(IProject.class);
+ if (project != null) {
+ Map<String, ILaunchConfiguration> configMap = configs.get(project);
+ if (configMap == null) {
+ configMap = new HashMap<>();
+ }
+ String connection = target.getAttribute(
+ IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$
+ String imageId = target
+ .getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, ""); //$NON-NLS-1$
+ String imageName = connection + "-" + imageId; //$NON-NLS-1$
+ config = configMap.get(imageName);
+ if (config == null) {
+ config = createLaunchConfiguration(descriptor, target);
+ // launch config added will get called below to add it to the
+ // configs map
+ }
+ }
+ return config;
+ }
+
+ private String getImageName(ILaunchConfiguration config)
+ throws CoreException {
+ String connection = config
+ .getAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$
+ String image = config.getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID,
+ ""); //$NON-NLS-1$
+ String imageName = connection + "-" + image; //$NON-NLS-1$
+
+ return imageName;
+ }
+
+ @Override
+ protected void populateLaunchConfiguration(ILaunchDescriptor descriptor, ILaunchTarget target,
+ ILaunchConfigurationWorkingCopy wc) throws CoreException {
+ super.populateLaunchConfiguration(descriptor, target, wc);
+
+ // Set the project and the connection
+ IProject project = descriptor.getAdapter(IProject.class);
+ wc.setAttribute(
+ ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
+ project.getName());
+ wc.setAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI,
+ target.getAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI,
+ null));
+ wc.setAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, target
+ .getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, null));
+
+ // DSF settings...use GdbUIPlugin preference store for defaults
+ IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
+ .getPreferenceStore();
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
+ preferenceStore.getString(
+ IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_COMMAND));
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT,
+ preferenceStore.getString(
+ IGdbDebugPreferenceConstants.PREF_DEFAULT_GDB_INIT));
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP,
+ preferenceStore.getBoolean(
+ IGdbDebugPreferenceConstants.PREF_DEFAULT_NON_STOP));
+ wc.setAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_REVERSE,
+ IGDBLaunchConfigurationConstants.DEBUGGER_REVERSE_DEFAULT);
+ wc.setAttribute(
+ IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND,
+ IGDBLaunchConfigurationConstants.DEBUGGER_UPDATE_THREADLIST_ON_SUSPEND_DEFAULT);
+ wc.setAttribute(
+ IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_DEBUG_ON_FORK,
+ IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_ON_FORK_DEFAULT);
+ wc.setAttribute(
+ IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_TRACEPOINT_MODE,
+ IGDBLaunchConfigurationConstants.DEBUGGER_TRACEPOINT_MODE_DEFAULT);
+ wc.setAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
+ (String) null); // default is the project directory
+
+ wc.setMappedResources(new IResource[] { project });
+ }
+
+ @Override
+ public boolean launchConfigurationAdded(ILaunchConfiguration configuration) throws CoreException {
+ if (ownsLaunchConfiguration(configuration)) {
+ IProject project = configuration.getMappedResources()[0].getProject();
+ Map<String, ILaunchConfiguration> configMap = configs.get(project);
+ if (configMap == null) {
+ configMap = new HashMap<>();
+ configs.put(project, configMap);
+ }
+ String imageName = getImageName(configuration);
+ if (!imageName.equals("-")) { //$NON-NLS-1$
+ configMap.put(imageName, configuration);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean launchConfigurationRemoved(ILaunchConfiguration configuration) throws CoreException {
+ for (Entry<IProject, Map<String, ILaunchConfiguration>> entry : configs
+ .entrySet()) {
+ for (Entry<String, ILaunchConfiguration> innerEntry : entry
+ .getValue().entrySet()) {
+ if (configuration.equals(innerEntry.getValue())) {
+ entry.getValue().remove(innerEntry.getKey());
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean launchConfigurationChanged(ILaunchConfiguration configuration) throws CoreException {
+ // if (ownsLaunchConfiguration(configuration)) {
+ // IProject project = configuration.getMappedResources()[0]
+ // .getProject();
+ // Map<String, ILaunchConfiguration> configMap = configs.get(project);
+ // if (configMap == null) {
+ // configMap = new HashMap<>();
+ // configs.put(project, configMap);
+ // }
+ // String imageName = getImageName(configuration);
+ // if (!imageName.isEmpty()) {
+ // configMap.put(imageName, configuration);
+ // }
+ // return true;
+ // }
+ return false;
+ }
+
+ @Override
+ public void launchDescriptorRemoved(ILaunchDescriptor descriptor) throws CoreException {
+ IProject project = descriptor.getAdapter(IProject.class);
+ if (project != null) {
+ configs.remove(project);
+ }
+ }
+
+ @Override
+ public void launchTargetRemoved(ILaunchTarget target) throws CoreException {
+ // nothing to do since the Local connection can't be removed
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchDescriptorType.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchDescriptorType.java
new file mode 100644
index 00000000000..2117d94e8ec
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/CoreBuildContainerLaunchDescriptorType.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.docker.launcher.ui.launchbar;
+
+import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.launchbar.core.ILaunchDescriptor;
+import org.eclipse.launchbar.core.ILaunchDescriptorType;
+import org.eclipse.launchbar.core.ProjectLaunchDescriptor;
+import org.eclipse.launchbar.core.internal.Activator;
+
+/**
+ * The launch descriptor type for launch objects built with the Core Build
+ * System.
+ *
+ * @since 1.2
+ */
+public class CoreBuildContainerLaunchDescriptorType implements ILaunchDescriptorType {
+
+ @Override
+ public ILaunchDescriptor getDescriptor(Object launchObject) throws CoreException {
+ if (launchObject instanceof IProject) {
+ // Make sure it's a new style build
+ IProject project = (IProject) launchObject;
+ if (Activator.getService(ICBuildConfigurationManager.class).supports(project)) {
+ return new ProjectLaunchDescriptor(this, project);
+ }
+ }
+ // TODO IBinary
+ return null;
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/Messages.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/Messages.java
new file mode 100644
index 00000000000..002e391f1c8
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/Messages.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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
+ *
+ * Red Hat Inc. - initial version
+ *******************************************************************************/
+package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @since 1.2
+ * @author jjohnstn
+ *
+ */
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.docker.launcher.ui.launchbar.messages"; //$NON-NLS-1$
+
+ public static String ContainerGCCToolChainProvider_Saving1;
+ public static String ContainerGCCToolChainProvider_Saving;
+ public static String ContainerGCCToolChainProvider_NotOurs;
+ public static String ContainerGCCToolChainProvider_Loading;
+
+ public static String NewContainerTargetWizard_title;
+ public static String NewContainerTargetWizardPage_name;
+ public static String NewContainerTargetWizardPage_title;
+ public static String NewContainerTargetWizardPage_description;
+ public static String NewContainerTargetWizardPage_no_connections;
+ public static String NewContainerTargetWizardPage_no_images;
+ public static String NewContainerTargetWizardPage_connection;
+ public static String NewContainerTargetWizardPage_image;
+
+ public static String EditContainerTargetWizard_title;
+ public static String EditContainerTargetWizardPage_title;
+ public static String EditContainerTargetWizardPage_description;
+
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
+
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizard.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizard.java
new file mode 100644
index 00000000000..d2e00ece221
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizard.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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 contribution
+ *******************************************************************************/
+package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.core.build.IToolChain;
+import org.eclipse.cdt.core.build.IToolChainManager;
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider;
+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.launchbar.core.target.ILaunchTargetManager;
+import org.eclipse.launchbar.core.target.ILaunchTargetWorkingCopy;
+import org.eclipse.launchbar.ui.internal.Activator;
+import org.eclipse.launchbar.ui.target.LaunchTargetWizard;
+
+@SuppressWarnings("restriction")
+/**
+ * @since 1.2
+ * @author jjohnstn
+ *
+ */
+public class NewContainerTargetWizard extends LaunchTargetWizard {
+
+ private NewContainerTargetWizardPage page;
+ protected IToolChainManager toolChainManager = CDebugCorePlugin
+ .getService(IToolChainManager.class);
+
+ public NewContainerTargetWizard() {
+ if (getLaunchTarget() == null) {
+ setWindowTitle(Messages.NewContainerTargetWizard_title);
+ } else {
+ setWindowTitle(Messages.EditContainerTargetWizard_title);
+ }
+ }
+
+ @Override
+ public void addPages() {
+ super.addPages();
+
+ page = new NewContainerTargetWizardPage(getLaunchTarget());
+ addPage(page);
+ }
+
+ @Override
+ public boolean performFinish() {
+ ILaunchTargetManager manager = CDebugUIPlugin
+ .getService(ILaunchTargetManager.class);
+ String typeId = ContainerTargetTypeProvider.TYPE_ID;
+ String id = page.getTargetName();
+
+ ILaunchTarget target = getLaunchTarget();
+ if (target == null) {
+ target = manager.addLaunchTarget(typeId, id);
+ }
+
+ ILaunchTargetWorkingCopy wc = target.getWorkingCopy();
+ wc.setId(id);
+ wc.setAttribute(ILaunchTarget.ATTR_OS, Platform.getOS());
+ wc.setAttribute(ILaunchTarget.ATTR_ARCH,
+ ContainerTargetTypeProvider.CONTAINER_LINUX);
+ wc.setAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI,
+ page.getConnectionURI());
+ wc.setAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID,
+ page.getImageId());
+ wc.save();
+
+ // Pick the first one that matches
+ Map<String, String> properties = new HashMap<>();
+ properties.putAll(wc.getAttributes());
+ Collection<IToolChain> toolChains = Collections.emptyList();
+ try {
+ toolChains = toolChainManager.getToolChainsMatching(properties);
+ } catch (CoreException e) {
+ // do nothing
+ }
+
+ // if (toolChains.size() == 0) {
+ // // add new Container toolchain with attributes above
+ // ContainerToolChain toolChain = new ContainerToolChain();
+ // toolChain.add(properties);
+ // }
+
+ return true;
+ }
+
+ @Override
+ public boolean canDelete() {
+ return true;
+ }
+
+ @Override
+ public void performDelete() {
+ ILaunchTargetManager manager = Activator
+ .getService(ILaunchTargetManager.class);
+ ILaunchTarget target = getLaunchTarget();
+ if (target != null) {
+ manager.removeLaunchTarget(getLaunchTarget());
+ }
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizardPage.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizardPage.java
new file mode 100644
index 00000000000..d6c821a021a
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/NewContainerTargetWizardPage.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * 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
+ *
+ * Contibutors:
+ * Red Hat Inc. - initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.docker.launcher.ui.launchbar;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget;
+import org.eclipse.cdt.internal.docker.launcher.SWTImagesFactory;
+import org.eclipse.jface.wizard.WizardPage;
+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;
+import org.eclipse.linuxtools.docker.core.IDockerImageListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @since 1.2
+ * @author jjohnstn
+ *
+ */
+public class NewContainerTargetWizardPage extends WizardPage
+ implements IDockerImageListener, IDockerConnectionManagerListener {
+
+ private final ILaunchTarget launchTarget;
+
+ private Text nameText;
+ private Combo imageCombo;
+ private Combo connectionSelector;
+ private IDockerConnection connection;
+ private IDockerConnection[] connections;
+ private IDockerImageListener wizardPage;
+ private String imageName;
+ private String connectionName;
+ private String connectionUri = "";
+
+
+ public NewContainerTargetWizardPage(ILaunchTarget launchTarget) {
+ super(NewContainerTargetWizardPage.class.getName());
+ if (launchTarget == null) {
+ setTitle(Messages.NewContainerTargetWizardPage_title);
+ setDescription(Messages.NewContainerTargetWizardPage_description);
+ } else {
+ setTitle(Messages.EditContainerTargetWizardPage_title);
+ setDescription(Messages.EditContainerTargetWizardPage_description);
+ }
+ this.launchTarget = launchTarget;
+ this.wizardPage = this;
+ if (launchTarget != null) {
+ connectionUri = launchTarget.getAttribute(
+ IContainerLaunchTarget.ATTR_CONNECTION_URI, null);
+ imageName = launchTarget
+ .getAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, null);
+ }
+ }
+
+ private ModifyListener connectionModifyListener = new ModifyListener() {
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ int index = connectionSelector.getSelectionIndex();
+ if (connection != null)
+ connection.removeImageListener(wizardPage);
+ connection = connections[index];
+ connectionUri = connection.getUri();
+ if (!connectionName.equals(connection.getName())) {
+ setErrorMessage(null);
+ imageName = null;
+ initializeImageCombo();
+ setPageComplete(false);
+ }
+ connectionName = connection.getName();
+ }
+
+ };
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ comp.setLayout(new GridLayout(2, false));
+
+ Label label = new Label(comp, SWT.NONE);
+ label.setText(Messages.NewContainerTargetWizardPage_name);
+
+ nameText = new Text(comp, SWT.BORDER);
+ nameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ if (launchTarget != null) {
+ nameText.setText(launchTarget.getId());
+ nameText.setEnabled(false);
+ }
+
+ label = new Label(comp, SWT.NONE);
+ label.setText(Messages.NewContainerTargetWizardPage_connection);
+
+ connectionSelector = new Combo(comp, SWT.BORDER | SWT.READ_ONLY);
+ initializeConnectionSelector();
+ connectionSelector.addModifyListener(connectionModifyListener);
+ // Following is a kludge so that on Linux the Combo is read-only but
+ // has a white background.
+ connectionSelector.addVerifyListener(new VerifyListener() {
+ @Override
+ public void verifyText(VerifyEvent e) {
+ e.doit = false;
+ }
+ });
+ GridData gd = new GridData();
+ gd.horizontalSpan = 2;
+ gd.horizontalIndent = 5;
+ connectionSelector.setLayoutData(gd);
+
+ Label imageSelectorLabel = new Label(comp, SWT.NULL);
+ imageSelectorLabel.setText(Messages.NewContainerTargetWizardPage_image);
+ imageCombo = new Combo(comp, SWT.DROP_DOWN);
+ GridData gd2 = new GridData();
+ gd2.horizontalSpan = 2;
+ gd2.horizontalIndent = 5;
+ imageCombo.setLayoutData(gd2);
+
+ initializeImageCombo();
+
+ imageCombo.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ imageName = imageCombo.getText();
+ setPageComplete(imageName != null && !imageName.isEmpty());
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ });
+
+ setPageComplete(false);
+ setControl(comp);
+ }
+
+ public String getTargetName() {
+ return nameText.getText().trim();
+ }
+
+ public String getConnectionURI() {
+ return connectionUri;
+ }
+
+ public String getImageId() {
+ return imageName;
+ }
+
+ @Override
+ public Image getImage() {
+ return SWTImagesFactory.get(SWTImagesFactory.IMG_CONTAINER);
+ }
+
+ private void initializeConnectionSelector() {
+ int defaultIndex = -1;
+ connections = DockerConnectionManager.getInstance().getConnections();
+ if (connections.length == 0) {
+ setErrorMessage(
+ Messages.NewContainerTargetWizardPage_no_connections);
+ return;
+ }
+ String[] connectionNames = new String[connections.length];
+ for (int i = 0; i < connections.length; ++i) {
+ connectionNames[i] = connections[i].getName();
+ if (connections[i].getUri().equals(connectionUri))
+ defaultIndex = i;
+ }
+ if (defaultIndex < 0) {
+ defaultIndex = 0;
+ }
+ connectionSelector.setItems(connectionNames);
+ if (connections.length > 0) {
+ connectionSelector.setText(connectionNames[defaultIndex]);
+ connection = connections[defaultIndex];
+ connectionName = connection.getName();
+ connectionUri = connection.getUri();
+ }
+ }
+
+ private void initializeImageCombo() {
+ if (connection != null) {
+ java.util.List<IDockerImage> images = connection.getImages();
+ if (images == null || images.size() == 0) {
+ setErrorMessage(
+ Messages.NewContainerTargetWizardPage_no_images);
+ return;
+ }
+ connection.removeImageListener(wizardPage);
+ ArrayList<String> imageNames = new ArrayList<String>();
+ for (IDockerImage image : images) {
+ java.util.List<String> tags = image.repoTags();
+ if (tags != null) {
+ for (String tag : tags) {
+ if (!tag.equals("<none>:<none>")) //$NON-NLS-1$
+ imageNames.add(tag);
+ }
+ }
+ }
+ imageCombo.setItems(imageNames.toArray(new String[0]));
+ if (imageName != null)
+ imageCombo.setText(imageName);
+ connection.addImageListener(wizardPage);
+ }
+ }
+
+ @Override
+ public void changeEvent(IDockerConnection changedConnection, int type) {
+ String currUri = null;
+ int currIndex = 0;
+ setErrorMessage(null);
+ connections = DockerConnectionManager.getInstance().getConnections();
+ if (connection != null) {
+ currUri = connection.getUri();
+ currIndex = connectionSelector.getSelectionIndex();
+ }
+ String[] connectionNames = new String[connections.length];
+ int index = 0;
+ for (int i = 0; i < connections.length; ++i) {
+ connectionNames[i] = connections[i].getName();
+ if (connections[i].getUri().equals(currUri))
+ index = i;
+ }
+ if (type == IDockerConnectionManagerListener.RENAME_EVENT) {
+ index = currIndex; // no change in connection displayed
+ }
+ connectionSelector.removeModifyListener(connectionModifyListener);
+ connectionSelector.setItems(connectionNames);
+ if (connectionNames.length > 0) {
+ connectionSelector.setText(connectionNames[index]);
+ connection = connections[index];
+ connectionUri = connection.getUri();
+ java.util.List<IDockerImage> images = connection.getImages();
+ if (images == null || images.size() == 0) {
+ setErrorMessage(
+ Messages.NewContainerTargetWizardPage_no_images);
+ }
+ } else {
+ setErrorMessage(
+ Messages.NewContainerTargetWizardPage_no_connections);
+ connection = null;
+ connectionUri = "";
+ connectionSelector.setText("");
+ }
+ connectionSelector.addModifyListener(connectionModifyListener);
+ }
+
+ public void listChanged(IDockerConnection c,
+ java.util.List<IDockerImage> list) {
+ setErrorMessage(null);
+ final IDockerImage[] finalList = list.toArray(new IDockerImage[0]);
+ if (finalList.length == 0) {
+ setErrorMessage(Messages.NewContainerTargetWizardPage_no_images);
+ }
+ if (c.getName().equals(connection.getName())) {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ connection.removeImageListener(wizardPage);
+ ArrayList<String> imageNames = new ArrayList<String>();
+ for (IDockerImage image : finalList) {
+ java.util.List<String> tags = image.repoTags();
+ if (tags != null) {
+ for (String tag : tags) {
+ imageNames.add(tag);
+ }
+ }
+ }
+ if (!imageCombo.isDisposed())
+ imageCombo.setItems(imageNames.toArray(new String[0]));
+ connection.addImageListener(wizardPage);
+ }
+
+ });
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (connection != null)
+ connection.removeImageListener(this);
+ super.dispose();
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/messages.properties b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/messages.properties
new file mode 100644
index 00000000000..521d1242d76
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/messages.properties
@@ -0,0 +1,28 @@
+################################################################################
+# 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
+#
+# Red Hat Inc. - initial implementation
+################################################################################
+NewContainerTargetWizard_title=New Docker Container Target
+NewContainerTargetWizardPage_name=Name:
+NewContainerTargetWizardPage_image=Image:
+NewContainerTargetWizardPage_title=Container Target
+NewContainerTargetWizardPage_description=Enter name and properties for the target.
+NewContainerTargetWizardPage_no_connections=No Docker connections are available
+NewContainerTargetWizardPage_no_images=Docker connection has no pulled images
+NewContainerTargetWizardPage_connection=Connection:
+
+EditContainerTargetWizard_title=Edit Docker Container Target
+EditContainerTargetWizardPage_title=Container Target
+EditContainerTargetWizardPage_description=Edit properties for the target.
+
+ContainerGCCToolChainProvider_Saving1=Saving Container toolchain file
+ContainerGCCToolChainProvider_Saving=Saving Container toolchain file
+ContainerGCCToolChainProvider_NotOurs=Not ours
+ContainerGCCToolChainProvider_Loading=Loading Container toolchain file
+
+

Back to the top