use of org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData in project arduino-eclipse-plugin by Sloeber.
the class ArduinoManagedBuildGnuToolInfo method calculateOutputs.
/*
* The priorities for determining the names of the outputs of a tool are: 1.
* If the tool is the build target and primary output, use artifact name &
* extension 2. If an option is specified, use the value of the option 3. If
* a nameProvider is specified, call it 4. If outputNames is specified, use
* it 5. Use the name pattern to generate a transformation macro so that the
* source names can be transformed into the target names using the built-in
* string substitution functions of <code>make</code>.
*
* NOTE: If an option is not specified and this is not the primary output
* type, the outputs from the type are not added to the command line
*/
public boolean calculateOutputs(ArduinoGnuMakefileGenerator makeGen, IConfiguration config, HashSet<String> handledInputExtensions, boolean lastChance) {
boolean done = true;
Vector<String> myCommandOutputs = new Vector<>();
Vector<String> myEnumeratedPrimaryOutputs = new Vector<>();
Vector<String> myEnumeratedSecondaryOutputs = new Vector<>();
HashMap<String, List<IPath>> myOutputMacros = new HashMap<>();
// The next two fields are used together
Vector<String> myBuildVars = new Vector<>();
Vector<Vector<String>> myBuildVarsValues = new Vector<>();
// Get the outputs for this tool invocation
IOutputType[] outTypes = this.tool.getOutputTypes();
if (outTypes != null && outTypes.length > 0) {
for (int i = 0; i < outTypes.length; i++) {
Vector<String> typeEnumeratedOutputs = new Vector<>();
IOutputType type = outTypes[i];
String outputPrefix = type.getOutputPrefix();
if (config != null) {
try {
outputPrefix = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(// $NON-NLS-1$
outputPrefix, // $NON-NLS-1$
"", // $NON-NLS-1$
" ", IBuildMacroProvider.CONTEXT_CONFIGURATION, config);
} catch (BuildMacroException e) {
// JABA is not going to add
// code
}
}
String variable = type.getBuildVariable();
boolean multOfType = type.getMultipleOfType();
boolean primaryOutput = (type == this.tool.getPrimaryOutputType());
IOption option = this.tool.getOptionBySuperClassId(type.getOptionId());
IManagedOutputNameProvider nameProvider = type.getNameProvider();
String[] outputNames = type.getOutputNames();
// use artifact name & extension
if (this.bIsTargetTool && primaryOutput) {
String outputName = outputPrefix + this.targetName;
if (this.targetExt.length() > 0) {
outputName += (DOT + this.targetExt);
}
myCommandOutputs.add(outputName);
typeEnumeratedOutputs.add(outputName);
// But this doesn't use any output macro...
} else // 2. If an option is specified, use the value of the option
if (option != null) {
try {
List<String> outputs = new ArrayList<>();
int optType = option.getValueType();
if (optType == IOption.STRING) {
outputs.add(outputPrefix + option.getStringValue());
} else if (optType == IOption.STRING_LIST || optType == IOption.LIBRARIES || optType == IOption.OBJECTS || optType == IOption.INCLUDE_FILES || optType == IOption.LIBRARY_PATHS || optType == IOption.LIBRARY_FILES || optType == IOption.MACRO_FILES) {
@SuppressWarnings("unchecked") List<String> value = (List<String>) option.getValue();
outputs = value;
this.tool.filterValues(optType, outputs);
// Add outputPrefix to each if necessary
if (outputPrefix.length() > 0) {
for (int j = 0; j < outputs.size(); j++) {
outputs.set(j, outputPrefix + outputs.get(j));
}
}
}
for (int j = 0; j < outputs.size(); j++) {
String outputName = outputs.get(j);
try {
// try to resolve the build macros in the output
// names
String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(// $NON-NLS-1$
outputName, // $NON-NLS-1$
"", // $NON-NLS-1$
" ", IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option, this.tool));
if ((resolved = resolved.trim()).length() > 0)
outputs.set(j, resolved);
} catch (BuildMacroException e) {
// JABA is not
// going to add
// code
}
}
// NO - myCommandOutputs.addAll(outputs);
typeEnumeratedOutputs.addAll(outputs);
if (variable.length() > 0) {
List<IPath> outputPaths = new ArrayList<>();
for (int j = 0; j < outputs.size(); j++) {
outputPaths.add(Path.fromOSString(outputs.get(j)));
}
if (myOutputMacros.containsKey(variable)) {
List<IPath> currList = myOutputMacros.get(variable);
currList.addAll(outputPaths);
myOutputMacros.put(variable, currList);
} else {
myOutputMacros.put(variable, outputPaths);
}
}
} catch (BuildException ex) {
// JABA is not going to add
// code
}
} else // 3. If a nameProvider is specified, call it
if (nameProvider != null) {
// The inputs must have been calculated before we can do
// this
IPath[] outNames = null;
if (!this.inputsCalculated) {
done = false;
} else {
Vector<String> inputs = getEnumeratedInputs();
IPath[] inputPaths = new IPath[inputs.size()];
for (int j = 0; j < inputPaths.length; j++) {
inputPaths[j] = Path.fromOSString(inputs.get(j));
}
// if (inputPaths.length == 0) {
try {
IManagedOutputNameProviderJaba newNameProvider = (IManagedOutputNameProviderJaba) nameProvider;
outNames = newNameProvider.getOutputNames(this.project, config, this.tool, inputPaths);
} catch (Exception e) {
// The provided class is not a
// IManagedOutputNameProviderJaba class;
Common.log(new Status(IStatus.ERROR, Const.CORE_PLUGIN_ID, "The provided class is not of type IManagedOutputNameProviderJaba", // $NON-NLS-1$
e));
}
// JABA end of insertion
if (outNames != null) {
for (int j = 0; j < outNames.length; j++) {
String outputName = outNames[j].toOSString();
try {
// try to resolve the build macros in the
// output names
String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(// $NON-NLS-1$
outputName, // $NON-NLS-1$
"", // $NON-NLS-1$
" ", IBuildMacroProvider.CONTEXT_CONFIGURATION, config);
if ((resolved = resolved.trim()).length() > 0) {
outputName = resolved;
outNames[j] = Path.fromOSString(resolved);
}
} catch (BuildMacroException e) {
// JABA is not
// going to add
// code
}
if (primaryOutput) {
myCommandOutputs.add(outputName);
}
typeEnumeratedOutputs.add(outputName);
}
}
}
if (variable.length() > 0 && outNames != null) {
if (myOutputMacros.containsKey(variable)) {
List<IPath> currList = myOutputMacros.get(variable);
currList.addAll(Arrays.asList(outNames));
myOutputMacros.put(variable, currList);
} else {
myOutputMacros.put(variable, new ArrayList<>(Arrays.asList(outNames)));
}
}
} else // 4. If outputNames is specified, use it
if (outputNames != null) {
if (outputNames.length > 0) {
for (int j = 0; j < outputNames.length; j++) {
String outputName = outputNames[j];
try {
// try to resolve the build macros in the output
// names
String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(// $NON-NLS-1$
outputName, // $NON-NLS-1$
"", // $NON-NLS-1$
" ", IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option, this.tool));
if ((resolved = resolved.trim()).length() > 0)
outputNames[j] = resolved;
} catch (BuildMacroException e) {
// JABA is not
// going to add
// code
}
}
List<String> namesList = Arrays.asList(outputNames);
if (primaryOutput) {
myCommandOutputs.addAll(namesList);
}
typeEnumeratedOutputs.addAll(namesList);
if (variable.length() > 0) {
List<IPath> outputPaths = new ArrayList<>();
for (int j = 0; j < namesList.size(); j++) {
outputPaths.add(Path.fromOSString(namesList.get(j)));
}
if (myOutputMacros.containsKey(variable)) {
List<IPath> currList = myOutputMacros.get(variable);
currList.addAll(outputPaths);
myOutputMacros.put(variable, currList);
} else {
myOutputMacros.put(variable, outputPaths);
}
}
}
} else {
// <code>make</code>.
if (multOfType) {
// This case is not handled - a nameProvider or
// outputNames must be specified
List<String> errList = new ArrayList<>();
// $NON-NLS-1$
errList.add(ManagedMakeMessages.getResourceString("MakefileGenerator.error.no.nameprovider"));
myCommandOutputs.addAll(errList);
} else {
String namePattern = type.getNamePattern();
if (namePattern == null || namePattern.length() == 0) {
namePattern = outputPrefix + IManagedBuilderMakefileGenerator.WILDCARD;
String outExt = (type.getOutputExtensions(this.tool))[0];
if (outExt != null && outExt.length() > 0) {
namePattern += DOT + outExt;
}
} else if (outputPrefix.length() > 0) {
namePattern = outputPrefix + namePattern;
}
// this
if (!this.inputsCalculated) {
done = false;
} else {
Vector<String> inputs = getEnumeratedInputs();
String fileName;
if (inputs.size() > 0) {
// Get the input file name
fileName = (Path.fromOSString(inputs.get(0))).removeFileExtension().lastSegment();
// the raw macro name.
if (fileName.startsWith("$(") && fileName.endsWith(")")) {
// $NON-NLS-1$ //$NON-NLS-2$
fileName = fileName.substring(2, fileName.length() - 1);
}
} else {
// $NON-NLS-1$
fileName = "default";
}
// Replace the % with the file name
if (primaryOutput) {
// $NON-NLS-1$
myCommandOutputs.add(namePattern.replaceAll("%", fileName));
}
// $NON-NLS-1$
typeEnumeratedOutputs.add(namePattern.replaceAll("%", fileName));
if (variable.length() > 0) {
List<IPath> outputs = new ArrayList<>();
outputs.add(Path.fromOSString(fileName));
if (myOutputMacros.containsKey(variable)) {
List<IPath> currList = myOutputMacros.get(variable);
currList.addAll(outputs);
myOutputMacros.put(variable, currList);
} else {
myOutputMacros.put(variable, outputs);
}
}
}
}
}
if (variable.length() > 0) {
myBuildVars.add(variable);
myBuildVarsValues.add(typeEnumeratedOutputs);
}
if (primaryOutput) {
myEnumeratedPrimaryOutputs.addAll(typeEnumeratedOutputs);
} else {
myEnumeratedSecondaryOutputs.addAll(typeEnumeratedOutputs);
}
}
} else {
if (this.bIsTargetTool) {
String outputPrefix = this.tool.getOutputPrefix();
String outputName = outputPrefix + this.targetName;
if (this.targetExt.length() > 0) {
outputName += (DOT + this.targetExt);
}
myCommandOutputs.add(outputName);
myEnumeratedPrimaryOutputs.add(outputName);
} else {
// For support of pre-CDT 3.0 integrations.
// NOTE WELL: This only supports the case of a single
// "target tool"
// that consumes exactly all of the object files, $OBJS,
// produced
// by other tools in the build and produces a single output
}
}
// Add the output macros of this tool to the buildOutVars map
Set<Entry<String, List<IPath>>> entrySet = myOutputMacros.entrySet();
for (Entry<String, List<IPath>> entry : entrySet) {
String macroName = entry.getKey();
List<IPath> newMacroValue = entry.getValue();
Map<String, List<IPath>> map = makeGen.getBuildOutputVars();
if (map.containsKey(macroName)) {
List<IPath> macroValue = map.get(macroName);
macroValue.addAll(newMacroValue);
map.put(macroName, macroValue);
} else {
map.put(macroName, newMacroValue);
}
}
this.outputVariablesCalculated = true;
if (done) {
this.commandOutputs.addAll(myCommandOutputs);
this.enumeratedPrimaryOutputs.addAll(myEnumeratedPrimaryOutputs);
this.enumeratedSecondaryOutputs.addAll(myEnumeratedSecondaryOutputs);
this.outputVariables.addAll(myOutputMacros.keySet());
this.outputsCalculated = true;
for (int i = 0; i < myBuildVars.size(); i++) {
makeGen.addMacroAdditionFiles(makeGen.getTopBuildOutputVars(), myBuildVars.get(i), myBuildVarsValues.get(i));
}
return true;
}
return false;
}
use of org.eclipse.cdt.managedbuilder.internal.macros.OptionContextData in project arduino-eclipse-plugin by Sloeber.
the class ArduinoManagedBuildGnuToolInfo method calculateInputs.
/*
* Other Methods
*/
public boolean calculateInputs(ArduinoGnuMakefileGenerator makeGen, IConfiguration config, IResource[] projResources, ToolInfoHolder h, boolean lastChance) {
// Get the inputs for this tool invocation
// Note that command inputs that are also dependencies are also added to
// the command dependencies list
/*
* The priorities for determining the names of the inputs of a tool are:
* 1. If an option is specified, use the value of the option. 2. If a
* build variable is specified, use the files that have been added to
* the build variable as the output(s) of other build steps. 3. Use the
* file extensions and the resources in the project
*/
boolean done = true;
// Inputs for the
Vector<String> myCommandInputs = new Vector<>();
// tool command
// line
// Dependencies
Vector<String> myCommandDependencies = new Vector<>();
// for the
// make
// rule
// Complete
Vector<String> myEnumeratedInputs = new Vector<>();
// list of
// individual
// inputs
IInputType[] inTypes = this.tool.getInputTypes();
if (inTypes != null && inTypes.length > 0) {
for (IInputType type : inTypes) {
// Inputs
Vector<String> itCommandInputs = new Vector<>();
// for
// the
// tool
// command
// line
// for
// this
// input-type
// Dependencies
Vector<String> itCommandDependencies = new Vector<>();
// for
// the
// make
// rule
// for
// this
// input-type
// Complete
Vector<String> itEnumeratedInputs = new Vector<>();
// list
// of
// individual
// inputs
// for
// this
// input-type
String variable = type.getBuildVariable();
boolean primaryInput = type.getPrimaryInput();
boolean useFileExts = false;
IOption option = this.tool.getOptionBySuperClassId(type.getOptionId());
IOption assignToOption = this.tool.getOptionBySuperClassId(type.getAssignToOptionId());
// Option?
if (option != null) {
try {
List<String> inputs = new ArrayList<>();
int optType = option.getValueType();
if (optType == IOption.STRING) {
inputs.add(option.getStringValue());
} else if (optType == IOption.STRING_LIST || optType == IOption.LIBRARIES || optType == IOption.OBJECTS || optType == IOption.INCLUDE_FILES || optType == IOption.LIBRARY_PATHS || optType == IOption.LIBRARY_FILES || optType == IOption.MACRO_FILES) {
@SuppressWarnings("unchecked") List<String> valueList = (List<String>) option.getValue();
inputs = valueList;
this.tool.filterValues(optType, inputs);
this.tool.filterValues(optType, inputs);
}
for (int j = 0; j < inputs.size(); j++) {
String inputName = inputs.get(j);
try {
// try to resolve the build macros in the output
// names
String resolved = null;
// TODO: support other special characters
if (// $NON-NLS-1$
inputName.indexOf(" ") != -1) {
// resolve to string
resolved = // $NON-NLS-1$
ManagedBuildManager.getBuildMacroProvider().resolveValue(// $NON-NLS-1$
inputName, // $NON-NLS-1$
"", // $NON-NLS-1$
" ", IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option, this.tool));
} else {
// resolve to makefile variable format
resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(// $NON-NLS-1$
inputName, // $NON-NLS-1$
"", // $NON-NLS-1$
" ", IBuildMacroProvider.CONTEXT_OPTION, new OptionContextData(option, this.tool));
}
if ((resolved = resolved.trim()).length() > 0)
inputName = resolved;
} catch (BuildMacroException e) {
// JABA is not
// going to add
// code
}
if (primaryInput) {
itCommandDependencies.add(j, inputName);
} else {
itCommandDependencies.add(inputName);
}
// NO - itCommandInputs.add(inputName);
// NO - itEnumeratedInputs.add(inputName);
}
} catch (BuildException ex) {
// JABA is not going to add
// code
}
} else {
// Build Variable?
if (variable.length() > 0) {
// $NON-NLS-1$ //$NON-NLS-2$
String cmdVariable = variable = "$(" + variable + ")";
itCommandInputs.add(cmdVariable);
if (primaryInput) {
itCommandDependencies.add(0, cmdVariable);
} else {
itCommandDependencies.add(cmdVariable);
}
// If there is an output variable with the same name,
// get
// the files associated with it.
List<String> outMacroList = makeGen.getBuildVariableList(h, variable, ArduinoGnuMakefileGenerator.PROJECT_RELATIVE, null, true);
if (outMacroList != null) {
itEnumeratedInputs.addAll(outMacroList);
} else {
// extensions below
if (lastChance) {
useFileExts = true;
} else {
done = false;
break;
}
}
}
// Use file extensions
if (variable.length() == 0 || useFileExts) {
// if (type.getMultipleOfType()) {
// Calculate EnumeratedInputs 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
// Determine the set of source input macros to use
HashSet<String> handledInputExtensions = new HashSet<>();
String[] exts = type.getSourceExtensions(this.tool);
if (projResources != null) {
for (IResource rc : projResources) {
if (rc.getType() == IResource.FILE) {
String fileExt = rc.getFileExtension();
// fix for NPE, bugzilla 99483
if (fileExt == null) {
// $NON-NLS-1$
fileExt = "";
}
for (int k = 0; k < exts.length; k++) {
if (fileExt.equals(exts[k])) {
if (!useFileExts) {
if (!handledInputExtensions.contains(fileExt)) {
handledInputExtensions.add(fileExt);
String buildMacro = // $NON-NLS-1$
"$(" + makeGen.getSourceMacroName(fileExt).toString() + // $NON-NLS-1$
")";
itCommandInputs.add(buildMacro);
if (primaryInput) {
itCommandDependencies.add(0, buildMacro);
} else {
itCommandDependencies.add(buildMacro);
}
}
}
if (type.getMultipleOfType() || itEnumeratedInputs.size() == 0) {
// Add a path that is relative
// to the project directory
itEnumeratedInputs.add(rc.getProjectRelativePath().toOSString());
}
break;
}
}
}
}
}
// }
}
}
// Get any additional inputs specified in the manifest file or
// the project file
IAdditionalInput[] addlInputs = type.getAdditionalInputs();
if (addlInputs != null) {
for (int j = 0; j < addlInputs.length; j++) {
IAdditionalInput addlInput = addlInputs[j];
int kind = addlInput.getKind();
if (kind == IAdditionalInput.KIND_ADDITIONAL_INPUT || kind == IAdditionalInput.KIND_ADDITIONAL_INPUT_DEPENDENCY) {
String[] paths = addlInput.getPaths();
if (paths != null) {
for (int k = 0; k < paths.length; k++) {
String path = paths[k];
itEnumeratedInputs.add(path);
// to build directory relative
if (!(path.startsWith("$("))) {
// $NON-NLS-1$
IResource addlResource = this.project.getFile(path);
if (addlResource != null) {
IPath addlPath = addlResource.getLocation();
if (addlPath != null) {
path = ManagedBuildManager.calculateRelativePath(makeGen.getTopBuildDir(), addlPath).toOSString();
}
}
}
itCommandInputs.add(path);
}
}
}
}
}
// input(s) as the value of that option
if (assignToOption != null && option == null) {
try {
int optType = assignToOption.getValueType();
if (optType == IOption.STRING) {
// $NON-NLS-1$
String optVal = "";
for (int j = 0; j < itCommandInputs.size(); j++) {
if (j != 0) {
// $NON-NLS-1$
optVal += " ";
}
optVal += itCommandInputs.get(j);
}
ManagedBuildManager.setOption(config, this.tool, assignToOption, optVal);
} else if (optType == IOption.STRING_LIST || optType == IOption.LIBRARIES || optType == IOption.OBJECTS || optType == IOption.INCLUDE_FILES || optType == IOption.LIBRARY_PATHS || optType == IOption.LIBRARY_FILES || optType == IOption.MACRO_FILES) {
// TODO: do we need to do anything with undefs here?
// Mote that when using the enumerated inputs, the
// path(s) must be translated from project relative
// to top build directory relative
String[] paths = new String[itEnumeratedInputs.size()];
for (int j = 0; j < itEnumeratedInputs.size(); j++) {
paths[j] = itEnumeratedInputs.get(j);
IResource enumResource = this.project.getFile(paths[j]);
if (enumResource != null) {
IPath enumPath = enumResource.getLocation();
if (enumPath != null) {
paths[j] = ManagedBuildManager.calculateRelativePath(makeGen.getTopBuildDir(), enumPath).toOSString();
}
}
}
ManagedBuildManager.setOption(config, this.tool, assignToOption, paths);
} else if (optType == IOption.BOOLEAN) {
if (itEnumeratedInputs.size() > 0) {
ManagedBuildManager.setOption(config, this.tool, assignToOption, true);
} else {
ManagedBuildManager.setOption(config, this.tool, assignToOption, false);
}
} else if (optType == IOption.ENUMERATED || optType == IOption.TREE) {
if (itCommandInputs.size() > 0) {
ManagedBuildManager.setOption(config, this.tool, assignToOption, itCommandInputs.firstElement());
}
}
itCommandInputs.removeAllElements();
// itEnumeratedInputs.removeAllElements();
} catch (BuildException ex) {
// JABA is not going to add
// code
}
}
myCommandInputs.addAll(itCommandInputs);
myCommandDependencies.addAll(itCommandDependencies);
myEnumeratedInputs.addAll(itEnumeratedInputs);
}
} else {
// For support of pre-CDT 3.0 integrations.
if (this.bIsTargetTool) {
// NOTE WELL: This only supports the case of a single
// "target tool"
// with the following characteristics:
// 1. The tool consumes exactly all of the object files produced
// by other tools in the build and produces a single output
// 2. The target name comes from the configuration artifact name
// The rule looks like:
// <targ_prefix><target>.<extension>: $(OBJS) <refd_project_1
// ... refd_project_n>
// $NON-NLS-1$
myCommandInputs.add("$(OBJS)");
// $NON-NLS-1$
myCommandInputs.add("$(USER_OBJS)");
// $NON-NLS-1$
myCommandInputs.add("$(LIBS)");
} else {
// Rule will be generated by addRuleForSource
}
}
if (done) {
this.commandInputs.addAll(myCommandInputs);
this.commandDependencies.addAll(0, myCommandDependencies);
this.enumeratedInputs.addAll(myEnumeratedInputs);
this.inputsCalculated = true;
return true;
}
return false;
}
Aggregations