From 234e98d71db943ded5e091423081e9ec81bc68d8 Mon Sep 17 00:00:00 2001 From: John Moule Date: Thu, 9 Jun 2022 17:40:16 +0100 Subject: [PATCH] Bug 580015: add support for multiple bin parsers Added ability to return a list of binary parser IDs, rather than a single ID. This supports build configurations that have multiple binaries with for example cross toolchains. Change-Id: I1b7e47bf6a86bbd9f1c6b9646d008bac9479417d --- .../META-INF/MANIFEST.MF | 3 +- .../core/build/TestICBuildConfiguration.java | 71 ++++++++++ .../cdt/core/build/TestIToolChain.java | 121 ++++++++++++++++++ .../.settings/.api_filters | 16 +++ .../internal/core/model/CModelManager.java | 5 +- .../cdt/core/build/CBuildConfiguration.java | 5 + .../cdt/core/build/ICBuildConfiguration.java | 15 +++ .../eclipse/cdt/core/build/IToolChain.java | 13 ++ 8 files changed, 244 insertions(+), 5 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestICBuildConfiguration.java create mode 100644 core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestIToolChain.java diff --git a/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF index 69844003b2d..d30d00aa493 100644 --- a/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core.tests/META-INF/MANIFEST.MF @@ -45,7 +45,8 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.ltk.core.refactoring;bundle-version="3.4.0", org.hamcrest.core, org.hamcrest.library, - com.google.gson;bundle-version="[2.8.6,3.0.0)" + com.google.gson;bundle-version="[2.8.6,3.0.0)", + org.eclipse.cdt.build.gcc.core Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestICBuildConfiguration.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestICBuildConfiguration.java new file mode 100644 index 00000000000..2d427aa5a14 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestICBuildConfiguration.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2022 Renesas Electronics Europe. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.cdt.core.build; + +import org.eclipse.cdt.core.testplugin.CTestPlugin; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +/** + * Tests for org.eclipse.cdt.core.build.ICBuildConfiguration + */ +public class TestICBuildConfiguration { + + @Before + public void setup() { + } + + @After + public void shutdown() { + } + + /** + * Tests that ICBuildConfiguration.getBinaryParserIds() meets API.
+ * + * List getBinaryParserIds() + * + */ + @Test + public void getBinaryParserIdsTest00() throws Exception { + } + + /** + * Tests that ICBuildConfiguration.getBinaryParserIds() can return a list of Binary Parser IDs. + */ + @Test + public void getBinaryParserIdsTest01() throws Exception { + } + + /** + * org.eclipse.cdt.internal.core.model.CModelManager.getBinaryParser(IProject) + */ + @Test + public void getBinaryParserTest00() throws Exception { + } + + // ICBuildConfiguration cBuildConfig = null; + // String binParserId = cBuildConfig.getBinaryParserId(); + // IBinary[] binaries = cBuildConfig.getBuildOutput(); + // for (IBinary binary : binaries) { + // binary.exists(); + // } + + private static T getService(Class serviceClass) { + BundleContext bundleContext = FrameworkUtil.getBundle(CTestPlugin.class).getBundleContext(); + ServiceReference serviceReference = bundleContext.getServiceReference(serviceClass); + return bundleContext.getService(serviceReference); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestIToolChain.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestIToolChain.java new file mode 100644 index 00000000000..6c1bf557563 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/build/TestIToolChain.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2022 Renesas Electronics Europe. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.cdt.core.build; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.nio.file.Path; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.build.gcc.core.GCCToolChain; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.testplugin.CTestPlugin; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +/** + * Tests for org.eclipse.cdt.core.build.IToolChain + */ +public class TestIToolChain { + private final static List expectedBinParserIds = List.of("binParserId0", "binParserId1"); + private IToolChainManager toolchainMgr = null; + + @Before + public void setup() { + toolchainMgr = getService(IToolChainManager.class); + assertNotNull("toolchainMgr must not be null", toolchainMgr); + } + + @After + public void shutdown() { + } + + /** + * Tests that IToolChain.getBinaryParserIds() meets API.
+ * + * List getBinaryParserIds() + * + */ + @Test + public void getBinaryParserIdsTest00() throws Exception { + Collection toolChains = toolchainMgr.getAllToolChains(); + assertNotNull("toolChains list must not be null", toolChains); + assertTrue("toolChains list must contain at 1 items", !toolChains.isEmpty()); + IToolChain tc = toolChains.iterator().next(); + List ids = tc.getBinaryParserIds(); + assertNotNull("IToolChain.getBinaryParserIds() must return a list", ids); + } + + /** + * Tests that IToolChain.getBinaryParserIds() can return a list of Binary Parser IDs. + */ + @Test + public void getBinaryParserIdsTest01() throws Exception { + // Add our test toolchain. + { + IToolChain testTc = new TestToolchain(null, null, "testArch", null); + toolchainMgr.addToolChain(testTc); + } + + // Get our test toolchain. + Map props = new HashMap(); + props.put(IToolChain.ATTR_OS, "testOs"); + props.put(IToolChain.ATTR_ARCH, "testArch"); + Collection testTcs = toolchainMgr.getToolChainsMatching(props); + assertTrue("toolChains list must contain exactly 1 item", testTcs.size() == 1); + IToolChain testTc = testTcs.iterator().next(); + assertNotNull("ourTc must not be null", testTc); + + // Check our test toolchain returns multiple binary parsers + List actualBinParserIds = testTc.getBinaryParserIds(); + assertArrayEquals("Binary Parser Ids must match", expectedBinParserIds.toArray(new String[0]), + actualBinParserIds.toArray(new String[0])); + } + + private class TestToolchain extends GCCToolChain { + + public TestToolchain(IToolChainProvider provider, Path pathToToolChain, String arch, + IEnvironmentVariable[] envVars) { + super(provider, pathToToolChain, arch, envVars); + } + + @Override + public String getProperty(String key) { + if (key.equals(IToolChain.ATTR_OS)) { + return "testOs"; + } else if (key.equals(IToolChain.ATTR_ARCH)) { + return "testArch"; + } else { + return super.getProperty(key); + } + } + + @Override + public List getBinaryParserIds() { + return expectedBinParserIds; + } + } + + private static T getService(Class serviceClass) { + BundleContext bundleContext = FrameworkUtil.getBundle(CTestPlugin.class).getBundleContext(); + ServiceReference serviceReference = bundleContext.getServiceReference(serviceClass); + return bundleContext.getService(serviceReference); + } +} diff --git a/core/org.eclipse.cdt.core/.settings/.api_filters b/core/org.eclipse.cdt.core/.settings/.api_filters index a05364d729a..27d8c70d449 100644 --- a/core/org.eclipse.cdt.core/.settings/.api_filters +++ b/core/org.eclipse.cdt.core/.settings/.api_filters @@ -166,6 +166,22 @@ + + + + + + + + + + + + + + + + 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 47d2fb12516..7a2ca7f43ab 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 @@ -618,10 +618,7 @@ public class CModelManager implements IResourceChangeListener, IContentTypeChang for (IBuildConfiguration config : project.getBuildConfigs()) { ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); if (cconfig != null) { - String id = cconfig.getBinaryParserId(); - if (id != null) { - parserIds.add(cconfig.getBinaryParserId()); - } + parserIds.addAll(cconfig.getBinaryParserIds()); } } if (!parserIds.isEmpty()) { 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 9dccfcba379..440df02fc08 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 @@ -218,6 +218,11 @@ public abstract class CBuildConfiguration extends PlatformObject implements ICBu return toolChain != null ? toolChain.getBinaryParserId() : CCorePlugin.DEFAULT_BINARY_PARSER_UNIQ_ID; } + @Override + public List getBinaryParserIds() throws CoreException { + return toolChain != null ? toolChain.getBinaryParserIds() : List.of(CCorePlugin.DEFAULT_BINARY_PARSER_UNIQ_ID); + } + public IContainer getBuildContainer() throws CoreException { // TODO make the name of this folder a project property IProject project = getProject(); 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 8869ca114f9..949913322c0 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 @@ -11,6 +11,7 @@ package org.eclipse.cdt.core.build; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; @@ -79,9 +80,23 @@ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider { * * @return binary parser ids * @throws CoreException + * @deprecated As of 10.??? replaced by {@link ICBuildConfiguration#getBinaryParserIds} */ + @Deprecated(since = "7.5") String getBinaryParserId() throws CoreException; + /** + * Ids for the Binary Parsers to use when checking whether a file is a + * binary that can be launched. + * + * @return binary parser ids + * @throws CoreException + * @since 7.5 + */ + default List getBinaryParserIds() throws CoreException { + return List.of(getBinaryParserId()); + } + /** * Return a build environment variable with a given name. * 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 b38f7eb2546..aa509dac0c3 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 @@ -165,9 +165,22 @@ public interface IToolChain extends IAdaptable { * the toolchain. * * @return binary parser IDs for this toolchain + * @deprecated As of 7.5 replaced by {@link IToolChain#getBinaryParserIds} */ + @Deprecated(since = "7.5") String getBinaryParserId(); + /** + * Returns the IDs for the binary parsers that can parse the build output of + * the toolchain. + * + * @return binary parser IDs for this toolchain + * @since 7.5 + */ + default List getBinaryParserIds() { + return List.of(getBinaryParserId()); + } + /** * Get the scanner info for a given build config, command, base scanner * info, resource and build directory.