From 0d9fa844bf94f70a6166248f3becff2dcf8b8246 Mon Sep 17 00:00:00 2001 From: John Dallaway Date: Sat, 15 Apr 2023 17:07:50 +0100 Subject: [PATCH] Set tool prefix for spawning GNU tool processes Allows the GNU tool prefix to be specified by a CDT build variable. Modifies the Cross GCC toolchain description to provide the GNU tool prefix. Part of #361 --- .../META-INF/MANIFEST.MF | 2 +- .../macros/AbstractGnuToolPrefixMacro.java | 50 +++++++++++++++ .../cdt/utils/DefaultGnuToolFactory.java | 40 ++++++++++-- .../eclipse/cdt/utils/IGnuToolFactory.java | 6 +- .../org.eclipse.cdt.build.crossgcc/plugin.xml | 6 +- .../crossgcc/CrossBuildMacroSupplier.java | 62 +++++++++++++++++++ 6 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/AbstractGnuToolPrefixMacro.java create mode 100644 cross/org.eclipse.cdt.build.crossgcc/src/org/eclipse/cdt/internal/build/crossgcc/CrossBuildMacroSupplier.java diff --git a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF index b03bcd50a0a..8b896ab2b29 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core; singleton:=true -Bundle-Version: 9.5.100.qualifier +Bundle-Version: 9.6.0.qualifier Bundle-Activator: org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/AbstractGnuToolPrefixMacro.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/AbstractGnuToolPrefixMacro.java new file mode 100644 index 00000000000..73bb0531c6f --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/AbstractGnuToolPrefixMacro.java @@ -0,0 +1,50 @@ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.cdt.core.cdtvariables.CdtVariableException; +import org.eclipse.cdt.core.cdtvariables.ICdtVariableStatus; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.utils.IGnuToolFactory; +import org.eclipse.core.runtime.Status; + +/** + * A CDT build variable defining the GNU tool prefix for use by + * an {@link org.eclipse.cdt.utils.IGnuToolFactory} implementation. + * + * @since 9.6 + */ +public abstract class AbstractGnuToolPrefixMacro implements IBuildMacro { + + @Override + public String getName() { + return IGnuToolFactory.GNU_TOOL_PREFIX_VARIABLE; + } + + @Override + public int getValueType() { + return IBuildMacro.VALUE_TEXT; + } + + @Override + public int getMacroValueType() { + return getValueType(); + } + + @Override + public abstract String getStringValue() throws BuildMacroException; + + @Override + public String[] getStringListValue() throws BuildMacroException { + throw new BuildMacroException( + new CdtVariableException(ICdtVariableStatus.TYPE_MACRO_NOT_STRINGLIST, getName(), null, getName())); + } + + protected String getStringValue(IOption option) throws BuildMacroException { + try { + return option.getStringValue(); + } catch (BuildException e) { + throw new BuildMacroException(Status.error("Error getting macro value: " + getName(), e)); //$NON-NLS-1$ + } + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java index 00729b18c45..7f31273bba9 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/DefaultGnuToolFactory.java @@ -10,7 +10,7 @@ * * Contributors: * QNX Software Systems - initial API and implementation - * John Dallaway - set environment for spawning GNU tool processes (#361) + * John Dallaway - set environment and tool prefix (#361) *******************************************************************************/ package org.eclipse.cdt.utils; @@ -19,11 +19,15 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ICExtension; +import org.eclipse.cdt.core.cdtvariables.CdtVariableException; +import org.eclipse.cdt.core.cdtvariables.ICdtVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; public class DefaultGnuToolFactory implements IGnuToolFactory { protected ICExtension fExtension; @@ -94,7 +98,7 @@ protected IPath getAddr2linePath() { ICConfigExtensionReference ref = fExtension.getConfigExtensionReference(); String value = ref.getExtensionData("addr2line"); //$NON-NLS-1$ if (value == null || value.length() == 0) { - value = "addr2line"; //$NON-NLS-1$ + value = getToolPrefix() + "addr2line"; //$NON-NLS-1$ } return new Path(value); } @@ -103,7 +107,7 @@ protected IPath getObjdumpPath() { ICConfigExtensionReference ref = fExtension.getConfigExtensionReference(); String value = ref.getExtensionData("objdump"); //$NON-NLS-1$ if (value == null || value.length() == 0) { - value = "objdump"; //$NON-NLS-1$ + value = getToolPrefix() + "objdump"; //$NON-NLS-1$ } return new Path(value); } @@ -121,7 +125,7 @@ protected IPath getCPPFiltPath() { ICConfigExtensionReference ref = fExtension.getConfigExtensionReference(); String value = ref.getExtensionData("c++filt"); //$NON-NLS-1$ if (value == null || value.length() == 0) { - value = "c++filt"; //$NON-NLS-1$ + value = getToolPrefix() + "c++filt"; //$NON-NLS-1$ } return new Path(value); } @@ -130,7 +134,7 @@ protected IPath getStripPath() { ICConfigExtensionReference ref = fExtension.getConfigExtensionReference(); String value = ref.getExtensionData("strip"); //$NON-NLS-1$ if (value == null || value.length() == 0) { - value = "strip"; //$NON-NLS-1$ + value = getToolPrefix() + "strip"; //$NON-NLS-1$ } return new Path(value); } @@ -139,7 +143,7 @@ protected IPath getNMPath() { ICConfigExtensionReference ref = fExtension.getConfigExtensionReference(); String value = ref.getExtensionData("nm"); //$NON-NLS-1$ if (value == null || value.length() == 0) { - value = "nm"; //$NON-NLS-1$ + value = getToolPrefix() + "nm"; //$NON-NLS-1$ } return new Path(value); } @@ -161,4 +165,28 @@ protected String[] getEnvironment() { return Arrays.stream(vars).map(v -> String.format("%s=%s", v.getName(), v.getValue())) //$NON-NLS-1$ .toArray(String[]::new); } + + /** @since 8.2 */ + protected String getToolPrefix() { + ICConfigExtensionReference ref = fExtension.getConfigExtensionReference(); + ICConfigurationDescription cfg = ref.getConfiguration(); + ICdtVariable[] userVars = CCorePlugin.getUserVarSupplier().getMacros(cfg); + ICdtVariable var = Arrays.stream(userVars).filter(v -> v.getName().equals(GNU_TOOL_PREFIX_VARIABLE)).findFirst() + .orElse(null); + + // if user-defined variable not found, look for system variable provided by toolchain integration + if (var == null) { + var = CCorePlugin.getDefault().getCdtVariableManager().getVariable(GNU_TOOL_PREFIX_VARIABLE, cfg); + } + + if (var != null) { + try { + return var.getStringValue(); + } catch (CdtVariableException e) { + Platform.getLog(getClass()) + .log(Status.error("Error getting CDT variable string value: " + GNU_TOOL_PREFIX_VARIABLE, e)); //$NON-NLS-1$ + } + } + return ""; //$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/IGnuToolFactory.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/IGnuToolFactory.java index f93c9d93352..cc0058952ec 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/IGnuToolFactory.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/IGnuToolFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 QNX Software Systems and others. + * Copyright (c) 2005, 2023 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * QNX Software Systems - initial API and implementation + * John Dallaway - support GNU tool prefix lookup (#361) *******************************************************************************/ /* * Created on Jul 5, 2004 @@ -27,6 +28,9 @@ */ public interface IGnuToolFactory { + /** @since 8.2 */ + public static final String GNU_TOOL_PREFIX_VARIABLE = "gnu_tool_prefix"; //$NON-NLS-1$ + Addr2line getAddr2line(IPath path); CPPFilt getCPPFilt(); diff --git a/cross/org.eclipse.cdt.build.crossgcc/plugin.xml b/cross/org.eclipse.cdt.build.crossgcc/plugin.xml index d7f5eca6409..75a29d50e04 100644 --- a/cross/org.eclipse.cdt.build.crossgcc/plugin.xml +++ b/cross/org.eclipse.cdt.build.crossgcc/plugin.xml @@ -1,7 +1,7 @@ @@ -24,6 +25,7 @@ diff --git a/cross/org.eclipse.cdt.build.crossgcc/src/org/eclipse/cdt/internal/build/crossgcc/CrossBuildMacroSupplier.java b/cross/org.eclipse.cdt.build.crossgcc/src/org/eclipse/cdt/internal/build/crossgcc/CrossBuildMacroSupplier.java new file mode 100644 index 00000000000..3bdfe4fbcd1 --- /dev/null +++ b/cross/org.eclipse.cdt.build.crossgcc/src/org/eclipse/cdt/internal/build/crossgcc/CrossBuildMacroSupplier.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2023 John Dallaway and others. + * + * 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 + * + * Contributors: + * John Dallaway - initial API and implementation (#361) + *******************************************************************************/ +package org.eclipse.cdt.internal.build.crossgcc; + +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.macros.AbstractGnuToolPrefixMacro; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; +import org.eclipse.cdt.utils.IGnuToolFactory; +import org.eclipse.core.runtime.Status; + +public class CrossBuildMacroSupplier implements IConfigurationBuildMacroSupplier { + + private static class GnuToolPrefixMacro extends AbstractGnuToolPrefixMacro { + + private static final String GNU_TOOL_PREFIX_OPTION = "cdt.managedbuild.option.gnu.cross.prefix"; //$NON-NLS-1$ + private final IConfiguration configuration; + + public GnuToolPrefixMacro(IConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public String getStringValue() throws BuildMacroException { + final IOption option = configuration.getToolChain().getOptionBySuperClassId(GNU_TOOL_PREFIX_OPTION); + if (null == option) { + throw new BuildMacroException(Status.error("Toolchain option not found: " + GNU_TOOL_PREFIX_OPTION)); //$NON-NLS-1$ + } + return getStringValue(option); + } + + } + + @Override + public IBuildMacro getMacro(String macroName, IConfiguration configuration, IBuildMacroProvider provider) { + if (IGnuToolFactory.GNU_TOOL_PREFIX_VARIABLE.equals(macroName)) { + return new GnuToolPrefixMacro(configuration); + } + return null; + } + + @Override + public IBuildMacro[] getMacros(IConfiguration configuration, IBuildMacroProvider provider) { + final IBuildMacro macro = getMacro(IGnuToolFactory.GNU_TOOL_PREFIX_VARIABLE, configuration, provider); + return (null == macro) ? new IBuildMacro[0] : new IBuildMacro[] { macro }; + } + +}