Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Johnston2017-02-09 23:43:05 +0000
committerJeff Johnston2017-06-22 22:10:09 +0000
commitdb3ee42b31a2b958b3eece4ad243a9635e1f0fe6 (patch)
treea15d3e19c899ee58145b03d1e75190c8710fb01a
parent195ae127766bcd5ef01c94be2f906692a2ca97b9 (diff)
downloadorg.eclipse.cdt-db3ee42b31a2b958b3eece4ad243a9635e1f0fe6.tar.gz
org.eclipse.cdt-db3ee42b31a2b958b3eece4ad243a9635e1f0fe6.tar.xz
org.eclipse.cdt-db3ee42b31a2b958b3eece4ad243a9635e1f0fe6.zip
Bug 513589 - Add support to build CDT projects in a Docker Container
- add IOptionalBuildObjectPropertiesContainer interface to use for objects that supply optional build properties - add new IOptionalBuildProperties interface that defines optional build properties donated by external plug-ins - add new - change IConfiguration to an IOptionalBuildObjectPropertiesContainer - change IManagedProject to be an IOptionalBuildObjectPropertiesContainer - fix ProcessClosure to ensure that readers are not null before accessing them - fix Container launch delegate to look at project optional build properties for active configuration to fetch connection and image info and use said info to find a matching launch or create a new one - have Container launch delegate use the image name as part of the launch config name - have Container launch short-cut also use the project's optional build properties for the active config to get connection and image information before any defaulting - change AutotoolsNewMarkerGenerator to store the command launcher as an ICommandLauncher - add new CommandLauncherFactory extension to cdt.core that allows plug-ins to specify a CommandLauncherFactory that will return an ICommandLauncher based on the project - add macros for new extension to CCorePlugin - add new CommandLauncherFactoryManager class that loads CommandLauncherFactory extensions and is used to give an ICommandLauncher wrapper that will go through the list of CommandLauncherFactory extensions until one returns non-null ICommandLauncher - add code to RemoteCommandLauncher so it will use the CommandLauncherFactoryManager to get the local launcher - also change RemoteCommandLauncher to check at execution time whether the command is local and in that case use the local command launcher - add new ICommandLauncherFactory interface - add new ContainerCommandLauncher to launch - add new ContainerCommandLauncherFactory class for returning a ContainerCommandLauncher instance to launch commands in a Docker Container - change MakeBuilder to use CommandLauncherFactoryManager to get its ICommandLauncher - change CommandBuilder to use CommandLauncherFactoryManager too - ditto for Builder and AbstractBuiltinSpecsDetector and ExternalToolInvoker - change Configuration to load/store optional build properties as well as return the properties to get/set - ditto for MultiConfiguration - change ManagedProject to implement IOptionalBuildOptionProperties interface - ditto for ProjectType - create new OptionalBuildProperties class to store optional build properties for a configuration - bump cdt.managedbuilder.core to 8.5.0 - bump cdt.docker.launcher to 1.1.0 - use CommandLauncherFactory extension to define ContainerCommandLauncherFactory - add optional ContainerPropertyTab which allows the end-user to optionally choose to build a C/C++ project in a Container and specify the connection/image to use Change-Id: Id4d202d5eeb0dd52e528a45bf44d3e386f67376d
-rw-r--r--build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/AutotoolsNewMakeGenerator.java4
-rw-r--r--build/org.eclipse.cdt.autotools.tests/src/org/eclipse/cdt/autotools/tests/ProjectTools.java5
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java4
-rw-r--r--build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java4
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/buildproperties/IOptionalBuildProperties.java30
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuildObjectPropertiesContainer.java1
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java6
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedProject.java6
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOptionalBuildObjectPropertiesContainer.java21
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java2
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/CommandBuilder.java4
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java4
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java43
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java28
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java9
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionalBuildProperties.java104
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java24
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java4
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestConfiguration.java8
-rw-r--r--build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestProjectType.java3
-rw-r--r--codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java4
-rw-r--r--core/org.eclipse.cdt.core/META-INF/MANIFEST.MF2
-rw-r--r--core/org.eclipse.cdt.core/plugin.xml1
-rw-r--r--core/org.eclipse.cdt.core/schema/CommandLauncherFactory.exsd122
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java11
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncherFactoryManager.java206
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICommandLauncherFactory.java27
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProcessClosure.java16
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/META-INF/MANIFEST.MF6
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/plugin.properties5
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/plugin.xml22
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java50
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerCommandLauncher.java353
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerLaunchConfigurationDelegate.java3
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java428
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/LaunchShortcut.java102
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/Messages.java6
-rw-r--r--launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/messages.properties7
-rw-r--r--remote/org.eclipse.cdt.remote.core/src/org/eclipse/cdt/remote/core/RemoteCommandLauncher.java35
39 files changed, 1676 insertions, 44 deletions
diff --git a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/AutotoolsNewMakeGenerator.java b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/AutotoolsNewMakeGenerator.java
index 813fd3b4b5..2833538ef0 100644
--- a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/AutotoolsNewMakeGenerator.java
+++ b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/AutotoolsNewMakeGenerator.java
@@ -893,7 +893,7 @@ public class AutotoolsNewMakeGenerator extends MarkerGenerator {
consoleOutStream.flush();
// Get a launcher for the config command
- RemoteCommandLauncher launcher = new RemoteCommandLauncher();
+ ICommandLauncher launcher = new RemoteCommandLauncher();
launcher.setProject(project);
// Set the environment
IEnvironmentVariable variables[] =
@@ -1207,7 +1207,7 @@ public class AutotoolsNewMakeGenerator extends MarkerGenerator {
consoleOutStream.flush();
// Get a launcher for the config command
- RemoteCommandLauncher launcher = new RemoteCommandLauncher();
+ ICommandLauncher launcher = new RemoteCommandLauncher();
launcher.setProject(project);
// Set the environment
IEnvironmentVariable variables[] =
diff --git a/build/org.eclipse.cdt.autotools.tests/src/org/eclipse/cdt/autotools/tests/ProjectTools.java b/build/org.eclipse.cdt.autotools.tests/src/org/eclipse/cdt/autotools/tests/ProjectTools.java
index ad5aad0d3b..e2df9dc56b 100644
--- a/build/org.eclipse.cdt.autotools.tests/src/org/eclipse/cdt/autotools/tests/ProjectTools.java
+++ b/build/org.eclipse.cdt.autotools.tests/src/org/eclipse/cdt/autotools/tests/ProjectTools.java
@@ -18,6 +18,8 @@ import java.util.zip.ZipFile;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
+import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager;
import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration;
@@ -129,7 +131,8 @@ public class ProjectTools {
*/
public static boolean markExecutable(IProject project, String filePath) {
// Get a launcher for the config command
- CommandLauncher launcher = new CommandLauncher();
+ ICommandLauncher launcher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
+ launcher.setProject(project);
OutputStream stdout = new ByteArrayOutputStream();
OutputStream stderr = new ByteArrayOutputStream();
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java
index 4d9b9ad51c..cffa0635fe 100644
--- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java
@@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IConsoleParser;
@@ -180,7 +180,7 @@ public class MakeBuilder extends ACBuilder {
console.start(project);
// Prepare launch parameters for BuildRunnerHelper
- ICommandLauncher launcher = new CommandLauncher();
+ ICommandLauncher launcher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
String[] targets = getTargets(kind, info);
if (targets.length != 0 && targets[targets.length - 1].equals(info.getCleanBuildTarget()))
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java
index cd8b03563b..787d23f48e 100644
--- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java
@@ -19,7 +19,7 @@ import java.util.List;
import java.util.Properties;
import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IConsoleParser;
@@ -120,7 +120,7 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
}
console.start(project);
- ICommandLauncher launcher = new CommandLauncher();
+ ICommandLauncher launcher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
launcher.setProject(project);
IPath program = getCommandToLaunch();
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/buildproperties/IOptionalBuildProperties.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/buildproperties/IOptionalBuildProperties.java
new file mode 100644
index 0000000000..23043aed06
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/buildproperties/IOptionalBuildProperties.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.buildproperties;
+
+/**
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @since 8.5
+ */
+public interface IOptionalBuildProperties extends Cloneable {
+ String[] getProperties();
+
+ String getProperty(String id);
+
+ void setProperty(String propertyId, String propertyValue);
+
+ void removeProperty(String id);
+
+ void clear();
+
+ Object clone();
+} \ No newline at end of file
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuildObjectPropertiesContainer.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuildObjectPropertiesContainer.java
index 3bc55876f6..a3704a24f0 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuildObjectPropertiesContainer.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuildObjectPropertiesContainer.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.core;
-
/**
* @noextend This class is not intended to be subclassed by clients.
* @noimplement This interface is not intended to be implemented by clients.
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
index f04149faef..81d1f28bbb 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
@@ -36,7 +36,7 @@ import org.eclipse.core.runtime.IPath;
* @noextend This class is not intended to be subclassed by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesContainer {
+public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesContainer, IOptionalBuildObjectPropertiesContainer {
public static final String ARTIFACT_NAME = "artifactName"; //$NON-NLS-1$
public static final String CLEAN_COMMAND = "cleanCommand"; //$NON-NLS-1$
public static final String PREBUILD_STEP = "prebuildStep"; //$NON-NLS-1$
@@ -54,6 +54,10 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont
public static final String DESCRIPTION = "description"; //$NON-NLS-1$
public static final String BUILD_PROPERTIES = "buildProperties"; //$NON-NLS-1$
+ /**
+ * @since 8.5
+ */
+ public static final String OPTIONAL_BUILD_PROPERTIES = "optionalBuildProperties"; //$NON-NLS-1$
public static final String BUILD_ARTEFACT_TYPE = "buildArtefactType"; //$NON-NLS-1$
public static final String IS_SYSTEM = "isSystem"; //$NON-NLS-1$
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedProject.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedProject.java
index e0d527e939..8e5a0d7857 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedProject.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedProject.java
@@ -38,10 +38,14 @@ import org.eclipse.core.resources.IResource;
* @noextend This class is not intended to be subclassed by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface IManagedProject extends IBuildObject, IBuildObjectPropertiesContainer {
+public interface IManagedProject extends IBuildObject, IBuildObjectPropertiesContainer, IOptionalBuildObjectPropertiesContainer {
public static final String MANAGED_PROJECT_ELEMENT_NAME = "project"; //$NON-NLS-1$
public static final String PROJECTTYPE = "projectType"; //$NON-NLS-1$
public static final String BUILD_PROPERTIES = "buildProperties"; //$NON-NLS-1$
+ /**
+ * @since 8.5
+ */
+ public static final String OPTIONAL_BUILD_PROPERTIES = "optionalBuildProperties"; //$NON-NLS-1$
public static final String BUILD_ARTEFACT_TYPE = "buildArtefactType"; //$NON-NLS-1$
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOptionalBuildObjectPropertiesContainer.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOptionalBuildObjectPropertiesContainer.java
new file mode 100644
index 0000000000..68cfa186bc
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IOptionalBuildObjectPropertiesContainer.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.core;
+
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
+
+/**
+ * @since 8.5
+ */
+public interface IOptionalBuildObjectPropertiesContainer {
+ IOptionalBuildProperties getOptionalBuildProperties();
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java
index 1eea850c35..6d810e7110 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java
@@ -44,7 +44,7 @@ import org.eclipse.cdt.managedbuilder.macros.IProjectBuildMacroSupplier;
* @noextend This class is not intended to be subclassed by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface IProjectType extends IBuildObject, IBuildObjectPropertiesContainer {
+public interface IProjectType extends IBuildObject, IBuildObjectPropertiesContainer, IOptionalBuildObjectPropertiesContainer {
public static final String PROJECTTYPE_ELEMENT_NAME = "projectType"; //$NON-NLS-1$
public static final String SUPERCLASS = "superClass"; //$NON-NLS-1$
public static final String IS_ABSTRACT = "isAbstract"; //$NON-NLS-1$
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/CommandBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/CommandBuilder.java
index 4fe8091783..7bcec107c7 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/CommandBuilder.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/buildmodel/CommandBuilder.java
@@ -18,7 +18,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
@@ -143,7 +143,7 @@ public class CommandBuilder implements IBuildModelBuilder {
}
protected ICommandLauncher createLauncher() {
- return new CommandLauncher();
+ return CommandLauncherFactoryManager.getInstance().getCommandLauncher();
}
public String getErrMsg() {
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java
index 2b61d3e6ca..914a6f1e92 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java
@@ -25,7 +25,7 @@ import java.util.SortedMap;
import java.util.StringTokenizer;
import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
@@ -2858,7 +2858,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
return getSuperClass().getCommandLauncher();
else if(fCommandLauncher == null) // catch all for backwards compatibility
- fCommandLauncher = new CommandLauncher();
+ fCommandLauncher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
return fCommandLauncher;
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
index bba687d816..ac7b3f22ae 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
@@ -45,6 +45,7 @@ import org.eclipse.cdt.internal.core.SafeStringInterner;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IBuildObject;
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
@@ -114,6 +115,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
private String description;
private ICSourceEntry[] sourceEntries;
private BuildObjectProperties buildProperties;
+ private OptionalBuildProperties optionalBuildProperties;
private boolean isTest;
private SupportedProperties supportedProperties;
@@ -261,6 +263,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if(props != null)
buildProperties = new BuildObjectProperties(props, this, this);
+ String optionalProps = SafeStringInterner.safeIntern(element.getAttribute(OPTIONAL_BUILD_PROPERTIES));
+ if(props != null)
+ optionalBuildProperties = new OptionalBuildProperties(optionalProps);
+
String artType = SafeStringInterner.safeIntern(element.getAttribute(BUILD_ARTEFACT_TYPE));
if(artType != null){
if(buildProperties == null)
@@ -482,6 +488,9 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if(baseCfg.buildProperties != null)
this.buildProperties = new BuildObjectProperties(baseCfg.buildProperties, this, this);
+ if (baseCfg.optionalBuildProperties != null)
+ this.optionalBuildProperties = new OptionalBuildProperties(baseCfg.optionalBuildProperties);
+
// set managedBuildRevision
setManagedBuildRevision(baseCfg.getManagedBuildRevision());
@@ -625,6 +634,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if(cloneConfig.buildProperties != null) {
this.buildProperties = new BuildObjectProperties(cloneConfig.buildProperties, this, this);
}
+
+ if (cloneConfig.optionalBuildProperties != null) {
+ this.optionalBuildProperties = new OptionalBuildProperties(cloneConfig.optionalBuildProperties);
+ }
this.description = cloneConfig.getDescription();
@@ -819,6 +832,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if(props != null)
buildProperties = new BuildObjectProperties(props, this, this);
+ String optionalProps = element.getAttribute(OPTIONAL_BUILD_PROPERTIES);
+ if (optionalProps != null)
+ optionalBuildProperties = new OptionalBuildProperties(optionalProps);
+
String artType = SafeStringInterner.safeIntern(element.getAttribute(BUILD_ARTEFACT_TYPE));
if(artType != null){
if(buildProperties == null)
@@ -908,6 +925,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
}
}
+ if(optionalBuildProperties != null){
+ element.setAttribute(OPTIONAL_BUILD_PROPERTIES, optionalBuildProperties.toString());
+ }
+
if (parent != null)
element.setAttribute(IConfiguration.PARENT, parent.getId());
@@ -2398,6 +2419,18 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
return buildProperties;
}
+ @Override
+ public IOptionalBuildProperties getOptionalBuildProperties() {
+ if (optionalBuildProperties == null){
+ OptionalBuildProperties parentProps = findOptionalBuildProperties();
+ if(parentProps != null)
+ optionalBuildProperties = new OptionalBuildProperties(parentProps);
+ else
+ optionalBuildProperties = new OptionalBuildProperties();
+ }
+ return optionalBuildProperties;
+ }
+
private BuildObjectProperties findBuildProperties(){
if(buildProperties == null){
if(parent != null){
@@ -2407,6 +2440,16 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
}
return buildProperties;
}
+
+ private OptionalBuildProperties findOptionalBuildProperties(){
+ if (optionalBuildProperties == null){
+ if (parent != null){
+ return ((Configuration)parent).findOptionalBuildProperties();
+ }
+ return null;
+ }
+ return optionalBuildProperties;
+ }
public boolean supportsType(IBuildPropertyType type) {
return supportsType(type.getId());
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java
index 22bbaa7cde..68d59d2f27 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java
@@ -24,6 +24,7 @@ import org.eclipse.cdt.core.settings.model.ICStorageElement;
import org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IBuildObject;
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
import org.eclipse.cdt.managedbuilder.core.IBuildPropertiesRestriction;
@@ -57,6 +58,7 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
// private StorableEnvironment userDefinedEnvironment;
private BuildObjectProperties buildProperties;
+ private OptionalBuildProperties optionalBuildProperties;
/*
* C O N S T R U C T O R S
@@ -191,6 +193,10 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
String props = element.getAttribute(BUILD_PROPERTIES);
if(props != null && props.length() != 0)
buildProperties = new BuildObjectProperties(props, this, this);
+
+ String optionalProps = element.getAttribute(OPTIONAL_BUILD_PROPERTIES);
+ if (optionalProps != null && optionalProps.length() != 0)
+ optionalBuildProperties = new OptionalBuildProperties(optionalProps);
String artType = element.getAttribute(BUILD_ARTEFACT_TYPE);
if(artType != null){
@@ -576,6 +582,18 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
return buildProperties;
}
+ @Override
+ public IOptionalBuildProperties getOptionalBuildProperties() {
+ if(optionalBuildProperties == null){
+ OptionalBuildProperties parentProps = findOptionalBuildProperties();
+ if(parentProps != null)
+ optionalBuildProperties = new OptionalBuildProperties(parentProps);
+ else
+ optionalBuildProperties = new OptionalBuildProperties();
+ }
+ return optionalBuildProperties;
+ }
+
private BuildObjectProperties findBuildProperties(){
if(buildProperties == null){
if(projectType != null){
@@ -586,6 +604,16 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
return buildProperties;
}
+ private OptionalBuildProperties findOptionalBuildProperties(){
+ if(optionalBuildProperties == null){
+ if(projectType != null){
+ return ((ProjectType)projectType).findOptionalBuildProperties();
+ }
+ return null;
+ }
+ return optionalBuildProperties;
+ }
+
@Override
public void propertiesChanged() {
IConfiguration cfgs[] = getConfigurations();
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java
index f3e9bda6d7..0a7b5a0e4b 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java
@@ -22,6 +22,7 @@ import org.eclipse.cdt.core.settings.model.extension.CBuildData;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
import org.eclipse.cdt.managedbuilder.core.IBuilder;
@@ -1204,6 +1205,14 @@ public class MultiConfiguration extends MultiItemsHolder implements
return curr().getBuildProperties();
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.core.IBuildObjectPropertiesContainer#getOptionalBuildProperties()
+ */
+ @Override
+ public IOptionalBuildProperties getOptionalBuildProperties() {
+ return curr().getOptionalBuildProperties();
+ }
+
@Override
public boolean getParallelDef() {
for (IConfiguration cfg : fCfgs) {
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionalBuildProperties.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionalBuildProperties.java
new file mode 100644
index 0000000000..8ec750feba
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionalBuildProperties.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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 contribution
+ *******************************************************************************/
+package org.eclipse.cdt.managedbuilder.internal.core;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.cdt.internal.core.SafeStringInterner;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
+
+public class OptionalBuildProperties implements IOptionalBuildProperties {
+
+ public static final String PROPERTY_VALUE_SEPARATOR = "="; //$NON-NLS-1$
+ public static final String PROPERTIES_SEPARATOR = ","; //$NON-NLS-1$
+
+ private Map<String, String> fProperties = new HashMap<>();
+
+ public OptionalBuildProperties() {
+ }
+
+ public OptionalBuildProperties(String properties) {
+ StringTokenizer t = new StringTokenizer(properties, PROPERTIES_SEPARATOR);
+ while(t.hasMoreTokens()){
+ String property = t.nextToken();
+ int index = property.indexOf(PROPERTY_VALUE_SEPARATOR);
+ String id, value;
+ if(index != -1){
+ id = SafeStringInterner.safeIntern(property.substring(0, index));
+ value = SafeStringInterner.safeIntern(property.substring(index + 1));
+ } else {
+ id = SafeStringInterner.safeIntern(property);
+ value = null;
+ }
+ fProperties.put(id, value);
+ }
+ }
+
+ public OptionalBuildProperties(OptionalBuildProperties properties) {
+ fProperties.putAll(properties.fProperties);
+ }
+
+ @Override
+ public String getProperty(String id) {
+ return fProperties.get(id);
+ }
+
+ @Override
+ public void setProperty(String id, String value) {
+ fProperties.put(id, value);
+ }
+
+ @Override
+ public String[] getProperties(){
+ return fProperties.values().toArray(new String[fProperties.size()]);
+ }
+
+ @Override
+ public void removeProperty(String id) {
+ fProperties.remove(id);
+ }
+
+ @Override
+ public String toString(){
+ int size = fProperties.size();
+ Set<Entry<String,String>> entries = fProperties.entrySet();
+ if(size == 0)
+ return ""; //$NON-NLS-1$
+
+ StringBuilder buf = new StringBuilder();
+ Iterator<Entry<String,String>> iterator = entries.iterator();
+ Entry<String,String> entry = iterator.next();
+ buf.append(entry.getKey() + PROPERTY_VALUE_SEPARATOR + entry.getValue());
+
+ while (iterator.hasNext()) {
+ buf.append(PROPERTIES_SEPARATOR);
+ entry = iterator.next();
+ buf.append(entry.getKey() + PROPERTY_VALUE_SEPARATOR + entry.getValue());
+ }
+ return buf.toString();
+ }
+
+ @Override
+ public Object clone() {
+ return new OptionalBuildProperties(this);
+ }
+
+ @Override
+ public void clear() {
+ fProperties.clear();
+ }
+
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java
index 780b7f374e..c95d833b50 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java
@@ -22,6 +22,7 @@ import org.eclipse.cdt.internal.core.SafeStringInterner;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
import org.eclipse.cdt.managedbuilder.core.IBuildPropertiesRestriction;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
@@ -66,6 +67,7 @@ public class ProjectType extends BuildObject implements IProjectType, IBuildProp
private IProjectBuildMacroSupplier buildMacroSupplier = null;
BuildObjectProperties buildProperties;
+ OptionalBuildProperties optionalBuildProperties;
// Miscellaneous
@@ -708,6 +710,28 @@ public class ProjectType extends BuildObject implements IProjectType, IBuildProp
}
@Override
+ public IOptionalBuildProperties getOptionalBuildProperties() {
+ if(optionalBuildProperties == null){
+ OptionalBuildProperties parentProps = findOptionalBuildProperties();
+ if(parentProps != null)
+ optionalBuildProperties = new OptionalBuildProperties(parentProps);
+ else
+ optionalBuildProperties = new OptionalBuildProperties();
+ }
+ return optionalBuildProperties;
+ }
+
+ OptionalBuildProperties findOptionalBuildProperties(){
+ if(optionalBuildProperties == null){
+ if(superClass != null){
+ return ((ProjectType)superClass).findOptionalBuildProperties();
+ }
+ return null;
+ }
+ return optionalBuildProperties;
+ }
+
+ @Override
public void propertiesChanged() {
List<Configuration> list = getConfigurationList();
for(int i = 0; i < list.size(); i++){
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java
index 3ed6c14997..b4f98d12a5 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java
@@ -26,7 +26,7 @@ import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IConsoleParser;
@@ -656,7 +656,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
}
console.start(currentProject);
- ICommandLauncher launcher = new CommandLauncher();
+ ICommandLauncher launcher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
launcher.setProject(currentProject);
IPath program = new Path(""); //$NON-NLS-1$
diff --git a/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestConfiguration.java b/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestConfiguration.java
index 6bb61e8299..d3c139e359 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestConfiguration.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestConfiguration.java
@@ -14,6 +14,7 @@ import org.eclipse.cdt.core.settings.model.ICSourceEntry;
import org.eclipse.cdt.core.settings.model.extension.CBuildData;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
import org.eclipse.cdt.managedbuilder.core.IBuilder;
@@ -632,6 +633,13 @@ public class TestConfiguration implements IConfiguration {
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public IOptionalBuildProperties getOptionalBuildProperties() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
@Override
public IResource getOwner() { return null; }
diff --git a/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestProjectType.java b/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestProjectType.java
index d22f0878a6..0727d3bdc7 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestProjectType.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui.tests/src/org/eclipse/cdt/managedbuilder/ui/tests/util/TestProjectType.java
@@ -11,6 +11,7 @@
package org.eclipse.cdt.managedbuilder.ui.tests.util;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IConfigurationNameProvider;
@@ -76,6 +77,8 @@ public class TestProjectType implements IProjectType {
public void setVersion(Version version) {}
@Override
public IBuildObjectProperties getBuildProperties() { return null; }
+ @Override
+ public IOptionalBuildProperties getOptionalBuildProperties() { return null; }
@Override
public IBuildPropertyValue getBuildArtefactType() {
diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java
index 8343815c42..ba3de1969c 100644
--- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java
+++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java
@@ -18,7 +18,7 @@ import org.eclipse.cdt.codan.core.cxx.externaltool.ConfigurationSettings;
import org.eclipse.cdt.codan.core.cxx.externaltool.InvocationFailure;
import org.eclipse.cdt.codan.core.cxx.externaltool.InvocationParameters;
import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IConsoleParser;
import org.eclipse.cdt.core.resources.IConsole;
@@ -85,7 +85,7 @@ public class ExternalToolInvoker {
final OutputStream out = sniffer.getOutputStream();
final OutputStream err = sniffer.getErrorStream();
try {
- ICommandLauncher launcher = new CommandLauncher();
+ ICommandLauncher launcher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
launcher.showCommand(true);
launcher.setProject(project);
Process p = launcher.execute(commandPath, commandArgs, commandEnv, workingDirectory, new SubProgressMonitor(monitor, 50));
diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
index 3b39f4d4b1..cafe7f2bc1 100644
--- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.core; singleton:=true
-Bundle-Version: 6.3.1.qualifier
+Bundle-Version: 6.3.0.qualifier
Bundle-Activator: org.eclipse.cdt.core.CCorePlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml
index 81354a3bcb..086b08d5ef 100644
--- a/core/org.eclipse.cdt.core/plugin.xml
+++ b/core/org.eclipse.cdt.core/plugin.xml
@@ -692,6 +692,7 @@
<extension-point id="ProblemMarkerFilter" name="%problemMarkerFilter.name" schema="schema/ProblemMarkerFilter.exsd"/>
<extension-point id="buildConfigProvider" name="buildConfigProvider" schema="schema/buildConfigProvider.exsd"/>
<extension-point id="toolChainProvider" name="Tool Chain Provider" schema="schema/toolChainProvider.exsd"/>
+ <extension-point id="CommandLauncherFactory" name="CommandLauncherFactory" schema="schema/CommandLauncherFactory.exsd"/>
<extension
point="org.eclipse.cdt.core.templateProcessTypes">
diff --git a/core/org.eclipse.cdt.core/schema/CommandLauncherFactory.exsd b/core/org.eclipse.cdt.core/schema/CommandLauncherFactory.exsd
new file mode 100644
index 0000000000..272418d837
--- /dev/null
+++ b/core/org.eclipse.cdt.core/schema/CommandLauncherFactory.exsd
@@ -0,0 +1,122 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.cdt.core" id="CommandLauncherFactory" name="CommandLauncherFactory"/>
+ </appInfo>
+ <documentation>
+ This extension point is used to contribute a Command Launcher factory to CDT. A Command Launcher factory creates a Command Launcher for running commands.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="cextension"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="cextension">
+ <complexType>
+ <sequence>
+ <element ref="run"/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="run">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Command Launcher factory class that implements org.eclipse.cdt.core.ICommandLauncherFactory.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.ICommandLauncherFactory"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ CDT 9.3.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ Plug-ins that want to extend this extension point must implement &lt;samp&gt;org.eclipse.cdt.core.ICommandLauncherFactory&lt;/samp&gt; interface.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2017 Red Hat Inc. and others.&lt;br/&gt;
+All rights reserved. This program and the accompanying materials&lt;br/&gt;
+are made available under the terms of the Eclipse Public License v1.0&lt;br/&gt;
+which accompanies this distribution, and is available at&lt;br/&gt;
+http://www.eclipse.org/legal/epl-v10.html&lt;br/&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
index 6909c65f18..d4ca846574 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
@@ -147,6 +147,17 @@ public class CCorePlugin extends Plugin {
*/
public static final String ERROR_PARSER_UNIQ_ID = PLUGIN_ID + "." + ERROR_PARSER_SIMPLE_ID; //$NON-NLS-1$
+ /**
+ * Name of the extension point for contributing a Command Launcher factory
+ * @since 6.3
+ */
+ public static final String COMMAND_LAUNCHER_FACTORY_SIMPLE_ID = "CommandLauncherFactory"; //$NON-NLS-1$
+ /**
+ * Full unique name of the extension point for contributing a Command Launcher factory
+ * @since 6.3
+ */
+ public static final String COMMAND_LAUNCHER_FACTORY_UNIQ_ID = PLUGIN_ID + "." + COMMAND_LAUNCHER_FACTORY_SIMPLE_ID; //$NON-NLS-1$
+
// default store for pathentry
public static final String DEFAULT_PATHENTRY_STORE_ID = PLUGIN_ID + ".cdtPathEntryStore"; //$NON-NLS-1$
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncherFactoryManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncherFactoryManager.java
new file mode 100644
index 0000000000..cac12d153d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncherFactoryManager.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * @since 6.3
+ */
+public class CommandLauncherFactoryManager {
+
+ private static CommandLauncherFactoryManager instance;
+
+ private List<ICommandLauncherFactory> factories = new ArrayList<>();
+
+ private CommandLauncherFactoryManager() {
+ loadCommandLauncherFactoryExtensions();
+ }
+
+ public static synchronized CommandLauncherFactoryManager getInstance() {
+ if (instance == null) {
+ instance = new CommandLauncherFactoryManager();
+ }
+ return instance;
+ }
+
+ public ICommandLauncher getCommandLauncher() {
+ return new CommandLauncherWrapper(this);
+ }
+
+
+ private class CommandLauncherWrapper implements ICommandLauncher {
+
+ private ICommandLauncher launcher;
+ private IProject fProject;
+ private boolean fShowCommand;
+ private String fErrorMessage;
+ private CommandLauncherFactoryManager manager;
+
+ public CommandLauncherWrapper(CommandLauncherFactoryManager manager) {
+ this.manager = manager;
+ }
+
+ @Override
+ public void setProject(IProject project) {
+ if (launcher != null) {
+ launcher.setProject(project);
+ } else {
+ fProject = project;
+ }
+ }
+
+ @Override
+ public IProject getProject() {
+ if (launcher != null) {
+ return launcher.getProject();
+ }
+ return fProject;
+ }
+
+ @Override
+ public void showCommand(boolean show) {
+ if (launcher != null) {
+ launcher.showCommand(show);
+ } else {
+ fShowCommand = show;
+ }
+ }
+
+ @Override
+ public String getErrorMessage() {
+ if (launcher != null) {
+ return launcher.getErrorMessage();
+ }
+ return fErrorMessage;
+ }
+
+ @Override
+ public void setErrorMessage(String error) {
+ if (launcher != null) {
+ launcher.setErrorMessage(error);
+ } else {
+ fErrorMessage = error;
+ }
+ }
+
+ @Override
+ public String[] getCommandArgs() {
+ if (launcher != null) {
+ return launcher.getCommandArgs();
+ }
+ return new String[0];
+ }
+
+ @Override
+ public Properties getEnvironment() {
+ if (launcher != null) {
+ return launcher.getEnvironment();
+ }
+ return null;
+ }
+
+ @Override
+ public String getCommandLine() {
+ if (launcher != null) {
+ return launcher.getCommandLine();
+ }
+ return null;
+ }
+
+ @Override
+ public Process execute(IPath commandPath, String[] args, String[] env, IPath workingDirectory,
+ IProgressMonitor monitor) throws CoreException {
+ if (launcher == null) {
+ launcher = manager.getCommandLauncher(fProject);
+ launcher.setProject(fProject);
+ launcher.showCommand(fShowCommand);
+ launcher.setErrorMessage(fErrorMessage);
+ }
+ return launcher.execute(commandPath, args, env, workingDirectory, monitor);
+ }
+
+ @Override
+ public int waitAndRead(OutputStream out, OutputStream err) {
+ if (launcher != null) {
+ return launcher.waitAndRead(out, err);
+ }
+ return 0;
+ }
+
+ @Override
+ public int waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor) {
+ if (launcher != null) {
+ return launcher.waitAndRead(output, err, monitor);
+ }
+ return 0;
+ }
+
+ }
+ /**
+ * Get a command launcher.
+ *
+ * @param project - optional input to determine launcher.
+ * @return an ICommandLauncher for running commands
+ */
+ public ICommandLauncher getCommandLauncher(IProject project) {
+ // loop through list of factories and return first launcher
+ // returned
+ for (ICommandLauncherFactory factory : factories) {
+ ICommandLauncher launcher = factory.getCommandLauncher(project);
+ if (launcher != null) {
+ return launcher;
+ }
+ }
+ // default to local CommandLauncher
+ return new CommandLauncher();
+ }
+
+ /**
+ * Load command launcher factory contributed extensions from extension registry.
+ *
+ */
+ private void loadCommandLauncherFactoryExtensions() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint extension = registry.getExtensionPoint(CCorePlugin.PLUGIN_ID, CCorePlugin.COMMAND_LAUNCHER_FACTORY_SIMPLE_ID);
+ if (extension != null) {
+ IExtension[] extensions = extension.getExtensions();
+ for (IExtension ext : extensions) {
+ try {
+ IConfigurationElement element[] = extension.getConfigurationElements();
+ for (IConfigurationElement element2 : element) {
+ if (element2.getName().equalsIgnoreCase("cextension")) { //$NON-NLS-1$
+ ICommandLauncherFactory factory = (ICommandLauncherFactory) element2.createExecutableExtension("run"); //$NON-NLS-1$
+ factories.add(factory);
+ }
+ }
+ } catch (Exception e) {
+ CCorePlugin.log("Cannot load CommandLauncherFactory extension " + ext.getUniqueIdentifier(), e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICommandLauncherFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICommandLauncherFactory.java
new file mode 100644
index 0000000000..29855a9d8e
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICommandLauncherFactory.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core;
+
+import org.eclipse.core.resources.IProject;
+
+/**
+ * @since 6.3
+ */
+public interface ICommandLauncherFactory {
+
+ /**
+ * Get a Command Launcher for a project (optional)
+ * @param project - optional parameter to help determine appropriate launcher
+ * @return ICommandLauncher or null if not appropriate for project
+ */
+ public ICommandLauncher getCommandLauncher(IProject project);
+
+}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProcessClosure.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProcessClosure.java
index 771cb6e4b0..668457e1d7 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProcessClosure.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProcessClosure.java
@@ -217,14 +217,18 @@ public class ProcessClosure {
fProcess.destroy();
fProcess = null;
}
- if (!fOutputReader.finished()) {
- fOutputReader.waitFor();
+ if (fOutputReader != null) {
+ if (!fOutputReader.finished()) {
+ fOutputReader.waitFor();
+ }
+ fOutputReader.close();
}
- if (!fErrorReader.finished()) {
- fErrorReader.waitFor();
+ if (fErrorReader != null) {
+ if (!fErrorReader.finished()) {
+ fErrorReader.waitFor();
+ }
+ fErrorReader.close();
}
- fOutputReader.close();
- fErrorReader.close();
fOutputReader = null;
fErrorReader = null;
}
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 c24f2f4939..964621fbfa 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.0.0.qualifier
+Bundle-Version: 1.1.0.qualifier
Bundle-Activator: org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin
Bundle-Vendor: %Plugin.vendor
Bundle-Localization: plugin
@@ -20,7 +20,9 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.cdt.debug.ui;bundle-version="7.5.0",
org.eclipse.cdt.dsf.gdb;bundle-version="4.6.0",
org.eclipse.cdt.dsf.gdb.ui;bundle-version="2.4.0",
- org.eclipse.core.variables
+ org.eclipse.core.variables,
+ org.eclipse.cdt.managedbuilder.ui,
+ org.eclipse.cdt.managedbuilder.core
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.docker.launcher;x-internal:=true,
diff --git a/launch/org.eclipse.cdt.docker.launcher/plugin.properties b/launch/org.eclipse.cdt.docker.launcher/plugin.properties
index 0669aa80aa..aae650077a 100644
--- a/launch/org.eclipse.cdt.docker.launcher/plugin.properties
+++ b/launch/org.eclipse.cdt.docker.launcher/plugin.properties
@@ -16,3 +16,8 @@ must be set-up to supply the C/C++ application what it needs to run.
LaunchConfigurationType.name=C/C++ Container Launcher
Shortcut.label=C/C++ Container Application
DockerLaunchPreferencePage.name=Docker Container Launch
+ContainerCommandLauncherFactory.name=Container Command Launcher Factory
+Container.settings=Container Settings
+ContainerBuild.property.enablement=Container Build Enablement
+ContainerBuild.property.connection=Container Build Connection
+ContainerBuild.property.image=Container Build Image
diff --git a/launch/org.eclipse.cdt.docker.launcher/plugin.xml b/launch/org.eclipse.cdt.docker.launcher/plugin.xml
index a8e0a2cdb8..48250b9418 100644
--- a/launch/org.eclipse.cdt.docker.launcher/plugin.xml
+++ b/launch/org.eclipse.cdt.docker.launcher/plugin.xml
@@ -88,5 +88,25 @@
id="org.eclipse.cdt.docker.launcher.launchConfigurationTypeImage1">
</launchConfigurationTypeImage>
</extension>
-
+ <extension
+ id="ContainerCommandLauncherFactory"
+ name="%ContainerCommandLauncherFactory.name"
+ point="org.eclipse.cdt.core.CommandLauncherFactory">
+ <cextension>
+ <run
+ class="org.eclipse.cdt.docker.launcher.ContainerCommandLauncherFactory">
+ </run>
+ </cextension>
+ </extension>
+ <extension
+ point="org.eclipse.cdt.ui.cPropertyTab">
+ <tab
+ class="org.eclipse.cdt.internal.docker.launcher.ContainerPropertyTab"
+ icon="icons/repository-middle.gif"
+ name="%Container.settings"
+ parent="org.eclipse.cdt.managedbuilder.ui.properties.Page_BuildSettings"
+ weight="020">
+ </tab>
+ </extension>
+
</plugin>
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
new file mode 100644
index 0000000000..c19724f9e9
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncherFactory.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.docker.launcher;
+
+import org.eclipse.cdt.core.ICommandLauncher;
+import org.eclipse.cdt.core.ICommandLauncherFactory;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.internal.docker.launcher.ContainerCommandLauncher;
+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;
+
+public class ContainerCommandLauncherFactory
+ implements ICommandLauncherFactory {
+
+ @Override
+ public ICommandLauncher getCommandLauncher(IProject project) {
+ // check if container build enablement has been checked
+ ICConfigurationDescription cfgd = CoreModel.getDefault()
+ .getProjectDescription(project).getActiveConfiguration();
+ IConfiguration cfg = ManagedBuildManager
+ .getConfigurationForDescription(cfgd);
+ IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
+ if (props != null) {
+ String enablementProperty = props.getProperty(
+ ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
+ if (enablementProperty != null) {
+ boolean enableContainer = Boolean
+ .parseBoolean(enablementProperty);
+ // enablement has occurred, we can return a
+ // ContainerCommandLauncher
+ if (enableContainer) {
+ return new ContainerCommandLauncher();
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerCommandLauncher.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerCommandLauncher.java
new file mode 100644
index 0000000000..660d0baf3d
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerCommandLauncher.java
@@ -0,0 +1,353 @@
+package org.eclipse.cdt.internal.docker.launcher;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.cdt.core.ICommandLauncher;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
+import org.eclipse.cdt.internal.core.ProcessClosure;
+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.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.linuxtools.docker.ui.launch.ContainerLauncher;
+import org.eclipse.linuxtools.docker.ui.launch.IErrorMessageHolder;
+import org.eclipse.linuxtools.internal.docker.ui.launch.ContainerCommandProcess;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.service.prefs.Preferences;
+
+@SuppressWarnings("restriction")
+public class ContainerCommandLauncher
+ implements ICommandLauncher, IErrorMessageHolder {
+
+ public final static String CONTAINER_BUILD_ENABLED = "org.eclipse.cdt.docker.launcher.containerbuild.property.enablement"; // $NON-NLS-0$
+ public final static String CONNECTION_ID = "org.eclipse.cdt.docker.launcher.containerbuild.property.connection"; // $NON-NLS-0$
+ public final static String IMAGE_ID = "org.eclipse.cdt.docker.launcher.containerbuild.property.image"; // $NON-NLS-0$
+
+ private IProject fProject;
+ private Process fProcess;
+ private boolean fShowCommand;
+ private String fErrorMessage;
+ private Properties fEnvironment;
+
+ private String[] commandArgs;
+ private String fImageName = ""; //$NON-NLS-1$
+
+ public final static int COMMAND_CANCELED = ICommandLauncher.COMMAND_CANCELED;
+ public final static int ILLEGAL_COMMAND = ICommandLauncher.ILLEGAL_COMMAND;
+ public final static int OK = ICommandLauncher.OK;
+
+ private static final String NEWLINE = System.getProperty("line.separator", //$NON-NLS-1$
+ "\n"); //$NON-NLS-1$
+
+ /**
+ * The number of milliseconds to pause between polling.
+ */
+ protected static final long DELAY = 50L;
+
+ @Override
+ public void setProject(IProject project) {
+ this.fProject = project;
+ }
+
+ @Override
+ public IProject getProject() {
+ return fProject;
+ }
+
+ private String getImageName() {
+ return fImageName;
+ }
+
+ private void setImageName(String imageName) {
+ fImageName = imageName;
+ }
+
+ @Override
+ public void showCommand(boolean show) {
+ this.fShowCommand = show;
+ }
+
+ @Override
+ public String getErrorMessage() {
+ return fErrorMessage;
+ }
+
+ @Override
+ public void setErrorMessage(String error) {
+ fErrorMessage = error;
+ }
+
+ @Override
+ public String[] getCommandArgs() {
+ return commandArgs;
+ }
+
+ @Override
+ public Properties getEnvironment() {
+ return fEnvironment;
+ }
+
+ @Override
+ public String getCommandLine() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Process execute(IPath commandPath, String[] args, String[] env,
+ IPath workingDirectory, IProgressMonitor monitor)
+ throws CoreException {
+
+ HashMap<String, String> labels = new HashMap<>();
+ labels.put("org.eclipse.cdt.container-command", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ String projectName = fProject.getName();
+ labels.put("org.eclipse.cdt.project-name", projectName); //$NON-NLS-1$
+
+ List<String> additionalDirs = new ArrayList<>();
+
+ ArrayList<String> commandSegments = new ArrayList<>();
+
+ StringBuilder b = new StringBuilder();
+ b.append(commandPath.toString().trim());
+ commandSegments.add(commandPath.toString().trim());
+ for (String arg : args) {
+ b.append(" "); //$NON-NLS-1$
+ String realArg = VariablesPlugin.getDefault()
+ .getStringVariableManager().performStringSubstitution(arg);
+ b.append(realArg);
+ if (realArg.startsWith("/")) { //$NON-NLS-1$
+ // check if file exists and if so, add an additional directory
+ IPath p = new Path(realArg);
+ if (p.isValidPath(realArg)) {
+ p = p.makeAbsolute();
+ File f = p.toFile();
+ if (f.exists()) {
+ if (f.isFile()) {
+ p = p.removeLastSegments(1);
+ }
+ additionalDirs.add(p.toPortableString());
+ }
+ }
+ }
+ commandSegments.add(realArg);
+ }
+
+ commandArgs = commandSegments.toArray(new String[0]);
+
+ String commandDir = commandPath.removeLastSegments(1).toString();
+ if (commandDir.isEmpty()) {
+ commandDir = null;
+ }
+
+ IProject[] referencedProjects = fProject.getReferencedProjects();
+ for (IProject referencedProject : referencedProjects) {
+ additionalDirs
+ .add(referencedProject.getLocation().toPortableString());
+ }
+
+ String command = b.toString();
+
+ String workingDir = workingDirectory.toPortableString();
+ parseEnvironment(env);
+ Map<String, String> origEnv = null;
+
+ boolean supportStdin = false;
+
+ boolean privilegedMode = false;
+
+ ContainerLauncher launcher = new ContainerLauncher();
+
+ Preferences prefs = InstanceScope.INSTANCE
+ .getNode(DockerLaunchUIPlugin.PLUGIN_ID);
+
+ boolean keepContainer = prefs.getBoolean(
+ PreferenceConstants.KEEP_CONTAINER_AFTER_LAUNCH, false);
+
+ ICConfigurationDescription cfgd = CoreModel.getDefault()
+ .getProjectDescription(fProject).getActiveConfiguration();
+ IConfiguration cfg = ManagedBuildManager
+ .getConfigurationForDescription(cfgd);
+ if (cfg == null) {
+ return null;
+ }
+ IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
+ String connectionName = props
+ .getProperty(ContainerCommandLauncher.CONNECTION_ID);
+ if (connectionName == null) {
+ return null;
+ }
+ String imageName = props
+ .getProperty(ContainerCommandLauncher.IMAGE_ID);
+ if (imageName == null) {
+ return null;
+ }
+ setImageName(imageName);
+
+ fProcess = launcher.runCommand(connectionName, imageName, fProject,
+ this,
+ command,
+ commandDir,
+ workingDir,
+ additionalDirs,
+ origEnv, fEnvironment, supportStdin, privilegedMode,
+ labels, keepContainer);
+
+ return fProcess;
+ }
+
+ /**
+ * Parse array of "ENV=value" pairs to Properties.
+ */
+ private void parseEnvironment(String[] env) {
+ fEnvironment = null;
+ if (env != null) {
+ fEnvironment = new Properties();
+ for (String envStr : env) {
+ // Split "ENV=value" and put in Properties
+ int pos = envStr.indexOf('='); // $NON-NLS-1$
+ if (pos < 0)
+ pos = envStr.length();
+ String key = envStr.substring(0, pos);
+ String value = envStr.substring(pos + 1);
+ fEnvironment.put(key, value);
+ }
+ }
+ }
+
+ @Override
+ public int waitAndRead(OutputStream out, OutputStream err) {
+ printImageHeader(out);
+
+ if (fShowCommand) {
+ printCommandLine(out);
+ }
+
+ if (fProcess == null) {
+ return ILLEGAL_COMMAND;
+ }
+ ProcessClosure closure = new ProcessClosure(fProcess, out, err);
+ closure.runBlocking(); // a blocking call
+ return OK;
+ }
+
+ @Override
+ public int waitAndRead(OutputStream output, OutputStream err,
+ IProgressMonitor monitor) {
+ printImageHeader(output);
+
+ if (fShowCommand) {
+ printCommandLine(output);
+ }
+
+ if (fProcess == null) {
+ return ILLEGAL_COMMAND;
+ }
+
+ ProcessClosure closure = new ProcessClosure(fProcess, output, err);
+ closure.runNonBlocking();
+ Runnable watchProcess = () -> {
+ try {
+ fProcess.waitFor();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ closure.terminate();
+ };
+ Thread t = new Thread(watchProcess);
+ t.start();
+ while (!monitor.isCanceled() && closure.isAlive()) {
+ try {
+ Thread.sleep(DELAY);
+ } catch (InterruptedException ie) {
+ break;
+ }
+ }
+ try {
+ t.join(500);
+ } catch (InterruptedException e1) {
+ // ignore
+ }
+ int state = OK;
+
+ // Operation canceled by the user, terminate abnormally.
+ if (monitor.isCanceled()) {
+ closure.terminate();
+ state = COMMAND_CANCELED;
+ setErrorMessage(Messages.CommandLauncher_CommandCancelled);
+ }
+ try {
+ fProcess.waitFor();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
+ monitor.done();
+ return state;
+ }
+
+ protected void printImageHeader(OutputStream os) {
+ if (os != null) {
+ try {
+ os.write(NLS
+ .bind(Messages.ContainerCommandLauncher_image_msg,
+ ((ContainerCommandProcess) fProcess).getImage())
+ .getBytes());
+ os.write(NEWLINE.getBytes());
+ os.flush();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ protected void printCommandLine(OutputStream os) {
+ if (os != null) {
+ try {
+ os.write(getCommandLineQuoted(getCommandArgs(), true)
+ .getBytes());
+ os.flush();
+ } catch (IOException e) {
+ // ignore;
+ }
+ }
+ }
+
+ @SuppressWarnings("nls")
+ private String getCommandLineQuoted(String[] commandArgs, boolean quote) {
+ StringBuilder buf = new StringBuilder();
+ if (commandArgs != null) {
+ for (String commandArg : commandArgs) {
+ if (quote && (commandArg.contains(" ")
+ || commandArg.contains("\"")
+ || commandArg.contains("\\"))) {
+ commandArg = '"' + commandArg.replaceAll("\\\\", "\\\\\\\\")
+ .replaceAll("\"", "\\\\\"") + '"';
+ }
+ buf.append(commandArg);
+ buf.append(' ');
+ }
+ buf.append(NEWLINE);
+ }
+ return buf.toString();
+ }
+
+ protected String getCommandLine(String[] commandArgs) {
+ return getCommandLineQuoted(commandArgs, false);
+ }
+
+}
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 4f74b99ab7..d0f14f22c8 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
@@ -79,7 +79,8 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
@Override
public void newOutput(String output) {
- if (output.contains(Messages.Gdbserver_up)) {
+ if (output.contains(Messages.Gdbserver_up)
+ || output.contains("gdbserver:")) { //$NON-NLS-1$
started = true;
}
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java
new file mode 100644
index 0000000000..d6dc7d4180
--- /dev/null
+++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ContainerPropertyTab.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.docker.launcher;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICMultiConfigDescription;
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IMultiConfiguration;
+import org.eclipse.cdt.managedbuilder.internal.core.Configuration;
+import org.eclipse.cdt.managedbuilder.ui.properties.AbstractCBuildPropertyTab;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+@SuppressWarnings("restriction")
+public class ContainerPropertyTab extends AbstractCBuildPropertyTab
+ implements IDockerConnectionManagerListener, IDockerImageListener {
+
+ private Combo imageCombo;
+ private Combo connectionSelector;
+ private Button enableButton;
+
+ private IDockerConnection connection;
+ private IDockerConnection[] connections;
+ private IDockerImageListener containerTab;
+
+ private String connectionName;
+ private String connectionUri = ""; //$NON-NLS-1$
+
+ private boolean defaultEnabled;
+ private String defaultConnection;
+ private String defaultImage;
+
+ private IConfiguration iCfg;
+ private IOptionalBuildProperties properties;
+
+ private ModifyListener connectionModifyListener = new ModifyListener() {
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ int index = connectionSelector.getSelectionIndex();
+ if (connection != null)
+ connection.removeImageListener(containerTab);
+ connection = connections[index];
+ connectionUri = connection.getUri();
+ if (!connectionName.equals(connection.getName())) {
+ imageCombo.setText("");
+ defaultImage = null;
+ }
+ connectionName = connection.getName();
+ properties.setProperty(ContainerCommandLauncher.CONNECTION_ID,
+ connectionUri);
+ properties.setProperty(ContainerCommandLauncher.IMAGE_ID,
+ imageCombo.getText());
+ }
+
+ };
+
+ public ContainerPropertyTab() {
+ this.containerTab = this;
+ }
+
+ @Override
+ public void createControls(Composite parent) {
+ super.createControls(parent);
+
+ usercomp.setLayout(new GridLayout(5, false));
+ usercomp.setFont(parent.getFont());
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 1;
+
+ usercomp.setLayoutData(gd);
+
+ enableButton = new Button(usercomp, SWT.CHECK);
+ enableButton.setText(Messages.ContainerPropertyTab_Enable_Msg);
+
+ iCfg = getCfg();
+ properties = iCfg.getOptionalBuildProperties();
+
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 5;
+ enableButton.setLayoutData(gd);
+
+ Label connectionSelectorLabel = new Label(usercomp, SWT.NULL);
+ connectionSelectorLabel
+ .setText(Messages.ContainerTab_Connection_Selector_Label);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 1;
+ gd.grabExcessHorizontalSpace = false;
+ connectionSelectorLabel.setLayoutData(gd);
+
+ connectionSelector = new Combo(usercomp, SWT.BORDER | SWT.READ_ONLY);
+ initializeConnectionSelector(iCfg);
+ 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;
+ }
+ });
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 4;
+ gd.grabExcessHorizontalSpace = true;
+ connectionSelector.setLayoutData(gd);
+
+ Label imageSelectorLabel = new Label(usercomp, SWT.NULL);
+ imageSelectorLabel.setText(Messages.ContainerTab_Image_Selector_Label);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 1;
+ connectionSelectorLabel.setLayoutData(gd);
+
+ imageCombo = new Combo(usercomp, SWT.DROP_DOWN);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 4;
+ gd.grabExcessHorizontalSpace = true;
+ imageCombo.setLayoutData(gd);
+
+ initializeImageCombo(iCfg);
+
+ imageCombo.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ properties.setProperty(ContainerCommandLauncher.IMAGE_ID,
+ imageCombo.getText());
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ });
+
+ initializeEnablementButton(iCfg);
+ enableButton.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ setControlsEnabled(enableButton.getSelection());
+ properties.setProperty(
+ ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
+ Boolean.toString(enableButton.getSelection()));
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // ignore
+ }
+
+ });
+
+ }
+
+ private void setControlsEnabled(boolean enabled) {
+ imageCombo.setEnabled(enabled);
+ connectionSelector.setEnabled(enabled);
+ }
+
+ private void initializeEnablementButton(IConfiguration cfg) {
+ defaultEnabled = false;
+ IOptionalBuildProperties properties = cfg.getOptionalBuildProperties();
+ String savedEnabled = properties
+ .getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
+ if (savedEnabled != null) {
+ defaultEnabled = Boolean
+ .parseBoolean(savedEnabled);
+ }
+ enableButton.setSelection(defaultEnabled);
+ setControlsEnabled(defaultEnabled);
+ }
+
+ private void initializeConnectionSelector(IConfiguration cfg) {
+ int defaultIndex = -1;
+ defaultConnection = null;
+ String id = properties
+ .getProperty(ContainerCommandLauncher.CONNECTION_ID);
+ if (id != null) {
+ defaultConnection = id;
+ }
+ connections = DockerConnectionManager.getInstance().getConnections();
+ if (connections.length == 0) {
+ // setErrorMessage(Messages.ContainerTab_Error_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(defaultConnection))
+ defaultIndex = i;
+ }
+ if (defaultIndex < 0) {
+ defaultEnabled = false;
+ defaultIndex = 0;
+ }
+ connectionSelector.setItems(connectionNames);
+ if (connections.length > 0) {
+ connectionSelector.select(defaultIndex);
+ connection = connections[defaultIndex];
+ connectionName = connection.getName();
+ connectionUri = connection.getUri();
+ defaultConnection = connectionUri;
+ }
+ }
+
+ private void initializeImageCombo(IConfiguration cfg) {
+ defaultImage = null;
+ String id = properties
+ .getProperty(ContainerCommandLauncher.IMAGE_ID);
+ if (id != null) {
+ defaultImage = id;
+ }
+ if (connection != null) {
+ java.util.List<IDockerImage> images = connection.getImages();
+ if (images == null || images.size() == 0) {
+ // setsetErrorMessage(Messages.ContainerTab_Error_No_Images);
+ return;
+ }
+ connection.removeImageListener(containerTab);
+ 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 (defaultImage != null) {
+ int index = imageCombo.indexOf(defaultImage);
+ if (index > -1) {
+ imageCombo.getItem(index);
+ imageCombo.select(index);
+ } else {
+ }
+ }
+ connection.addImageListener(containerTab);
+ }
+ }
+
+ @Override
+ protected void performApply(ICResourceDescription src,
+ ICResourceDescription dst) {
+ if (page.isMultiCfg()) {
+ ICMultiConfigDescription mc1 = (ICMultiConfigDescription) src
+ .getConfiguration();
+ ICMultiConfigDescription mc2 = (ICMultiConfigDescription) dst
+ .getConfiguration();
+ ICConfigurationDescription[] cds1 = (ICConfigurationDescription[]) mc1
+ .getItems();
+ ICConfigurationDescription[] cds2 = (ICConfigurationDescription[]) mc2
+ .getItems();
+ for (int i = 0; i < cds1.length; i++)
+ applyToCfg(cds1[i], cds2[i]);
+ } else
+ applyToCfg(src.getConfiguration(), dst.getConfiguration());
+
+ }
+
+ private void applyToCfg(ICConfigurationDescription c1,
+ ICConfigurationDescription c2) {
+ Configuration cfg01 = (Configuration) getCfg(c1);
+ Configuration cfg02 = (Configuration) getCfg(c2);
+ IOptionalBuildProperties prop1 = cfg01.getOptionalBuildProperties();
+ IOptionalBuildProperties prop2 = cfg02.getOptionalBuildProperties();
+ String enablementProperty = prop1
+ .getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
+ prop2.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
+ enablementProperty);
+ String connectionProperty = prop1
+ .getProperty(ContainerCommandLauncher.CONNECTION_ID);
+ prop2.setProperty(ContainerCommandLauncher.CONNECTION_ID,
+ connectionProperty);
+ String imageProperty = prop1
+ .getProperty(ContainerCommandLauncher.IMAGE_ID);
+ prop2.setProperty(ContainerCommandLauncher.IMAGE_ID, imageProperty);
+ }
+
+
+ @Override
+ protected void performDefaults() {
+ if (iCfg instanceof IMultiConfiguration) {
+ IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg)
+ .getItems();
+ for (int i = 0; i < cfs.length; i++) {
+ IOptionalBuildProperties props = cfs[i]
+ .getOptionalBuildProperties();
+ props.setProperty(
+ ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
+ Boolean.toString(false));
+ if (connections.length > 0) {
+ props.setProperty(ContainerCommandLauncher.CONNECTION_ID,
+ connections[0].getUri());
+ } else {
+ props.setProperty(ContainerCommandLauncher.CONNECTION_ID,
+ null);
+ }
+ props.setProperty(ContainerCommandLauncher.IMAGE_ID, null);
+ }
+ } else {
+ IOptionalBuildProperties props = iCfg.getOptionalBuildProperties();
+ props.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
+ Boolean.toString(false));
+ if (connections.length > 0) {
+ props.setProperty(ContainerCommandLauncher.CONNECTION_ID,
+ connections[0].getUri());
+ } else {
+ props.setProperty(ContainerCommandLauncher.CONNECTION_ID, null);
+ }
+ props.setProperty(ContainerCommandLauncher.IMAGE_ID, null);
+ }
+ defaultEnabled = false;
+ if (connections.length > 0) {
+ connectionSelector.select(0);
+ }
+ imageCombo.setText(""); //$NON-NLS-1$
+ enableButton.setSelection(false);
+ setControlsEnabled(false);
+ }
+
+ @Override
+ public void updateData(ICResourceDescription cfgd) {
+ if (cfgd == null)
+ return;
+ iCfg = getCfg(cfgd.getConfiguration());
+ initializeConnectionSelector(iCfg);
+ initializeImageCombo(iCfg);
+ initializeEnablementButton(iCfg);
+ }
+
+ @Override
+ protected void updateButtons() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void changeEvent(int type) {
+ String currUri = null;
+ int currIndex = 0;
+ 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();
+ } else {
+ connection = null;
+ connectionUri = "";
+ connectionSelector.setText("");
+ }
+ connectionSelector.addModifyListener(connectionModifyListener);
+ }
+
+ @Override
+ public void listChanged(IDockerConnection c,
+ java.util.List<IDockerImage> list) {
+ final IDockerImage[] finalList = list.toArray(new IDockerImage[0]);
+ if (c.getName().equals(connection.getName())) {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ connection.removeImageListener(containerTab);
+ 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(containerTab);
+ }
+
+ });
+ }
+ }
+
+}
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 ed716c3361..5ad81d2dcd 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
@@ -19,13 +19,18 @@ import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
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.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.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
@@ -253,6 +258,31 @@ public class LaunchShortcut implements ILaunchShortcut {
ILaunchConfiguration configuration = null;
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);
+ }
+ }
+ }
+ }
try {
ILaunchConfiguration[] configs = DebugPlugin.getDefault()
.getLaunchManager().getLaunchConfigurations(configType);
@@ -265,7 +295,17 @@ public class LaunchShortcut implements ILaunchShortcut {
if (projectName != null
&& projectName.equals(bin.getCProject()
.getProject().getName())) {
- candidateConfigs.add(config);
+ // if we have an active configuration with container
+ // build properties, make sure they match, otherwise
+ // add the launch config as a candidate
+ if (connectionUri.equals(config.getAttribute(
+ ILaunchConstants.ATTR_CONNECTION_URI,
+ connectionUri))) {
+ if (imageName.equals(config.getAttribute(
+ ILaunchConstants.ATTR_IMAGE, imageName))) {
+ candidateConfigs.add(config);
+ }
+ }
}
}
}
@@ -312,11 +352,40 @@ public class LaunchShortcut implements ILaunchShortcut {
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;
+
+ 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);
+ }
+ }
+
ILaunchConfigurationType configType = getLaunchConfigType();
ILaunchConfigurationWorkingCopy wc = configType.newInstance(
null,
getLaunchManager().generateLaunchConfigurationName(
- bin.getElementName()));
+ bin.getResource().getName() + (imageName != null
+ ? ("[" + imageName + "]") //$NON-NLS-1$ //$NON-NLS-2$
+ : ""))); //$NON-NLS-1$
// DSF settings...use GdbUIPlugin preference store for defaults
IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
@@ -357,19 +426,25 @@ public class LaunchShortcut implements ILaunchShortcut {
Preferences prefs = InstanceScope.INSTANCE
.getNode(DockerLaunchUIPlugin.PLUGIN_ID);
- // get the connection from the ConnectionListener which waits for
- // any activity
- // from the DockerExplorerView
- IDockerConnection connection = ConnectionListener.getInstance()
+ // get the connection using following order:
+ // 1. connection used in build of project
+ // 2. current connection
+ // 3. first connection
+ IDockerConnection connection = null;
+ if (connectionId != null) {
+ connection = DockerConnectionManager.getInstance()
+ .getConnectionByUri(connectionId);
+ }
+ if (connection == null) {
+ connection = ConnectionListener.getInstance()
.getCurrentConnection();
+ }
if (connection == null) {
IDockerConnection[] connections = DockerConnectionManager
.getInstance().getConnections();
if (connections != null && connections.length > 0)
- connection = DockerConnectionManager.getInstance()
- .getConnections()[0];
+ connection = connections[0];
}
-
// issue error message if no connections exist
if (connection == null) {
Display.getDefault().syncExec(new Runnable() {
@@ -389,9 +464,14 @@ public class LaunchShortcut implements ILaunchShortcut {
wc.setAttribute(ILaunchConstants.ATTR_CONNECTION_URI,
connection.getUri());
- // get any default image if specified, otherwise use first
+ // use build image if one is specified, otherwise, see if a default
+ // image is set in preferences, otherwise find first image in image
+ // list
// image in image list for connection
- String image = prefs.get(PreferenceConstants.DEFAULT_IMAGE, null);
+ String image = imageName;
+ if (image == null) {
+ image = prefs.get(PreferenceConstants.DEFAULT_IMAGE, null);
+ }
if (image == null) {
List<IDockerImage> images = connection.getImages();
if (images != null && images.size() > 0)
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 f3d6003d8a..447f745a9a 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
@@ -90,6 +90,12 @@ public class Messages extends NLS {
public static String StandardGDBDebuggerPage14;
+ public static String ContainerPropertyTab_Title;
+ public static String ContainerPropertyTab_Enable_Msg;
+
+ public static String ContainerCommandLauncher_image_msg;
+ public static String CommandLauncher_CommandCancelled;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
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 15e1b19a0c..7f06d56a2f 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
@@ -40,6 +40,13 @@ ContainerTab_Error_No_Images=No Docker Images exist
ContainerTab_Warning_Connection_Not_Found=Docker Connection: {0} for Launch Configuration not found: defaulting to {1}
ContainerTab_Warning_Image_Not_Found=Docker Image: {0} is not a valid pulled image in current Connection: {1}
+ContainerPropertyTab_Title=Container Settings
+ContainerPropertyTab_Enable_Msg=Build inside Docker Image
+
+ContainerCommandLauncher_image_msg=[Running in image <{0}>]
+
+CommandLauncher_CommandCancelled=Command cancelled
+
Remote_GDB_Debugger_Options=Docker Container GDB Debugger Options
Gdbserver_Settings_Tab_Name=Gdbserver Settings
Gdbserver_name_textfield_label=Gdbserver path:
diff --git a/remote/org.eclipse.cdt.remote.core/src/org/eclipse/cdt/remote/core/RemoteCommandLauncher.java b/remote/org.eclipse.cdt.remote.core/src/org/eclipse/cdt/remote/core/RemoteCommandLauncher.java
index 8554685440..cfe9c89057 100644
--- a/remote/org.eclipse.cdt.remote.core/src/org/eclipse/cdt/remote/core/RemoteCommandLauncher.java
+++ b/remote/org.eclipse.cdt.remote.core/src/org/eclipse/cdt/remote/core/RemoteCommandLauncher.java
@@ -17,7 +17,7 @@ import java.net.URI;
import java.util.Map;
import java.util.Properties;
-import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.remote.internal.core.Activator;
import org.eclipse.cdt.remote.internal.core.messages.Messages;
@@ -40,6 +40,8 @@ import org.eclipse.remote.core.RemoteProcessAdapter;
public class RemoteCommandLauncher implements ICommandLauncher {
private static final String CYGWIN_PREFIX = "cygdrive"; //$NON-NLS-1$
+
+ private boolean usingLocalLauncher = false;
/**
* Convert a local (workspace) path into the remote equivalent. If the local path is not
@@ -102,7 +104,7 @@ public class RemoteCommandLauncher implements ICommandLauncher {
return s;
}
- private final ICommandLauncher fLocalLauncher = new CommandLauncher();
+ private ICommandLauncher fLocalLauncher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
private boolean fShowCommand;
private String[] fCommandArgs;
private IRemoteConnection fConnection;
@@ -129,13 +131,18 @@ public class RemoteCommandLauncher implements ICommandLauncher {
@Override
public Process execute(IPath commandPath, String[] args, String[] env, IPath workingDirectory, IProgressMonitor monitor)
throws CoreException {
+ ICommandLauncher localLauncher = CommandLauncherFactoryManager.getInstance().getCommandLauncher(getProject());
+ localLauncher.setProject(getProject());
+ localLauncher.setErrorMessage(getErrorMessage());
+ usingLocalLauncher = false;
+ fLocalLauncher = localLauncher;
if (getProject() != null) {
IRemoteResource remRes = (IRemoteResource) getProject().getAdapter(IRemoteResource.class);
if (remRes != null) {
URI uri = remRes.getActiveLocationURI();
IRemoteServicesManager remoteServicesManager = Activator.getService(IRemoteServicesManager.class);
IRemoteConnectionType connectionType = remoteServicesManager.getConnectionType(uri);
- if (connectionType != null) {
+ if (connectionType != null && !connectionType.getScheme().equals("file")) { //$NON-NLS-1$
fConnection = connectionType.getConnection(uri);
if (fConnection != null) {
parseEnvironment(env);
@@ -163,16 +170,23 @@ public class RemoteCommandLauncher implements ICommandLauncher {
}
}
}
+ usingLocalLauncher = true;
return fLocalLauncher.execute(commandPath, args, env, workingDirectory, monitor);
}
@Override
public String[] getCommandArgs() {
+ if (usingLocalLauncher) {
+ return fLocalLauncher.getCommandArgs();
+ }
return fCommandArgs;
}
@Override
public String getCommandLine() {
+ if (usingLocalLauncher) {
+ return fLocalLauncher.getCommandLine();
+ }
return getCommandLine(fCommandArgs);
}
@@ -202,6 +216,9 @@ public class RemoteCommandLauncher implements ICommandLauncher {
@Override
public Properties getEnvironment() {
+ if (usingLocalLauncher) {
+ return fLocalLauncher.getEnvironment();
+ }
return fEnvironment;
}
@@ -261,8 +278,15 @@ public class RemoteCommandLauncher implements ICommandLauncher {
fShowCommand = show;
}
+ @SuppressWarnings("deprecation")
@Override
public int waitAndRead(OutputStream out, OutputStream err) {
+
+ if (usingLocalLauncher) {
+ return fLocalLauncher.waitAndRead(out, err);
+ }
+
+ // otherwise remote process
if (fShowCommand) {
printCommandLine(out);
}
@@ -278,6 +302,11 @@ public class RemoteCommandLauncher implements ICommandLauncher {
@Override
public int waitAndRead(OutputStream out, OutputStream err, IProgressMonitor monitor) {
+ if (usingLocalLauncher) {
+ return fLocalLauncher.waitAndRead(out, err, monitor);
+ }
+
+ // otherwise remote process
if (fShowCommand) {
printCommandLine(out);
}

Back to the top