1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

RESOLVED - bug 268615: add a way to specify a command launcher for the managed builder

https://bugs.eclipse.org/bugs/show_bug.cgi?id=268615
This commit is contained in:
Chris Recoskie 2009-03-16 14:36:24 +00:00
parent 3e2fede4d5
commit 4d246d8477
12 changed files with 201 additions and 40 deletions

View file

@ -22,6 +22,7 @@ import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.core.resources.IConsole;
@ -153,7 +154,7 @@ public class MakeBuilder extends ACBuilder {
isClean = true;
String errMsg = null;
CommandLauncher launcher = new CommandLauncher();
ICommandLauncher launcher = new CommandLauncher();
// Print the command for visual interaction.
launcher.showCommand(true);
@ -218,7 +219,7 @@ public class MakeBuilder extends ACBuilder {
// Before launching give visual cues via the monitor
monitor.subTask(MakeMessages.getString("MakeBuilder.Invoking_Command") + launcher.getCommandLine()); //$NON-NLS-1$
if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0))
!= CommandLauncher.OK)
!= ICommandLauncher.OK)
errMsg = launcher.getErrorMessage();
monitor.subTask(MakeMessages.getString("MakeBuilder.Updating_project")); //$NON-NLS-1$
refreshProject(currProject);

View file

@ -19,6 +19,7 @@ import java.util.Properties;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.internal.core.ConsoleOutputSniffer;
@ -101,7 +102,7 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Reading_Specs")); //$NON-NLS-1$
String errMsg = null;
CommandLauncher launcher = new CommandLauncher();
ICommandLauncher launcher = new CommandLauncher();
// Print the command for visual interaction.
launcher.showCommand(true);
@ -125,7 +126,7 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
p.getOutputStream().close();
} catch (IOException e) {
}
if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) != CommandLauncher.OK) {
if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) != ICommandLauncher.OK) {
errMsg = launcher.getErrorMessage();
}
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Parsing_Output")); //$NON-NLS-1$
@ -213,7 +214,7 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
* @param launcher
* @return
*/
protected String[] setEnvironment(CommandLauncher launcher, Properties initialEnv) {
protected String[] setEnvironment(ICommandLauncher launcher, Properties initialEnv) {
// Set the environmennt, some scripts may need the CWD var to be set.
Properties props = initialEnv != null ? initialEnv : launcher.getEnvironment();

View file

@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.cdt.managedbuilder.core">
<schema targetNamespace="org.eclipse.cdt.managedbuilder.core" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appInfo>
<meta.schema plugin="org.eclipse.cdt.managedbuilder.core" id="buildDefinitions" name="Managed Build Definitions"/>
@ -11,6 +11,11 @@
</annotation>
<element name="extension">
<annotation>
<appInfo>
<meta.element />
</appInfo>
</annotation>
<complexType>
<sequence>
<element ref="projectType" minOccurs="0" maxOccurs="unbounded"/>
@ -1712,6 +1717,16 @@ If the builder supports specifying custom number of parallel jobs, the option de
</documentation>
</annotation>
</attribute>
<attribute name="commandLauncher" type="string">
<annotation>
<documentation>
A concrete Java class that implements org.eclipse.cdt.core.ICommandLauncher to launch the builder command.
</documentation>
<appInfo>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.ICommandLauncher"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>

View file

@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.core;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.settings.model.extension.CBuildData;
import org.eclipse.cdt.managedbuilder.macros.IFileContextBuildMacroValues;
import org.eclipse.cdt.managedbuilder.macros.IReservedMacroNameSupplier;
@ -88,6 +89,8 @@ public interface IBuilder extends IBuildObject, IMakeBuilderInfo {
static final String DEFAULT_TARGET_CLEAN = "clean"; //$NON-NLS-1$
static final String DEFAULT_TARGET_AUTO = "all"; //$NON-NLS-1$
static final String ATTRIBUTE_COMMAND_LAUNCHER = "commandLauncher"; //$NON-NLS-1$
/**
* Returns the command line arguments to pass to the build/make utility used
* to build a configuration.
@ -317,4 +320,12 @@ public interface IBuilder extends IBuildObject, IMakeBuilderInfo {
boolean isSystemObject();
String getUniqueRealName();
/**
* Returns the ICommandLauncher which should be used to launch the builder command.
*
* @return ICommandLauncher
* @since 5.1
*/
public ICommandLauncher getCommandLauncher();
}

View file

@ -19,6 +19,7 @@ import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
import org.eclipse.core.runtime.IProgressMonitor;
@ -154,7 +155,7 @@ public class CommandBuilder implements IBuildModelBuilder {
monitor.beginTask("", getNumCommands()); //$NON-NLS-1$
monitor.subTask(""/*getCommandLine()*/); //$NON-NLS-1$
CommandLauncher launcher = createLauncher();
ICommandLauncher launcher = createLauncher();
int status = STATUS_OK;
launcher.showCommand(true);
@ -173,11 +174,11 @@ public class CommandBuilder implements IBuildModelBuilder {
int st = launcher.waitAndRead(wrap(out), wrap(err),
new SubProgressMonitor(monitor, getNumCommands()));
switch(st){
case CommandLauncher.OK:
case ICommandLauncher.OK:
if(fProcess.exitValue() != 0)
status = STATUS_ERROR_BUILD;
break;
case CommandLauncher.COMMAND_CANCELED:
case ICommandLauncher.COMMAND_CANCELED:
status = STATUS_CANCELLED;
fErrMsg = launcher.getErrorMessage();
if(DbgUtil.DEBUG)
@ -185,7 +186,7 @@ public class CommandBuilder implements IBuildModelBuilder {
printMessage(fErrMsg, out);
break;
case CommandLauncher.ILLEGAL_COMMAND:
case ICommandLauncher.ILLEGAL_COMMAND:
default:
status = STATUS_ERROR_LAUNCH;
fErrMsg = launcher.getErrorMessage();
@ -200,7 +201,7 @@ public class CommandBuilder implements IBuildModelBuilder {
return status;
}
protected CommandLauncher createLauncher() {
protected ICommandLauncher createLauncher() {
// if(isWindows())
// return new CommandLauncher();
return new CommandSearchLauncher();

View file

@ -23,7 +23,9 @@ 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.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
import org.eclipse.cdt.core.settings.model.COutputEntry;
@ -131,6 +133,9 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider,
private List identicalList;
private ICOutputEntry[] outputEntries;
private ICommandLauncher fCommandLauncher = null;
private IConfigurationElement fCommandLauncherElement = null;
/*
* C O N S T R U C T O R S
@ -318,6 +323,9 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider,
} else {
setDirty(true);
}
fCommandLauncher = builder.fCommandLauncher;
fCommandLauncherElement = builder.fCommandLauncherElement;
}
public void copySettings(Builder builder, boolean allBuildSettings){
@ -563,6 +571,12 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider,
}
}
}
String commandLauncher = element.getAttribute(ATTRIBUTE_COMMAND_LAUNCHER);
if(commandLauncher != null && element instanceof DefaultManagedConfigElement){
fCommandLauncherElement = ((DefaultManagedConfigElement)element).getConfigurationElement();
}
}
/* (non-Javadoc)
@ -2712,4 +2726,25 @@ public class Builder extends BuildObject implements IBuilder, IMatchKeyProvider,
return getUniqueRealName();
}
public ICommandLauncher getCommandLauncher() {
if(fCommandLauncher != null)
return fCommandLauncher;
if(fCommandLauncher == null && fCommandLauncherElement != null){
try{
fCommandLauncher = (ICommandLauncher)fCommandLauncherElement.createExecutableExtension(ATTRIBUTE_COMMAND_LAUNCHER);
return fCommandLauncher;
}catch(CoreException e){
e.printStackTrace();
}
}
if(fCommandLauncher == null && superClass != null)
return superClass.getCommandLauncher();
else if(fCommandLauncher == null) // catch all for backwards compatibility
fCommandLauncher = new CommandLauncher();
return fCommandLauncher;
}
}

View file

@ -26,9 +26,9 @@ import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext;
import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set;
import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.core.ProblemMarkerInfo;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
@ -1934,7 +1934,7 @@ public class CommonBuilder extends ACBuilder {
isClean = true;
String errMsg = null;
CommandLauncher launcher = new CommandLauncher();
ICommandLauncher launcher = builder.getCommandLauncher();
// Print the command for visual interaction.
launcher.showCommand(true);
@ -1986,7 +1986,7 @@ public class CommonBuilder extends ACBuilder {
// Before launching give visual cues via the monitor
monitor.subTask(ManagedMakeMessages.getResourceString("MakeBuilder.Invoking_Command") + launcher.getCommandLine()); //$NON-NLS-1$
if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0))
!= CommandLauncher.OK)
!= ICommandLauncher.OK)
errMsg = launcher.getErrorMessage();
monitor.subTask(ManagedMakeMessages.getResourceString("MakeBuilder.Updating_project")); //$NON-NLS-1$

View file

@ -22,9 +22,9 @@ import java.util.Set;
import java.util.Vector;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.ACBuilder;
@ -34,6 +34,7 @@ import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildIOType;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildResource;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildStep;
import org.eclipse.cdt.managedbuilder.core.IBuilder;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
@ -945,7 +946,8 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Get a launcher for the make command
String errMsg = null;
CommandLauncher launcher = new CommandLauncher();
IBuilder builder = info.getDefaultConfiguration().getBuilder();
ICommandLauncher launcher = builder.getCommandLauncher();
launcher.showCommand(true);
// Set the environmennt
@ -1016,7 +1018,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(),
new SubProgressMonitor(monitor,
IProgressMonitor.UNKNOWN)) != CommandLauncher.OK) {
IProgressMonitor.UNKNOWN)) != ICommandLauncher.OK) {
errMsg = launcher.getErrorMessage();
}
} else {
@ -1087,10 +1089,10 @@ public class GeneratedMakefileBuilder extends ACBuilder {
int state = launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(),
new SubProgressMonitor(monitor,
IProgressMonitor.UNKNOWN));
if(state != CommandLauncher.OK){
if(state != ICommandLauncher.OK){
errMsg = launcher.getErrorMessage();
if(state == CommandLauncher.COMMAND_CANCELED){
if(state == ICommandLauncher.COMMAND_CANCELED){
//TODO: the better way of handling cancel is needed
//currently the rebuild state is set to true forcing the full rebuild
//on the next builder invocation

View file

@ -24,12 +24,13 @@ import org.eclipse.core.runtime.IProgressMonitor;
/**
* @noextend This class is not intended to be subclassed by clients.
*/
public class CommandLauncher {
public class CommandLauncher implements ICommandLauncher {
public final static int COMMAND_CANCELED = 1;
public final static int ILLEGAL_COMMAND = -1;
public final static int OK = 0;
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;
protected Process fProcess;
protected boolean fShowCommand;
protected String[] fCommandArgs;
@ -54,31 +55,43 @@ public class CommandLauncher {
lineSeparator = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Sets if the command should be printed out first before executing
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#showCommand(boolean)
*/
public void showCommand(boolean show) {
fShowCommand = show;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#getErrorMessage()
*/
public String getErrorMessage() {
return fErrorMessage;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#setErrorMessage(java.lang.String)
*/
public void setErrorMessage(String error) {
fErrorMessage = error;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#getCommandArgs()
*/
public String[] getCommandArgs() {
return fCommandArgs;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#getEnvironment()
*/
public Properties getEnvironment() {
return EnvironmentReader.getEnvVars();
}
/**
* return the constructed Command line.
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#getCommandLine()
*/
public String getCommandLine() {
return getCommandLine(getCommandArgs());
@ -94,8 +107,8 @@ public class CommandLauncher {
return args;
}
/**
* Execute a command
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#execute(org.eclipse.core.runtime.IPath, java.lang.String[], java.lang.String[], org.eclipse.core.runtime.IPath)
*/
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory) {
try {
@ -116,8 +129,8 @@ public class CommandLauncher {
return fProcess;
}
/**
* Reads output form the process to the streams.
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#waitAndRead(java.io.OutputStream, java.io.OutputStream)
*/
public int waitAndRead(OutputStream out, OutputStream err) {
if (fShowCommand) {
@ -133,11 +146,8 @@ public class CommandLauncher {
return OK;
}
/**
* Reads output form the process to the streams. A progress monitor is
* polled to test if the cancel button has been pressed. Destroys the
* process if the monitor becomes canceled override to implement a different
* way to read the process inputs
/* (non-Javadoc)
* @see org.eclipse.cdt.core.ICommandLauncher#waitAndRead(java.io.OutputStream, java.io.OutputStream, org.eclipse.core.runtime.IProgressMonitor)
*/
public int waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor) {
if (fShowCommand) {

View file

@ -0,0 +1,83 @@
package org.eclipse.cdt.core;
import java.io.OutputStream;
import java.util.Properties;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* An interface for launchers of external commands.
*
* @since 5.1
*/
public interface ICommandLauncher {
public final static int COMMAND_CANCELED = 1;
public final static int ILLEGAL_COMMAND = -1;
public final static int OK = 0;
/**
* Sets if the command should be printed out first before executing.
*/
public void showCommand(boolean show);
/**
* Returns a human readable error message corresponding to the last error encountered during command
* execution.
*
* @return A String corresponding to the error, or <code>null</code> if there has been no error.
*/
public String getErrorMessage();
/**
* Sets the human readable error message corresponding to the last error encountered during command
* execution. A subsequent call to getErrorMessage() will return this string.
*
* @param error A String corresponding to the error message, or <code>null</code> if the error state is
* intended to be cleared.
*/
public void setErrorMessage(String error);
/**
* Returns an array of the command line arguments that were last used to execute a command.
*
* @return an array of type String[] corresponding to the arguments. The array can be empty, but should not
* be null.
*/
public String[] getCommandArgs();
/**
* Returns the set of environment variables in the context of which
* this launcher will execute commands.
*
* @return Properties
*/
public Properties getEnvironment();
/**
* Returns the constructed command line of the last command executed.
*
* @return String
*/
public String getCommandLine();
/**
* Execute a command
*/
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory);
/**
* Reads output form the process to the streams.
*/
public int waitAndRead(OutputStream out, OutputStream err);
/**
* Reads output form the process to the streams. A progress monitor is
* polled to test if the cancel button has been pressed. Destroys the
* process if the monitor becomes canceled override to implement a different
* way to read the process inputs
*/
public int waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor);
}

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.debug.mi.core.command.factories.win32;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.core.runtime.Path;
/**
@ -24,14 +25,14 @@ public class CygwinMIEnvironmentCD extends WinMIEnvironmentCD {
CygwinMIEnvironmentCD( String miVersion, String path ) {
super( miVersion, path );
// Use the cygpath utility to convert the path
CommandLauncher launcher = new CommandLauncher();
ICommandLauncher launcher = new CommandLauncher();
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
String newPath = null;
launcher.execute( new Path( "cygpath" ), //$NON-NLS-1$
new String[]{ "-u", path }, //$NON-NLS-1$
new String[0], new Path( "." ) ); //$NON-NLS-1$
if ( launcher.waitAndRead( out, err ) == CommandLauncher.OK ) {
if ( launcher.waitAndRead( out, err ) == ICommandLauncher.OK ) {
newPath = out.toString();
if ( newPath != null ) {
newPath = newPath.trim();

View file

@ -14,6 +14,7 @@ import java.io.ByteArrayOutputStream;
import java.util.StringTokenizer;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentDirectory;
import org.eclipse.core.runtime.Path;
@ -85,14 +86,14 @@ public class CygwinMIEnvironmentDirectory extends MIEnvironmentDirectory {
*/
private String convertPath0(String path) {
String result = path;
CommandLauncher launcher = new CommandLauncher();
ICommandLauncher launcher = new CommandLauncher();
ByteArrayOutputStream out = new ByteArrayOutputStream();
launcher.execute(
new Path("cygpath"), //$NON-NLS-1$
new String[] { "-p", "-u", path }, //$NON-NLS-1$ //$NON-NLS-2$
new String[0],
new Path(".")); //$NON-NLS-1$
if (launcher.waitAndRead(out, out) == CommandLauncher.OK)
if (launcher.waitAndRead(out, out) == ICommandLauncher.OK)
result = out.toString().trim();
return result;
}