Skip to content
Merged
66 changes: 0 additions & 66 deletions bundles/com.espressif.idf.core/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -244,72 +244,6 @@ config-only component and an interface library is created instead."
name="KCONFIG_PROJBUILD">
</property>
</extension>
<extension point="com.espressif.idf.core.toolchain">
<ToolChain
arch="xtensa"
compilerPattern="(?:xtensa-esp-elf|xtensa-esp32-elf)[\\/]+bin[\\/]+xtensa-esp32-elf-gcc(?:\.exe)?$"
debuggerPattern="xtensa-esp32-elf-gdb(\.exe)?$"
fileName="toolchain-esp32.cmake"
id="xtensa-esp32-elf"
name="esp32">
</ToolChain>
<ToolChain
arch="xtensa"
compilerPattern="(?:xtensa-esp-elf|xtensa-esp32s2-elf)[\\/]+bin[\\/]+xtensa-esp32s2-elf-gcc(?:\.exe)?$"
debuggerPattern="xtensa-esp32s2-elf-gdb(\.exe)?$"
fileName="toolchain-esp32s2.cmake"
id="xtensa-esp32s2-elf"
name="esp32s2">
</ToolChain>
<ToolChain
arch="xtensa"
compilerPattern="(?:xtensa-esp-elf|xtensa-esp32s3-elf)[\\/]+bin[\\/]+xtensa-esp32s3-elf-gcc(?:\.exe)?$"
debuggerPattern="xtensa-esp32s3-elf-gdb(\.exe)?$"
fileName="toolchain-esp32s3.cmake"
id="xtensa-esp32s3-elf"
name="esp32s3">
</ToolChain>
<ToolChain
arch="riscv32"
compilerPattern="riscv32-esp-elf[\\/]+bin[\\/]+riscv32-esp-elf-gcc(?:\.exe)?$"
debuggerPattern="riscv32-esp-elf-gdb(\.exe)?$"
fileName="toolchain-esp32c2.cmake"
id="riscv32-esp-elf"
name="esp32c2">
</ToolChain>
<ToolChain
arch="riscv32"
compilerPattern="riscv32-esp-elf[\\/]+bin[\\/]+riscv32-esp-elf-gcc(?:\.exe)?$"
debuggerPattern="riscv32-esp-elf-gdb(\.exe)?$"
fileName="toolchain-esp32c3.cmake"
id="riscv32-esp-elf"
name="esp32c3">
</ToolChain>
<ToolChain
arch="riscv32"
compilerPattern="riscv32-esp-elf[\\/]+bin[\\/]+riscv32-esp-elf-gcc(?:\.exe)?$"
debuggerPattern="riscv32-esp-elf-gdb(\.exe)?$"
fileName="toolchain-esp32c6.cmake"
id="riscv32-esp-elf"
name="esp32c6">
</ToolChain>
<ToolChain
arch="riscv32"
compilerPattern="riscv32-esp-elf[\\/]+bin[\\/]+riscv32-esp-elf-gcc(?:\.exe)?$"
debuggerPattern="riscv32-esp-elf-gdb(\.exe)?$"
fileName="toolchain-esp32h2.cmake"
id="riscv32-esp-elf"
name="esp32h2">
</ToolChain>
<ToolChain
arch="riscv32"
compilerPattern="riscv32-esp-elf[\\/]+bin[\\/]+riscv32-esp-elf-gcc(?:\.exe)?$"
debuggerPattern="riscv32-esp-elf-gdb(\.exe)?$"
fileName="toolchain-esp32p4.cmake"
id="riscv32-esp-elf"
name="esp32p4">
</ToolChain>
</extension>
<extension point="org.eclipse.core.variables.dynamicVariables">
<variable
description="%openocd_bin_path"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ public String getDefaultBoard(String targetName)
{
List<Board> boardsList = this.espConfigParser.getBoardsForTarget(targetName);
String[] boards = boardsList.stream().map(Board::name).toArray(String[]::new);

if (boards.length == 0)
{
return EspTarget.enumOf(targetName).board;
}

return boards[getIndexOfDefaultBoard(targetName, boards)];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@
import org.eclipse.cdt.core.build.IToolChainManager;
import org.eclipse.cdt.core.build.IToolChainProvider;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.launchbar.core.target.ILaunchTargetWorkingCopy;
Expand Down Expand Up @@ -74,23 +72,27 @@ public ESPToolChainManager()

private static Map<String, ESPToolChainElement> readESPToolchainRegistry()
{
IConfigurationElement[] configElements = Platform.getExtensionRegistry()
.getConfigurationElementsFor("com.espressif.idf.core.toolchain"); //$NON-NLS-1$
for (IConfigurationElement iConfigurationElement : configElements)
// Read targets dynamically from ESP-IDF constants.py instead of plugin.xml
String idfPath = IDFUtil.getIDFPath();
IDFTargets idfTargets = IDFTargetsReader.readTargetsFromEspIdf(idfPath);

// Convert dynamic targets to toolchain elements
for (IDFTargets.IDFTarget target : idfTargets.getAllTargets())
{
String name = iConfigurationElement.getAttribute("name"); //$NON-NLS-1$
String id = iConfigurationElement.getAttribute("id"); //$NON-NLS-1$
String arch = iConfigurationElement.getAttribute("arch"); //$NON-NLS-1$
String fileName = iConfigurationElement.getAttribute("fileName"); //$NON-NLS-1$
String compilerPattern = iConfigurationElement.getAttribute("compilerPattern"); //$NON-NLS-1$
String debuggerPatten = iConfigurationElement.getAttribute("debuggerPattern"); //$NON-NLS-1$
String name = target.getName();
String id = target.getToolchainId();
String arch = target.getArchitecture();
String fileName = target.getToolchainFileName();
String compilerPattern = target.getCompilerPattern();
String debuggerPattern = target.getDebuggerPattern();

String uniqueToolChainId = name.concat("/").concat(arch).concat("/").concat(fileName); //$NON-NLS-1$ //$NON-NLS-2$

toolchainElements.put(uniqueToolChainId,
new ESPToolChainElement(name, id, arch, fileName, compilerPattern, debuggerPatten));

new ESPToolChainElement(name, id, arch, fileName, compilerPattern, debuggerPattern));
}

Logger.log("Dynamically loaded " + toolchainElements.size() + " toolchain elements from ESP-IDF"); //$NON-NLS-1$ //$NON-NLS-2$
return toolchainElements;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*******************************************************************************
* Copyright 2025 Espressif Systems (Shanghai) PTE LTD. All rights reserved.
* Use is subject to license terms.
*******************************************************************************/

package com.espressif.idf.core.toolchain;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.espressif.idf.core.toolchain.enums.Target;

/**
* Class to hold ESP-IDF target information including preview status
*
* @author Kondal Kolipaka <[email protected]>, Ali Azam Rana <[email protected]>
*
*/
public class IDFTargets
{
private List<IDFTarget> supportedTargets;
private List<IDFTarget> previewTargets;

public IDFTargets()
{
this.supportedTargets = new ArrayList<>();
this.previewTargets = new ArrayList<>();
}

public void addSupportedTarget(String targetName)
{
Target t = Target.fromString(targetName);
if (t != null)
supportedTargets.add(new IDFTarget(t, false));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Dropping unknown targets breaks “future-proof” discovery

Target.fromString(targetName) returns null for new targets (e.g., esp32c5), so they never get added. This contradicts the PR objective of zero plugin updates for new targets.

Apply this diff to fallback to a dynamic target for unknown names:

   public void addSupportedTarget(String targetName)
   {
     Target t = Target.fromString(targetName);
-    if (t != null)
-      supportedTargets.add(new IDFTarget(t, false));
+    if (t != null) {
+      supportedTargets.add(new IDFTarget(t, false));
+    } else {
+      supportedTargets.add(IDFTarget.dynamic(targetName, false));
+    }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void addSupportedTarget(String targetName)
{
Target t = Target.fromString(targetName);
if (t != null)
supportedTargets.add(new IDFTarget(t, false));
}
public void addSupportedTarget(String targetName)
{
Target t = Target.fromString(targetName);
if (t != null) {
supportedTargets.add(new IDFTarget(t, false));
} else {
supportedTargets.add(IDFTarget.dynamic(targetName, false));
}
}
🤖 Prompt for AI Agents
In
bundles/com.espressif.idf.core/src/com/espressif/idf/core/toolchain/IDFTargets.java
around lines 31 to 36, Target.fromString(targetName) returns null for
unknown/new targets so they are skipped; change the logic to fall back to
creating a dynamic target when t is null by constructing an IDFTarget that uses
the raw targetName and marks it as dynamic/unknown (instead of skipping), e.g.
when t != null keep existing new IDFTarget(t, false) else create a dynamic
IDFTarget using the name and a true dynamic flag so new targets (like esp32c5)
are preserved for “future-proof” discovery.


public void addPreviewTarget(String targetName)
{
Target t = Target.fromString(targetName);
if (t != null)
previewTargets.add(new IDFTarget(t, true));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Same issue for preview targets

Preview targets not present in the enum are silently ignored.

   public void addPreviewTarget(String targetName)
   {
     Target t = Target.fromString(targetName);
-    if (t != null)
-      previewTargets.add(new IDFTarget(t, true));
+    if (t != null) {
+      previewTargets.add(new IDFTarget(t, true));
+    } else {
+      previewTargets.add(IDFTarget.dynamic(targetName, true));
+    }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void addPreviewTarget(String targetName)
{
Target t = Target.fromString(targetName);
if (t != null)
previewTargets.add(new IDFTarget(t, true));
}
public void addPreviewTarget(String targetName)
{
Target t = Target.fromString(targetName);
if (t != null) {
previewTargets.add(new IDFTarget(t, true));
} else {
previewTargets.add(IDFTarget.dynamic(targetName, true));
}
}
🤖 Prompt for AI Agents
In
bundles/com.espressif.idf.core/src/com/espressif/idf/core/toolchain/IDFTargets.java
around lines 38 to 43, the method addPreviewTarget currently ignores unknown
target names because Target.fromString returning null is silently skipped;
change this to the same behavior as the non-preview addTarget path by validating
the result of Target.fromString and throwing an IllegalArgumentException (or
otherwise reporting an error) if the targetName is not found so unknown preview
targets are not silently ignored.


public List<IDFTarget> getAllTargets()
{
List<IDFTarget> all = new ArrayList<>(supportedTargets);
all.addAll(previewTargets);
return all;
}

public List<IDFTarget> getSupportedTargets()
{
return supportedTargets;
}

public List<IDFTarget> getPreviewTargets()
{
return previewTargets;
}

public boolean hasTarget(String targetName)
{
Target t = Target.fromString(targetName);
return t != null && getAllTargets().stream().anyMatch(x -> x.getTarget() == t);
}

public IDFTarget getTarget(String targetName)
{
Target t = Target.fromString(targetName);
return t == null ? null : getAllTargets().stream().filter(x -> x.getTarget() == t).findFirst().orElse(null);
}

public List<String> getAllTargetNames()
{
return getAllTargets().stream().map(IDFTarget::getName).collect(Collectors.toList());
}

public List<String> getSupportedTargetNames()
{
return getSupportedTargets().stream().map(IDFTarget::getName).collect(Collectors.toList());
}

public List<String> getPreviewTargetNames()
{
return getPreviewTargets().stream().map(IDFTarget::getName).collect(Collectors.toList());
}

/**
* Inner class representing a single IDF target
*/
public static class IDFTarget
{
private final Target target;
private final boolean isPreview;

public IDFTarget(Target target, boolean isPreview)
{
this.target = target;
this.isPreview = isPreview;
}

public String getName()
{
return target.idfName();
}

public boolean isPreview()
{
return isPreview;
}

public Target getTarget()
{
return target;
}

public String getArchitecture()
{
return target.architectureId();
}

public String getToolchainId()
{
return target.toolchainId();
}

public String getCompilerPattern()
{
return target.compilerPattern();
}

public String getDebuggerPattern()
{
return target.debuggerPattern();
}

public String getToolchainFileName()
{
return target.toolchainFileName();
}
}
}
Loading
Loading