1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-18 21:55:45 +02:00

Backport implementation of bug 259768: "Use optimal jobs number:

highly misleading" from 8.1 to 8.0.

Change-Id: I5a3d33b21b306b30411dc6eb2325d77d0383c9bf
Reviewed-on: https://git.eclipse.org/r/9731
Reviewed-by: Doug Schaefer <dschaefer@qnx.com>
IP-Clean: Doug Schaefer <dschaefer@qnx.com>
Tested-by: Doug Schaefer <dschaefer@qnx.com>
This commit is contained in:
Marc Gobeil 2013-01-16 18:04:19 -05:00 committed by Doug Schaefer
parent f0f4c6e022
commit 05cfb020bb
15 changed files with 891 additions and 681 deletions

View file

@ -1757,8 +1757,27 @@ If this attribute is not specified, MBS will assume that there are no reserved m
<attribute name="parallelBuildCmd" type="string">
<annotation>
<documentation>
specifies the &quot;parallel build&quot; builder option.
If the builder supports specifying custom number of parallel jobs, the option definition may contain &quot;*&quot; the Build System sill substitute the &quot;*&quot; with the number of parallel threads to be used.
Specifies the command for &quot;parallel build&quot;.
If the builder supports specifying custom number of parallel jobs the option definition may contain &quot;*&quot;. The Build System will substitute the &quot;*&quot; with the number of parallel threads to be used. In case of &quot;unlimited&quot; jobs jobs number will be omitted.
For example, builder representing GNU make would define parallelBuildCmd as &quot;-j*&quot;.
</documentation>
</annotation>
</attribute>
<attribute name="parallelBuildOn" type="boolean">
<annotation>
<documentation>
Defines if the parallel build is enabled in newly created project by default (when parallel build is supported). The number of jobs is defined by &quot;parallelizationNumber&quot; attribute. If &quot;parallelizationNumber&quot; is not defined &quot;optimal&quot; value will be used.
</documentation>
</annotation>
</attribute>
<attribute name="parallelizationNumber" type="string">
<annotation>
<documentation>
Sets maximum number of parallel threads/jobs to be used by builder (that value can be changed after creation of project by user).
A positive number or value &quot;optimal&quot; or &quot;unlimited&quot; are recognized:
- number 1 will cause parallel build to be turned off,
- &quot;optimal&quot; will set maximum number of jobs to number of processors on the system,
- &quot;unlimited&quot; will make builder to run as many threads/jobs as possible.
</documentation>
</annotation>
</attribute>

View file

@ -75,14 +75,17 @@ public interface IBuilder extends IHoldsOptions, IMakeBuilderInfo {
static final String ATTRIBUTE_CUSTOMIZED_ERROR_PARSERS = "customizedErrorParsers"; //$NON-NLS-1$
static final String ATTRIBUTE_CUSTOM_PROPS = "customBuilderProperties"; //$NON-NLS-1$
// static final String ATTRIBUTE_CUSTOMIZED_ERROR_PARSERS = "customizedErrorParsers"; //$NON-NLS-1$
static final String ATTRIBUTE_IGNORE_ERR_CMD = "ignoreErrCmd"; //$NON-NLS-1$
static final String ATTRIBUTE_STOP_ON_ERR = "stopOnErr"; //$NON-NLS-1$
static final String ATTRIBUTE_PARALLEL_BUILD_CMD = "parallelBuildCmd"; //$NON-NLS-1$
static final String ATTRIBUTE_PARALLELIZATION_NUMBER = "parallelizationNumber"; //$NON-NLS-1$
static final String ATTRIBUTE_PARALLEL_BUILD_ON = "parallelBuildOn"; //$NON-NLS-1$
static final String ATTRIBUTE_PARALLELIZATION_NUMBER = "parallelizationNumber"; //$NON-NLS-1$
/** @since 8.0 */
static final String VALUE_OPTIMAL = "optimal"; //$NON-NLS-1$
/** @since 8.0 */
static final String VALUE_UNLIMITED = "unlimited"; //$NON-NLS-1$
static final String PARALLEL_PATTERN_NUM = "*"; //$NON-NLS-1$
static final String PARALLEL_PATTERN_NUM_START = "["; //$NON-NLS-1$
static final String PARALLEL_PATTERN_NUM_END = "]"; //$NON-NLS-1$
@ -92,15 +95,9 @@ public interface IBuilder extends IHoldsOptions, IMakeBuilderInfo {
static final String DEFAULT_TARGET_INCREMENTAL = "all"; //$NON-NLS-1$
static final String DEFAULT_TARGET_CLEAN = "clean"; //$NON-NLS-1$
static final String DEFAULT_TARGET_AUTO = "all"; //$NON-NLS-1$
/**
* @since 6.0
*/
/** @since 6.0 */
static final String ATTRIBUTE_COMMAND_LAUNCHER = "commandLauncher"; //$NON-NLS-1$
/**
* @since 8.0
*/
/** @since 8.0 */
static final String ATTRIBUTE_BUILD_RUNNER = "buildRunner"; //$NON-NLS-1$
/**

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Intel Corporation and others.
* Copyright (c) 2007, 2011 Intel Corporation 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
@ -13,19 +13,56 @@ package org.eclipse.cdt.managedbuilder.core;
import org.eclipse.cdt.core.settings.model.ICMultiItemsHolder;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
import org.eclipse.cdt.managedbuilder.internal.core.Builder;
/**
* This class is to combine multiple configurations to one to support
* selection of multiple configurations on property pages.
*
* @noextend This class is not intended to be subclassed by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IMultiConfiguration extends IConfiguration, ICMultiItemsHolder {
/**
* Check if all configurations' builders are operating in parallel mode.
* @return {@code true} if parallel mode is enabled for all configurations,
* {@code false} otherwise.
*/
boolean getParallelDef();
void setParallelDef(boolean def);
int getParallelNumber();
void setParallelNumber(int num);
/**
* Set same parallel execution mode for all configurations' builders.
* @see Builder#setParallelBuildOn(boolean)
*
* @param parallel - the flag to enable or disable parallel mode.
*/
void setParallelDef(boolean parallel);
/**
* Returns maximum number of parallel threads/jobs used by the configurations' builders.
* @see #setParallelDef(boolean)
*
* @return - maximum number of parallel threads or jobs used by each builder or 0 if the numbers
* don't match.
*/
int getParallelNumber();
/**
* Sets maximum number of parallel threads/jobs to be used by each builder.
*
* @param jobs - maximum number of jobs or threads, see for more details
* {@link Builder#getOptimalParallelJobNum()}.
*/
void setParallelNumber(int jobs);
/**
* Check if all configurations' internal builders are operating in parallel mode.
* @return {@code true} if parallel mode is enabled for all configurations,
* {@code false} otherwise.
*
* @deprecated since CDT 9.0. Use {@link #getParallelDef()}
*/
@Deprecated
boolean getInternalBuilderParallel();
boolean isInternalBuilderEnabled();

View file

@ -65,7 +65,7 @@ public class InternalBuildRunner extends AbstractBuildRunner {
public boolean invokeBuild(int kind, IProject project, IConfiguration configuration,
IBuilder builder, IConsole console, IMarkerGenerator markerGenerator,
IncrementalProjectBuilder projectBuilder, IProgressMonitor monitor) throws CoreException {
boolean isParallel = builder.isParallelBuildOn() && builder.getParallelizationNum() > 1;
boolean isParallel = builder.getParallelizationNum() > 1;
// boolean buildIncrementaly = true;
boolean resumeOnErr = !builder.isStopOnError();
@ -173,8 +173,7 @@ public class InternalBuildRunner extends AbstractBuildRunner {
break;
case IBuildModelBuilder.STATUS_ERROR_LAUNCH:
default:
buf.append(ManagedMakeMessages
.getResourceString(BUILD_FAILED_ERR));
buf.append(ManagedMakeMessages.getResourceString(BUILD_FAILED_ERR));
break;
}
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$
@ -194,8 +193,7 @@ public class InternalBuildRunner extends AbstractBuildRunner {
epmOutputStream.close();
epmOutputStream = null;
// Generate any error markers that the build has discovered
monitor.subTask(ManagedMakeMessages
.getResourceString(MARKERS));
monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS));
bsMngr.setProjectBuildState(project, pBS);
} else {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 Intel Corporation and others.
* Copyright (c) 2006, 2011 Intel Corporation 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
@ -11,41 +11,27 @@
package org.eclipse.cdt.managedbuilder.internal.buildmodel;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* This class implements process pool management for internal builder
*
* NOTE: This class is subject to change and discuss,
* and is currently available in experimental mode only
*/
public class BuildProcessManager {
protected OutputStream out;
protected OutputStream err;
protected boolean show;
protected ProcessLauncher[] processes;
protected int maxProcesses;
// Number of CPUs is not dependent of object instance.
// But user can change UI settings for processes number.
// So we cannot set procNumber directly to maxProcesses.
static int procNumber = 0;
protected Vector<ProcessLauncher> processes;
protected int maxProcesses;
/**
* Initializes process manager
@ -59,7 +45,7 @@ public class BuildProcessManager {
err = _err;
show = _show;
maxProcesses = _procNumber;
processes = new ProcessLauncher[maxProcesses];
processes = new Vector<ProcessLauncher>(Math.min(10, maxProcesses), 10);
}
/**
@ -79,18 +65,19 @@ public class BuildProcessManager {
* @param monitor Progress monitor for this task
*/
public ProcessLauncher launchProcess(IBuildCommand cmd, IPath cwd, IProgressMonitor monitor) {
if (hasEmpty()) {
int i = 0;
for (; i < maxProcesses; i++) {
if (processes[i] == null || processes[i].queryState() == ProcessLauncher.STATE_DONE) {
break;
}
for (int i = 0; i < maxProcesses; i++) {
if (i >= processes.size()) {
ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show);
processes.add(process);
process.launch();
return process;
}
if (i < maxProcesses) {
processes[i] = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show);
processes[i].launch();
return processes[i];
if (processes.get(i).queryState() == ProcessLauncher.STATE_DONE) {
ProcessLauncher process = new ProcessLauncher(cmd.getCommand(), cmd.getArgs(), mapToStringArray(cmd.getEnvironment()), cwd, out, err, monitor, show);
processes.set(i, process);
process.launch();
return process;
}
}
return null;
@ -102,36 +89,37 @@ public class BuildProcessManager {
* returned as a result. Otherwise this method returns null.
*/
public ProcessLauncher queryStates() {
ProcessLauncher result = null;
for (int i = 0; i < maxProcesses; i++) {
if (processes[i] != null) {
int state = processes[i].queryState();
if (state != ProcessLauncher.STATE_RUNNING) {
if (state != ProcessLauncher.STATE_DONE && result == null)
result = processes[i];
}
}
for (ProcessLauncher process : processes) {
int state = process.queryState();
if (state != ProcessLauncher.STATE_RUNNING && state != ProcessLauncher.STATE_DONE)
return process;
}
return result;
return null;
}
/**
* Checks states of all currently running processes.
*/
public boolean hasEmpty() {
for (int i = 0; i < maxProcesses; i++) {
if (processes[i] == null)
if (processes.size() < maxProcesses)
return true;
for (ProcessLauncher process : processes) {
if (process.queryState() != ProcessLauncher.STATE_RUNNING)
return true;
else {
if (processes[i].queryState() != ProcessLauncher.STATE_RUNNING)
return true;
}
}
return false;
}
/**
* Returns maximum threads used up to that point
*/
public int getThreadsUsed() {
return processes.size();
}
/**
* Converts map to strings array
@ -152,40 +140,10 @@ public class BuildProcessManager {
/**
* @return Number of processors detected
* @deprecated since CDT 9.0 - just use Runtime.getRuntime().availableProcessors()
*/
@Deprecated
static public int checkCPUNumber() {
if (procNumber > 0) return procNumber;
procNumber = 1;
int x = 0;
String os = System.getProperty("os.name"); //$NON-NLS-1$
if (os != null) {
if (os.startsWith("Win")) { //$NON-NLS-1$
IEnvironmentVariableProvider evp = ManagedBuildManager.getEnvironmentVariableProvider();
if (evp != null) {
IBuildEnvironmentVariable var = evp.getVariable("NUMBER_OF_PROCESSORS", null, false, false); //$NON-NLS-1$
if (var != null) {
try {
x = new Integer(var.getValue()).intValue();
if (x > 0) { procNumber = x; }
} catch (NumberFormatException e) {} // fallthrough and return default
}
}
} else { // linux
String p = "/proc/cpuinfo"; //$NON-NLS-1$
try {
BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(p)));
String s;
while ((s = r.readLine() ) != null )
{ if (s.startsWith("processor\t:")) x++; } //$NON-NLS-1$
r.close();
if (x > 0) { procNumber = x; }
}
catch (IOException e) {} // fallthrough and return default
}
}
if(DbgUtil.DEBUG)
DbgUtil.trace("Number of processors detected: " + procNumber); //$NON-NLS-1$
return procNumber;
return Runtime.getRuntime().availableProcessors();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Intel Corporation and others.
* Copyright (c) 2006, 2011 Intel Corporation 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
@ -17,6 +17,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
@ -205,18 +206,16 @@ public class ParallelBuilder {
if(cwd == null) cwd = des.getDefaultBuildDirLocation();
int threads = 1;
if (cfg instanceof Configuration) {
if (((Configuration)cfg).getParallelDef())
threads = BuildProcessManager.checkCPUNumber();
else
threads = ((Configuration)cfg).getParallelNumber();
threads = ((Configuration)cfg).getParallelNumber();
}
ParallelBuilder builder = new ParallelBuilder(cwd, dirs, out, err, monitor, resumeOnErrors, buildIncrementally);
builder.enqueueAll(des);
builder.sortQueue();
monitor.beginTask("", builder.queue.size()); //$NON-NLS-1$
builder.dispatch(new BuildProcessManager(out, err, true, threads));
BuildProcessManager buildProcessManager = new BuildProcessManager(out, err, true, threads);
builder.dispatch(buildProcessManager);
lastThreadsUsed = buildProcessManager.getThreadsUsed();
monitor.done();
lastThreadsUsed = threads;
return IBuildModelBuilder.STATUS_OK;
}
@ -295,10 +294,8 @@ public class ParallelBuilder {
* Dispatches the build queue and returns build status
*/
protected int dispatch(BuildProcessManager mgr) {
ActiveBuildStep[] active = new ActiveBuildStep[mgr.getMaxProcesses()];
for (int i = 0; i < active.length; i++) {
active[i] = null; // new ActiveBuildStep();
}
int maxProcesses = mgr.getMaxProcesses();
Vector<ActiveBuildStep> active = new Vector<ActiveBuildStep>(Math.min(maxProcesses, 10), 10);
int activeCount = 0;
int maxLevel = 0;
@ -332,9 +329,8 @@ public class ParallelBuilder {
proceed = false;
} else {
// Check "active steps" list for completed ones
for (int i = 0; i < active.length; i++) {
if (active[i] == null) continue;
ProcessLauncher pl = active[i].getLauncher();
for (ActiveBuildStep buildStep : active) {
ProcessLauncher pl = buildStep.getLauncher();
if (pl == null) continue;
if (pl.queryState() == ProcessLauncher.STATE_DONE) {
// If process has terminated with error, break loop
@ -345,8 +341,8 @@ public class ParallelBuilder {
break main_loop;
}
// Try to launch next command for the current active step
if (active[i].isDone()) continue;
if (active[i].launchNextCmd(mgr)) {
if (buildStep.isDone()) continue;
if (buildStep.launchNextCmd(mgr)) {
// Command has been launched. Check if process pool is not maximized yet
if (!mgr.hasEmpty()) {
proceed = false;
@ -354,7 +350,7 @@ public class ParallelBuilder {
}
} else {
// Command has not been launched: step complete
refreshOutputs(active[i].getStep());
refreshOutputs(buildStep.getStep());
activeCount--;
monitor.worked(1);
}
@ -373,7 +369,7 @@ public class ParallelBuilder {
}
// Check if we need to schedule another process
if (queue.size() != 0 && activeCount < active.length) {
if (queue.size() != 0 && activeCount < maxProcesses) {
// Need to schedule another process
Iterator<BuildQueueElement> iter = queue.iterator();
@ -381,8 +377,8 @@ public class ParallelBuilder {
while (iter.hasNext()) {
BuildQueueElement elem = iter.next();
// If "active steps" list is full, then break loop
if (activeCount == active.length)
// If "active steps" list reaches maximum, then break loop
if (activeCount == maxProcesses)
break;
// If current element's level exceeds maximum level of currently built
@ -391,14 +387,13 @@ public class ParallelBuilder {
break;
//Check if all prerequisites are built
IBuildResource[] res = elem.getStep().getInputResources();
boolean prereqBuilt = true;
for (int j = 0; j < res.length; j++) {
IBuildStep stp = res[j].getProducerStep(); // step which produces input for curr
for (IBuildResource bldRes : elem.getStep().getInputResources()) {
IBuildStep step = bldRes.getProducerStep(); // step which produces input for curr
boolean built = true;
if (stp != stp.getBuildDescription().getInputStep()) {
for (int k = 0; k < active.length; k++) {
if (active[k] != null && active[k].getStep().equals(stp) && !active[k].isDone()) {
if (step != step.getBuildDescription().getInputStep()) {
for (ActiveBuildStep buildStep : active) {
if (buildStep != null && buildStep.getStep().equals(step) && !buildStep.isDone()) {
built = false;
break;
}
@ -417,10 +412,21 @@ public class ParallelBuilder {
// Remove element from the build queue and add it to the
// "active steps" list.
iter.remove();
for (int i = 0; i < active.length; i++) {
if (active[i] == null || active[i].isDone()) {
active[i] = new ActiveBuildStep(step);
if (active[i].launchNextCmd(mgr)) activeCount++;
for (int i = 0; i < maxProcesses; i++) {
if (i >= active.size()) {
// add new item
ActiveBuildStep buildStep = new ActiveBuildStep(step);
active.add(buildStep);
if (buildStep.launchNextCmd(mgr))
activeCount++;
break;
}
if (active.get(i).isDone()) {
// replace old item
ActiveBuildStep buildStep = new ActiveBuildStep(step);
active.set(i, buildStep);
if (buildStep.launchNextCmd(mgr))
activeCount++;
break;
}
}

View file

@ -40,10 +40,10 @@ import org.eclipse.cdt.core.settings.model.extension.CBuildData;
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.core.settings.model.util.LanguageSettingEntriesSerializer;
import org.eclipse.cdt.internal.core.SafeStringInterner;
import org.eclipse.cdt.managedbuilder.core.AbstractBuildRunner;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.ExternalBuildRunner;
import org.eclipse.cdt.managedbuilder.core.IBuildObject;
import org.eclipse.cdt.managedbuilder.core.AbstractBuildRunner;
import org.eclipse.cdt.managedbuilder.core.IBuilder;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement;
@ -66,6 +66,7 @@ import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator2;
import org.eclipse.cdt.managedbuilder.makegen.gnu.GnuMakefileGenerator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
@ -79,7 +80,7 @@ import org.eclipse.core.variables.VariablesPlugin;
import org.osgi.framework.Version;
public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider<Builder>, IRealBuildObjectAssociation {
public static final int UNLIMITED_JOBS = Integer.MAX_VALUE;
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
// Superclass
@ -119,10 +120,12 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
private HashMap<String, String> customBuildProperties;
// private Boolean isWorkspaceBuildPath;
private String ignoreErrCmd;
private String parallelBuildCmd;
private Boolean stopOnErr;
private Integer parallelNum;
private Boolean parallelBuildOn;
// parallelization
private String parallelBuildCmd;
private Boolean isParallelBuildEnabled;
private Integer parallelNumberAttribute; // negative number denotes "optimal" value, see getOptimalParallelJobNum()
private boolean isTest;
// Miscellaneous
@ -327,9 +330,10 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
stopOnErr = builder.stopOnErr;
ignoreErrCmd = builder.ignoreErrCmd;
isParallelBuildEnabled = builder.isParallelBuildEnabled;
parallelNumberAttribute = builder.parallelNumberAttribute;
parallelBuildCmd = builder.parallelBuildCmd;
parallelNum = builder.parallelNum;
parallelBuildOn = builder.parallelBuildOn;
if(builder.outputEntries != null){
outputEntries = builder.outputEntries.clone();
@ -372,17 +376,15 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
} catch (CoreException e) {
}
}
if(getParallelizationNum() != builder.getParallelizationNum()
&& supportsParallelBuild()){
if (isParallelBuildOn() != builder.isParallelBuildOn() && supportsParallelBuild()) {
try {
setParallelizationNum(builder.getParallelizationNum());
setParallelBuildOn(builder.isParallelBuildOn());
} catch (CoreException e) {
}
}
if(isParallelBuildOn() != builder.isParallelBuildOn()
&& supportsParallelBuild()){
if (getParallelizationNumAttribute() != builder.getParallelizationNumAttribute() && supportsParallelBuild()) {
try {
setParallelBuildOn(builder.isParallelBuildOn());
setParallelizationNum(builder.getParallelizationNumAttribute());
} catch (CoreException e) {
}
}
@ -552,23 +554,23 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
ignoreErrCmd = SafeStringInterner.safeIntern(element.getAttribute(ATTRIBUTE_IGNORE_ERR_CMD));
tmp = element.getAttribute(ATTRIBUTE_STOP_ON_ERR);
if(tmp != null)
stopOnErr = Boolean.valueOf(tmp);
parallelBuildCmd = SafeStringInterner.safeIntern(element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD));
tmp = element.getAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER);
if(tmp != null){
try {
parallelNum = Integer.decode(tmp);
} catch (NumberFormatException e){
}
}
tmp = element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_ON);
if(tmp != null)
parallelBuildOn = Boolean.valueOf(tmp);
tmp = element.getAttribute(ATTRIBUTE_STOP_ON_ERR);
if (tmp != null)
stopOnErr = Boolean.valueOf(tmp);
tmp = element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD);
if (tmp != null)
parallelBuildCmd = SafeStringInterner.safeIntern(tmp);
tmp = element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_ON);
if (tmp != null) {
isParallelBuildEnabled = Boolean.valueOf(tmp);
if (isParallelBuildEnabled) {
tmp = element.getAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER);
setParallelizationNumAttribute(decodeParallelizationNumber(element.getAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER)));
}
}
// Get the semicolon separated list of IDs of the error parsers
errorParserIds = SafeStringInterner.safeIntern(element.getAttribute(IToolChain.ERROR_PARSERS));
@ -618,6 +620,43 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
fBuildRunnerElement = ((DefaultManagedConfigElement)element).getConfigurationElement();
}
private String encodeParallelizationNumber(Integer jobsNumber) {
if (jobsNumber <= 0)
return VALUE_OPTIMAL;
if (jobsNumber.equals(UNLIMITED_JOBS))
return VALUE_UNLIMITED;
return jobsNumber.toString();
}
private int decodeParallelizationNumber(String value) {
int parallelNumber = -1;
if (VALUE_OPTIMAL.equals(value)) {
parallelNumber = -getOptimalParallelJobNum();
} else if (VALUE_UNLIMITED.equals(value)) {
parallelNumber = UNLIMITED_JOBS;
} else {
try {
parallelNumber = Integer.decode(value);
} catch (NumberFormatException e) {
ManagedBuilderCorePlugin.log(e);
parallelNumber = getOptimalParallelJobNum();
}
if (parallelNumber <= 0) {
// compatibility with legacy representation - it was that inconsistent
if (isInternalBuilder()) {
// "optimal" for Internal Builder
parallelNumber = -getOptimalParallelJobNum();
} else {
// unlimited for External Builder
parallelNumber = UNLIMITED_JOBS;
}
}
}
return parallelNumber;
}
/**
* Initialize the builder information from the XML element
* specified in the argument
@ -748,24 +787,22 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
if(element.getAttribute(ATTRIBUTE_IGNORE_ERR_CMD) != null)
ignoreErrCmd = SafeStringInterner.safeIntern(element.getAttribute(ATTRIBUTE_IGNORE_ERR_CMD));
tmp = element.getAttribute(ATTRIBUTE_STOP_ON_ERR);
if(tmp != null)
stopOnErr = Boolean.valueOf(tmp);
if(element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD) != null)
parallelBuildCmd = SafeStringInterner.safeIntern(element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD));
tmp = element.getAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER);
if(tmp != null){
try {
parallelNum = Integer.decode(tmp);
} catch (NumberFormatException e){
}
}
tmp = element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_ON);
if(tmp != null)
parallelBuildOn = Boolean.valueOf(tmp);
tmp = element.getAttribute(ATTRIBUTE_STOP_ON_ERR);
if (tmp != null)
stopOnErr = Boolean.valueOf(tmp);
tmp = element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD);
if (tmp != null)
parallelBuildCmd = SafeStringInterner.safeIntern(tmp);
tmp = element.getAttribute(ATTRIBUTE_PARALLEL_BUILD_ON);
if (tmp != null) {
isParallelBuildEnabled = Boolean.valueOf(tmp);
if (isParallelBuildEnabled) {
tmp = element.getAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER);
setParallelizationNumAttribute(decodeParallelizationNumber(element.getAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER)));
}
}
ICStorageElement[] children = element.getChildren();
for(int i = 0; i < children.length; i++){
@ -869,16 +906,19 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
if(customBuildProperties != null)
element.setAttribute(ATTRIBUTE_CUSTOM_PROPS, MapStorageElement.encodeMap(customBuildProperties));
if(ignoreErrCmd != null)
element.setAttribute(ATTRIBUTE_IGNORE_ERR_CMD, ignoreErrCmd);
if(stopOnErr != null)
element.setAttribute(ATTRIBUTE_STOP_ON_ERR, stopOnErr.toString());
if(parallelBuildCmd != null)
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD, parallelBuildCmd);
if(parallelNum != null)
element.setAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER, parallelNum.toString());
if(parallelBuildOn != null)
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_ON, parallelBuildOn.toString());
if (ignoreErrCmd != null)
element.setAttribute(ATTRIBUTE_IGNORE_ERR_CMD, ignoreErrCmd);
if (stopOnErr != null)
element.setAttribute(ATTRIBUTE_STOP_ON_ERR, stopOnErr.toString());
if (parallelBuildCmd != null)
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD, parallelBuildCmd);
if (isParallelBuildEnabled != null)
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_ON, isParallelBuildEnabled.toString());
if (isParallelBuildOn() && parallelNumberAttribute != null)
element.setAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER, encodeParallelizationNumber(parallelNumberAttribute));
// Note: build file generator cannot be specified in a project file because
// an IConfigurationElement is needed to load it!
if (buildFileGeneratorElement != null) {
@ -965,13 +1005,18 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
if(customBuildProperties != null)
element.setAttribute(ATTRIBUTE_CUSTOM_PROPS, MapStorageElement.encodeMap(customBuildProperties));
if(getIgnoreErrCmdAttribute() != null)
element.setAttribute(ATTRIBUTE_IGNORE_ERR_CMD, getIgnoreErrCmdAttribute());
element.setAttribute(ATTRIBUTE_STOP_ON_ERR, Boolean.valueOf(isStopOnError()).toString());
if(getParrallelBuildCmd() != null)
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD, getParrallelBuildCmd());
element.setAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER, new Integer(getParallelizationNumAttribute()).toString());
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_ON, Boolean.valueOf(isParallelBuildOn()).toString());
if (getIgnoreErrCmdAttribute() != null)
element.setAttribute(ATTRIBUTE_IGNORE_ERR_CMD, getIgnoreErrCmdAttribute());
element.setAttribute(ATTRIBUTE_STOP_ON_ERR, Boolean.valueOf(isStopOnError()).toString());
if (parallelBuildCmd != null)
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_CMD, parallelBuildCmd);
if (isParallelBuildEnabled != null)
element.setAttribute(ATTRIBUTE_PARALLEL_BUILD_ON, isParallelBuildEnabled.toString());
if (isParallelBuildOn() && parallelNumberAttribute != null)
element.setAttribute(ATTRIBUTE_PARALLELIZATION_NUMBER, encodeParallelizationNumber(parallelNumberAttribute));
// Note: build file generator cannot be specified in a project file because
// an IConfigurationElement is needed to load it!
if (buildFileGeneratorElement != null) {
@ -1042,16 +1087,17 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
public String getArguments() {
String args = getArgumentsAttribute();
String stopOnErrCmd = getStopOnErrCmd(isStopOnError());
String parallelBuildCmd = isParallelBuildOn() ? getParallelizationCmd(getParallelizationNum()) : EMPTY_STRING;
int parallelNum = getParallelizationNum();
String parallelCmd = isParallelBuildOn() ? getParallelizationCmd(parallelNum) : EMPTY_STRING;
String reversedStopOnErrCmd = getStopOnErrCmd(!isStopOnError());
String reversedParallelBuildCmd = !isParallelBuildOn() ? getParallelizationCmd(getParallelizationNum()) : EMPTY_STRING;
String reversedParallelBuildCmd = !isParallelBuildOn() ? getParallelizationCmd(parallelNum) : EMPTY_STRING;
args = removeCmd(args, reversedStopOnErrCmd);
args = removeCmd(args, reversedParallelBuildCmd);
args = addCmd(args, stopOnErrCmd);
args = addCmd(args, parallelBuildCmd);
args = addCmd(args, parallelCmd);
return args != null ? args.trim() : null;
}
@ -1114,18 +1160,27 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
return index;
}
public String getParallelizationCmd(int num){
public String getParallelizationCmd(int num) {
String pattern = getParrallelBuildCmd();
if(pattern.length() == 0){
return EMPTY_STRING;
}if(num == 0){
if (pattern.length() == 0 || num == 0) {
return EMPTY_STRING;
}
return processParallelPattern(pattern, num < 0, num);
// "unlimited" number of jobs results in not adding the number to parallelization cmd
// that behavior corresponds that of "make" flag "-j".
return processParallelPattern(pattern, num == UNLIMITED_JOBS, num);
}
/**
* This method turns the supplied pattern to parallelization command
*
* It supports 2 kinds of pattern where "*" is replaced with number of jobs:
* <li>Pattern 1 (supports "<b>-j*</b>"): "text*text" -> "text#text"</li>
* <li>Pattern 2 (supports "<b>-[j*]</b>"): "text[text*text]text" -> "texttext#texttext</li>
* <br>Where # is num or empty if {@code empty} is {@code true})
*/
private String processParallelPattern(String pattern, boolean empty, int num){
Assert.isTrue(num > 0);
int start = pattern.indexOf(PARALLEL_PATTERN_NUM_START);
int end = -1;
boolean hasStartChar = false;
@ -1238,10 +1293,10 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
if(newArgs != null){
String stopOnErrCmd = getStopOnErrCmd(isStopOnError());
String parallelBuildCmd = isParallelBuildOn() ? getParallelizationCmd(getParallelizationNum()) : EMPTY_STRING;
String parallelCmd = isParallelBuildOn() ? getParallelizationCmd(getParallelizationNum()) : EMPTY_STRING;
newArgs = removeCmd(newArgs, stopOnErrCmd);
newArgs = removeCmd(newArgs, parallelBuildCmd);
newArgs = removeCmd(newArgs, parallelCmd);
}
setArgumentsAttribute(newArgs);
}
@ -1915,7 +1970,6 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
return attr;
}
public String getFullBuildTarget() {
return getIncrementalBuildTarget();
@ -2385,34 +2439,80 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
return false;
}
public int getParallelizationNum() {
if(supportsParallelBuild())
return getParallelizationNumAttribute();
return 1;
/**
* Returns the optimal number of parallel jobs.
* The number is the number of available processors on the machine.
*
* The function never returns number smaller than 1.
*/
public int getOptimalParallelJobNum() {
return Runtime.getRuntime().availableProcessors();
}
public int getParallelizationNumAttribute(){
if(parallelNum == null){
/**
* Returns the internal representation of maximum number of parallel jobs
* to be used for a build.
* Note that negative number represents "optimal" value.
*
* The value of the number is encoded as follows:
* <pre>
* Status Returns
* No parallel 1
* Optimal -CPU# (negative number of processors)
* Specific >0 (positive number)
* Unlimited Builder.UNLIMITED_JOBS
* </pre>
*/
public int getParallelizationNumAttribute() {
if (!isParallelBuildOn())
return 1;
if(parallelNumberAttribute == null){
if(superClass != null){
return ((Builder)superClass).getParallelizationNumAttribute();
}
return 1;
}
return parallelNum.intValue();
return parallelNumberAttribute.intValue();
}
public void setParallelizationNum(int num) throws CoreException {
// if(num == 0 || supportsParallelBuild()){
Integer newParallelNum = new Integer(num);
private void setParallelizationNumAttribute(int parallelNumber) {
isParallelBuildEnabled = (parallelNumber != 1);
if (parallelNumber > 0) {
parallelNumberAttribute = parallelNumber;
} else {
// "optimal"
parallelNumberAttribute = -getOptimalParallelJobNum();
}
}
public int getParallelizationNum() {
return Math.abs(getParallelizationNumAttribute());
}
/**
* {@inheritDoc}
*
* @param jobs - maximum number of jobs. There are 2 special cases:
* <br>- any number <=0 is interpreted as setting "optimal" property,
* the value of the number itself is ignored in this case
* <br>- value 1 will turn parallel mode off.
*/
public void setParallelizationNum(int jobs) throws CoreException {
if (!supportsParallelBuild())
return;
if (parallelNumberAttribute == null || parallelNumberAttribute != jobs) {
String curCmd = getParallelizationCmd(getParallelizationNum());
String args = getArgumentsAttribute();
String updatedArgs = removeCmd(args, curCmd);
if(!updatedArgs.equals(args)){
if (!updatedArgs.equals(args)) {
setArgumentsAttribute(updatedArgs);
}
parallelNum = newParallelNum;
setParallelizationNumAttribute(jobs);
setDirty(true);
// }
}
}
public boolean supportsParallelBuild() {
@ -2446,10 +2546,10 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
return ignoreErrCmd;
}
public String getParrallelBuildCmd(){
if(parallelBuildCmd == null){
if(superClass != null){
return ((Builder)superClass).getParrallelBuildCmd();
public String getParrallelBuildCmd() {
if (parallelBuildCmd == null) {
if (superClass != null) {
return ((Builder) superClass).getParrallelBuildCmd();
}
return EMPTY_STRING;
}
@ -2457,31 +2557,35 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
}
public boolean isParallelBuildOn() {
if(parallelBuildOn == null){
if(superClass != null){
if (!supportsParallelBuild()) {
return false;
}
if (isParallelBuildEnabled == null) {
if (superClass != null) {
return getSuperClass().isParallelBuildOn();
}
return false;
}
return parallelBuildOn.booleanValue();
return isParallelBuildEnabled.booleanValue();
}
public void setParallelBuildOn(boolean on) throws CoreException{
if(isParallelBuildOn() == on)
return;
if(on && !supportsParallelBuild())
return;
String curCmd = getParallelizationCmd(getParallelizationNum());
String args = getArgumentsAttribute();
String updatedArgs = removeCmd(args, curCmd);
if(!updatedArgs.equals(args)){
setArgumentsAttribute(updatedArgs);
/**
* {@inheritDoc}
*
* @param on - the flag to enable or disable parallel mode.
* <br>{@code true} to enable, in this case the maximum number of jobs
* will be set to "optimal" number, see {@link #getOptimalParallelJobNum()}.
* <br>{@code false} to disable, the number of jobs will be set to 1.
*/
public void setParallelBuildOn(boolean on) throws CoreException {
if (on) {
// set "optimal" jobs by default when enabling parallel build
setParallelizationNum(-1);
} else {
setParallelizationNum(1);
}
parallelBuildOn = Boolean.valueOf(on);
setDirty(true);
}
public Set<String> contributeErrorParsers(Set<String> set){
if(getErrorParserIds() != null){
if(set == null)
@ -2638,6 +2742,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
public boolean isExtensionBuildObject() {
return isExtensionElement();
}
@Override
public String toString() {
return getUniqueRealName();

View file

@ -752,7 +752,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
* E L E M E N T A T T R I B U T E R E A D E R S A N D W R I T E R S
*/
/* (non-Javadoc)
/**
* Initialize the configuration information from an element in the
* manifest file or provided by a dynamicElementProvider
*
@ -803,7 +803,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
isTest = Boolean.valueOf(tmp).booleanValue();
}
/* (non-Javadoc)
/**
* Initialize the configuration information from the XML element
* specified in the argument
*
@ -874,8 +874,8 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if (element.getAttribute(CLEAN_COMMAND) != null) {
cleanCommand = SafeStringInterner.safeIntern(element.getAttribute(CLEAN_COMMAND));
}
// Get the pre-build and post-build commands
// Get the pre-build and post-build commands
if (element.getAttribute(PREBUILD_STEP) != null) {
prebuildStep = SafeStringInterner.safeIntern(element.getAttribute(PREBUILD_STEP));
}
@ -891,7 +891,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
if (element.getAttribute(POSTANNOUNCEBUILD_STEP) != null) {
postannouncebuildStep = SafeStringInterner.safeIntern(element.getAttribute(POSTANNOUNCEBUILD_STEP));
}
}
}
/**
@ -1568,7 +1568,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IConfiguration#setPrebuildStep(java.lang.String)
*/
public void setPrebuildStep(String step) {
public void setPrebuildStep(String step) {
if (step == null && prebuildStep == null) return;
if (prebuildStep == null || step == null || !prebuildStep.equals(step)) {
prebuildStep = step;
@ -1577,11 +1577,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IConfiguration#setPostbuildStep(java.lang.String)
*/
public void setPostbuildStep(String step) {
public void setPostbuildStep(String step) {
if (step == null && postbuildStep == null) return;
if (postbuildStep == null || step == null || !postbuildStep.equals(step)) {
postbuildStep = step;
@ -1593,7 +1592,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IConfiguration#setPreannouncebuildStep(java.lang.String)
*/
public void setPreannouncebuildStep(String announceStep) {
public void setPreannouncebuildStep(String announceStep) {
if (announceStep == null && preannouncebuildStep == null) return;
if (preannouncebuildStep == null || announceStep == null || !preannouncebuildStep.equals(announceStep)) {
preannouncebuildStep = announceStep;
@ -1605,7 +1604,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IConfiguration#setPostannouncebuildStep(java.lang.String)
*/
public void setPostannouncebuildStep(String announceStep) {
public void setPostannouncebuildStep(String announceStep) {
if (announceStep == null && postannouncebuildStep == null) return;
if (postannouncebuildStep == null || announceStep == null || !postannouncebuildStep.equals(announceStep)) {
postannouncebuildStep = announceStep;
@ -1785,7 +1784,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
((FolderInfo)getRootFolderInfo()).resetOptionSettings();
}
/*
/**
* Create a resource configuration object for the passed-in file
*/
public IResourceConfiguration createResourceConfiguration(IFile file)
@ -1932,7 +1931,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
return getRootFolderInfo().getToolFromInputExtension(sourceExtension);
}
/*
/**
* The resource delta passed to the builder is not always up-to-date
* for the given configuration because between two builds of the same configuration
* any number of other configuration builds may occur
@ -2004,7 +2003,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
prefs.getBoolean(pref, false) : defaultValue;
}
*/
/*
/**
* this method is used for enabling/disabling the internal builder
* for the given configuration
*
@ -2121,7 +2120,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
return null;
}
/*
/**
* returns whether the internal builder is enabled
* @return boolean
*/
@ -2129,7 +2128,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
return getBuilder().isInternalBuilder();
}
/*
/**
*
* sets the Internal Builder mode
*
@ -2144,7 +2143,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
}
}
/*
/**
* returns the Internal Builder mode
* if true, internal builder will ignore build errors while building,
* otherwise it will stop at the first build error
@ -2156,73 +2155,73 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
}
/**
*
* sets the Internal Builder Parallel mode
*
* @param parallel if true, internal builder will use parallel mode
*
* @deprecated since CDT 9.0. Use {@link #setParallelDef(boolean)}
*/
@Deprecated
public void setInternalBuilderParallel(boolean parallel){
if(getInternalBuilderParallel() == parallel)
return;
try {
getEditableBuilder().setParallelBuildOn(parallel);
} catch (CoreException e) {
}
setParallelDef(parallel);
}
/**
* returns the Internal Builder parallel mode
* if true, internal builder will work in parallel mode
* otherwise it will use only one thread
*
* @return boolean
*
* @deprecated since CDT 9.0. Use {@link #getParallelDef()}
*/
@Deprecated
public boolean getInternalBuilderParallel(){
return getBuilder().isParallelBuildOn();
return getParallelDef();
}
/**
* @param parallel if true, internal builder will use parallel mode
* Set parallel execution mode for the configuration's builder.
* @see Builder#setParallelBuildOn(boolean)
*
* @param parallel - the flag to enable or disable parallel mode.
*/
public void setParallelDef(boolean parallel){
if(getParallelDef() == parallel)
return;
int num = getParallelNumber();
if(num != 0){
setParallelNumber(-num);
} else {
if(parallel){
setParallelNumber(-1);
} else {
setParallelNumber(1);
}
try {
getEditableBuilder().setParallelBuildOn(parallel);
} catch (CoreException e) {
ManagedBuilderCorePlugin.log(e);
}
}
/**
* @return boolean
* Check if the configuration's builder is operating in parallel mode.
* @return {@code true} if parallel mode is enabled, {@code false} otherwise.
*/
public boolean getParallelDef(){
int num = getBuilder().getParallelizationNum();
return num <= 0;
return getBuilder().isParallelBuildOn();
}
/**
* sets number of Parallel threads
* Sets maximum number of parallel threads/jobs to be used by builder.
*
* @param jobs - maximum number of jobs or threads. For details how
* the number is interpreted see {@link Builder#setParallelizationNum(int)}.
*/
public void setParallelNumber(int n){
public void setParallelNumber(int jobs){
try {
getEditableBuilder().setParallelizationNum(n);
getEditableBuilder().setParallelizationNum(jobs);
} catch (CoreException e) {
ManagedBuilderCorePlugin.log(e);
}
}
/**
* returns number of Parallel threads
* Returns maximum number of parallel threads/jobs used by the configuration's builder.
* @see #setParallelDef(boolean)
*
* @return int
* @return - maximum number of parallel threads or jobs used by the builder.
*/
public int getParallelNumber(){
return getBuilder().getParallelizationNum();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2010 IBM Corporation and others.
* Copyright (c) 2002, 2011 IBM Corporation 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
@ -906,244 +906,242 @@ public class GeneratedMakefileBuilder extends ACBuilder {
}
IPath makeCommand = new Path(makeCmd);
if (makeCommand != null) {
String[] msgs = new String[2];
msgs[0] = makeCommand.toString();
msgs[1] = currentProject.getName();
monitor.subTask(ManagedMakeMessages.getFormattedString(MAKE, msgs));
String[] msgs = new String[2];
msgs[0] = makeCommand.toString();
msgs[1] = currentProject.getName();
monitor.subTask(ManagedMakeMessages.getFormattedString(MAKE, msgs));
// Get a build console for the project
StringBuffer buf = new StringBuffer();
IConsole console = CCorePlugin.getDefault().getConsole();
console.start(currentProject);
ConsoleOutputStream consoleOutStream = console.getOutputStream();
String[] consoleHeader = new String[3];
// Get a build console for the project
StringBuffer buf = new StringBuffer();
IConsole console = CCorePlugin.getDefault().getConsole();
console.start(currentProject);
ConsoleOutputStream consoleOutStream = console.getOutputStream();
String[] consoleHeader = new String[3];
switch (buildType) {
case FULL_BUILD:
case INCREMENTAL_BUILD:
consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC);
break;
case CLEAN_BUILD:
consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN);
break;
}
consoleHeader[1] = info.getConfigurationName();
consoleHeader[2] = currentProject.getName();
buf.append(NEWLINE);
buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)).append(NEWLINE);
buf.append(NEWLINE);
IConfiguration cfg = info.getDefaultConfiguration();
if(!cfg.isSupported()){
String msg = ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION,new String[] {cfg.getName(),cfg.getToolChain().getName()});
buf.append(msg).append(NEWLINE);
buf.append(NEWLINE);
}
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
// Remove all markers for this project
removeAllMarkers(currentProject);
// Get a launcher for the make command
String errMsg = null;
IBuilder builder = info.getDefaultConfiguration().getBuilder();
ICommandLauncher launcher = builder.getCommandLauncher();
launcher.setProject(currentProject);
launcher.showCommand(true);
// Set the environmennt
IBuildEnvironmentVariable variables[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true,true);
String[] env = null;
ArrayList<String> envList = new ArrayList<String>();
if (variables != null) {
for(int i = 0; i < variables.length; i++){
envList.add(variables[i].getName() + "=" + variables[i].getValue()); //$NON-NLS-1$
}
env = envList.toArray(new String[envList.size()]);
}
// Hook up an error parser manager
String[] errorParsers = info.getDefaultConfiguration().getErrorParserList();
ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectoryURI, this, errorParsers);
epm.setOutputStream(consoleOutStream);
// This variable is necessary to ensure that the EPM stream stay open
// until we explicitly close it. See bug#123302.
OutputStream epmOutputStream = epm.getOutputStream();
// Get the arguments to be passed to make from build model
ArrayList<String> makeArgs = new ArrayList<String>();
String arg = info.getBuildArguments();
if (arg.length() > 0) {
String[] args = arg.split("\\s"); //$NON-NLS-1$
for (int i = 0; i < args.length; ++i) {
makeArgs.add(args[i]);
}
}
String[] makeTargets;
String prebuildStep = info.getPrebuildStep();
//try to resolve the build macros in the prebuildStep
try{
prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(
prebuildStep,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_CONFIGURATION,
cfg);
} catch (BuildMacroException e){
}
boolean prebuildStepPresent = (prebuildStep.length() > 0);
Process proc = null;
boolean isuptodate = false;
if (prebuildStepPresent) {
@SuppressWarnings("unchecked")
ArrayList<String> premakeArgs = (ArrayList<String>) makeArgs.clone();
String[] premakeTargets;
switch (buildType) {
case FULL_BUILD:
case INCREMENTAL_BUILD:
consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC);
break;
case CLEAN_BUILD:
consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN);
break;
}
consoleHeader[1] = info.getConfigurationName();
consoleHeader[2] = currentProject.getName();
buf.append(NEWLINE);
buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)).append(NEWLINE);
buf.append(NEWLINE);
IConfiguration cfg = info.getDefaultConfiguration();
if(!cfg.isSupported()){
String msg = ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION,new String[] {cfg.getName(),cfg.getToolChain().getName()});
buf.append(msg).append(NEWLINE);
buf.append(NEWLINE);
}
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
// Remove all markers for this project
removeAllMarkers(currentProject);
// Get a launcher for the make command
String errMsg = null;
IBuilder builder = info.getDefaultConfiguration().getBuilder();
ICommandLauncher launcher = builder.getCommandLauncher();
launcher.setProject(currentProject);
launcher.showCommand(true);
// Set the environmennt
IBuildEnvironmentVariable variables[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true,true);
String[] env = null;
ArrayList<String> envList = new ArrayList<String>();
if (variables != null) {
for(int i = 0; i < variables.length; i++){
envList.add(variables[i].getName() + "=" + variables[i].getValue()); //$NON-NLS-1$
}
env = envList.toArray(new String[envList.size()]);
}
// Hook up an error parser manager
String[] errorParsers = info.getDefaultConfiguration().getErrorParserList();
ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectoryURI, this, errorParsers);
epm.setOutputStream(consoleOutStream);
// This variable is necessary to ensure that the EPM stream stay open
// until we explicitly close it. See bug#123302.
OutputStream epmOutputStream = epm.getOutputStream();
// Get the arguments to be passed to make from build model
ArrayList<String> makeArgs = new ArrayList<String>();
String arg = info.getBuildArguments();
if (arg.length() > 0) {
String[] args = arg.split("\\s"); //$NON-NLS-1$
for (int i = 0; i < args.length; ++i) {
makeArgs.add(args[i]);
}
}
String[] makeTargets;
String prebuildStep = info.getPrebuildStep();
//try to resolve the build macros in the prebuildStep
try{
prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(
prebuildStep,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_CONFIGURATION,
cfg);
} catch (BuildMacroException e){
}
boolean prebuildStepPresent = (prebuildStep.length() > 0);
Process proc = null;
boolean isuptodate = false;
if (prebuildStepPresent) {
@SuppressWarnings("unchecked")
ArrayList<String> premakeArgs = (ArrayList<String>) makeArgs.clone();
String[] premakeTargets;
switch (buildType) {
case INCREMENTAL_BUILD: {
// For an incremental build with a prebuild step:
// Check the status of the main build with "make -q main-build"
// If up to date:
// then: don't invoke the prebuild step, which should be run only if
// something needs to be built in the main build
// else: invoke the prebuild step and the main build step
premakeArgs.add("-q"); //$NON-NLS-1$
premakeArgs.add("main-build"); //$NON-NLS-1$
premakeTargets = premakeArgs.toArray(new String[premakeArgs.size()]);
proc = launcher.execute(makeCommand, premakeTargets, env, workingDirectory, monitor);
if (proc != null) {
try {
// Close the input of the process since we will never write to it
proc.getOutputStream().close();
} catch (IOException e) {
}
if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(),
new SubProgressMonitor(monitor,
IProgressMonitor.UNKNOWN)) != ICommandLauncher.OK) {
errMsg = launcher.getErrorMessage();
}
} else {
errMsg = launcher.getErrorMessage();
}
if ((errMsg != null && errMsg.length() > 0) || proc == null) {
// Can't tell if the build is needed, so assume it is, and let any errors be triggered
// when the "real" build is invoked below
makeArgs.add("pre-build"); //$NON-NLS-1$
makeArgs.add("main-build"); //$NON-NLS-1$
} else {
// The "make -q" command launch was successful
if (proc.exitValue() == 0) {
// If the status value returned from "make -q" is 0, then the build state is up-to-date
isuptodate = true;
// Report that the build was up to date, and thus nothing needs to be built
String uptodateMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, currentProject.getName());
buf = new StringBuffer();
buf.append(NEWLINE);
buf.append(uptodateMsg).append(NEWLINE);
// Write message on the console
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
epmOutputStream.close();
consoleOutStream.close();
} else {
// The status value was other than 0, so press on with the build process
makeArgs.add("pre-build"); //$NON-NLS-1$
makeArgs.add("main-build"); //$NON-NLS-1$
}
}
break;
}
case FULL_BUILD: {
// makeArgs.add("clean"); //$NON-NLS-1$
makeArgs.add("pre-build"); //$NON-NLS-1$
makeArgs.add("main-build"); //$NON-NLS-1$
break;
}
case CLEAN_BUILD: {
makeArgs.add("clean"); //$NON-NLS-1$
break;
}
}
} else {
// No prebuild step
//
makeArgs.addAll(Arrays.asList(getMakeTargets(buildType)));
}
makeTargets = makeArgs.toArray(new String[makeArgs.size()]);
// Launch make - main invocation
if (!isuptodate) {
proc = launcher.execute(makeCommand, makeTargets, env, workingDirectory, monitor);
case INCREMENTAL_BUILD: {
// For an incremental build with a prebuild step:
// Check the status of the main build with "make -q main-build"
// If up to date:
// then: don't invoke the prebuild step, which should be run only if
// something needs to be built in the main build
// else: invoke the prebuild step and the main build step
premakeArgs.add("-q"); //$NON-NLS-1$
premakeArgs.add("main-build"); //$NON-NLS-1$
premakeTargets = premakeArgs.toArray(new String[premakeArgs.size()]);
proc = launcher.execute(makeCommand, premakeTargets, env, workingDirectory, monitor);
if (proc != null) {
try {
// Close the input of the process since we will never write to it
proc.getOutputStream().close();
} catch (IOException e) {
}
int state = launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(),
if (launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(),
new SubProgressMonitor(monitor,
IProgressMonitor.UNKNOWN));
if(state != ICommandLauncher.OK){
IProgressMonitor.UNKNOWN)) != ICommandLauncher.OK) {
errMsg = launcher.getErrorMessage();
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
info.getDefaultConfiguration().setRebuildState(true);
}
}
// Force a resync of the projects without allowing the user to cancel.
// This is probably unkind, but short of this there is no way to insure
// the UI is up-to-date with the build results
monitor.subTask(ManagedMakeMessages
.getResourceString(REFRESH));
try {
//currentProject.refreshLocal(IResource.DEPTH_INFINITE, null);
// use the refresh scope manager to refresh
RefreshScopeManager refreshManager = RefreshScopeManager.getInstance();
IWorkspaceRunnable runnable = refreshManager.getRefreshRunnable(currentProject);
ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, null);
} catch (CoreException e) {
monitor.subTask(ManagedMakeMessages
.getResourceString(REFRESH_ERROR));
}
} else {
errMsg = launcher.getErrorMessage();
}
// Report either the success or failure of our mission
buf = new StringBuffer();
if (errMsg != null && errMsg.length() > 0) {
String errorDesc = ManagedMakeMessages.getResourceString(BUILD_ERROR);
buf.append(errorDesc).append(NEWLINE);
buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
if ((errMsg != null && errMsg.length() > 0) || proc == null) {
// Can't tell if the build is needed, so assume it is, and let any errors be triggered
// when the "real" build is invoked below
makeArgs.add("pre-build"); //$NON-NLS-1$
makeArgs.add("main-build"); //$NON-NLS-1$
} else {
// Report a successful build
String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED,
currentProject.getName());
buf.append(successMsg).append(NEWLINE);
// The "make -q" command launch was successful
if (proc.exitValue() == 0) {
// If the status value returned from "make -q" is 0, then the build state is up-to-date
isuptodate = true;
// Report that the build was up to date, and thus nothing needs to be built
String uptodateMsg = ManagedMakeMessages.getFormattedString(NOTHING_BUILT, currentProject.getName());
buf = new StringBuffer();
buf.append(NEWLINE);
buf.append(uptodateMsg).append(NEWLINE);
// Write message on the console
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
epmOutputStream.close();
consoleOutStream.close();
} else {
// The status value was other than 0, so press on with the build process
makeArgs.add("pre-build"); //$NON-NLS-1$
makeArgs.add("main-build"); //$NON-NLS-1$
}
}
break;
}
case FULL_BUILD: {
// makeArgs.add("clean"); //$NON-NLS-1$
makeArgs.add("pre-build"); //$NON-NLS-1$
makeArgs.add("main-build"); //$NON-NLS-1$
break;
}
case CLEAN_BUILD: {
makeArgs.add("clean"); //$NON-NLS-1$
break;
}
}
} else {
// No prebuild step
//
makeArgs.addAll(Arrays.asList(getMakeTargets(buildType)));
}
makeTargets = makeArgs.toArray(new String[makeArgs.size()]);
// Launch make - main invocation
if (!isuptodate) {
proc = launcher.execute(makeCommand, makeTargets, env, workingDirectory, monitor);
if (proc != null) {
try {
// Close the input of the process since we will never write to it
proc.getOutputStream().close();
} catch (IOException e) {
}
// Write message on the console
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
epmOutputStream.close();
int state = launcher.waitAndRead(epm.getOutputStream(), epm.getOutputStream(),
new SubProgressMonitor(monitor,
IProgressMonitor.UNKNOWN));
if(state != ICommandLauncher.OK){
errMsg = launcher.getErrorMessage();
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
info.getDefaultConfiguration().setRebuildState(true);
}
}
// Generate any error markers that the build has discovered
monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS));
addBuilderMarkers(epm);
consoleOutStream.close();
// Force a resync of the projects without allowing the user to cancel.
// This is probably unkind, but short of this there is no way to insure
// the UI is up-to-date with the build results
monitor.subTask(ManagedMakeMessages
.getResourceString(REFRESH));
try {
//currentProject.refreshLocal(IResource.DEPTH_INFINITE, null);
// use the refresh scope manager to refresh
RefreshScopeManager refreshManager = RefreshScopeManager.getInstance();
IWorkspaceRunnable runnable = refreshManager.getRefreshRunnable(currentProject);
ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, null);
} catch (CoreException e) {
monitor.subTask(ManagedMakeMessages
.getResourceString(REFRESH_ERROR));
}
} else {
errMsg = launcher.getErrorMessage();
}
// Report either the success or failure of our mission
buf = new StringBuffer();
if (errMsg != null && errMsg.length() > 0) {
String errorDesc = ManagedMakeMessages.getResourceString(BUILD_ERROR);
buf.append(errorDesc).append(NEWLINE);
buf.append("(").append(errMsg).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
// Report a successful build
String successMsg = ManagedMakeMessages.getFormattedString(BUILD_FINISHED,
currentProject.getName());
buf.append(successMsg).append(NEWLINE);
}
// Write message on the console
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
epmOutputStream.close();
// Generate any error markers that the build has discovered
monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS));
addBuilderMarkers(epm);
consoleOutStream.close();
}
} catch (Exception e) {
forgetLastBuiltState();
@ -1196,7 +1194,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
boolean resumeOnErr,
IProgressMonitor monitor) {
boolean isParallel = ((Configuration)cfg).getInternalBuilderParallel();
boolean isParallel = ((Configuration)cfg).getParallelDef();
// Get the project and make sure there's a monitor to cancel the build
IProject currentProject = cfg.getOwner().getProject();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Intel Corporation and others.
* Copyright (c) 2007, 2011 Intel Corporation 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
@ -44,6 +44,7 @@ import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSu
import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.osgi.framework.Version;
@ -253,15 +254,23 @@ public class MultiConfiguration extends MultiItemsHolder implements
return s;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IConfiguration#getBuildArguments()
/**
* @return build arguments if the arguments for all configurations match
* or {@code null} otherwise.
*/
public String getBuildArguments() {
String s = fCfgs[0].getBuildArguments();
for (int i=1; i<fCfgs.length; i++)
if (! s.equals(fCfgs[i].getBuildArguments()))
return EMPTY_STR;
return s;
String args0 = fCfgs[0].getBuildArguments();
if (args0 == null)
args0 = EMPTY_STR;
for (IConfiguration cfg : fCfgs) {
String args = cfg.getBuildArguments();
if (args == null)
args = EMPTY_STR;
if (!args0.equals(args))
return null;
}
return args0;
}
/* (non-Javadoc)
@ -1090,49 +1099,49 @@ public class MultiConfiguration extends MultiItemsHolder implements
}
public boolean getParallelDef() {
for (int i=0; i<fCfgs.length; i++)
if (fCfgs[i] instanceof Configuration) {
if (!((Configuration)fCfgs[i]).getParallelDef())
for (IConfiguration cfg : fCfgs) {
if (cfg instanceof Configuration) {
if (!((Configuration)cfg).getParallelDef())
return false;
} else
return false;
}
return true; // all cfgs report true
}
public void setParallelDef(boolean def) {
for (int i=0; i<fCfgs.length; i++)
if (fCfgs[i] instanceof Configuration)
((Configuration)fCfgs[i]).setParallelDef(def);
public void setParallelDef(boolean parallel) {
for (IConfiguration cfg : fCfgs) {
if (cfg instanceof Configuration)
((Configuration)cfg).setParallelDef(parallel);
}
}
public int getParallelNumber() {
int res = -1;
for (int i=0; i<fCfgs.length; i++)
if (fCfgs[i] instanceof Configuration) {
int x = ((Configuration)fCfgs[i]).getParallelNumber();
if (res == -1)
res = x;
else if (res != x)
int res = 0;
for (IConfiguration cfg : fCfgs) {
if (cfg instanceof Configuration) {
int num = ((Configuration)cfg).getParallelNumber();
Assert.isTrue(num != 0); // can't be 0, see IMakeCommonBuildInfo.getParallelizationNum()
if (res == 0)
res = num;
else if (res != num)
return 0; // values are different !
} else
return 0;
return (res == -1 ? 0: res); // all cfgs report true
}
return res; // all cfgs report same value
}
public void setParallelNumber(int num) {
for (int i=0; i<fCfgs.length; i++)
if (fCfgs[i] instanceof Configuration)
((Configuration)fCfgs[i]).setParallelNumber(num);
for (IConfiguration cfg : fCfgs) {
if (cfg instanceof Configuration)
((Configuration)cfg).setParallelNumber(num);
}
}
public boolean getInternalBuilderParallel() {
for (int i=0; i<fCfgs.length; i++)
if (fCfgs[i] instanceof Configuration) {
if (!((Configuration)fCfgs[i]).getInternalBuilderParallel())
return false;
} else
return false;
return true; // all cfgs report true
return getParallelDef();
}
public boolean isInternalBuilderEnabled() {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 QNX Software Systems and others.
* Copyright (c) 2004, 2011 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -12,6 +12,7 @@ package org.eclipse.cdt.newmake.core;
import java.util.Map;
import org.eclipse.cdt.managedbuilder.internal.core.Builder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@ -42,10 +43,39 @@ public interface IMakeCommonBuildInfo {
void setStopOnError(boolean on) throws CoreException;
boolean supportsStopOnError(boolean on);
/**
* @return the maximum number of parallel jobs to be used for build.
*/
int getParallelizationNum();
void setParallelizationNum(int num) throws CoreException;
/**
* Sets maximum number of parallel threads/jobs to be used by builder.
* Note that this number can be interpreted by builder in a special way.
* @see Builder#setParallelizationNum(int)
*
* @param jobs - maximum number of jobs.
*/
void setParallelizationNum(int jobs) throws CoreException;
/**
* @return {@code true} if builder supports parallel build,
* {@code false} otherwise.
*/
boolean supportsParallelBuild();
/**
* @return {@code true} if builder support for parallel build is enabled,
* {@code false} otherwise.
*/
boolean isParallelBuildOn();
/**
* Set parallel execution mode for the builder.
* @see Builder#setParallelBuildOn(boolean)
*
* @param on - the flag to enable or disable parallel mode.
*/
void setParallelBuildOn(boolean on) throws CoreException;
boolean isDefaultBuildCmd();

View file

@ -27,9 +27,10 @@ public class Messages extends NLS {
public static String BuilderSettingsTab_0;
public static String BuilderSettingsTab_1;
public static String BuilderSettingsTab_10;
public static String BuilderSettingsTab_11;
public static String BuilderSettingsTab_12;
public static String BuilderSettingsTab_13;
public static String BuilderSettingsTab_EnableParallelBuild;
public static String BuilderSettingsTab_UseOptimalJobs;
public static String BuilderSettingsTab_UseUnlimitedJobs;
public static String BuilderSettingsTab_UseParallelJobs;
public static String BuilderSettingsTab_14;
public static String BuilderSettingsTab_15;
public static String BuilderSettingsTab_16;

View file

@ -31,9 +31,10 @@ BuilderSettingsTab_7=&Generate Makefiles automatically
BuilderSettingsTab_8=&Expand Env. Variable Refs in Makefiles
BuilderSettingsTab_9=Build settings
BuilderSettingsTab_10=Stop on first build error
BuilderSettingsTab_11=Use parallel build
BuilderSettingsTab_12=Use optimal jobs number
BuilderSettingsTab_13=Use parallel jobs:
BuilderSettingsTab_EnableParallelBuild=Enable parallel build
BuilderSettingsTab_UseOptimalJobs=Use number of processors ({0})
BuilderSettingsTab_UseParallelJobs=Use parallel jobs:
BuilderSettingsTab_UseUnlimitedJobs=Use unlimited jobs
BuilderSettingsTab_14=Workbench Build Behavior
BuilderSettingsTab_15=Workbench build type:
BuilderSettingsTab_16=Make build target:

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Intel Corporation and others.
* Copyright (c) 2007, 2011 Intel Corporation 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
@ -11,6 +11,8 @@
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.ui.properties;
import java.text.MessageFormat;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICMultiConfigDescription;
import org.eclipse.cdt.core.settings.model.ICMultiItemsHolder;
@ -18,7 +20,6 @@ import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.cdt.managedbuilder.core.IBuilder;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IMultiConfiguration;
import org.eclipse.cdt.managedbuilder.internal.buildmodel.BuildProcessManager;
import org.eclipse.cdt.managedbuilder.internal.core.Builder;
import org.eclipse.cdt.managedbuilder.internal.core.Configuration;
import org.eclipse.cdt.managedbuilder.internal.core.MultiConfiguration;
@ -51,6 +52,8 @@ import org.eclipse.swt.widgets.Widget;
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
private static final int SPINNER_MAX_VALUE = 10000;
private static final int SPINNER_MIN_VALUE = 2;
private static final int TRI_STATES_SIZE = 4;
// Widgets
@ -58,9 +61,10 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
private Button b_stopOnError; // 3
private Button b_parallel; // 3
private Button b_parallelOpt;
private Button b_parallelNum;
private Spinner parallelProcesses;
private Button b_parallelOptimal;
private Button b_parallelSpecific;
private Button b_parallelUnlimited;
private Spinner s_parallelNumber;
private Label title2;
private Button b_autoBuild; //3
@ -70,11 +74,11 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
private Button b_cmdClean; // 3
private Text t_cmdClean;
private IBuilder bldr;
private Builder bldr;
private IConfiguration icfg;
private boolean canModify = true;
protected final int cpuNumber = BuildProcessManager.checkCPUNumber();
protected final int cpuNumber = Runtime.getRuntime().availableProcessors();
@Override
public void createControls(Composite parent) {
@ -110,7 +114,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
gl.marginHeight = 0;
c2.setLayout(gl);
b_parallel = setupCheck(c2, Messages.BuilderSettingsTab_11, 1, GridData.BEGINNING);
b_parallel = setupCheck(c2, Messages.BuilderSettingsTab_EnableParallelBuild, 1, GridData.BEGINNING);
Composite c3 = new Composite(g3, SWT.NONE);
setupControl(c3, 1, GridData.FILL_BOTH);
@ -120,39 +124,60 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
gl.marginHeight = 0;
c3.setLayout(gl);
b_parallelOpt= new Button(c3, SWT.RADIO);
b_parallelOpt.setText(Messages.BuilderSettingsTab_12);
setupControl(b_parallelOpt, 2, GridData.BEGINNING);
((GridData)(b_parallelOpt.getLayoutData())).horizontalIndent = 15;
b_parallelOpt.addSelectionListener(new SelectionAdapter() {
b_parallelOptimal= new Button(c3, SWT.RADIO);
b_parallelOptimal.setText(MessageFormat.format(Messages.BuilderSettingsTab_UseOptimalJobs, 1));
setupControl(b_parallelOptimal, 2, GridData.BEGINNING);
((GridData)(b_parallelOptimal.getLayoutData())).horizontalIndent = 15;
b_parallelOptimal.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
setParallelDef(b_parallelOpt.getSelection());
updateButtons();
if (b_parallelOptimal.getSelection()) {
setParallelDef(true);
setParallelNumber(-1);
updateButtons();
}
}});
b_parallelNum= new Button(c3, SWT.RADIO);
b_parallelNum.setText(Messages.BuilderSettingsTab_13);
setupControl(b_parallelNum, 1, GridData.BEGINNING);
((GridData)(b_parallelNum.getLayoutData())).horizontalIndent = 15;
b_parallelNum.addSelectionListener(new SelectionAdapter() {
b_parallelSpecific= new Button(c3, SWT.RADIO);
b_parallelSpecific.setText(Messages.BuilderSettingsTab_UseParallelJobs);
setupControl(b_parallelSpecific, 1, GridData.BEGINNING);
((GridData)(b_parallelSpecific.getLayoutData())).horizontalIndent = 15;
b_parallelSpecific.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
setParallelDef(!b_parallelNum.getSelection());
updateButtons();
if (b_parallelSpecific.getSelection()) {
setParallelDef(true);
setParallelNumber(s_parallelNumber.getSelection());
updateButtons();
}
}});
parallelProcesses = new Spinner(c3, SWT.BORDER);
setupControl(parallelProcesses, 1, GridData.BEGINNING);
parallelProcesses.setValues(cpuNumber, 1, 10000, 0, 1, 10);
parallelProcesses.addSelectionListener(new SelectionAdapter () {
s_parallelNumber = new Spinner(c3, SWT.BORDER);
setupControl(s_parallelNumber, 1, GridData.BEGINNING);
s_parallelNumber.setValues(cpuNumber, SPINNER_MIN_VALUE, SPINNER_MAX_VALUE, 0, 1, 10);
s_parallelNumber.addSelectionListener(new SelectionAdapter () {
@Override
public void widgetSelected(SelectionEvent e) {
setParallelNumber(parallelProcesses.getSelection());
setParallelDef(true);
setParallelNumber(s_parallelNumber.getSelection());
updateButtons();
}
});
b_parallelUnlimited= new Button(c3, SWT.RADIO);
b_parallelUnlimited.setText(Messages.BuilderSettingsTab_UseUnlimitedJobs);
setupControl(b_parallelUnlimited, 2, GridData.BEGINNING);
((GridData)(b_parallelUnlimited.getLayoutData())).horizontalIndent = 15;
b_parallelUnlimited.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
if (b_parallelUnlimited.getSelection()) {
setParallelDef(true);
setParallelNumber(Builder.UNLIMITED_JOBS);
updateButtons();
}
}});
// Workbench behaviour group
AccessibleListener makeTargetLabelAccessibleListener = new AccessibleAdapter() {
@Override
@ -191,6 +216,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
}
/**
* Calculate enablements when multiple configurations selected on property page.
*
* @return:
* Mode 0:
@ -202,56 +228,52 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
* 0: isStopOnError
* 1: supportsStopOnError(true)
* 2: bld.supportsStopOnError(false)
* 3: cfg.getInternalBuilderParallel()
* 3: N/A
* Mode 2:
* 0: b.isAutoBuildEnable()
* 1: b.isIncrementalBuildEnabled()
* 2: b.isCleanBuildEnabled()
* 3: getParallelDef()
* 3: N/A
*/
static int[] calc3states(ICPropertyProvider p,
IConfiguration c,
int mode) {
if (p.isMultiCfg() &&
c instanceof ICMultiItemsHolder)
{
boolean p0 = (mode == 0);
boolean p1 = (mode == 1);
static int[] calc3states(ICPropertyProvider p, IConfiguration mcfg, int mode) {
if (p.isMultiCfg() && mcfg instanceof ICMultiItemsHolder) {
boolean m0 = (mode == 0);
boolean m1 = (mode == 1);
IConfiguration[] cfs = (IConfiguration[])((ICMultiItemsHolder)c).getItems();
IBuilder b = cfs[0].getBuilder();
int[] res = new int[TRI_STATES_SIZE];
boolean[] x = new boolean[TRI_STATES_SIZE];
x[0] = p0 ? b.isManagedBuildOn() :
(p1 ? b.isStopOnError() : b.isAutoBuildEnable());
x[1] = p0 ? b.isDefaultBuildCmd():
(p1 ? b.supportsStopOnError(true) : b.isIncrementalBuildEnabled() );
x[2] = p0 ? b.canKeepEnvironmentVariablesInBuildfile() :
(p1 ? b.supportsStopOnError(false) : b.isCleanBuildEnabled());
x[3] = p0 ? b.keepEnvironmentVariablesInBuildfile() :
( p1 ? ((Configuration)cfs[0]).getInternalBuilderParallel() : getParallelDef(c));
for (int i=1; i<cfs.length; i++) {
b = cfs[i].getBuilder();
if (x[0] != (p0 ? b.isManagedBuildOn() :
(p1 ? b.isStopOnError() : b.isAutoBuildEnable())))
IConfiguration[] cfgs = (IConfiguration[])((ICMultiItemsHolder)mcfg).getItems();
IBuilder bldr0 = cfgs[0].getBuilder();
int[] res = new int[TRI_STATES_SIZE];
boolean[] b = new boolean[TRI_STATES_SIZE];
b[0] = m0 ? bldr0.isManagedBuildOn() :
(m1 ? bldr0.isStopOnError() : bldr0.isAutoBuildEnable());
b[1] = m0 ? bldr0.isDefaultBuildCmd():
(m1 ? bldr0.supportsStopOnError(true) : bldr0.isIncrementalBuildEnabled() );
b[2] = m0 ? bldr0.canKeepEnvironmentVariablesInBuildfile() :
(m1 ? bldr0.supportsStopOnError(false) : bldr0.isCleanBuildEnabled());
b[3] = m0 ? bldr0.keepEnvironmentVariablesInBuildfile() : false;
for (int i=1; i<cfgs.length; i++) {
IBuilder bldr = cfgs[i].getBuilder();
if (b[0] != (m0 ? bldr.isManagedBuildOn() :
(m1 ? bldr.isStopOnError() : bldr.isAutoBuildEnable())))
res[0] = TRI_UNKNOWN;
if (x[1] != (p0 ? b.isDefaultBuildCmd() :
(p1 ? b.supportsStopOnError(true) : b.isIncrementalBuildEnabled())))
if (b[1] != (m0 ? bldr.isDefaultBuildCmd() :
(m1 ? bldr.supportsStopOnError(true) : bldr.isIncrementalBuildEnabled())))
res[1] = TRI_UNKNOWN;
if (x[2] != (p0 ? b.canKeepEnvironmentVariablesInBuildfile() :
(p1 ? b.supportsStopOnError(false) : b.isCleanBuildEnabled())))
if (b[2] != (m0 ? bldr.canKeepEnvironmentVariablesInBuildfile() :
(m1 ? bldr.supportsStopOnError(false) : bldr.isCleanBuildEnabled())))
res[2] = TRI_UNKNOWN;
if (x[3] != (p0 ? b.keepEnvironmentVariablesInBuildfile() :
(p1 ? ((Configuration)cfs[i]).getInternalBuilderParallel() : getParallelDef(c))))
if (b[3] != (m0 ? bldr.keepEnvironmentVariablesInBuildfile() : false)) {
res[3] = TRI_UNKNOWN;
}
}
for (int i=0; i<TRI_STATES_SIZE; i++) {
if (res[i] != TRI_UNKNOWN)
res[i] = x[i] ? TRI_YES : TRI_NO;
res[i] = b[i] ? TRI_YES : TRI_NO;
}
return res;
} else
return null;
}
return null;
}
/**
@ -259,10 +281,11 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
*/
@Override
protected void updateButtons() {
bldr = icfg.getEditableBuilder();
bldr = (Builder) icfg.getEditableBuilder();
canModify = false;
int[] extStates = calc3states(page, icfg, 1);
// Stop on error
if (extStates != null) {
setTriSelection(b_stopOnError, extStates[0]);
b_stopOnError.setEnabled(
@ -273,42 +296,24 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
b_stopOnError.setEnabled(
bldr.supportsStopOnError(true) &&
bldr.supportsStopOnError(false));
}
// parallel
if (extStates == null) // no extended states
setTriSelection(b_parallel, getInternalBuilderParallel());
else
setTriSelection(b_parallel, extStates[3]);
}
updateParallelBlock();
int n = getParallelNumber();
if (n < 0) n = -n;
parallelProcesses.setSelection(n);
b_parallel.setVisible(bldr.supportsParallelBuild());
b_parallelOpt.setVisible(bldr.supportsParallelBuild());
b_parallelNum.setVisible(bldr.supportsParallelBuild());
parallelProcesses.setVisible(bldr.supportsParallelBuild());
// Build commands
extStates = calc3states(page, icfg, 2);
if (extStates == null) {
setTriSelection(b_autoBuild, bldr.isAutoBuildEnable());
setTriSelection(b_cmdBuild, bldr.isIncrementalBuildEnabled());
setTriSelection(b_cmdClean, bldr.isCleanBuildEnabled());
b_parallelOpt.setSelection(getParallelDef(icfg));
b_parallelNum.setSelection(!getParallelDef(icfg));
} else {
if (extStates != null) {
// multiple configurations selected
setTriSelection(b_autoBuild, extStates[0]);
setTriSelection(b_cmdBuild, extStates[1]);
setTriSelection(b_cmdClean, extStates[2]);
if (extStates[3] == TRI_UNKNOWN) {
b_parallelOpt.setSelection(false);
b_parallelNum.setSelection(false);
} else {
b_parallelOpt.setSelection(getParallelDef(icfg));
b_parallelNum.setSelection(!getParallelDef(icfg));
}
} else {
setTriSelection(b_autoBuild, bldr.isAutoBuildEnable());
setTriSelection(b_cmdBuild, bldr.isIncrementalBuildEnabled());
setTriSelection(b_cmdClean, bldr.isCleanBuildEnabled());
}
if (page.isMultiCfg()) {
MultiConfiguration mc = (MultiConfiguration)icfg;
t_autoBuild.setText(mc.getBuildAttribute(IBuilder.BUILD_TARGET_AUTO, EMPTY_STR));
@ -320,13 +325,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
t_cmdClean.setText(bldr.getBuildAttribute(IBuilder.BUILD_TARGET_CLEAN, EMPTY_STR));
}
boolean external = ! isInternalBuilderEnabled();
boolean parallel = b_parallel.getSelection();
b_parallelNum.setEnabled(parallel);
b_parallelOpt.setEnabled(parallel);
parallelProcesses.setEnabled(parallel & b_parallelNum.getSelection());
boolean external = ! isInternalBuilderEnabled();
title2.setVisible(external);
t_autoBuild.setVisible(external);
((Control)t_autoBuild.getData()).setVisible(external);
@ -334,7 +333,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
((Control)t_cmdBuild.getData()).setVisible(external);
t_cmdClean.setVisible(external);
((Control)t_cmdClean.getData()).setVisible(external);
if (external) {
checkPressed(b_autoBuild, false);
checkPressed(b_cmdBuild, false);
@ -343,6 +342,79 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
canModify = true;
}
private void updateParallelBlock() {
// note: for multi-config selection bldr is from Active cfg
boolean isParallelSupported = bldr.supportsParallelBuild();
boolean isParallelOn = bldr.isParallelBuildOn();
int triSelection = isParallelOn ? TRI_YES : TRI_NO;
int parallelizationNumInternal = bldr.getParallelizationNumAttribute();
int optimalParallelNumber = bldr.getOptimalParallelJobNum();
int parallelNumber = bldr.getParallelizationNum();
if (icfg instanceof ICMultiItemsHolder) {
IConfiguration[] cfgs = (IConfiguration[])((ICMultiItemsHolder)icfg).getItems();
boolean isAnyParallelOn = isParallelOn;
boolean isAnyParallelSupported = isParallelSupported;
boolean isParallelDiffers = false;
for (IConfiguration cfg : cfgs) {
Builder builder = (Builder) cfg.getBuilder();
isParallelDiffers = isParallelDiffers
|| builder.isParallelBuildOn() != isParallelOn
|| builder.getParallelizationNumAttribute() != parallelizationNumInternal;
isAnyParallelOn = isAnyParallelOn || builder.isParallelBuildOn();
isAnyParallelSupported = isAnyParallelSupported || builder.supportsParallelBuild();
}
// reset initial display to "optimal" to enhance user experience:
if ((!isParallelSupported && isAnyParallelSupported) // parallel is supported by other than Active cfg
|| (!isParallelOn && isAnyParallelOn) // prevent showing the 1 job as parallel in the spinner
) {
isParallelSupported = true;
parallelizationNumInternal = -optimalParallelNumber;
parallelNumber = optimalParallelNumber;
}
if (isParallelSupported && isParallelDiffers) {
triSelection = TRI_UNKNOWN;
}
}
b_parallel.setVisible(isParallelSupported);
b_parallelOptimal.setVisible(isParallelSupported);
b_parallelSpecific.setVisible(isParallelSupported);
b_parallelUnlimited.setVisible(isParallelSupported);
s_parallelNumber.setVisible(isParallelSupported);
if (isParallelSupported) {
setTriSelection(b_parallel, triSelection);
boolean isParallelSelected = b_parallel.getSelection();
b_parallelOptimal.setText(MessageFormat.format(Messages.BuilderSettingsTab_UseOptimalJobs, optimalParallelNumber));
b_parallelOptimal.setEnabled(isParallelSelected);
b_parallelSpecific.setEnabled(isParallelSelected);
b_parallelUnlimited.setEnabled(isParallelSelected);
if (isParallelSelected) {
boolean isOptimal = parallelizationNumInternal <= 0;
boolean isUnlimited = parallelizationNumInternal == Builder.UNLIMITED_JOBS;
b_parallelOptimal.setSelection(isOptimal);
b_parallelSpecific.setSelection(!isOptimal && !isUnlimited);
b_parallelUnlimited.setSelection(isUnlimited);
s_parallelNumber.setEnabled(b_parallelSpecific.getEnabled() && b_parallelSpecific.getSelection());
s_parallelNumber.setSelection(s_parallelNumber.isEnabled() ? parallelNumber : optimalParallelNumber);
} else {
b_parallelOptimal.setSelection(true);
b_parallelSpecific.setSelection(false);
b_parallelUnlimited.setSelection(false);
s_parallelNumber.setEnabled(false);
s_parallelNumber.setSelection(optimalParallelNumber);
}
}
}
/**
* Sets up text + corresponding button
* Checkbox can be implemented either by Button or by TriButton
@ -446,7 +518,7 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
}
b2.setStopOnError(b1.isStopOnError());
b2.setParallelBuildOn(b1.isParallelBuildOn());
b2.setParallelizationNum(b1.getParallelizationNum());
b2.setParallelizationNum(((Builder) b1).getParallelizationNumAttribute());
if (b2.canKeepEnvironmentVariablesInBuildfile())
b2.setKeepEnvironmentVariablesInBuildfile(b1.keepEnvironmentVariablesInBuildfile());
((Builder)b2).setBuildPath(((Builder)b1).getBuildPathAttribute());
@ -488,14 +560,6 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
updateData(getResDesc());
}
private static boolean getParallelDef(IConfiguration cfg) {
if (cfg instanceof Configuration)
return ((Configuration)cfg).getParallelDef();
if (cfg instanceof IMultiConfiguration)
return ((IMultiConfiguration)cfg).getParallelDef();
return false;
}
private void setParallelDef(boolean def) {
if (icfg instanceof Configuration)
((Configuration)icfg).setParallelDef(def);
@ -503,13 +567,6 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
((IMultiConfiguration)icfg).setParallelDef(def);
}
private int getParallelNumber() {
if (icfg instanceof Configuration)
return ((Configuration)icfg).getParallelNumber();
if (icfg instanceof IMultiConfiguration)
return ((IMultiConfiguration)icfg).getParallelNumber();
return 0;
}
private void setParallelNumber(int num) {
if (icfg instanceof Configuration)
((Configuration)icfg).setParallelNumber(num);
@ -517,14 +574,6 @@ public class BuildBehaviourTab extends AbstractCBuildPropertyTab {
((IMultiConfiguration)icfg).setParallelNumber(num);
}
private boolean getInternalBuilderParallel() {
if (icfg instanceof Configuration)
return ((Configuration)icfg).getInternalBuilderParallel();
if (icfg instanceof IMultiConfiguration)
return ((IMultiConfiguration)icfg).getInternalBuilderParallel();
return false;
}
private boolean isInternalBuilderEnabled() {
if (icfg instanceof Configuration)
return ((Configuration)icfg).isInternalBuilderEnabled();

View file

@ -171,7 +171,7 @@ public class BuilderSettingsTab extends AbstractCBuildPropertyTab {
canEnableInternalBuilder(true) &&
canEnableInternalBuilder(false));
t_buildCmd.setText(getMC());
t_buildCmd.setText(getMakeCommand());
if (page.isMultiCfg()) {
group_dir.setVisible(false);
@ -293,11 +293,14 @@ public class BuilderSettingsTab extends AbstractCBuildPropertyTab {
/**
* @return make command
*/
private String getMC() {
String makeCommand = bldr.getCommand();
String makeArgs = bldr.getArguments();
if (makeArgs != null) { makeCommand += " " + makeArgs; } //$NON-NLS-1$
return makeCommand;
private String getMakeCommand() {
String makeCommand = icfg.getBuildCommand();
String makeArgs = icfg.getBuildArguments();
if (!(makeCommand.length() == 0) && makeArgs != null) {
return makeCommand + " " + makeArgs; //$NON-NLS-1$
}
return EMPTY_STR;
}
/**
* Performs common settings for all controls