From 2e99babe5bfda9c9e2d5bb4f53bab74ec1bcad6d Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Wed, 4 Apr 2018 12:50:19 -0400 Subject: [PATCH] Bug 533222 - Add Container Build support to Std Make Core Build - add new getConsoleHeader() method to ICBuildCommandLauncher interface and ContainerCommandLauncher class - modify MakefileBuildConfigurationProvider to create build configurations based on an Image name when building for Container and as well support the linux-container os that is used for Container targets - add new IConsoleParser2 interface that extends IConsoleParser and adds new processLine method that takes a List of Job as a parameter - make CBuildConfiguration implement IConsoleParser2 and add new processLine method - modify watchProcess to recognize an IConsoleParser2 and pass a Job List then wait for all jobs to finish before calling shutdown() and possibly reindex - add new IToolChain2 interface with startBuildProcess() method - add new startBuildProcess() method to CBuildConfiguration to look for new IToolChain2 and use its startBuildProcess() method to perform the build - make ContainerGCCToolChain implement IToolChain2 and add new startBuildProcess() method to build in Container - change StandardBuildConfiguration to use startBuildProcess() to do build and clean Change-Id: Icae9a55ef6abfa1b7f611544ad591b6062c72585 --- .../MakefileBuildConfigurationProvider.java | 20 +++-- .../.settings/.api_filters | 20 ----- .../org/eclipse/cdt/core/IConsoleParser2.java | 31 +++++++ .../cdt/core/build/CBuildConfiguration.java | 63 +++++++++++++-- .../core/build/ICBuildCommandLauncher.java | 5 ++ .../eclipse/cdt/core/build/IToolChain2.java | 31 +++++++ .../build/StandardBuildConfiguration.java | 80 +++++++++++-------- .../cdt/internal/core/build/Messages.java | 4 +- .../internal/core/build/messages.properties | 4 +- .../launcher/ContainerCommandLauncher.java | 33 ++++++++ .../ui/launchbar/ContainerGCCToolChain.java | 50 +++++++++++- 11 files changed, 272 insertions(+), 69 deletions(-) create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IConsoleParser2.java create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain2.java diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java index 1406011df48..5d6f82d2927 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java @@ -43,14 +43,20 @@ public class MakefileBuildConfigurationProvider implements ICBuildConfigurationP StringBuilder configName = new StringBuilder("make."); //$NON-NLS-1$ configName.append(launchMode); String os = toolChain.getProperty(IToolChain.ATTR_OS); - if (os != null) { + if ("linux-container".equals(os)) { //$NON-NLS-1$ + String osConfigName = toolChain.getProperty("linux-container-id"); //$NON-NLS-1$ configName.append('.'); - configName.append(os); - } - String arch = toolChain.getProperty(IToolChain.ATTR_ARCH); - if (arch != null && !arch.isEmpty()) { - configName.append('.'); - configName.append(arch); + configName.append(osConfigName); + } else { + if (os != null) { + configName.append('.'); + configName.append(os); + } + String arch = toolChain.getProperty(IToolChain.ATTR_ARCH); + if (arch != null && !arch.isEmpty()) { + configName.append('.'); + configName.append(arch); + } } String name = configName.toString(); int i = 0; diff --git a/core/org.eclipse.cdt.core/.settings/.api_filters b/core/org.eclipse.cdt.core/.settings/.api_filters index 5380e1fd78c..23a1d1aab40 100644 --- a/core/org.eclipse.cdt.core/.settings/.api_filters +++ b/core/org.eclipse.cdt.core/.settings/.api_filters @@ -68,24 +68,4 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IConsoleParser2.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IConsoleParser2.java new file mode 100644 index 00000000000..894369d56cb --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IConsoleParser2.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - Initial Contribution + *******************************************************************************/ +package org.eclipse.cdt.core; + +import java.util.List; + +import org.eclipse.core.runtime.jobs.Job; + +/** + * @since 6.5 + * + */ +public interface IConsoleParser2 extends IConsoleParser { + + /** + * Process a line of output in a job + * @param s - String to process + * @param jobList - list of jobs to add to + * @return true if line processed, false otherwise + */ + boolean processLine (String s, List jobList); + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java index 56798e31210..309421877b4 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java @@ -34,6 +34,7 @@ import java.util.regex.Pattern; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IConsoleParser; +import org.eclipse.cdt.core.IConsoleParser2; import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.ProblemMarkerInfo; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; @@ -102,7 +103,7 @@ import com.google.gson.JsonParseException; */ public abstract class CBuildConfiguration extends PlatformObject implements ICBuildConfiguration, ICBuildConfiguration2, IMarkerGenerator, - IConsoleParser, IElementChangedListener { + IConsoleParser2, IElementChangedListener { private static final String LAUNCH_MODE = "cdt.launchMode"; //$NON-NLS-1$ @@ -473,6 +474,32 @@ public abstract class CBuildConfiguration extends PlatformObject } return null; } + + /** + * @since 6.5 + */ + public Process startBuildProcess(List commands, IEnvironmentVariable[] envVars, IConsole console, IProgressMonitor monitor) throws IOException, CoreException { + Process process = null; + IToolChain tc = getToolChain(); + if (tc instanceof IToolChain2) { + process = ((IToolChain2)tc).startBuildProcess(this, commands, getBuildDirectory().toString(), envVars, console, monitor); + } else { + // verify command can be found locally on path + Path commandPath = findCommand(commands.get(0)); + if (commandPath == null) { + console.getErrorStream() + .write(String.format(Messages.CBuildConfiguration_CommandNotFound, commands.get(0))); + return null; + } + commands.set(0, commandPath.toString()); + + ProcessBuilder processBuilder = new ProcessBuilder(commands) + .directory(getBuildDirectory().toFile()); + setBuildEnvironment(processBuilder.environment()); + process = processBuilder.start(); + } + return process; + } @Deprecated protected int watchProcess(Process process, IConsoleParser[] consoleParsers, IConsole console) @@ -503,8 +530,8 @@ public abstract class CBuildConfiguration extends PlatformObject */ protected int watchProcess(Process process, IConsoleParser[] consoleParsers) throws CoreException { - new ReaderThread(process.getInputStream(), consoleParsers).start(); - new ReaderThread(process.getErrorStream(), consoleParsers).start(); + new ReaderThread(this, process.getInputStream(), consoleParsers).start(); + new ReaderThread(this, process.getErrorStream(), consoleParsers).start(); try { return process.waitFor(); } catch (InterruptedException e) { @@ -514,11 +541,13 @@ public abstract class CBuildConfiguration extends PlatformObject } private static class ReaderThread extends Thread { + CBuildConfiguration config; private final BufferedReader in; private final IConsoleParser[] consoleParsers; private final PrintStream out; - public ReaderThread(InputStream in, IConsoleParser[] consoleParsers) { + public ReaderThread(CBuildConfiguration config, InputStream in, IConsoleParser[] consoleParsers) { + this.config = config; this.in = new BufferedReader(new InputStreamReader(in)); this.out = null; this.consoleParsers = consoleParsers; @@ -528,17 +557,25 @@ public abstract class CBuildConfiguration extends PlatformObject this.in = new BufferedReader(new InputStreamReader(in)); this.out = new PrintStream(out); this.consoleParsers = null; + this.config = null; } @Override public void run() { + List jobList = new ArrayList<>(); try { for (String line = in.readLine(); line != null; line = in.readLine()) { if (consoleParsers != null) { for (IConsoleParser consoleParser : consoleParsers) { // Synchronize to avoid interleaving of lines synchronized (consoleParser) { - consoleParser.processLine(line); + // if we have an IConsoleParser2, use the processLine method that + // takes a job list (Container Build support) + if (consoleParser instanceof IConsoleParser2) { + ((IConsoleParser2)consoleParser).processLine(line, jobList); + } else { + consoleParser.processLine(line); + } } } } @@ -546,6 +583,16 @@ public abstract class CBuildConfiguration extends PlatformObject out.println(line); } } + for (Job j : jobList) { + try { + j.join(); + } catch (InterruptedException e) { + // ignore + } + } + if (config != null) { + config.shutdown(); + } } catch (IOException e) { CCorePlugin.log(e); } @@ -939,7 +986,8 @@ public abstract class CBuildConfiguration extends PlatformObject * * @since 6.5 */ - protected boolean processLine(String line, List jobsArray) { + @Override + public boolean processLine(String line, List jobsArray) { // Split line into args, taking into account quotes List command = stripArgs(line); @@ -1036,7 +1084,8 @@ public abstract class CBuildConfiguration extends PlatformObject * @throws CoreException */ protected void refreshScannerInfo() throws CoreException { - // do nothing by default + CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(getProject())); + infoChanged = false; } @Override diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildCommandLauncher.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildCommandLauncher.java index 2abaa206631..78f7d975845 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildCommandLauncher.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildCommandLauncher.java @@ -28,5 +28,10 @@ public interface ICBuildCommandLauncher { * @param config - CBuildConfiguration to register */ public void setBuildConfiguration(ICBuildConfiguration config); + + /** + * Get any special console header (e.g. Container Image used) + */ + public String getConsoleHeader(); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain2.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain2.java new file mode 100644 index 00000000000..3ee96fe69eb --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain2.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat Inc. - initial version + *******************************************************************************/ +package org.eclipse.cdt.core.build; + +import java.io.IOException; +import java.util.List; + +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * @since 6.5 + * @author jjohnstn + * + */ +public interface IToolChain2 { + + public Process startBuildProcess(ICBuildConfiguration config, List command, String buildDirectory, IEnvironmentVariable[] envVars, + IConsole console, IProgressMonitor monitor) throws CoreException, IOException; + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java index e8716ada7da..6fff0677116 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java @@ -229,26 +229,22 @@ public class StandardBuildConfiguration extends CBuildConfiguration { project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); ConsoleOutputStream outStream = console.getOutputStream(); - + Path buildDir = getBuildDirectory(); - + outStream.write(String.format(Messages.StandardBuildConfiguration_0, buildDir.toString())); - Path make = findCommand(buildCommand[0]); - if (make == null) { - console.getErrorStream() - .write(String.format(Messages.StandardBuildConfiguration_CommandNotFound, buildCommand[0])); - return null; - } - List command = new ArrayList<>(); - command.add(make.toString()); + command.add(buildCommand[0]); + + if (!getBuildContainer().equals(getProject())) { Path makefile = Paths.get(getProject().getFile("Makefile").getLocationURI()); //$NON-NLS-1$ Path relative = getBuildDirectory().relativize(makefile); command.add("-f"); //$NON-NLS-1$ command.add(relative.toString()); } + for (int i = 1; i < buildCommand.length; i++) { command.add(buildCommand[i]); } @@ -258,19 +254,23 @@ public class StandardBuildConfiguration extends CBuildConfiguration { epm.setOutputStream(console.getOutputStream()); // run make console.getOutputStream().write(String.format("%s\n", String.join(" ", command))); //$NON-NLS-1$ //$NON-NLS-2$ - ProcessBuilder processBuilder = new ProcessBuilder(command) - .directory(getBuildDirectory().toFile()); - setBuildEnvironment(processBuilder.environment()); - Process process = processBuilder.start(); + + Process p = startBuildProcess(command, envVars, console, monitor); + + if (p == null) { + console.getErrorStream().write(String.format(Messages.StandardBuildConfiguration_Failure, "")); //$NON-NLS-1$ + return null; + } + IConsoleParser[] consoleParsers = new IConsoleParser[] { epm, this }; - watchProcess(process, consoleParsers); + watchProcess(p, consoleParsers); + project.refreshLocal(IResource.DEPTH_INFINITE, monitor); outStream.write(String.format(Messages.StandardBuildConfiguration_1, epm.getErrorCount(), epm.getWarningCount(), buildDir.toString())); } - return new IProject[] { project }; } catch (IOException e) { throw new CoreException( @@ -285,29 +285,45 @@ public class StandardBuildConfiguration extends CBuildConfiguration { project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); ConsoleOutputStream outStream = console.getOutputStream(); + + Path buildDir = getBuildDirectory(); + + outStream.write(String.format(Messages.StandardBuildConfiguration_0, buildDir.toString())); - List command; + List command = new ArrayList<>(); + List buildCommand; if (cleanCommand != null) { - command = Arrays.asList(cleanCommand); + buildCommand = Arrays.asList(cleanCommand); } else { - command = new ArrayList<>(); - command.add(findCommand("make").toString()); //$NON-NLS-1$ - if (!getBuildContainer().equals(getProject())) { - Path makefile = Paths.get(getProject().getFile("Makefile").getLocationURI()); //$NON-NLS-1$ - Path relative = getBuildDirectory().relativize(makefile); - command.add("-f"); //$NON-NLS-1$ - command.add(relative.toString()); - } - command.add("clean"); //$NON-NLS-1$ + buildCommand = Arrays.asList(DEFAULT_CLEAN_COMMAND); + } + + command.add(buildCommand.get(0)); + + // we need to add -f if the makefile isn't in the build directory + if (!getBuildContainer().equals(getProject())) { + Path makefile = Paths.get(getProject().getFile("Makefile").getLocationURI()); //$NON-NLS-1$ + Path relative = getBuildDirectory().relativize(makefile); + command.add("-f"); //$NON-NLS-1$ + command.add(relative.toString()); + } + + for (int i = 1; i < buildCommand.size(); ++i) { + command.add(buildCommand.get(i)); } // run make outStream.write(String.format("%s\n", String.join(" ", command))); //$NON-NLS-1$ //$NON-NLS-2$ - ProcessBuilder processBuilder = new ProcessBuilder(command) - .directory(getBuildDirectory().toFile()); - setBuildEnvironment(processBuilder.environment()); - Process process = processBuilder.start(); - watchProcess(process, console); + + Process p = startBuildProcess(command, envVars, console, monitor); + if (p == null) { + console.getErrorStream().write(String.format(Messages.StandardBuildConfiguration_Failure, "")); //$NON-NLS-1$ + return; + } + + watchProcess(p, console); + + outStream.write(Messages.CBuildConfiguration_BuildComplete); project.refreshLocal(IResource.DEPTH_INFINITE, monitor); } catch (IOException e) { diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/Messages.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/Messages.java index ba5626fc452..7af98d98f33 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/Messages.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/Messages.java @@ -19,9 +19,11 @@ public class Messages extends NLS { public static String CBuilder_ExceptionWhileBuilding2; public static String CBuilder_NotConfiguredCorrectly; public static String CBuilder_NotConfiguredCorrectly2; + public static String CBuildConfiguration_CommandNotFound; + public static String CBuildConfiguration_BuildComplete; public static String StandardBuildConfiguration_0; public static String StandardBuildConfiguration_1; - public static String StandardBuildConfiguration_CommandNotFound; + public static String StandardBuildConfiguration_Failure; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/messages.properties b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/messages.properties index 9a5d1a8926f..461748ec808 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/messages.properties +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/messages.properties @@ -11,7 +11,9 @@ CBuilder_NotConfiguredCorrectly=Build not configured correctly\n CBuilder_NotConfiguredCorrectly2=Build not configured correctly\n StandardBuildConfiguration_0=Building in: %s\n StandardBuildConfiguration_1=Build complete (%d errors, %d warnings): %s\n -StandardBuildConfiguration_CommandNotFound=Error: build command '%s' not found +StandardBuildConfiguration_Failure=Error: %s +CBuildConfiguration_BuildComplete=Build complete\n +CBuildConfiguration_CommandNotFound=Error: build command '%s' not found CBuildConfiguration_CreateJob=Create Build Folder CBuildConfiguration_Location=line %d, external location: %s CBuildConfiguration_ToolchainMissing=Toolchain is missing for build configuration diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java index 53613f74c7d..3a9d9d1f1f2 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerCommandLauncher.java @@ -322,6 +322,33 @@ public class ContainerCommandLauncher return fProcess; } + private String calculateImageName() { + ICBuildConfiguration buildCfg = getBuildConfiguration(); + String imageName = ""; //$NON-NLS-1$ + + if (buildCfg != null) { + IToolChain toolChain; + try { + toolChain = buildCfg.getToolChain(); + } catch (CoreException e) { + return imageName; + } + imageName = toolChain + .getProperty(IContainerLaunchTarget.ATTR_IMAGE_ID); + } else { + ICConfigurationDescription cfgd = CoreModel.getDefault() + .getProjectDescription(fProject).getActiveConfiguration(); + IConfiguration cfg = ManagedBuildManager + .getConfigurationForDescription(cfgd); + if (cfg == null) { + return imageName; + } + IOptionalBuildProperties props = cfg.getOptionalBuildProperties(); + imageName = props.getProperty(ContainerCommandLauncher.IMAGE_ID); + } + return imageName; + } + /** * Parse array of "ENV=value" pairs to Properties. */ @@ -427,6 +454,12 @@ public class ContainerCommandLauncher } } + @Override + public String getConsoleHeader() { + return NLS.bind(Messages.ContainerCommandLauncher_image_msg, + calculateImageName()) + NEWLINE; + } + protected void printCommandLine(OutputStream os) { if (os != null) { try { diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java index c773a3204c0..9d6524e43e1 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChain.java @@ -29,8 +29,10 @@ import java.util.regex.Pattern; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CommandLauncherManager; import org.eclipse.cdt.core.ICommandLauncher; +import org.eclipse.cdt.core.build.ICBuildCommandLauncher; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.build.IToolChain2; import org.eclipse.cdt.core.build.IToolChainProvider; import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; @@ -38,6 +40,7 @@ import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.parser.ExtendedScannerInfo; import org.eclipse.cdt.core.parser.IExtendedScannerInfo; +import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.docker.launcher.ContainerCommandLauncher; import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider; import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin; @@ -48,6 +51,7 @@ import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PlatformObject; @@ -59,7 +63,8 @@ import org.eclipse.linuxtools.docker.ui.Activator; * * @since 1.2 */ -public class ContainerGCCToolChain extends PlatformObject implements IToolChain { +public class ContainerGCCToolChain extends PlatformObject + implements IToolChain, IToolChain2 { public static final String TYPE_ID = "org.eclipse.cdt.docker.launcher.gcc"; //$NON-NLS-1$ @@ -601,4 +606,47 @@ public class ContainerGCCToolChain extends PlatformObject implements IToolChain return result; } + @Override + public Process startBuildProcess(ICBuildConfiguration config, + List command, String buildDirectory, + IEnvironmentVariable[] envVars, IConsole console, + IProgressMonitor monitor) throws CoreException, IOException { + + IPath cmdPath = new org.eclipse.core.runtime.Path("/usr/bin/env"); //$NON-NLS-1$ + + List argList = new ArrayList<>(); + for (IEnvironmentVariable var : envVars) { + argList.add(var.getName() + "=" + var.getValue()); //$NON-NLS-1$ + } + + argList.add("sh"); //$NON-NLS-1$ + argList.add("-c"); //$NON-NLS-1$ + + StringBuffer buf = new StringBuffer(); + for (String s : command) { + buf.append(s); + buf.append(" "); //$NON-NLS-1$ + } + buf.deleteCharAt(buf.length() - 1); // remove last blank; + argList.add(buf.toString()); + + ICommandLauncher launcher = CommandLauncherManager.getInstance() + .getCommandLauncher(config); + + launcher.setProject(config.getBuildConfiguration().getProject()); + if (launcher instanceof ICBuildCommandLauncher) { + ((ICBuildCommandLauncher) launcher).setBuildConfiguration(config); + console.getOutputStream().write( + ((ICBuildCommandLauncher) launcher).getConsoleHeader()); + } + + org.eclipse.core.runtime.Path workingDir = new org.eclipse.core.runtime.Path( + buildDirectory); + + Process p = launcher.execute(cmdPath, argList.toArray(new String[0]), + new String[0], workingDir, monitor); + + return p; + } + }