if (outputExtension == null)
outputExtension = EMPTY_STRING;
// Get the dependency generator information for this tool and file
// extension
IManagedDependencyGenerator oldDepGen = null; // This interface is
// deprecated but still
// supported
IManagedDependencyGenerator2 depGen = null; // This is the recommended
// interface
IManagedDependencyInfo depInfo = null;
IManagedDependencyCommands depCommands = null;
IManagedDependencyPreBuild depPreBuild = null;
IPath[] depFiles = null;
boolean doDepGen = false;
{
IManagedDependencyGeneratorType t = null;
if (tool != null)
t = tool.getDependencyGeneratorForExtension(inputExtension);
if (t != null) {
int calcType = t.getCalculatorType();
if (calcType <= IManagedDependencyGeneratorType.TYPE_OLD_TYPE_LIMIT) {
oldDepGen = (IManagedDependencyGenerator) t;
doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_COMMAND);
if (doDepGen) {
IPath depFile = Path.fromOSString(relativePath + fileName + DOT + DEP_EXT);
getDependencyMakefiles(h).add(depFile);
generatedDepFiles.add(depFile);
}
} else {
depGen = (IManagedDependencyGenerator2) t;
doDepGen = (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS);
IBuildObject buildContext = rcInfo;// (resConfig != null) ?
// (IBuildObject)resConfig
// :
// (IBuildObject)config;
depInfo = depGen.getDependencySourceInfo(resource.getProjectRelativePath(), resource, buildContext, tool, getBuildWorkingDir());
if (calcType == IManagedDependencyGeneratorType.TYPE_BUILD_COMMANDS) {
depCommands = (IManagedDependencyCommands) depInfo;
depFiles = depCommands.getDependencyFiles();
} else if (calcType == IManagedDependencyGeneratorType.TYPE_PREBUILD_COMMANDS) {
depPreBuild = (IManagedDependencyPreBuild) depInfo;
depFiles = depPreBuild.getDependencyFiles();
}
if (depFiles != null) {
for (IPath depFile : depFiles) {
getDependencyMakefiles(h).add(depFile);
generatedDepFiles.add(depFile);
}
}
}
}
}
// Figure out the output paths
String optDotExt = EMPTY_STRING;
if (outputExtension.length() > 0)
optDotExt = DOT + outputExtension;
Vector<IPath> ruleOutputs = new Vector<IPath>();
Vector<IPath> enumeratedPrimaryOutputs = new Vector<IPath>(); // IPaths
// relative
// to the
// top
// build
// directory
Vector<IPath> enumeratedSecondaryOutputs = new Vector<IPath>(); // IPaths
// relative
// to
// the
// top
// build
// directory
usedOutType = tool.getPrimaryOutputType();
calculateOutputsForSource(tool, relativePath, resource, sourceLocation, ruleOutputs, enumeratedPrimaryOutputs, enumeratedSecondaryOutputs);
enumeratedOutputs.addAll(enumeratedPrimaryOutputs);
enumeratedOutputs.addAll(enumeratedSecondaryOutputs);
String primaryOutputName = null;
if (enumeratedPrimaryOutputs.size() > 0) {
primaryOutputName = escapeWhitespaces(enumeratedPrimaryOutputs.get(0).toString());
} else {
primaryOutputName = escapeWhitespaces(relativePath + fileName + optDotExt);
}
String otherPrimaryOutputs = EMPTY_STRING;
for (int i = 1; i < enumeratedPrimaryOutputs.size(); i++) { // Starting
// with 1 is
// intentional
otherPrimaryOutputs += WHITESPACE + escapeWhitespaces(enumeratedPrimaryOutputs.get(i).toString());
}
// Output file location needed for the file-specific build macros
IPath outputLocation = Path.fromOSString(primaryOutputName);
if (!outputLocation.isAbsolute()) {
outputLocation = getPathForResource(project).append(getBuildWorkingDir()).append(primaryOutputName);
}
// A separate rule is needed for the resource in the case where explicit
// file-specific macros
// are referenced, or if the resource contains special characters in its
// path (e.g., whitespace)
/*
* fix for 137674
*
* We only need an explicit rule if one of the following is true: - The resource is linked, and its full path to its real location contains
* special characters - The resource is not linked, but its project relative path contains special characters
*/
boolean resourceNameRequiresExplicitRule = (resource.isLinked() && containsSpecialCharacters(sourceLocation.toString()))
|| (!resource.isLinked() && containsSpecialCharacters(resource.getProjectRelativePath().toString()));
boolean needExplicitRuleForFile = resourceNameRequiresExplicitRule
|| BuildMacroProvider.getReferencedExplitFileMacros(tool).length > 0
|| BuildMacroProvider.getReferencedExplitFileMacros(tool.getToolCommand(), IBuildMacroProvider.CONTEXT_FILE, new FileContextData(
sourceLocation, outputLocation, null, tool)).length > 0;
// Get and resolve the command
String cmd = tool.getToolCommand();
try {
String resolvedCommand = null;
if (!needExplicitRuleForFile) {
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValueToMakefileFormat(cmd, EMPTY_STRING, WHITESPACE, IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(sourceLocation, outputLocation, null, tool)).replaceFirst(" -w ", " ");
} else {
// if we need an explicit rule then don't use any builder
// variables, resolve everything
// to explicit strings
resolvedCommand = ManagedBuildManager
.getBuildMacroProvider()
.resolveValue(cmd, EMPTY_STRING, WHITESPACE, IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(sourceLocation, outputLocation, null, tool)).replaceFirst(" -w ", " ");
}
if ((resolvedCommand = resolvedCommand.trim()).length() > 0)
cmd = resolvedCommand;
} catch (BuildMacroException e) {// JABA is not going to write this code
}
String defaultOutputName = EMPTY_STRING;
String primaryDependencyName = EMPTY_STRING;
String patternPrimaryDependencyName = EMPTY_STRING;
String home = (generatedSource) ? DOT : ROOT;
String resourcePath = null;
boolean patternRule = true;
boolean isItLinked = false;
if (resource.isLinked(IResource.CHECK_ANCESTORS)) {
// it IS linked, so use the actual location
isItLinked = true;
resourcePath = sourceLocation.toString();
// Need a hardcoded rule, not a pattern rule, as a linked file
// can reside in any path
defaultOutputName = escapeWhitespaces(relativePath + fileName + optDotExt);
primaryDependencyName = escapeWhitespaces(resourcePath);
patternRule = false;
} else {
// Use the relative path (not really needed to store per se but in
// the future someone may want this)
resourcePath = relativePath;
// The rule and command to add to the makefile
if (rcInfo instanceof IFileInfo || needExplicitRuleForFile) {
// Need a hardcoded rule, not a pattern rule
defaultOutputName = escapeWhitespaces(resourcePath + fileName + optDotExt);
patternRule = false;
} else {
defaultOutputName = relativePath + WILDCARD + optDotExt;
}
primaryDependencyName = escapeWhitespaces(home + SEPARATOR + resourcePath + fileName + DOT + inputExtension);
patternPrimaryDependencyName = home + SEPARATOR + resourcePath + WILDCARD + DOT + inputExtension;
} // end fix for PR 70491
// If the tool specifies a dependency calculator of TYPE_BUILD_COMMANDS,
// ask whether
// the dependency commands are "generic" (i.e., we can use a pattern
// rule)
boolean needExplicitDependencyCommands = false;
if (depCommands != null) {
needExplicitDependencyCommands = !depCommands.areCommandsGeneric();
}
// If we still think that we are using a pattern rule, check a few more
// things
if (patternRule) {
patternRule = false;
// Make sure that at least one of the rule outputs contains a %.
for (int i = 0; i < ruleOutputs.size(); i++) {
String ruleOutput = ruleOutputs.get(i).toString();
if (ruleOutput.indexOf('%') >= 0) {
patternRule = true;
break;
}
}
if (patternRule) {
patternRule = !needExplicitDependencyCommands;
}
}
// Begin building the rule for this source file
String buildRule = EMPTY_STRING;
if (patternRule) {
if (ruleOutputs.size() == 0) {
buildRule += defaultOutputName;
} else {
boolean first = true;
for (int i = 0; i < ruleOutputs.size(); i++) {
String ruleOutput = ruleOutputs.get(i).toString();
if (ruleOutput.indexOf('%') >= 0) {
if (first) {
first = false;
} else {
buildRule += WHITESPACE;
}
buildRule += ruleOutput;
}
}
}
} else {
buildRule += primaryOutputName;
}
String buildRuleDependencies = primaryDependencyName;
String patternBuildRuleDependencies = patternPrimaryDependencyName;
// Other additional inputs
// Get any additional dependencies specified for the tool in other
// InputType elements and AdditionalInput elements
IPath[] addlDepPaths = tool.getAdditionalDependencies();
for (IPath addlDepPath : addlDepPaths) {
// Translate the path from project relative to build directory
// relative
IPath addlPath = addlDepPath;
if (!(addlPath.toString().startsWith("$("))) { //$NON-NLS-1$
if (!addlPath.isAbsolute()) {
IPath tempPath = project.getLocation().append(new Path(ensureUnquoted(addlPath.toString())));
if (tempPath != null) {
addlPath = ManagedBuildManager.calculateRelativePath(getTopBuildDir(), tempPath);
}
}
}
String suitablePath = ensurePathIsGNUMakeTargetRuleCompatibleSyntax(addlPath.toString());
buildRuleDependencies += WHITESPACE + suitablePath;
patternBuildRuleDependencies += WHITESPACE + suitablePath;
}
buildRule += COLON + WHITESPACE + (patternRule ? patternBuildRuleDependencies : buildRuleDependencies);
// No duplicates in a makefile. If we already have this rule, don't add
// it or the commands to build the file
if (getRuleList().contains(buildRule)) {
// TODO: Should we assert that this is a pattern rule?
} else {
getRuleList().add(buildRule);
// Echo starting message
buffer.append(buildRule + NEWLINE);
buffer.append(TAB + AT + escapedEcho(MESSAGE_START_FILE + WHITESPACE + IN_MACRO));
buffer.append(TAB + AT + escapedEcho(tool.getAnnouncement()));
// If the tool specifies a dependency calculator of
// TYPE_BUILD_COMMANDS, ask whether
// there are any pre-tool commands.
if (depCommands != null) {
String[] preToolCommands = depCommands.getPreToolDependencyCommands();
if (preToolCommands != null && preToolCommands.length > 0) {
for (String preCmd : preToolCommands) {
try {
String resolvedCommand;
IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider();
if (!needExplicitRuleForFile) {
resolvedCommand = provider.resolveValueToMakefileFormat(preCmd, EMPTY_STRING, WHITESPACE,
IBuildMacroProvider.CONTEXT_FILE, new FileContextData(sourceLocation, outputLocation, null, tool))
.replaceFirst(" -w ", " ");
} else {
// if we need an explicit rule then don't use
// any builder
// variables, resolve everything to explicit
// strings
resolvedCommand = provider.resolveValue(preCmd, EMPTY_STRING, WHITESPACE, IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(sourceLocation, outputLocation, null, tool)).replaceFirst(" -w ", " ");
}
if (resolvedCommand != null)
buffer.append(resolvedCommand + NEWLINE);
} catch (BuildMacroException e) {// JABA is not going to
// write this code
}
}
}
}
// Generate the command line
Vector<String> inputs = new Vector<String>();
inputs.add(IN_MACRO);
// Other additional inputs
// Get any additional dependencies specified for the tool in other
// InputType elements and AdditionalInput elements
IPath[] addlInputPaths = getAdditionalResourcesForSource(tool);
for (IPath addlInputPath : addlInputPaths) {
// Translate the path from project relative to build directory
// relative
IPath addlPath = addlInputPath;
if (!(addlPath.toString().startsWith("$("))) { //$NON-NLS-1$
if (!addlPath.isAbsolute()) {
IPath tempPath = getPathForResource(project).append(addlPath);
if (tempPath != null) {
addlPath = ManagedBuildManager.calculateRelativePath(getTopBuildDir(), tempPath);
}
}
}
inputs.add(addlPath.toString());
}
String[] inputStrings = inputs.toArray(new String[inputs.size()]);
String[] flags = null;
// Get the tool command line options
try {
flags = tool.getToolCommandFlags(sourceLocation, outputLocation);
} catch (BuildException ex) {
// TODO add some routines to catch this
flags = EMPTY_STRING_ARRAY;
}
// If we have a TYPE_BUILD_COMMANDS dependency generator, determine
// if there are any options that
// it wants added to the command line
if (depCommands != null) {
flags = addDependencyOptions(depCommands, flags);
}
IManagedCommandLineInfo cmdLInfo = null;
String outflag = null;
String outputPrefix = null;
if (rcInfo instanceof IFileInfo || needExplicitRuleForFile || needExplicitDependencyCommands) {
outflag = tool.getOutputFlag();
outputPrefix = tool.getOutputPrefix();
// Call the command line generator
IManagedCommandLineGenerator cmdLGen = tool.getCommandLineGenerator();
cmdLInfo = cmdLGen.generateCommandLineInfo(tool, cmd, flags, outflag, outputPrefix, OUT_MACRO + otherPrimaryOutputs, inputStrings,
tool.getCommandLinePattern());
} else {
outflag = tool.getOutputFlag();// config.getOutputFlag(outputExtension);
outputPrefix = tool.getOutputPrefix();// config.getOutputPrefix(outputExtension);
// Call the command line generator
cmdLInfo = generateToolCommandLineInfo(tool, inputExtension, flags, outflag, outputPrefix, OUT_MACRO + otherPrimaryOutputs,
inputStrings, sourceLocation, outputLocation);
}
// The command to build
String buildCmd;
if (cmdLInfo != null) {
buildCmd = cmdLInfo.getCommandLine();
} else {
StringBuffer buildFlags = new StringBuffer();
for (String flag : flags) {
if (flag != null) {
buildFlags.append(flag + WHITESPACE);
}
}
buildCmd = cmd + WHITESPACE + buildFlags.toString().trim() + WHITESPACE + outflag + WHITESPACE + outputPrefix + OUT_MACRO
+ otherPrimaryOutputs + WHITESPACE + IN_MACRO;
}
// resolve any remaining macros in the command after it has been
// generated
try {
String resolvedCommand;
IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider();
if (!needExplicitRuleForFile) {
resolvedCommand = provider.resolveValueToMakefileFormat(buildCmd, EMPTY_STRING, WHITESPACE, IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(sourceLocation, outputLocation, null, tool)).replaceFirst(" -w ", " ");
} else {
// if we need an explicit rule then don't use any builder
// variables, resolve everything to explicit strings
resolvedCommand = provider.resolveValue(buildCmd, EMPTY_STRING, WHITESPACE, IBuildMacroProvider.CONTEXT_FILE,
new FileContextData(sourceLocation, outputLocation, null, tool)).replaceFirst(" -w ", " ");
}
if ((resolvedCommand = resolvedCommand.trim()).length() > 0)
buildCmd = resolvedCommand;
} catch (BuildMacroException e) {// JABA is not going to write this
// code
}
// buffer.append(TAB + AT + escapedEcho(buildCmd));
// buffer.append(TAB + AT + buildCmd);
buffer.append(TAB + buildCmd);
// Determine if there are any dependencies to calculate
if (doDepGen) {
// Get the dependency rule out of the generator
String[] depCmds = null;
if (oldDepGen != null) {
depCmds = new String[1];
depCmds[0] = oldDepGen.getDependencyCommand(resource, ManagedBuildManager.getBuildInfo(project));
} else {
if (depCommands != null) {
depCmds = depCommands.getPostToolDependencyCommands();
}
}
if (depCmds != null) {
for (String depCmd : depCmds) {
// Resolve any macros in the dep command after it has
// been generated.
// Note: do not trim the result because it will strip
// out necessary tab characters.
buffer.append(WHITESPACE + LOGICAL_AND + WHITESPACE + LINEBREAK);
try {
if (!needExplicitRuleForFile) {
depCmd = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(depCmd, EMPTY_STRING, WHITESPACE,
IBuildMacroProvider.CONTEXT_FILE, new FileContextData(sourceLocation, outputLocation, null, tool));
}
else {
depCmd = ManagedBuildManager.getBuildMacroProvider().resolveValue(depCmd, EMPTY_STRING, WHITESPACE,
IBuildMacroProvider.CONTEXT_FILE, new FileContextData(sourceLocation, outputLocation, null, tool));
}
} catch (BuildMacroException e) {// JABA is not going to
// write this code
}
buffer.append(depCmd);
}
}
}
// Echo finished message
buffer.append(NEWLINE);
buffer.append(TAB + AT + escapedEcho(MESSAGE_FINISH_FILE + WHITESPACE + IN_MACRO));
buffer.append(TAB + AT + ECHO_BLANK_LINE + NEWLINE);
}
// Determine if there are calculated dependencies
IPath[] addlDeps = null; // IPath's that are relative to the build
// directory
IPath[] addlTargets = null; // IPath's that are relative to the build
// directory
String calculatedDependencies = null;
boolean addedDepLines = false;
String depLine;
if (oldDepGen != null && oldDepGen.getCalculatorType() != IManagedDependencyGeneratorType.TYPE_COMMAND) {
addlDeps = oldCalculateDependenciesForSource(oldDepGen, tool, relativePath, resource);
} else {
if (depGen != null && depGen.getCalculatorType() == IManagedDependencyGeneratorType.TYPE_CUSTOM) {
if (depInfo instanceof IManagedDependencyCalculator) {
IManagedDependencyCalculator depCalculator = (IManagedDependencyCalculator) depInfo;