diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml index 565b947e544..455c53885ea 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/plugin.xml @@ -9391,6 +9391,15 @@ resourceFilter="all" valueType="string"> + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java index 3d6bfe896f1..c10b4405bec 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuiltinSpecsDetectorTest.java @@ -84,6 +84,15 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { } } + class MockLspToolchainBuiltinSpecsDetectorCommandResolver extends MockGCCBuiltinSpecsDetectorCommandResolver { + // ID must match the tool-chain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point + private static final String MOCK_TOOLCHAIN_ID = "cdt.managedbuilder.lsp.tests.toolchain"; + @Override + public String getToolchainId() { + return MOCK_TOOLCHAIN_ID; + } + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -163,6 +172,19 @@ public class GCCBuiltinSpecsDetectorTest extends BaseTestCase { } } + /** + * Test expansion of relevant tool options in build command. + */ + public void testGCCBuiltinSpecsDetector_ResolvedCommand_Flags() throws Exception { + // check ${FLAGS} + MockLspToolchainBuiltinSpecsDetectorCommandResolver detector = new MockLspToolchainBuiltinSpecsDetectorCommandResolver(); + detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID_C);}}); + detector.setCommand("gcc ${FLAGS}"); + + String resolvedCommand = detector.resolveCommand(LANGUAGE_ID_C); + assertEquals("gcc -bool-option -str-option=str-value -enum-option -list-option1 -list-option2 -tree-option", resolvedCommand); + } + /** * Test parsing of macro without value. */ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties index 20bc65cd8d1..7cbc02775af 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties @@ -42,7 +42,7 @@ ManagedMakeBuilder.warning.unsupported.configuration=**** WARNING: The "{0}" Co ManagedMakeBuilder.error.prefix=Error: # Option exception messages -Option.error.bad_value_type=Bad value for type +Option.error.bad_value_type=Type of option value is inconsistent with option type # Managed build manager exception messages ManagedBuildManager.error.owner_not_null=addTarget: owner not null diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java index 2287de07a38..4ab8d3246a8 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuiltinSpecsDetector.java @@ -93,6 +93,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti public static final String JOB_FAMILY_BUILTIN_SPECS_DETECTOR = "org.eclipse.cdt.managedbuilder.AbstractBuiltinSpecsDetector"; //$NON-NLS-1$ protected static final String COMPILER_MACRO = "${COMMAND}"; //$NON-NLS-1$ + protected static final String FLAGS_MACRO = "${FLAGS}"; //$NON-NLS-1$ protected static final String SPEC_FILE_MACRO = "${INPUTS}"; //$NON-NLS-1$ protected static final String SPEC_EXT_MACRO = "${EXT}"; //$NON-NLS-1$ protected static final String SPEC_FILE_BASE = "spec"; //$NON-NLS-1$ @@ -305,6 +306,11 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti if (compiler != null) cmd = cmd.replace(COMPILER_MACRO, compiler); } + if (cmd.contains(FLAGS_MACRO)) { + String flags = getToolOptions(languageId); + if (flags != null) + cmd = cmd.replace(FLAGS_MACRO, flags); + } if (cmd.contains(SPEC_FILE_MACRO)) { String specFileName = getSpecFile(languageId); if (specFileName != null) @@ -814,6 +820,17 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti return ext; } + /** + * Determine additional options to pass to scanner discovery command. + * These options are intended to come from the tool-chain. + * + * @param languageId - language ID. + * @return additional options to pass to scanner discovery command. + */ + protected String getToolOptions(String languageId) { + return ""; //$NON-NLS-1$ + } + @Override public Element serializeAttributes(Element parentElement) { Element elementProvider = super.serializeAttributes(parentElement); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java index cb4ccc7639b..0fbb79a93c3 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/ToolchainBuiltinSpecsDetector.java @@ -16,8 +16,10 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; @@ -39,6 +41,7 @@ import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManager * @since 8.1 */ public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector { + private static final String EMPTY_QUOTED_STRING = "\"\""; //$NON-NLS-1$ private Map toolMap = new HashMap(); /** @@ -55,13 +58,16 @@ public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecs * This returns the first tool found. */ private ITool getTool(String languageId) { - ITool tool = toolMap.get(languageId); - if (tool != null) { - return tool; + if (currentCfgDescription == null) { + ITool tool = toolMap.get(languageId); + if (tool != null) { + return tool; + } } String toolchainId = null; IToolChain toolchain = null; + ITool tool = null; if (currentCfgDescription != null) { IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(currentCfgDescription); toolchain = cfg != null ? cfg.getToolChain() : null; @@ -130,6 +136,58 @@ public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecs return ext; } + @Override + protected String getToolOptions(String languageId) { + String flags = ""; //$NON-NLS-1$ + ITool tool = getTool(languageId); + if (tool != null) { + IOption[] options = tool.getOptions(); + for (IOption option : options) { + if (option.isForScannerDiscovery()) { + try { + String optionValue = null; + switch (option.getBasicValueType()) { + case IOption.BOOLEAN: + if (option.getBooleanValue()) { + optionValue = option.getCommand(); + } else { + optionValue = option.getCommandFalse(); + } + break; + case IOption.ENUMERATED: + optionValue = option.getEnumCommand(option.getSelectedEnum()); + break; + case IOption.STRING: + optionValue = option.getCommand() + option.getStringValue(); + break; + case IOption.STRING_LIST: + String[] values = option.getBasicStringListValue(); + if(values != null) { + optionValue = ""; //$NON-NLS-1$ + String cmd = option.getCommand(); + for (String value : values) { + if(!value.isEmpty() && !value.equals(EMPTY_QUOTED_STRING)) + optionValue = optionValue + cmd + value + ' '; + } + } + break; + case IOption.TREE: + optionValue = option.getCommand(option.getStringValue()); + break; + default: + } + if (optionValue != null) { + flags = flags + ' ' + optionValue.trim(); + } + } catch (BuildException e) { + ManagedBuilderCorePlugin.log(e); + } + } + } + } + return flags.trim(); + } + @Override protected List getEnvironmentVariables() { if (envMngr == null && currentCfgDescription == null) {