From f313f3dc6e0cbbd9639b6b685ec810c7d0dcd16c Mon Sep 17 00:00:00 2001 From: "donghyuk.yang" Date: Mon, 4 Feb 2013 22:14:38 +0900 Subject: [PATCH] [Title] Added ExternalBuildRunner for building platform project --- org.tizen.nativeplatform/plugin.xml | 1 + .../build/PlatformBuildCommandLauncher.java | 72 ++--- .../build/PlatformExternalBuildRunner.java | 354 +++++++++++++++++++++ .../build/PlatformProjectDependentPackager.java | 63 +++- 4 files changed, 432 insertions(+), 58 deletions(-) create mode 100644 org.tizen.nativeplatform/src/org/tizen/nativeplatform/build/PlatformExternalBuildRunner.java diff --git a/org.tizen.nativeplatform/plugin.xml b/org.tizen.nativeplatform/plugin.xml index aa6d6a4..00e0885 100644 --- a/org.tizen.nativeplatform/plugin.xml +++ b/org.tizen.nativeplatform/plugin.xml @@ -105,6 +105,7 @@ commandLauncher="org.tizen.nativeplatform.build.PlatformBuildCommandLauncher" id="org.tizen.nativeide.target.sbi.gcc45.platform.builder" incrementalBuildTarget="build" + buildRunner="org.tizen.nativeplatform.build.PlatformExternalBuildRunner" name="%Platform.proj.builder"> + * DongHee Yang + * Kangho Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +package org.tizen.nativeplatform.build; + +import java.io.OutputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext; +import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set; +import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager; +import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.ICommandLauncher; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.cdt.core.resources.RefreshScopeManager; +import org.eclipse.cdt.internal.core.ConsoleOutputSniffer; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; +import org.eclipse.cdt.make.core.scannerconfig.InfoContext; +import org.eclipse.cdt.make.internal.core.StreamMonitor; +import org.eclipse.cdt.make.internal.core.scannerconfig2.SCProfileInstance; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile; +import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager; +import org.eclipse.cdt.managedbuilder.core.ExternalBuildRunner; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IFileInfo; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IResourceInfo; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.cdt.utils.CommandLineUtil; +import org.eclipse.cdt.utils.EFSExtensionManager; +import org.eclipse.cdt.utils.PathUtil; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; +import org.eclipse.cdt.managedbuilder.core.IFolderInfo; + + +public class PlatformExternalBuildRunner extends ExternalBuildRunner { + + private static final String TYPE_CLEAN = "ManagedMakeBuilder.type.clean"; //$NON-NLS-1$ + private static final String TYPE_INC = "ManagedMakeBuider.type.incremental"; //$NON-NLS-1$ + private static final String CONSOLE_HEADER = "ManagedMakeBuilder.message.console.header"; //$NON-NLS-1$ + private static final String WARNING_UNSUPPORTED_CONFIGURATION = "ManagedMakeBuilder.warning.unsupported.configuration"; //$NON-NLS-1$ + private static final String NEWLINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + private static final String PATH_ENV = "PATH"; //$NON-NLS-1$ + + protected boolean invokeExternalBuild(int kind, IProject project, IConfiguration configuration, + IBuilder builder, IConsole console, IMarkerGenerator markerGenerator, + IncrementalProjectBuilder projectBuilder, IProgressMonitor monitor) throws CoreException { + boolean isClean = false; + + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask(ManagedMakeMessages.getResourceString("MakeBuilder.Invoking_Make_Builder") + project.getName(), 100); //$NON-NLS-1$ + + try { + IPath buildCommand = builder.getBuildCommand(); + if (buildCommand != null) { + OutputStream cos = console.getOutputStream(); + StringBuffer buf = new StringBuffer(); + + String[] consoleHeader = new String[3]; + switch (kind) { + case IncrementalProjectBuilder.FULL_BUILD: + case IncrementalProjectBuilder.INCREMENTAL_BUILD: + case IncrementalProjectBuilder.AUTO_BUILD: + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_INC); + break; + case IncrementalProjectBuilder.CLEAN_BUILD: + consoleHeader[0] = ManagedMakeMessages.getResourceString(TYPE_CLEAN); + break; + } + + consoleHeader[1] = configuration.getName(); + consoleHeader[2] = project.getName(); + buf.append(NEWLINE); + buf.append(ManagedMakeMessages.getFormattedString(CONSOLE_HEADER, consoleHeader)).append(NEWLINE); + buf.append(NEWLINE); + + if(!configuration.isSupported()){ + String unsupportedToolchainMsg = ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION, + new String[] { configuration.getName(), configuration.getToolChain().getName() }); + buf.append(unsupportedToolchainMsg).append(NEWLINE); + buf.append(NEWLINE); + } + cos.write(buf.toString().getBytes()); + cos.flush(); + + // 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); + + URI workingDirectoryURI = ManagedBuildManager.getBuildLocationURI(configuration, builder); + final String pathFromURI = EFSExtensionManager.getDefault().getPathFromURI(workingDirectoryURI); + if(pathFromURI == null) { + throw new CoreException(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, ManagedMakeMessages.getString("ManagedMakeBuilder.message.error"), null)); //$NON-NLS-1$ + } + + IPath workingDirectory = new Path(pathFromURI); + + String[] targets = getTargets(kind, builder); + if (targets.length != 0 && targets[targets.length - 1].equals(builder.getCleanBuildTarget())) + isClean = true; + + String errMsg = null; + ICommandLauncher launcher = builder.getCommandLauncher(); + launcher.setProject(project); + // Print the command for visual interaction. + launcher.showCommand(true); + + // Set the environment + Map envMap = getEnvironment(builder); + String[] env = getEnvStrings(envMap); + String[] buildArguments = targets; + + String[] newArgs = CommandLineUtil.argumentsToArray(builder.getBuildArguments()); + buildArguments = new String[targets.length + newArgs.length]; + System.arraycopy(newArgs, 0, buildArguments, 0, newArgs.length); + System.arraycopy(targets, 0, buildArguments, newArgs.length, targets.length); + + QualifiedName qName = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "progressMonitor"); //$NON-NLS-1$ + Integer last = (Integer)project.getSessionProperty(qName); + if (last == null) { + last = new Integer(100); + } + ErrorParserManager epm = new ErrorParserManager(project, workingDirectoryURI, markerGenerator, builder.getErrorParsers()); + epm.setOutputStream(cos); + StreamMonitor streamMon = new StreamMonitor(new SubProgressMonitor(monitor, 100), epm, last.intValue()); + OutputStream stdout = streamMon; + OutputStream stderr = streamMon; + + // Sniff console output for scanner info + ConsoleOutputSniffer sniffer = createBuildOutputSniffer(stdout, stderr, project, configuration, workingDirectory, markerGenerator, null); + OutputStream consoleOut = (sniffer == null ? stdout : sniffer.getOutputStream()); + OutputStream consoleErr = (sniffer == null ? stderr : sniffer.getErrorStream()); + Process p = launcher.execute(buildCommand, buildArguments, env, workingDirectory, monitor); + if (p != null) { + /* + try { + // Close the input of the Process explicitly. + // We will never write to it. + p.getOutputStream().close(); + } catch (IOException e) { + } + */ + // Before launching give visual cues via the monitor + monitor.subTask(ManagedMakeMessages.getResourceString("MakeBuilder.Invoking_Command") + launcher.getCommandLine()); //$NON-NLS-1$ + if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) + != ICommandLauncher.OK) + errMsg = launcher.getErrorMessage(); + monitor.subTask(ManagedMakeMessages.getResourceString("MakeBuilder.Updating_project")); //$NON-NLS-1$ + + try { + // Do not allow the cancel of the refresh, since the builder is external + // to Eclipse, files may have been created/modified and we will be out-of-sync. + // The caveat is for huge projects, it may take sometimes at every build. + + // TODO should only refresh output folders + //project.refreshLocal(IResource.DEPTH_INFINITE, null); + + // use the refresh scope manager to refresh + RefreshScopeManager refreshManager = RefreshScopeManager.getInstance(); + IWorkspaceRunnable runnable = refreshManager.getRefreshRunnable(project); + ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, null); + } catch (CoreException e) { + } + } else { + buf = new StringBuffer(launcher.getCommandLine()).append(NEWLINE); + errMsg = launcher.getErrorMessage(); + } + project.setSessionProperty(qName, !monitor.isCanceled() && !isClean ? new Integer(streamMon.getWorkDone()) : null); + + if (errMsg != null) { + // Launching failed, trying to figure out possible cause + String errorPrefix = ManagedMakeMessages.getResourceString("ManagedMakeBuilder.error.prefix"); //$NON-NLS-1$ + String buildCommandStr = buildCommand.toString(); + String envPath = envMap.get(PATH_ENV); + if (envPath==null) { + envPath = System.getenv(PATH_ENV); + } + if (PathUtil.findProgramLocation(buildCommandStr, envPath)==null) { + buf.append(errMsg).append(NEWLINE); + errMsg = ManagedMakeMessages.getFormattedString("ManagedMakeBuilder.message.program.not.in.path", buildCommandStr); //$NON-NLS-1$ + buf.append(errorPrefix).append(errMsg).append(NEWLINE); + buf.append(NEWLINE); + buf.append(PATH_ENV+"=["+envPath+"]").append(NEWLINE); //$NON-NLS-1$//$NON-NLS-2$ + } else { + buf.append(errorPrefix).append(errMsg).append(NEWLINE); + } + consoleErr.write(buf.toString().getBytes()); + consoleErr.flush(); + } + + buf = new StringBuffer(NEWLINE); + buf.append(ManagedMakeMessages.getResourceString("ManagedMakeBuilder.message.build.finished")).append(NEWLINE); //$NON-NLS-1$ + consoleOut.write(buf.toString().getBytes()); + + stdout.close(); + stderr.close(); + + monitor.subTask(ManagedMakeMessages.getResourceString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$ + consoleOut.close(); + consoleErr.close(); + cos.close(); + } + } catch (Exception e) { + ManagedBuilderCorePlugin.log(e); + throw new CoreException(new Status(IStatus.ERROR, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + e.getLocalizedMessage(), + e)); + } finally { + monitor.done(); + } + return (isClean); + } + + private ConsoleOutputSniffer createBuildOutputSniffer(OutputStream outputStream, + OutputStream errorStream, + IProject project, + IConfiguration cfg, + IPath workingDirectory, + IMarkerGenerator markerGenerator, + IScannerInfoCollector collector){ + ICfgScannerConfigBuilderInfo2Set container = CfgScannerConfigProfileManager.getCfgScannerConfigBuildInfo(cfg); + Map map = container.getInfoMap(); + List clParserList = new ArrayList(); + + if(container.isPerRcTypeDiscovery()){ + for (IResourceInfo rcInfo : cfg.getResourceInfos()) { + ITool tools[]; + if(rcInfo instanceof IFileInfo){ + tools = ((IFileInfo)rcInfo).getToolsToInvoke(); + } else { + tools = ((IFolderInfo)rcInfo).getFilteredTools(); + } + for (ITool tool : tools) { + IInputType[] types = tool.getInputTypes(); + + if(types.length != 0){ + for (IInputType type : types) { + CfgInfoContext c = new CfgInfoContext(rcInfo, tool, type); + contributeToConsoleParserList(project, map, c, workingDirectory, markerGenerator, collector, clParserList); + } + } else { + CfgInfoContext c = new CfgInfoContext(rcInfo, tool, null); + contributeToConsoleParserList(project, map, c, workingDirectory, markerGenerator, collector, clParserList); + } + } + } + } + + if(clParserList.size() == 0){ + contributeToConsoleParserList(project, map, new CfgInfoContext(cfg), workingDirectory, markerGenerator, collector, clParserList); + } + + if(clParserList.size() != 0){ + return new ConsoleOutputSniffer(outputStream, errorStream, + clParserList.toArray(new IScannerInfoConsoleParser[clParserList.size()])); + } + + return null; + } + + private boolean contributeToConsoleParserList( + IProject project, + Map map, + CfgInfoContext context, + IPath workingDirectory, + IMarkerGenerator markerGenerator, + IScannerInfoCollector collector, + List parserList){ + IScannerConfigBuilderInfo2 info = map.get(context); + InfoContext ic = context.toInfoContext(); + boolean added = false; + if (info != null && + info.isAutoDiscoveryEnabled() && + info.isBuildOutputParserEnabled()) { + + String id = info.getSelectedProfileId(); + ScannerConfigProfile profile = ScannerConfigProfileManager.getInstance().getSCProfileConfiguration(id); + if(profile.getBuildOutputProviderElement() != null){ + // get the make builder console parser + SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance(). + getSCProfileInstance(project, ic, id); + + IScannerInfoConsoleParser clParser = profileInstance.createBuildOutputParser(); + if (collector == null) { + collector = profileInstance.getScannerInfoCollector(); + } + if(clParser != null){ + clParser.startup(project, workingDirectory, collector, + info.isProblemReportingEnabled() ? markerGenerator : null); + parserList.add(clParser); + added = true; + } + + } + } + + return added; + } +} diff --git a/org.tizen.nativeplatform/src/org/tizen/nativeplatform/build/PlatformProjectDependentPackager.java b/org.tizen.nativeplatform/src/org/tizen/nativeplatform/build/PlatformProjectDependentPackager.java index e2c814c..f324f25 100644 --- a/org.tizen.nativeplatform/src/org/tizen/nativeplatform/build/PlatformProjectDependentPackager.java +++ b/org.tizen.nativeplatform/src/org/tizen/nativeplatform/build/PlatformProjectDependentPackager.java @@ -31,6 +31,7 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.tizen.nativecommon.build.CommonProjectDependentPackager; import org.tizen.nativecommon.build.SmartBuildInterface; import org.tizen.nativecommon.build.exception.SBIException; @@ -42,6 +43,9 @@ import org.tizen.nativeplatform.views.model.PlatformRootstrap; public class PlatformProjectDependentPackager extends CommonProjectDependentPackager { + private static final String ACTION_BUILDPACKAGE = "buildpackage"; + private static final String ACTION_CHECKPKGDEPS = "checkbuilddeps"; + private static final String CONSOLE_NAME = "Packaging"; private static PlatformProjectDependentPackager instance = new PlatformProjectDependentPackager(); public static final CommonProjectDependentPackager getInstance() { @@ -142,19 +146,44 @@ public class PlatformProjectDependentPackager extends CommonProjectDependentPack // command "build package" from specified configuration and pkgType - private void buildPackage(IConfiguration config, String pkgType) throws SBIException { - String targetId = getTargetID(config); + private void buildPackage(IConfiguration config, String pkgType) throws SBIException { String projectDir = getProjectPath(); - String rootId = sbi.getRootstrapIDFromTargetID(targetId); - PlatformRootstrap rt = RootstrapManager.getRootstrap(rootId); - - String options = getPackageOption(config, rt); - - if (options == null) { - return; - } - - String[] new_envs = null; + String[] new_envs = getEnvsWithProxy(); + String cmd = getBuildPackageCmd(config); + sbi.actionConsole(cmd, projectDir, new_envs, CONSOLE_NAME); + } + + public String getCleanCmd(IConfiguration config) { + String targetId = getTargetID(config); + IPath configPath = project.getLocation().append(config.getName()); + + return String.format("%s action %s -- %s -CONFIG_DIR=\"%s\"", + sbi.getSBICommandPath("sbi"), + targetId, + "clean", + configPath.toOSString()); + } + + public String getBuildPackageCmd(IConfiguration config) { + String targetId = getTargetID(config); + String rootId = sbi.getRootstrapIDFromTargetID(targetId); + PlatformRootstrap rt = RootstrapManager.getRootstrap(rootId); + + String options = getPackageOption(config, rt); + + if (options == null) { + return ""; + } + + return String.format("%s action %s -- %s %s", + sbi.getSBICommandPath("sbi"), + targetId, + ACTION_BUILDPACKAGE, + options); + } + + public String[] getEnvsWithProxy() { + String[] envs = sbi.getEnvironmentVariables(); if ( PreferencesManager.isProxyUsed() ) { String protocol = PreferencesManager.getProxyProtocol(); String host = PreferencesManager.getProxyHost(); @@ -162,11 +191,11 @@ public class PlatformProjectDependentPackager extends CommonProjectDependentPack SmartBuildInterface sbi = SmartBuildInterface.getInstance(); String envKey = String.format("%s_proxy", protocol); String envValue = String.format("%s://%s:%d", protocol, host, port); - new_envs = sbi.addEnvironmentVariableArray(envKey, envValue); - } - sbi.actionConsole("buildpackage", options, targetId, projectDir, new_envs, "Packaging" ); //$NON-NLS-1$ //$NON-NLS-2$ + envs = sbi.addEnvironmentVariableArray(envKey, envValue); + } + + return envs; } - public void buildPackageDependencyCheck() throws SBIException { @@ -175,7 +204,7 @@ public class PlatformProjectDependentPackager extends CommonProjectDependentPack String projectDir = getProjectPath(); String options = getPackageDependencyCheckOption(); - sbi.actionConsole("checkbuilddeps", options, targetID, projectDir, "Packaging" ); + sbi.actionConsole(ACTION_CHECKPKGDEPS, options, targetID, projectDir, CONSOLE_NAME); } -- 2.7.4