diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java index 38a8de16414..460f9508ea1 100644 --- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java +++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java @@ -47,6 +47,8 @@ import org.eclipse.core.runtime.PlatformObject; public class GCCToolChain extends PlatformObject implements IToolChain { private final IToolChainProvider provider; + private final String id; + private final String version; private final String name; private final Path path; private final String prefix; @@ -55,17 +57,19 @@ public class GCCToolChain extends PlatformObject implements IToolChain { protected String[] compileCommands; - public GCCToolChain(IToolChainProvider provider, String name) { - this(provider, name, null, null); + public GCCToolChain(IToolChainProvider provider, String id, String version) { + this(provider, id, version, null, null); } - public GCCToolChain(IToolChainProvider provider, String name, Path path) { - this(provider, name, path, null); + public GCCToolChain(IToolChainProvider provider, String id, String version, Path path) { + this(provider, id, version, path, null); } - public GCCToolChain(IToolChainProvider provider, String name, Path path, String prefix) { + public GCCToolChain(IToolChainProvider provider, String id, String version, Path path, String prefix) { this.provider = provider; - this.name = name; + this.id = id; + this.version = version; + this.name = id + " - " + version; //$NON-NLS-1$ this.path = path; this.prefix = prefix; @@ -84,6 +88,16 @@ public class GCCToolChain extends PlatformObject implements IToolChain { return provider; } + @Override + public String getId() { + return id; + } + + @Override + public String getVersion() { + return version; + } + @Override public String getName() { return name; @@ -100,6 +114,20 @@ public class GCCToolChain extends PlatformObject implements IToolChain { } return null; } + + @Override + public String getBinaryParserId() { + // Assume local builds + // TODO be smarter and use the id which should be the target + switch (Platform.getOS()) { + case Platform.OS_WIN32: + return CCorePlugin.PLUGIN_ID + ".PE"; //$NON-NLS-1$ + case Platform.OS_MACOSX: + return CCorePlugin.PLUGIN_ID + ".MachO64"; //$NON-NLS-1$ + default: + return CCorePlugin.PLUGIN_ID + ".ELF"; //$NON-NLS-1$ + } + } protected void addDiscoveryOptions(List command) { command.add("-E"); //$NON-NLS-1$ diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java index c057e806bda..f9967defeb3 100644 --- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java +++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/GCCPathToolChainProvider.java @@ -28,15 +28,17 @@ public class GCCPathToolChainProvider implements IToolChainProvider { private static final String ID = "org.eclipse.cdt.build.gcc.core.gccPathProvider"; //$NON-NLS-1$ private static final Pattern gccPattern = Pattern.compile("(.*-)?(gcc|g\\+\\+|clang|clang\\+\\+)"); //$NON-NLS-1$ + private static final Pattern versionPattern = Pattern.compile(".*(gcc|LLVM) version .*"); //$NON-NLS-1$ + private static final Pattern targetPattern = Pattern.compile("Target: (.*)"); //$NON-NLS-1$ @Override public String getId() { return ID; } - + @Override public void init(IToolChainManager manager) { - Set versions = new HashSet<>(); + Set names = new HashSet<>(); String path = System.getenv("PATH"); //$NON-NLS-1$ for (String dirStr : path.split(File.pathSeparator)) { @@ -47,52 +49,40 @@ public class GCCPathToolChainProvider implements IToolChainProvider { if (matcher.matches()) { String prefix = matcher.group(1); String command = dirStr + File.separatorChar + file; - String version = getVersion(command); - if (version != null && !versions.contains(version)) { - versions.add(version); - manager.addToolChain(new GCCToolChain(this, version, dir.toPath(), prefix)); + try { + Process proc = new ProcessBuilder(new String[] { command, "-v" }).redirectErrorStream(true) //$NON-NLS-1$ + .start(); + String version = null; + String target = null; + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(proc.getInputStream()))) { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + Matcher versionMatcher = versionPattern.matcher(line); + if (versionMatcher.matches()) { + version = line.trim(); + continue; + } + Matcher targetMatcher = targetPattern.matcher(line); + if (targetMatcher.matches()) { + target = targetMatcher.group(1); + continue; + } + } + } + if (target != null && version != null) { + String name = target + " - " + version; //$NON-NLS-1$ + if (!names.contains(name)) { + names.add(name); + manager.addToolChain(new GCCToolChain(this, target, version, dir.toPath(), prefix)); + } + } + } catch (IOException e) { + Activator.log(e); } } } } } } - - private static Pattern versionPattern = Pattern.compile(".*(gcc|LLVM) version .*"); //$NON-NLS-1$ - private static Pattern targetPattern = Pattern.compile("Target: (.*)"); //$NON-NLS-1$ - - private String getVersion(String command) { - try { - Process proc = new ProcessBuilder(new String[] { command, "-v" }).redirectErrorStream(true) //$NON-NLS-1$ - .start(); - String version = null; - String target = null; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) { - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - Matcher versionMatcher = versionPattern.matcher(line); - if (versionMatcher.matches()) { - version = line.trim(); - continue; - } - Matcher targetMatcher = targetPattern.matcher(line); - if (targetMatcher.matches()) { - target = targetMatcher.group(1); - continue; - } - } - } - if (version != null) { - if (target != null) { - return version + " " + target; //$NON-NLS-1$ - } else { - return version; - } - } else { - return null; - } - } catch (IOException e) { - return null; - } - } } diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java index 263453a0950..64dec9b9496 100644 --- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java +++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/internal/Msys2ToolChainProvider.java @@ -38,7 +38,7 @@ public class Msys2ToolChainProvider implements IToolChainProvider { String installLocation = registry.getCurrentUserValue(compKey, "InstallLocation"); //$NON-NLS-1$ Path gccPath = Paths.get(installLocation + "\\mingw64\\bin\\gcc.exe"); //$NON-NLS-1$ if (Files.exists(gccPath)) { - manager.addToolChain(new GCCToolChain(this, "msys2.x86_64", gccPath.getParent())); //$NON-NLS-1$ + manager.addToolChain(new GCCToolChain(this, "msys2.x86_64", "", gccPath.getParent())); //$NON-NLS-1$ //$NON-NLS-2$ } } } diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java index 3c9748dd41b..0b33e646af7 100644 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfiguration.java @@ -30,13 +30,12 @@ import org.eclipse.core.runtime.IProgressMonitor; public class CMakeBuildConfiguration extends CBuildConfiguration { - public CMakeBuildConfiguration(IBuildConfiguration config, String name) { + public CMakeBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { super(config, name); } public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) { - super(config, name); - setToolChain(toolChain); + super(config, name, toolChain); } @Override @@ -54,7 +53,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { // TODO assuming cmake is in the path here, probably need a // preference in case it isn't. List command = Arrays.asList("cmake", //$NON-NLS-1$ - "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", new File(project.getLocationURI()).getAbsolutePath()); + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", new File(project.getLocationURI()).getAbsolutePath()); //$NON-NLS-1$ ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); Process process = processBuilder.start(); outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ @@ -63,8 +62,8 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { // TODO need to figure out which builder to call. Hardcoding to make // for now. - List command = Arrays.asList("make"); - ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); //$NON-NLS-1$ + List command = Arrays.asList("make"); //$NON-NLS-1$ + ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); Process process = processBuilder.start(); outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ @@ -74,7 +73,7 @@ public class CMakeBuildConfiguration extends CBuildConfiguration { project.refreshLocal(IResource.DEPTH_INFINITE, monitor); return new IProject[] { project }; } catch (IOException e) { - throw new CoreException(Activator.errorStatus("Building " + project.getName(), e)); + throw new CoreException(Activator.errorStatus(String.format("Building %s", project.getName()), e)); } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java index 400ae89cdbd..b9e110c6499 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CCorePlugin; @@ -34,6 +35,7 @@ import org.eclipse.cdt.core.IBinaryParser; import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsChangeEvent; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsChangeListener; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; @@ -68,6 +70,7 @@ import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -604,22 +607,51 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang public BinaryParserConfig[] getBinaryParser(IProject project) { BinaryParserConfig[] parsers = binaryParsersMap.get(project); if (parsers == null) { - ICProjectDescription desc = CCorePlugin.getDefault().getProjectDescription(project, false); - if (desc != null) { - ICConfigurationDescription cfgDesc = desc.getDefaultSettingConfiguration(); - if (cfgDesc != null) { - ICConfigExtensionReference[] refs = cfgDesc.get(CCorePlugin.BINARY_PARSER_UNIQ_ID); - if (refs.length > 0) { - ArrayList list = new ArrayList<>(refs.length); - for (ICConfigExtensionReference ref : refs) { - BinaryParserConfig config = new BinaryParserConfig(ref); - list.add(config); + try { + // Check for new style build configs first + Set parserIds = new HashSet<>(); + for (IBuildConfiguration config : project.getBuildConfigs()) { + if (!IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(config.getName())) { + ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + if (cconfig != null) { + parserIds.add(cconfig.getBinaryParserId()); + } + } + } + if (!parserIds.isEmpty()) { + String[] ids = parserIds.toArray(new String[parserIds.size()]); + parsers = new BinaryParserConfig[parserIds.size()]; + for (int i = 0; i < parsers.length; ++i) { + String id = ids[i]; + IBinaryParser parser = CCorePlugin.getDefault().getBinaryParser(id); + if (parser != null) { + parsers[i] = new BinaryParserConfig(parser, id); + } + } + } + } catch (CoreException e) { + CCorePlugin.log(e); + parsers = null; + } + + if (parsers == null) { + ICProjectDescription desc = CCorePlugin.getDefault().getProjectDescription(project, false); + if (desc != null) { + ICConfigurationDescription cfgDesc = desc.getDefaultSettingConfiguration(); + if (cfgDesc != null) { + ICConfigExtensionReference[] refs = cfgDesc.get(CCorePlugin.BINARY_PARSER_UNIQ_ID); + if (refs.length > 0) { + ArrayList list = new ArrayList<>(refs.length); + for (ICConfigExtensionReference ref : refs) { + BinaryParserConfig config = new BinaryParserConfig(ref); + list.add(config); + } + parsers = new BinaryParserConfig[list.size()]; + list.toArray(parsers); + } else { + // no parser configured + parsers = new BinaryParserConfig[0]; } - parsers = new BinaryParserConfig[list.size()]; - list.toArray(parsers); - } else { - // no parser configured - parsers = new BinaryParserConfig[0]; } } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java index 50ebcc512e4..1078303db97 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java @@ -781,6 +781,33 @@ public class CCorePlugin extends Plugin { return parser; } + /** + * Returns the binary parser with the given id. + * + * @param id id of binary parser + * @return binary parser + * @throws CoreException + * @since 6.0 + */ + public IBinaryParser getBinaryParser(String id) throws CoreException { + IExtensionPoint extensionPoint = Platform.getExtensionRegistry() + .getExtensionPoint(CCorePlugin.PLUGIN_ID, BINARY_PARSER_SIMPLE_ID); + IExtension extension = extensionPoint.getExtension(id); + if (extension != null) { + IConfigurationElement element[] = extension.getConfigurationElements(); + for (IConfigurationElement element2 : element) { + if (element2.getName().equalsIgnoreCase("cextension")) { //$NON-NLS-1$ + return (IBinaryParser) element2.createExecutableExtension("run"); //$NON-NLS-1$ + } + } + } else { + IStatus s = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, + CCorePlugin.getResourceString("CCorePlugin.exception.noBinaryFormat"), null); //$NON-NLS-1$ + throw new CoreException(s); + } + return null; + } + public CoreModel getCoreModel() { return fCoreModel; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java index a673e5e3d0a..e4b644edd3a 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java @@ -19,6 +19,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -47,9 +48,11 @@ import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.osgi.util.NLS; import org.osgi.service.prefs.BackingStoreException; @@ -66,15 +69,53 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBuildConfiguration, IMarkerGenerator, IConsoleParser { private static final String TOOLCHAIN_TYPE = "cdt.toolChain.type"; //$NON-NLS-1$ - private static final String TOOLCHAIN_NAME = "cdt.toolChain.name"; //$NON-NLS-1$ + private static final String TOOLCHAIN_ID = "cdt.toolChain.id"; //$NON-NLS-1$ + private static final String TOOLCHAIN_VERSION = "cdt.toolChain.version"; //$NON-NLS-1$ private final String name; private final IBuildConfiguration config; - private IToolChain toolChain; + private final IToolChain toolChain; - protected CBuildConfiguration(IBuildConfiguration config, String name) { + protected CBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { this.config = config; this.name = name; + + Preferences settings = getSettings(); + String typeId = settings.get(TOOLCHAIN_TYPE, ""); //$NON-NLS-1$ + String id = settings.get(TOOLCHAIN_ID, ""); //$NON-NLS-1$ + String version = settings.get(TOOLCHAIN_VERSION, ""); //$NON-NLS-1$ + IToolChainManager toolChainManager = CCorePlugin.getService(IToolChainManager.class); + IToolChain tc = toolChainManager.getToolChain(typeId, id, version); + + if (tc == null) { + // check for other versions + Collection tcs = toolChainManager.getToolChains(typeId, id); + if (!tcs.isEmpty()) { + // TODO grab the newest version + tc = tcs.iterator().next(); + } else { + throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, + String.format("Toolchain missing for config: %s", config.getName()))); + } + } + + toolChain = tc; + } + + public CBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) { + this.config = config; + this.name = name; + this.toolChain = toolChain; + + Preferences settings = getSettings(); + settings.put(TOOLCHAIN_TYPE, toolChain.getProvider().getId()); + settings.put(TOOLCHAIN_ID, toolChain.getId()); + settings.put(TOOLCHAIN_VERSION, toolChain.getVersion()); + try { + settings.flush(); + } catch (BackingStoreException e) { + CCorePlugin.log(e); + } } @Override @@ -90,6 +131,11 @@ public abstract class CBuildConfiguration extends PlatformObject return config.getProject(); } + @Override + public String getBinaryParserId() throws CoreException { + return toolChain != null ? toolChain.getBinaryParserId() : CCorePlugin.DEFAULT_BINARY_PARSER_UNIQ_ID; + } + public IContainer getBuildContainer() throws CoreException { // TODO should really be passing a monitor in here or create this in // a better spot. should also throw the core exception @@ -145,34 +191,9 @@ public abstract class CBuildConfiguration extends PlatformObject @Override public IToolChain getToolChain() throws CoreException { - if (toolChain == null) { - Preferences settings = getSettings(); - String typeId = settings.get(TOOLCHAIN_TYPE, ""); //$NON-NLS-1$ - String id = settings.get(TOOLCHAIN_NAME, ""); //$NON-NLS-1$ - IToolChainManager toolChainManager = CCorePlugin.getService(IToolChainManager.class); - toolChain = toolChainManager.getToolChain(typeId, id); - - if (toolChain == null) { - CCorePlugin.log(String.format("Toolchain missing for config: %s", config.getName())); - } - } - return toolChain; } - protected void setToolChain(IToolChain toolChain) { - this.toolChain = toolChain; - - Preferences settings = getSettings(); - settings.put(TOOLCHAIN_TYPE, toolChain.getProvider().getId()); - settings.put(TOOLCHAIN_NAME, toolChain.getName()); - try { - settings.flush(); - } catch (BackingStoreException e) { - CCorePlugin.log(e); - } - } - @Override public IEnvironmentVariable getVariable(String name) { // By default, none diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java index e40be338c3a..2b4c46e4097 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java @@ -42,6 +42,8 @@ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider { * @return the toolchain for this build configuration */ IToolChain getToolChain() throws CoreException; + + String getBinaryParserId() throws CoreException; IEnvironmentVariable getVariable(String name) throws CoreException; @@ -50,5 +52,5 @@ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider { IProject[] build(int kind, Map args, IConsole console, IProgressMonitor monitor) throws CoreException; void clean(IConsole console, IProgressMonitor monitor) throws CoreException; - + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java index 375f6afbb51..2d341e28866 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java @@ -30,6 +30,10 @@ public interface IToolChain extends IAdaptable { IToolChainProvider getProvider(); + String getId(); + + String getVersion(); + String getName(); /** @@ -58,4 +62,6 @@ public interface IToolChain extends IAdaptable { IResource[] getResourcesFromCommand(String[] command, URI buildDirectoryURI); + String getBinaryParserId(); + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainManager.java index bd5282fbd62..c6e19379537 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainManager.java @@ -21,10 +21,12 @@ public interface IToolChainManager { IToolChainProvider getProvider(String providerId) throws CoreException; - IToolChain getToolChain(String providerId, String name) throws CoreException; + IToolChain getToolChain(String providerId, String id, String version) throws CoreException; Collection getToolChains(String providerId) throws CoreException; + Collection getToolChains(String providerId, String id) throws CoreException; + /** * Returns the list of toolchains that have the given properties. * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainProvider.java index e17dc46f7ec..0b9c78ef7cc 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChainProvider.java @@ -34,15 +34,17 @@ public interface IToolChainProvider { } /** - * Called by the manager to dynamically create the named toolchain. + * Called by the manager to dynamically create the toolchain. * * @param name * the name of the toolchain + * @param version + * the version of the toolchain * @param properties * the persisted settings for the toolchain * @return the toolchain initialized with the settings. */ - default IToolChain getToolChain(String name) throws CoreException { + default IToolChain getToolChain(String id, String version) throws CoreException { // By default, assumes all toolchains were added at init time. return null; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java index fcd123d1741..065afe9caa1 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; +import org.eclipse.cdt.internal.core.model.CModelManager; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; @@ -153,6 +154,9 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager, if (provider != null && provider.supports(buildConfig.getProject())) { config = provider.getProvider().getCBuildConfiguration(buildConfig, configName); configs.put(buildConfig, config); + + // Also make sure we reset the binary parser cache for the new config + CModelManager.getDefault().resetBinaryParser(buildConfig.getProject()); } } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java index 67572bccdfe..ed83798bccf 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/ToolChainManager.java @@ -9,7 +9,6 @@ package org.eclipse.cdt.internal.core.build; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,7 +27,7 @@ public class ToolChainManager implements IToolChainManager { private Map providerElements; private Map providers; - private Map> toolChains; + private Map, IToolChain> toolChains; private void init() { if (providerElements == null) { @@ -60,24 +59,22 @@ public class ToolChainManager implements IToolChainManager { } } + private List getId(IToolChain toolChain) { + List id = new ArrayList<>(3); + id.add(toolChain.getProvider().getId()); + id.add(toolChain.getId()); + id.add(toolChain.getVersion()); + return id; + } + @Override public void addToolChain(IToolChain toolChain) { - String providerId = toolChain.getProvider().getId(); - Map provider = toolChains.get(providerId); - if (provider == null) { - provider = new HashMap<>(); - toolChains.put(providerId, provider); - } - provider.put(toolChain.getName(), toolChain); + toolChains.put(getId(toolChain), toolChain); } @Override public void removeToolChain(IToolChain toolChain) { - String providerId = toolChain.getProvider().getId(); - Map provider = toolChains.get(providerId); - if (provider != null) { - provider.remove(toolChain.getName()); - } + toolChains.remove(getId(toolChain)); } @Override @@ -95,26 +92,24 @@ public class ToolChainManager implements IToolChainManager { } @Override - public IToolChain getToolChain(String providerId, String name) throws CoreException { + public IToolChain getToolChain(String providerId, String id, String version) throws CoreException { init(); - Map provider = toolChains.get(providerId); - if (provider != null) { - IToolChain toolChain = provider.get(name); - if (toolChain != null) { - return toolChain; - } + List tid = new ArrayList<>(3); + tid.add(providerId); + tid.add(id); + tid.add(version); + + IToolChain toolChain = toolChains.get(tid); + if (toolChain != null) { + return toolChain; } // Try the provider IToolChainProvider realProvider = providers.get(providerId); if (realProvider != null) { - IToolChain toolChain = realProvider.getToolChain(name); + toolChain = realProvider.getToolChain(id, version); if (toolChain != null) { - if (provider == null) { - provider = new HashMap<>(); - toolChains.put(providerId, provider); - } - provider.put(name, toolChain); + toolChains.put(getId(toolChain), toolChain); return toolChain; } } @@ -126,14 +121,15 @@ public class ToolChainManager implements IToolChainManager { public Collection getToolChainsMatching(Map properties) { init(); List tcs = new ArrayList<>(); - for (Map types : toolChains.values()) { - tcLoop: for (IToolChain toolChain : types.values()) { - for (Map.Entry property : properties.entrySet()) { - if (!property.getValue().equals(toolChain.getProperty(property.getKey()))) { - // doesn't match, move on to next toolchain - continue tcLoop; - } + for (IToolChain toolChain : toolChains.values()) { + boolean matches = true; + for (Map.Entry property : properties.entrySet()) { + if (!property.getValue().equals(toolChain.getProperty(property.getKey()))) { + matches = false; + break; } + } + if (matches) { tcs.add(toolChain); } } @@ -143,12 +139,25 @@ public class ToolChainManager implements IToolChainManager { @Override public Collection getToolChains(String providerId) { init(); - Map provider = toolChains.get(providerId); - if (provider != null) { - return Collections.unmodifiableCollection(provider.values()); - } else { - return Collections.emptyList(); + List tcs = new ArrayList<>(); + for (IToolChain toolChain : toolChains.values()) { + if (toolChain.getProvider().getId().equals(providerId)) { + tcs.add(toolChain); + } } + return tcs; + } + + @Override + public Collection getToolChains(String providerId, String id) throws CoreException { + init(); + List tcs = new ArrayList<>(); + for (IToolChain toolChain : toolChains.values()) { + if (toolChain.getProvider().getId().equals(providerId) && toolChain.getId().equals(id)) { + tcs.add(toolChain); + } + } + return tcs; } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java index c1ed39c347c..571a76d10f8 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java @@ -56,7 +56,7 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild private final String launchMode; private Map properties; - public QtBuildConfiguration(IBuildConfiguration config, String name) { + public QtBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { super(config, name); Preferences settings = getSettings(); @@ -74,8 +74,7 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild QtBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain, IQtInstall qtInstall, String launchMode) throws CoreException { - super(config, name); - setToolChain(toolChain); + super(config, name, toolChain); this.qtInstall = qtInstall; this.launchMode = launchMode; @@ -206,7 +205,6 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild @Override public IScannerInfo getScannerInformation(IResource resource) { - IProject project = resource.getProject(); IQtInstall qtInstall = getQtInstall(); String cxx = getProperty("QMAKE_CXX"); //$NON-NLS-1$ diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java index f97e3efcb6e..ae3c784efd2 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java @@ -50,9 +50,10 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide return new QtBuildConfiguration(config, name); } catch (CoreException e) { + // Failed to create the build config. Return null so it gets recreated. Activator.log(e); + return null; } - return null; } @Override diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java index ad8babf5c5a..e6bcd016a11 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtLaunchConfigurationDelegate.java @@ -53,11 +53,11 @@ public abstract class QtLaunchConfigurationDelegate extends LaunchConfigurationT protected void populateToolChainProperties(ILaunchTarget target, Map properties) { String os = target.getAttribute(ILaunchTarget.ATTR_OS, null); if (os != null) { - properties.put(IToolChain.ATTR_OS, os); + properties.put(IToolChain.ATTR_OS, os.toLowerCase()); } String arch = target.getAttribute(ILaunchTarget.ATTR_ARCH, null); if (arch != null) { - properties.put(IToolChain.ATTR_ARCH, arch); + properties.put(IToolChain.ATTR_ARCH, arch.toLowerCase()); } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java index 2fb4a213577..5e984911dc2 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtMinGWToolChainProvider.java @@ -44,7 +44,7 @@ public class QtMinGWToolChainProvider implements IToolChainProvider { try { Files.walk(Paths.get(installLocation).resolve("Tools"), 1) //$NON-NLS-1$ .filter((path) -> Files.exists(path.resolve(gcc))) - .map((path) -> new GCCToolChain(this, "qt.mingw", path.resolve("bin"))) //$NON-NLS-1$ //$NON-NLS-2$ + .map((path) -> new GCCToolChain(this, "qt.mingw", "", path.resolve("bin"))) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ .forEach(toolChain -> manager.addToolChain(toolChain)); } catch (IOException e) { Activator.log(e); diff --git a/qt/org.eclipse.cdt.qt.ui/plugin.xml b/qt/org.eclipse.cdt.qt.ui/plugin.xml index 3392f1e27eb..240ebb106a4 100644 --- a/qt/org.eclipse.cdt.qt.ui/plugin.xml +++ b/qt/org.eclipse.cdt.qt.ui/plugin.xml @@ -150,4 +150,12 @@ labelProvider="org.eclipse.cdt.internal.qt.ui.launch.QtLaunchDescriptorLabelProvider"> + + + + diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java index c0ee4bcb215..6ef03d51bd5 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java @@ -46,8 +46,6 @@ import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.IConsoleParser; import org.eclipse.cdt.core.build.CBuildConfiguration; import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; -import org.eclipse.cdt.core.build.IToolChainProvider; import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.parser.ExtendedScannerInfo; @@ -118,19 +116,12 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te this.launchMode = name.substring(i + 1); } - ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoBoard board, String launchMode) + ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoBoard board, String launchMode, IToolChain toolChain) throws CoreException { - super(config, name); + super(config, name, toolChain); this.board = board; this.launchMode = launchMode; - // Create the toolChain - IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); - IToolChain toolChain = new ArduinoToolChain(provider, this); - toolChainManager.addToolChain(toolChain); - setToolChain(toolChain); - // Store the board identifer ArduinoPlatform platform = board.getPlatform(); ArduinoPackage pkg = platform.getPackage(); @@ -148,8 +139,8 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration implements Te } ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoRemoteConnection target, - String launchMode) throws CoreException { - this(config, name, target.getBoard(), launchMode); + String launchMode, IToolChain toolChain) throws CoreException { + this(config, name, target.getBoard(), launchMode, toolChain); // Store the menu settings HierarchicalProperties menus = board.getMenus(); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java index 3268020022e..ead1a26531f 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java @@ -16,6 +16,9 @@ import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.build.IToolChainManager; +import org.eclipse.cdt.core.build.IToolChainProvider; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -65,8 +68,15 @@ public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationPr String configName = ArduinoBuildConfiguration.generateName(board, launchMode); IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, null); + + // Create the toolChain + IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); + IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); + IToolChain toolChain = new ArduinoToolChain(provider, config); + toolChainManager.addToolChain(toolChain); + ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, board, - launchMode); + launchMode, toolChain); arduinoConfig.setActive(null); configManager.addBuildConfiguration(config, arduinoConfig); return arduinoConfig; @@ -98,7 +108,12 @@ public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationPr String configName = ArduinoBuildConfiguration.generateName(board, launchMode); IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, monitor); - ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, target, launchMode); + IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); + IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); + IToolChain toolChain = new ArduinoToolChain(provider, config); + toolChainManager.addToolChain(toolChain); + ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, target, launchMode, toolChain); + configManager.addBuildConfiguration(config, arduinoConfig); return arduinoConfig; } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChain.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChain.java index 2f4fd2effef..44bb51d7a3b 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChain.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChain.java @@ -1,49 +1,21 @@ package org.eclipse.cdt.arduino.core.internal.build; -import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.build.gcc.core.GCCToolChain; -import org.eclipse.cdt.core.build.ICBuildConfiguration; -import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.build.IToolChainProvider; import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; public class ArduinoToolChain extends GCCToolChain { - private final ArduinoBuildConfiguration buildConfig; - - public ArduinoToolChain(IToolChainProvider provider, ArduinoBuildConfiguration config) { - super(provider, config.getProject().getName() + '#' + config.getName()); - this.buildConfig = config; + ArduinoToolChain(IToolChainProvider provider, IBuildConfiguration config) throws CoreException { + super(provider, config.getProject().getName() + '#' + config.getName(), ""); //$NON-NLS-1$ } - - ArduinoToolChain(IToolChainProvider provider, String name) throws CoreException { - super(provider, name); - String[] segments = name.split("#"); //$NON-NLS-1$ - if (segments.length == 2) { - String projectName = segments[0]; - String configName = segments[1]; - - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); - if (project != null) { - ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class); - IBuildConfiguration config = configManager.getBuildConfiguration( - configManager.getProvider(ArduinoBuildConfigurationProvider.ID), project, configName); - ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); - buildConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class); - } else { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "No project")); - } - } else { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Bad Name")); - } + + public ArduinoToolChain(IToolChainProvider provider, String id, String version) { + super(provider, id, version); } - + @Override public String getProperty(String key) { // TODO architecture if I need it @@ -54,9 +26,4 @@ public class ArduinoToolChain extends GCCToolChain { } } - // TODO do I really need this? - public ArduinoBuildConfiguration getBuildConfig() { - return buildConfig; - } - } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChainProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChainProvider.java index 79ecce03562..63ce9542283 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChainProvider.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChainProvider.java @@ -14,8 +14,8 @@ public class ArduinoToolChainProvider implements IToolChainProvider { } @Override - public IToolChain getToolChain(String name) throws CoreException { - return new ArduinoToolChain(this, name); + public IToolChain getToolChain(String id, String version) throws CoreException { + return new ArduinoToolChain(this, id, version); } }