/*******************************************************************************
* Copyright (c) 2004, 2010 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.makegen.gnu;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IFolderInfo;
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator;
import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo;
import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration;
import org.eclipse.cdt.managedbuilder.core.ITool;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData;
import org.eclipse.cdt.managedbuilder.macros.BuildMacroException;
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
/**
* @since 2.0
* @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class DefaultGCCDependencyCalculator implements IManagedDependencyGenerator {
private static final String EMPTY_STRING = new String();
private static final String[] EMPTY_STRING_ARRAY = new String[0];
public final String WHITESPACE = " "; //$NON-NLS-1$
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#findDependencies(org.eclipse.core.resources.IResource)
*/
public IResource[] findDependencies(IResource resource, IProject project) {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getCalculatorType()
*/
public int getCalculatorType() {
return TYPE_COMMAND;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderDependencyCalculator#getDependencyCommand()
*/
public String getDependencyCommand(IResource resource, IManagedBuildInfo info) {
/*
* For a given input, <path>/<resource_name>.<ext>, return a string containing
* echo -n $(@:%.<out_ext>=%.d) '<path>/' >> $(@:%.<out_ext>=%.d) && \
* <tool_command> -P -MM -MG <tool_flags> $< >> $(@:%.<out_ext>=%.d)
*
*/
StringBuffer buffer = new StringBuffer();
// Get what we need to create the dependency generation command
IConfiguration config = info.getDefaultConfiguration();
// We need to check whether we have any resource specific build information.
IResourceConfiguration resConfig = null;
if( config != null ) resConfig = config.getResourceConfiguration(resource.getFullPath().toString());
String inputExtension = resource.getFileExtension();
String outputExtension = info.getOutputExtension(inputExtension);
// Work out the build-relative path for the output files
IContainer resourceLocation = resource.getParent();
String relativePath = new String();
if (resourceLocation != null) {
relativePath += resourceLocation.getProjectRelativePath().toString();
}
if (relativePath.length() > 0) {
relativePath += IManagedBuilderMakefileGenerator.SEPARATOR;
}
// Calculate the dependency rule
// <path>/$(@:%.<out_ext>=%.d)
String depRule = "'$(@:%." + //$NON-NLS-1$
outputExtension +
"=%." + //$NON-NLS-1$
IManagedBuilderMakefileGenerator.DEP_EXT +
")'"; //$NON-NLS-1$
// Add the rule that will actually create the right format for the dep
buffer.append(IManagedBuilderMakefileGenerator.TAB +
IManagedBuilderMakefileGenerator.ECHO +
IManagedBuilderMakefileGenerator.WHITESPACE +
"-n" + //$NON-NLS-1$
IManagedBuilderMakefileGenerator.WHITESPACE +
depRule +
IManagedBuilderMakefileGenerator.WHITESPACE +
"$(dir $@)" + //$NON-NLS-1$
IManagedBuilderMakefileGenerator.WHITESPACE +
">" + //$NON-NLS-1$
IManagedBuilderMakefileGenerator.WHITESPACE +
depRule +
IManagedBuilderMakefileGenerator.WHITESPACE +
IManagedBuilderMakefileGenerator.LOGICAL_AND +
IManagedBuilderMakefileGenerator.WHITESPACE +
IManagedBuilderMakefileGenerator.LINEBREAK);
// Add the line that will do the work to calculate dependencies
IManagedCommandLineInfo cmdLInfo = null;
String buildCmd = null;
String[] inputs= new String[1]; inputs[0] = IManagedBuilderMakefileGenerator.IN_MACRO;
String outflag = ""; //$NON-NLS-1$
String outputPrefix = ""; //$NON-NLS-1$
String outputFile = ""; //$NON-NLS-1$
ITool[] tools;
if( resConfig != null && (tools = resConfig.getToolsToInvoke()) != null && tools.length > 0) {
ITool tool = tools[0];
String cmd = tool.getToolCommand();
//try to resolve the build macros in the tool command
try {
String resolvedCommand = null;
// does the resource have spaces in its name?
if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { //$NON-NLS-1$
// use fully qualified strings
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValueToMakefileFormat(
cmd,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(resource.getLocation(),
null, null, tool));
} else {
// use builder variables
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValueToMakefileFormat(
cmd,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(resource.getLocation(),
null, null, tool));
}
if((resolvedCommand = resolvedCommand.trim()).length() > 0)
cmd = resolvedCommand;
} catch (BuildMacroException e){
}
String[] toolFlags = null;
try {
toolFlags = tool.getToolCommandFlags(resource.getLocation(),null);
} catch( BuildException ex ) {
// TODO add some routines to catch this
toolFlags = EMPTY_STRING_ARRAY;
}
String[] flags = new String[toolFlags.length + 4];
flags[0] = "-MM"; //$NON-NLS-1$
flags[1] = "-MG"; //$NON-NLS-1$
flags[2] = "-P"; //$NON-NLS-1$
flags[3] = "-w"; //$NON-NLS-1$
for (int i=0; i<toolFlags.length; i++) {
flags[4+i] = toolFlags[i];
}
IManagedCommandLineGenerator cmdLGen = tool.getCommandLineGenerator();
cmdLInfo = cmdLGen.generateCommandLineInfo( tool, cmd, flags, outflag, outputPrefix,
outputFile, inputs, tool.getCommandLinePattern() );
buildCmd = cmdLInfo.getCommandLine();
// resolve any remaining macros in the command after it has been generated
try {
String resolvedCommand = null;
// does the resource have spaces in its name?
if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { //$NON-NLS-1$
// use fully qualified strings
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValueToMakefileFormat(
buildCmd,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(resource.getLocation(),
null, null, tool));
} else {
// use builder variables
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValueToMakefileFormat(
buildCmd,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(resource.getLocation(),
null, null, tool));
}
if((resolvedCommand = resolvedCommand.trim()).length() > 0)
buildCmd = resolvedCommand;
} catch (BuildMacroException e){
}
} else {
ITool tool = null;
IFolderInfo foInfo = (IFolderInfo)config.getResourceInfo(resource.getProjectRelativePath(), false);
tools = foInfo.getFilteredTools();
for (int index = 0; index < tools.length; index++) {
ITool tmp = tools[index];
if (tmp.buildsFileType(inputExtension)) {
tool = tmp;
break;
}
}
String cmd = tool != null ? tool.getToolCommand() : null;
//try to resolve the build macros in the tool command
try{
String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(resource.getLocation(),null,null,tool));
if((resolvedCommand = resolvedCommand.trim()).length() > 0)
cmd = resolvedCommand;
} catch (BuildMacroException e){
}
String buildFlags = "-MM -MG -P -w " + info.getToolFlagsForSource(inputExtension, resource.getLocation(), null); //$NON-NLS-1$
String[] flags = buildFlags.split( "\\s" ); //$NON-NLS-1$
cmdLInfo = info.generateToolCommandLineInfo( inputExtension, flags, outflag, outputPrefix,
outputFile, inputs, resource.getLocation(), null);
// The command to build
if( cmdLInfo == null ) buildCmd =
cmd +
IManagedBuilderMakefileGenerator.WHITESPACE +
"-MM -MG -P -w " + //$NON-NLS-1$
buildFlags +
IManagedBuilderMakefileGenerator.WHITESPACE +
IManagedBuilderMakefileGenerator.IN_MACRO;
else {
buildCmd = cmdLInfo.getCommandLine();
}
// resolve any remaining macros in the command after it has been
// generated
try {
String resolvedCommand = null;
// does the resource have spaces in its name?
if (resource.getProjectRelativePath().toString().indexOf(" ") != -1) { //$NON-NLS-1$
// use fully qualified strings
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValueToMakefileFormat(
buildCmd,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(resource.getLocation(),
null, null, tool));
} else {
// use builder variables
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValueToMakefileFormat(
buildCmd,
"", //$NON-NLS-1$
" ", //$NON-NLS-1$
IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(resource.getLocation(),
null, null, tool));
}
if ((resolvedCommand = resolvedCommand.trim()).length() > 0)
buildCmd = resolvedCommand;
} catch (BuildMacroException e) {
}
}
buffer.append(IManagedBuilderMakefileGenerator.TAB +
buildCmd +
IManagedBuilderMakefileGenerator.WHITESPACE +
">>" + //$NON-NLS-1$
IManagedBuilderMakefileGenerator.WHITESPACE + depRule );
return buffer.toString();
}
}