From 2496e20554ec5c0d0c44cedc5069747479b46af6 Mon Sep 17 00:00:00 2001 From: Leo Treggiari Date: Fri, 20 May 2005 02:34:37 +0000 Subject: [PATCH] Additional fixes for multiple inputs & outputs after additional testing --- .../managedbuilder/internal/core/Tool.java | 4 +- .../makegen/gnu/GnuMakefileGenerator.java | 400 ++++++++++++------ .../makegen/gnu/ManagedBuildGnuToolInfo.java | 28 +- 3 files changed, 300 insertions(+), 132 deletions(-) diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java index d06d5c95c8f..c9e66ed6067 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java @@ -1574,7 +1574,7 @@ public class Tool extends BuildObject implements ITool, IOptionCategory { allDeps.add(deps[j]); } // 2. From InputTypes that other than the primary input type - if (!type.getPrimaryInput()) { + if (type != getPrimaryInputType()) { if (type.getOptionId() != null) { IOption option = getOptionBySuperClassId(type.getOptionId()); if (option != null) { @@ -1619,7 +1619,7 @@ public class Tool extends BuildObject implements ITool, IOptionCategory { allRes.add(res[j]); } // 2. From InputTypes that other than the primary input type - if (!type.getPrimaryInput()) { + if (type != getPrimaryInputType()) { String var = type.getBuildVariable(); if (var != null && var.length() > 0) { allRes.add(Path.fromOSString("$(" + type.getBuildVariable() + ")")); //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java index b6c974b52f6..e971b7f3f5f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java @@ -255,6 +255,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // Local variables needed by generator private String buildTargetName; private String buildTargetExt; + private IConfiguration config; private ITool[] buildTools; private boolean[] buildToolsUsed; private ManagedBuildGnuToolInfo[] gnuToolInfos; @@ -338,7 +339,8 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { buildTargetExt = new String(); } // Cache the build tools - buildTools = info.getDefaultConfiguration().getFilteredTools(); + config = info.getDefaultConfiguration(); + buildTools = config.getFilteredTools(); buildToolsUsed = new boolean[buildTools.length]; for (int i=0; i 0) { + for (int j=0; jnull, use the file extension to find the name */ protected void addFragmentMakefileEntriesForSource (HashMap buildVarToRuleStringMap, StringBuffer ruleBuffer, IFolder folder, String relativePath, IResource resource, String varName, boolean generatedSource) { // Determine which tool, if any, builds files with this extension String ext = resource.getFileExtension(); + boolean toolFound = false; for (int j=0; j 0) { @@ -1855,9 +1872,9 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { buildVariable = outType.getBuildVariable(); } else { // For support of pre-CDT 3.0 integrations. - buildVariable = OBJS_MACRO; //$NON-NLS-1$ + buildVariable = OBJS_MACRO; } - Vector generatedOutputs = calculateOutputsForSource(tool, relativePath, resource, false); + for (int k=0; k 0) { + if (isSecondaryOutputVar(secondaryOutputs, varName)) { + addMacroAdditionFile(buildVarToRuleStringMap, varName, relativePath, resource, generatedSource); + } + } + } } } /* (non-Javadoc) - * Create the pattern rule in the format: + * Create a rule for this source file. We create a pattern rule if possible. + * + * This is an example of a pattern rule: + * * /%.: $(ROOT)//%. * @echo 'Building file: $<' + * @echo 'Invoking tool xxx' * @echo $@ $< * @ $@ $< && \ * echo -n $(@:%.o=%.d) ' /' >> $(@:%.o=%.d) && \ @@ -1887,6 +1919,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { * makefile, so a real command might look something like: * source1/%.o: $(ROOT)/source1/%.cpp * @echo 'Building file: $<' + * @echo 'Invoking tool xxx' * @echo g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< * @ g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o$@ $< && \ * echo -n $(@:%.o=%.d) ' source1/' >> $(@:%.o=%.d) && \ @@ -1900,45 +1933,14 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { * @param generatedSource true if the resource is a generated output * @param generatedDepFile passed in as an empty string; append the dependency file name * to it if one is generated by the rule + * @param enumeratedOutputs vector of the filenames that are the output of this rule */ protected void addRuleForSource(String relativePath, StringBuffer buffer, IResource resource, - boolean generatedSource, StringBuffer generatedDepFile) { + boolean generatedSource, StringBuffer generatedDepFile, Vector enumeratedOutputs) { String resourceName = getFileName(resource); String inputExtension = resource.getFileExtension(); -// String cmd = info.getToolForSource(inputExtension); String outputExtension = info.getOutputExtension(inputExtension); - String outflag = null; - String outputPrefix = null; - IManagedDependencyGenerator depGen = info.getDependencyGenerator(inputExtension); - boolean doDepGen = (depGen != null && depGen.getCalculatorType() == IManagedDependencyGenerator.TYPE_COMMAND); - boolean patternRule = false; - - // If the tool creates a dependency file, add it to the list - if (doDepGen) { - String depFile = relativePath + resourceName + DOT + DEP_EXT; - getDependencyMakefiles().add(depFile); - generatedDepFile.append(resourceName + DOT + DEP_EXT); - } - - /* - * fix for PR 70491 - * We need to check if the current resource is LINKED, because - * the default CDT doesn't handle this properly. If it IS linked, - * then we must get the actual location of the resource, rather - * than the relative path. - */ - IPath resourceLocation = resource.getLocation(); - String projectLocation = project.getLocation().toString(); - String resourcePath = null; - String buildRule = null; - String OptDotExt = ""; //$NON-NLS-1$ - boolean isItLinked = false; - - if (outputExtension != null && outputExtension.length() > 0) - OptDotExt = DOT + outputExtension; - - IConfiguration config = info.getDefaultConfiguration(); // We need to check whether we have any resource specific build information. IResourceConfiguration resConfig = null; @@ -1951,11 +1953,56 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { } else { tool = info.getToolFromInputExtension(inputExtension); } + + // Get the dependency generator associated with this tool and file extension + IManagedDependencyGenerator depGen = tool.getDependencyGeneratorForExtension(inputExtension); + boolean doDepGen = (depGen != null && depGen.getCalculatorType() == IManagedDependencyGenerator.TYPE_COMMAND); + + // If the tool creates a dependency file, add it to the list + if (doDepGen) { + String depFile = relativePath + resourceName + DOT + DEP_EXT; + getDependencyMakefiles().add(depFile); + generatedDepFile.append(resourceName + DOT + DEP_EXT); + } - //optput file location needed for the file-specific build macros - IPath outputLocation = project.getLocation().append(getBuildWorkingDir()).append(relativePath + resourceName + OptDotExt); - //the separate rule is needed for the resource in case the explicit file-specific macros - //are referenced + // Figure out the output paths + String OptDotExt = EMPTY_STRING; + if (outputExtension != null && outputExtension.length() > 0) + OptDotExt = DOT + outputExtension; + + Vector ruleOutputs = new Vector(); + Vector enumeratedPrimaryOutputs = new Vector(); + Vector enumeratedSecondaryOutputs = new Vector(); + calculateOutputsForSource(tool, relativePath, resource, ruleOutputs, enumeratedPrimaryOutputs, enumeratedSecondaryOutputs); + enumeratedOutputs.addAll(enumeratedPrimaryOutputs); + enumeratedOutputs.addAll(enumeratedSecondaryOutputs); + String primaryOutputName = null; + if (enumeratedPrimaryOutputs.size() > 0) { + primaryOutputName = ((IPath)enumeratedPrimaryOutputs.get(0)).toString(); + } else { + primaryOutputName = relativePath + resourceName + OptDotExt; + } + String otherPrimaryOutputs = EMPTY_STRING; + for (int i=1; i 0 || MacroResolver.getReferencedExplitFileMacros(tool.getToolCommand(),IBuildMacroProvider.CONTEXT_FILE, new FileContextData(resourceLocation,outputLocation,null,config.getToolChain())).length > 0; //get and resolve command @@ -1972,47 +2019,78 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { } catch (BuildMacroException e){ } - // figure out path to use to resource - String primaryOutputName = EMPTY_STRING; + String defaultOutputName = EMPTY_STRING; String primaryDependencyName = EMPTY_STRING; + String home = (generatedSource)? DOT : ROOT; + String resourcePath = null; + boolean patternRule = true; + //boolean isItLinked = false; //if (resource.isLinked()) { NOTE: we don't use this since children of linked resources return false if(!resourceLocation.toString().startsWith(projectLocation)) { // it IS linked, so use the actual location - isItLinked = true; + //isItLinked = true; resourcePath = resourceLocation.toString(); // Need a hardcoded rule, not a pattern rule, as a linked file // can reside in any path - primaryOutputName = relativePath + resourceName + OptDotExt; + defaultOutputName = relativePath + resourceName + OptDotExt; primaryDependencyName = 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 - String home = (generatedSource)? DOT : ROOT; if( resConfig != null || fileExplicitMacrosReferenced) { // Need a hardcoded rule, not a pattern rule - primaryOutputName = resourcePath + resourceName + OptDotExt; + defaultOutputName = resourcePath + resourceName + OptDotExt; primaryDependencyName = home + SEPARATOR + resourcePath + resourceName + DOT + inputExtension; + patternRule = false; } else { - primaryOutputName = relativePath + WILDCARD + OptDotExt; + defaultOutputName = relativePath + WILDCARD + OptDotExt; primaryDependencyName = home + SEPARATOR + resourcePath + WILDCARD + DOT + inputExtension; - patternRule = true; } } // end fix for PR 70491 - - buildRule = primaryOutputName; - - // If this is a pattern rule, add any additional outputs here - String otherPrimaryOutputs = EMPTY_STRING; + + // If we still think that we are using a pattern rule, make sure that at least one of the rule + // outputs contains a %. if (patternRule) { - Vector addlOutputs = calculateOutputsForSource(tool, relativePath, resource, true); - for (int i=0; i= 0) { //$NON-NLS-1$ + patternRule = true; + break; + } + } + if (!patternRule) { + // Need to reset the primary dependency to be a filename rather than a pattern + primaryDependencyName = home + SEPARATOR + resourcePath + resourceName + DOT + inputExtension; } } + + // 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= 0) { //$NON-NLS-1$ + if (first) { + first = false; + } else { + buildRule += WHITESPACE; + } + buildRule += ruleOutput; + } + } + } + } else { + buildRule += primaryOutputName; + } - buildRule += otherPrimaryOutputs + COLON + WHITESPACE + primaryDependencyName; + buildRule += COLON + WHITESPACE + primaryDependencyName; // Other additional inputs // Get any additional dependencies specified for the tool in other InputType elements and AdditionalInput elements @@ -2021,19 +2099,26 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { buildRule += WHITESPACE + addlDepPaths[i].toString(); } - // No duplicates in a makefile + // No duplicates in a makefile. If we already have this rule, return if (getRuleList().contains(buildRule)) { + // TODO: Should we assert that this is a pattern rule? return; } else { getRuleList().add(buildRule); } + + // Echo starting message buffer.append(buildRule + NEWLINE); buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + MESSAGE_START_FILE + WHITESPACE + IN_MACRO + SINGLE_QUOTE + NEWLINE); + // Generate the command line IManagedCommandLineInfo cmdLInfo = null; Vector inputs = new Vector(); inputs.add(IN_MACRO); + String outflag = null; + String outputPrefix = null; + if( resConfig != null || fileExplicitMacrosReferenced) { buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + tool.getAnnouncement() + SINGLE_QUOTE + NEWLINE); outflag = tool.getOutputFlag(); @@ -2111,13 +2196,14 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { } } - // If this is NOT a pattern rule, add any additional outputs here using dependency lines - if (!patternRule) { - Vector addlOutputs = calculateOutputsForSource(tool, relativePath, resource, true); - for (int i=0; imake. if (multOfType) { @@ -2212,22 +2334,32 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // TODO - report error } else { String namePattern = type.getNamePattern(); + IPath namePatternPath = null; if (namePattern == null || namePattern.length() == 0) { - namePattern = outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; + namePattern = relativePath + outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; + if (outExt != null && outExt.length() > 0) { + namePattern += DOT + outExt; + } + namePatternPath = Path.fromOSString(namePattern); } - else if (outputPrefix.length() > 0) { - namePattern = outputPrefix + namePattern; - } - if (outExt != null && outExt.length() > 0) { - namePattern += DOT + outExt; + else { + if (outputPrefix.length() > 0) { + namePattern = outputPrefix + namePattern; + } + namePatternPath = Path.fromOSString(namePattern); + // If only a file name is specified, add the relative path of this output directory + if (namePatternPath.segmentCount() == 1) { + namePatternPath = Path.fromOSString(relativePath + namePatternPath.toString()); + } } - // Get the input file name - String fileName = resource.getFullPath().removeFileExtension().lastSegment(); - // Replace the % with the file name - String outName = namePattern.replaceAll("%", fileName); //$NON-NLS-1$ - IPath outPath = Path.fromOSString(outName); - outputs.add(outPath); + if (primaryOutput) { + ruleOutputs.add(0, namePatternPath); + enumeratedPrimaryOutputs.add(0, resolvePercent(namePatternPath, resource)); + } else { + ruleOutputs.add(namePatternPath); + enumeratedSecondaryOutputs.add(resolvePercent(namePatternPath, resource)); + } } } } @@ -2239,21 +2371,28 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // In this case, the output file name is the input file name with // the output extension. - if (!ignorePrimary) { - IPath outPath = Path.fromOSString(resource.getFullPath().removeFileExtension().lastSegment()); + //if (!ignorePrimary) { String outPrefix = tool.getOutputPrefix(); - if (outPrefix.length() > 0) { - String outName = outPrefix + outPath.lastSegment(); - outPath = outPath.removeLastSegments(1).append(outName); - } + IPath outPath = Path.fromOSString(relativePath + outPrefix + WILDCARD); outPath = outPath.addFileExtension(outExt); - outputs.add(outPath); - } + ruleOutputs.add(0, outPath); + enumeratedPrimaryOutputs.add(0, resolvePercent(outPath, resource)); + //} } - - return outputs; } - + + /* (non-Javadoc) + * If the path contains a %, returns the path resolved using the resource name + * + */ + protected IPath resolvePercent(IPath outPath, IResource resource) { + // Get the input file name + String fileName = resource.getFullPath().removeFileExtension().lastSegment(); + // Replace the % with the file name + String outName = outPath.toOSString().replaceAll("%", fileName); //$NON-NLS-1$ + return Path.fromOSString(outName); + } + /* (non-Javadoc) * Returns the dependency IPaths for this invocation of the tool with the specified source file * @@ -2416,6 +2555,30 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { map.put(macroName, buffer.toString()); } + /* (non-Javadoc) + * Adds a file to an entry in a map of macro names to entries. + * File additions look like: + * example.c, \ + */ + protected void addMacroAdditionFile(HashMap map, String macroName, + String relativePath, IResource resource, boolean generatedSource) { + // Add the resource name to the makefile line that adds resources to the build variable + String srcName; + if (generatedSource) { + srcName = resource.getName(); + } else { + String resourceLocation = resource.getLocation().toString(); + String projectLocation = project.getLocation().toString(); + //if (resource.isLinked()) { NOTE: we don't use this since children of linked resources return false + if(!resourceLocation.startsWith(projectLocation)) { + srcName = resourceLocation; + } else { + srcName = "$(ROOT)/" + relativePath + resource.getName(); //$NON-NLS-1$ + } + } + addMacroAdditionFile(map, macroName, srcName); + } + /* (non-Javadoc) * Adds file(s) to an entry in a map of macro names to entries. * File additions look like: @@ -2504,7 +2667,6 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { int[] doneState = new int[buildTools.length]; // Identify the target tool - IConfiguration config = info.getDefaultConfiguration(); ITool targetTool = config.getTargetTool(); if (targetTool == null) { targetTool = info.getToolFromOutputExtension(buildTargetExt); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java index 71f933b9831..0078034c988 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/ManagedBuildGnuToolInfo.java @@ -216,8 +216,10 @@ public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo { // Use file extensions if (variable.length() == 0 || useFileExts) { - if (type.getMultipleOfType()) { + //if (type.getMultipleOfType()) { // Calculate myEnumeratedInputs using the file extensions and the resources in the project + // Note: This is only correct for tools with multipleOfType == true, but for other tools + // it gives us an input resource for generating default names String[] exts = tool.getAllInputExtensions(); if (projResources != null) { for (int j=0; j 0 && outNames != null) { @@ -438,14 +444,14 @@ public class ManagedBuildGnuToolInfo implements IManagedBuildGnuToolInfo { String namePattern = type.getNamePattern(); if (namePattern == null || namePattern.length() == 0) { namePattern = outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD; + String outExt = (type.getOutputExtensions())[0]; + if (outExt != null && outExt.length() > 0) { + namePattern += DOT + outExt; + } } else if (outputPrefix.length() > 0) { namePattern = outputPrefix + namePattern; } - String outExt = (type.getOutputExtensions())[0]; - if (outExt != null && outExt.length() > 0) { - namePattern += DOT + outExt; - } // Calculate the output name // The inputs must have been calculated before we can do this