/******************************************************************************* * Copyright (c) 2010, 2011 Wind River Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - Initial API and implementation * James Blackburn (Broadcom Corp.) *******************************************************************************/ package org.eclipse.cdt.managedbuilder.core; import java.io.IOException; import java.io.OutputStream; import org.eclipse.cdt.core.ConsoleOutputStream; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.managedbuilder.buildmodel.BuildDescriptionManager; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription; import org.eclipse.cdt.managedbuilder.internal.buildmodel.BuildStateManager; import org.eclipse.cdt.managedbuilder.internal.buildmodel.DescriptionBuilder; import org.eclipse.cdt.managedbuilder.internal.buildmodel.IBuildModelBuilder; import org.eclipse.cdt.managedbuilder.internal.buildmodel.IConfigurationBuildState; import org.eclipse.cdt.managedbuilder.internal.buildmodel.IProjectBuildState; import org.eclipse.cdt.managedbuilder.internal.buildmodel.ParallelBuilder; import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; /** * The build runner for the internal builder. * * @author dschaefer * @since 8.0 */ public class InternalBuildRunner extends AbstractBuildRunner { private static final String INTERNAL_BUILDER = "ManagedMakeBuilder.message.internal.builder"; //$NON-NLS-1$ private static final String TYPE_INC = "ManagedMakeBuider.type.incremental"; //$NON-NLS-1$ private static final String TYPE_REBUILD = "ManagedMakeBuider.type.rebuild"; //$NON-NLS-1$ private static final String CONSOLE_HEADER = "ManagedMakeBuilder.message.console.header"; //$NON-NLS-1$ private static final String INTERNAL_BUILDER_HEADER_NOTE = "ManagedMakeBuilder.message.internal.builder.header.note"; //$NON-NLS-1$ private static final String WARNING_UNSUPPORTED_CONFIGURATION = "ManagedMakeBuilder.warning.unsupported.configuration"; //$NON-NLS-1$ private static final String BUILD_FINISHED = "ManagedMakeBuilder.message.finished"; //$NON-NLS-1$ private static final String BUILD_CANCELLED = "ManagedMakeBuilder.message.cancelled"; //$NON-NLS-1$ private static final String BUILD_FINISHED_WITH_ERRS = "ManagedMakeBuilder.message.finished.with.errs"; //$NON-NLS-1$ private static final String BUILD_STOPPED_ERR = "ManagedMakeBuilder.message.stopped.error"; //$NON-NLS-1$ private static final String BUILD_FAILED_ERR = "ManagedMakeBuilder.message.internal.builder.error"; //$NON-NLS-1$ private static final String MARKERS = "ManagedMakeBuilder.message.creating.markers"; //$NON-NLS-1$ private static final String NOTHING_BUILT = "ManagedMakeBuilder.message.no.build"; //$NON-NLS-1$ private static final String BUILD_ERROR = "ManagedMakeBuilder.message.error"; //$NON-NLS-1$ @Override 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 buildIncrementaly = true; boolean resumeOnErr = !builder.isStopOnError(); // Get the project and make sure there's a monitor to cancel the build if (monitor == null) { monitor = new NullProgressMonitor(); } String[] msgs = new String[2]; msgs[0] = ManagedMakeMessages.getResourceString(INTERNAL_BUILDER); msgs[1] = project.getName(); ConsoleOutputStream consoleOutStream = null; OutputStream epmOutputStream = null; try { int flags = 0; IResourceDelta delta = projectBuilder.getDelta(project); BuildStateManager bsMngr = BuildStateManager.getInstance(); IProjectBuildState pBS = bsMngr.getProjectBuildState(project); IConfigurationBuildState cBS = pBS.getConfigurationBuildState(configuration.getId(), true); // if(delta != null){ flags = BuildDescriptionManager.REBUILD | BuildDescriptionManager.REMOVED | BuildDescriptionManager.DEPS; // delta = getDelta(currentProject); // } boolean buildIncrementaly = delta != null; // Get a build console for the project StringBuffer buf = new StringBuffer(); consoleOutStream = console.getOutputStream(); String[] consoleHeader = new String[3]; if(buildIncrementaly) consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); else consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_REBUILD); consoleHeader[1] = configuration.getName(); consoleHeader[2] = project.getName(); buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)); buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ buf.append(ManagedMakeMessages.getResourceString(INTERNAL_BUILDER_HEADER_NOTE)); buf.append("\n"); //$NON-NLS-1$ if(!configuration.isSupported()){ buf.append(ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION, new String[] { configuration.getName(), configuration.getToolChain().getName()})); buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ } consoleOutStream.write(buf.toString().getBytes()); consoleOutStream.flush(); IBuildDescription des = BuildDescriptionManager.createBuildDescription(configuration, cBS, delta, flags); DescriptionBuilder dBuilder = null; if (!isParallel) dBuilder = new DescriptionBuilder(des, buildIncrementaly, resumeOnErr, cBS); if(isParallel || dBuilder.getNumCommands() > 0) { // Remove all markers for this project IWorkspace workspace = project.getWorkspace(); IMarker[] markers = project.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); if (markers != null) workspace.deleteMarkers(markers); // Hook up an error parser manager String[] errorParsers = builder.getErrorParsers(); ErrorParserManager epm = new ErrorParserManager(project, des.getDefaultBuildDirLocationURI(), markerGenerator, errorParsers); epm.setOutputStream(consoleOutStream); // This variable is necessary to ensure that the EPM stream stay open // until we explicitly close it. See bug#123302. epmOutputStream = epm.getOutputStream(); int status = 0; long t1 = System.currentTimeMillis(); if (isParallel) status = ParallelBuilder.build(des, null, null, epmOutputStream, epmOutputStream, monitor, resumeOnErr, buildIncrementaly); else status = dBuilder.build(epmOutputStream, epmOutputStream, monitor); long t2 = System.currentTimeMillis(); // Report either the success or failure of our mission buf = new StringBuffer(); switch(status){ case IBuildModelBuilder.STATUS_OK: buf.append(ManagedMakeMessages .getFormattedString(BUILD_FINISHED, project.getName())); break; case IBuildModelBuilder.STATUS_CANCELLED: buf.append(ManagedMakeMessages .getResourceString(BUILD_CANCELLED)); break; case IBuildModelBuilder.STATUS_ERROR_BUILD: String msg = resumeOnErr ? ManagedMakeMessages.getResourceString(BUILD_FINISHED_WITH_ERRS) : ManagedMakeMessages.getResourceString(BUILD_STOPPED_ERR); buf.append(msg); break; case IBuildModelBuilder.STATUS_ERROR_LAUNCH: default: buf.append(ManagedMakeMessages .getResourceString(BUILD_FAILED_ERR)); break; } buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ // Report time and number of threads used buf.append(ManagedMakeMessages.getFormattedString("CommonBuilder.6", Integer.toString((int)(t2 - t1)))); //$NON-NLS-1$ // buf.append(t2 - t1); // buf.append(" ms. "); if (isParallel) { buf.append(ManagedMakeMessages.getFormattedString("CommonBuilder.7", Integer.toString(ParallelBuilder.lastThreadsUsed))); //$NON-NLS-1$ // buf.append(ParallelBuilder.lastThreadsUsed); } buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ // Write message on the console consoleOutStream.write(buf.toString().getBytes()); consoleOutStream.flush(); epmOutputStream.close(); epmOutputStream = null; // Generate any error markers that the build has discovered monitor.subTask(ManagedMakeMessages .getResourceString(MARKERS)); bsMngr.setProjectBuildState(project, pBS); } else { buf = new StringBuffer(); buf.append(ManagedMakeMessages.getFormattedString(NOTHING_BUILT, project.getName())); buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ consoleOutStream.write(buf.toString().getBytes()); consoleOutStream.flush(); } } catch (Exception e) { if(consoleOutStream != null){ StringBuffer buf = new StringBuffer(); String errorDesc = ManagedMakeMessages .getResourceString(BUILD_ERROR); buf.append(errorDesc); buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ buf.append(e.getLocalizedMessage()); buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ try { consoleOutStream.write(buf.toString().getBytes()); consoleOutStream.flush(); } catch (IOException e1) { } } projectBuilder.forgetLastBuiltState(); } finally { if(epmOutputStream != null){ try { epmOutputStream.close(); } catch (IOException e) { } } if(consoleOutStream != null){ try { consoleOutStream.close(); } catch (IOException e) { } } monitor.done(); } return false; } }