diff --git a/bundles/com.espressif.idf.core/META-INF/MANIFEST.MF b/bundles/com.espressif.idf.core/META-INF/MANIFEST.MF index abe1556d5..aff2e770c 100644 --- a/bundles/com.espressif.idf.core/META-INF/MANIFEST.MF +++ b/bundles/com.espressif.idf.core/META-INF/MANIFEST.MF @@ -63,6 +63,7 @@ Bundle-ClassPath: ., lib/commons-text-1.10.0.jar, lib/commons-compress-1.21.jar, lib/xz-1.9.jar -Import-Package: org.eclipse.embedcdt.core, +Import-Package: org.eclipse.cdt.debug.core.launch, + org.eclipse.embedcdt.core, org.eclipse.launchbar.ui.target, org.eclipse.ui.console diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFBuildConfiguration.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFBuildConfiguration.java index 43ef6f3fb..b1e02af2d 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFBuildConfiguration.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFBuildConfiguration.java @@ -29,7 +29,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Stream; import org.eclipse.cdt.build.gcc.core.ClangToolChain; import org.eclipse.cdt.cmake.core.ICMakeToolChainFile; @@ -67,7 +66,6 @@ import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.ILaunchMode; import org.eclipse.launchbar.core.ILaunchBarManager; import org.eclipse.launchbar.core.target.ILaunchTarget; @@ -85,6 +83,7 @@ import com.espressif.idf.core.util.DfuCommandsUtil; import com.espressif.idf.core.util.HintsUtil; import com.espressif.idf.core.util.IDFUtil; +import com.espressif.idf.core.util.LaunchUtil; import com.espressif.idf.core.util.LspService; import com.espressif.idf.core.util.ParitionSizeHandler; import com.espressif.idf.core.util.ProjectDescriptionReader; @@ -113,7 +112,6 @@ public class IDFBuildConfiguration extends CBuildConfiguration * To work around that, we run cmake in advance with its dedicated working error parser. */ private ICMakeToolChainFile toolChainFile; - private String customBuildDir; private IProgressMonitor monitor; public boolean isProgressSet; @@ -158,43 +156,12 @@ public IContainer getBuildContainer() throws CoreException public IPath getBuildContainerPath() throws CoreException { - if (hasCustomBuild()) + org.eclipse.core.runtime.Path path = new org.eclipse.core.runtime.Path(IDFUtil.getBuildDir(getProject())); + if (!path.toFile().exists()) { - org.eclipse.core.runtime.Path path = new org.eclipse.core.runtime.Path(customBuildDir); - if (!path.toFile().exists()) - { - path.toFile().mkdirs(); - } - return path; - } - - return getBuildContainer().getLocation(); - } - - private boolean hasCustomBuild() - { - String userArgs = getProperty(CMAKE_ARGUMENTS); - // Custom build directory - String[] cmakeArgumentsArr = userArgs.split(" "); //$NON-NLS-1$ - customBuildDir = StringUtil.EMPTY; - for (int i = 0; i < cmakeArgumentsArr.length; i++) - { - if (cmakeArgumentsArr[i].equals("-B")) //$NON-NLS-1$ - { - customBuildDir = cmakeArgumentsArr[i + 1]; - break; - } - } - try - { - IDFUtil.setBuildDir(getProject(), customBuildDir); - } - catch (CoreException e) - { - Logger.log(e); + path.toFile().mkdirs(); } - - return !customBuildDir.isBlank(); + return path; } @Override @@ -232,7 +199,8 @@ public String getProperty(String name) if (configuration != null && configuration.getType().getIdentifier().equals(IDFLaunchConstants.DEBUG_LAUNCH_CONFIG_TYPE)) { - configuration = getBoundConfiguration(configuration); + configuration = new LaunchUtil(DebugPlugin.getDefault().getLaunchManager()) + .getBoundConfiguration(configuration); } String property = configuration == null ? StringUtil.EMPTY : configuration.getAttribute(name, StringUtil.EMPTY); @@ -247,22 +215,6 @@ public String getProperty(String name) return super.getProperty(name); } - /* - * In case when the active configuration is debugging, we are using bound launch configuration to build the project - */ - private ILaunchConfiguration getBoundConfiguration(ILaunchConfiguration configuration) throws CoreException - { - String bindedLaunchConfigName = configuration.getAttribute(IDFLaunchConstants.ATTR_LAUNCH_CONFIGURATION_NAME, - StringUtil.EMPTY); - ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); - ILaunchConfiguration[] launchConfigurations = launchManager.getLaunchConfigurations(DebugPlugin.getDefault() - .getLaunchManager().getLaunchConfigurationType(IDFLaunchConstants.RUN_LAUNCH_CONFIG_TYPE)); - ILaunchConfiguration defaultConfiguration = launchConfigurations[0]; - return Stream.of(launchConfigurations).filter(config -> config.getName().contentEquals(bindedLaunchConfigName)) - .findFirst().orElse(defaultConfiguration); - - } - private IBinary[] getBuildOutput(final IBinaryContainer binaries, final IPath outputPath) throws CoreException { return Arrays.stream(binaries.getBinaries()).filter(b -> b.isExecutable() && outputPath.isPrefixOf(b.getPath())) diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFLaunchConstants.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFLaunchConstants.java index fc6d15961..0d0b407e9 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFLaunchConstants.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/build/IDFLaunchConstants.java @@ -17,4 +17,5 @@ public final class IDFLaunchConstants public static final String IDF_TARGET_TYPE = "com.espressif.idf.launch.serial.core.serialFlashTarget"; //$NON-NLS-1$ public static final String OPEN_SERIAL_MONITOR = "OPEN_SERIAL_MONITOR"; //$NON-NLS-1$ public static final String SERIAL_MONITOR_ENCODING = "SERIAL_MONITOR_ENCODING"; //$NON-NLS-1$ + public static final String BUILD_FOLDER_PATH = "com.espressif.idf.launch.serial.core.idfBuildFolderPath"; //$NON-NLS-1$ } diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IDFUtil.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IDFUtil.java index b1f26e3a7..73a38153a 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IDFUtil.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IDFUtil.java @@ -18,6 +18,7 @@ import java.util.stream.Stream; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.debug.core.launch.CoreBuildLaunchConfigDelegate; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; @@ -31,6 +32,7 @@ import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.launchbar.core.ILaunchBarManager; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.swt.widgets.Display; @@ -46,6 +48,7 @@ import com.espressif.idf.core.LaunchBarTargetConstants; import com.espressif.idf.core.ProcessBuilderFactory; import com.espressif.idf.core.SystemExecutableFinder; +import com.espressif.idf.core.build.IDFLaunchConstants; import com.espressif.idf.core.logging.Logger; import com.espressif.idf.core.toolchain.ESPToolChainManager; @@ -560,6 +563,46 @@ public static void setBuildDir(IProject project, String pathToBuildDir) throws C pathToBuildDir); } + /** + * Updates the build folder for the specified project in the given launch configuration. + * + * This method retrieves the project associated with the given launch configuration, checks if a build folder path + * is specified in the configuration, and sets the build directory for the project. If no build folder path is + * specified, a default value is used. If the specified path is relative, it is converted to an absolute path based + * on the project's location. + * + * @param configuration The launch configuration whose associated project’s build folder is to be updated. This + * parameter cannot be {@code null}. + * @throws CoreException If there is an issue with accessing the project or updating the build folder. This + * exception is logged, but not rethrown. + */ + public static void updateProjectBuildFolder(ILaunchConfigurationWorkingCopy configuration) + { + try + { + IProject project = CoreBuildLaunchConfigDelegate.getProject(configuration); + if (project == null) + { + return; + } + String buildFolder = configuration.getAttribute(IDFLaunchConstants.BUILD_FOLDER_PATH, + IDFUtil.getBuildDir(project)); + buildFolder = buildFolder.isBlank() ? IDFConstants.BUILD_FOLDER : buildFolder; + + IPath path = new Path(buildFolder); + if (!path.isAbsolute()) + { + IPath projectLocation = project.getLocation(); + path = projectLocation.append(path); + } + IDFUtil.setBuildDir(project, path.toOSString()); + } + catch (CoreException e) + { + Logger.log(e); + } + } + /** * Project .map file path * @@ -765,7 +808,7 @@ public static boolean isReparseTag(File file) } return false; } - + public static String resolveEnvVariable(String path) { Pattern winEnvPattern = Pattern.compile("%(\\w+)%"); //$NON-NLS-1$ @@ -801,7 +844,7 @@ public static String resolveEnvVariable(String path) return resolvedPath.toString(); } - + public static Map getSystemEnv() { Map env = new HashMap(System.getenv()); @@ -810,17 +853,17 @@ public static Map getSystemEnv() env.put(IDFCorePreferenceConstants.IDF_TOOLS_PATH, idfToolsPath); return env; } - + public static String getIDFToolsPathFromPreferences() { String idfToolsPath = Platform.getPreferencesService().getString(IDFCorePlugin.PLUGIN_ID, IDFCorePreferenceConstants.IDF_TOOLS_PATH, IDFCorePreferenceConstants.IDF_TOOLS_PATH_DEFAULT, null); return idfToolsPath; } - + public static void closeWelcomePage(IWorkbenchWindow activeww) { - Display.getDefault().syncExec(()-> { + Display.getDefault().syncExec(() -> { if (activeww != null) { IWorkbenchPage page = activeww.getActivePage(); diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IdfCommandExecutor.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IdfCommandExecutor.java index c55b58f9a..23a2d12ca 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IdfCommandExecutor.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/IdfCommandExecutor.java @@ -54,7 +54,6 @@ public IStatus executeReconfigure(IProject project) private IStatus runIdfReconfigureCommand(IProject project) { ProcessBuilderFactory processRunner = new ProcessBuilderFactory(); - setBuildFolder(project); List arguments = prepareCmakeArguments(project); Map environment = new HashMap<>(new IDFEnvironmentVariables().getSystemEnvMap()); @@ -97,32 +96,6 @@ private List prepareCmakeArguments(IProject project) return arguments; } - private boolean setBuildFolder(IProject project) - { - String userArgs = getProperty(CMAKE_ARGUMENTS); - // Custom build directory - String[] cmakeArgumentsArr = userArgs.split(" "); //$NON-NLS-1$ - String customBuildDir = StringUtil.EMPTY; - for (int i = 0; i < cmakeArgumentsArr.length; i++) - { - if (cmakeArgumentsArr[i].equals("-B")) //$NON-NLS-1$ - { - customBuildDir = cmakeArgumentsArr[i + 1]; - break; - } - } - try - { - IDFUtil.setBuildDir(project, customBuildDir); - } - catch (CoreException e) - { - Logger.log(e); - } - - return !customBuildDir.isBlank(); - } - public String getProperty(String name) { try diff --git a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/LaunchUtil.java b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/LaunchUtil.java index 11025cd8f..ddce63076 100644 --- a/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/LaunchUtil.java +++ b/bundles/com.espressif.idf.core/src/com/espressif/idf/core/util/LaunchUtil.java @@ -4,13 +4,18 @@ *******************************************************************************/ package com.espressif.idf.core.util; +import java.util.stream.Stream; + import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.launchbar.core.ILaunchDescriptor; +import com.espressif.idf.core.build.IDFLaunchConstants; + public class LaunchUtil { private final ILaunchManager launchManager; @@ -36,4 +41,19 @@ public ILaunchConfiguration findAppropriateLaunchConfig(ILaunchDescriptor descri return null; } + /* + * In case when the active configuration is debugging, we are using bound launch configuration to build the project + */ + public ILaunchConfiguration getBoundConfiguration(ILaunchConfiguration configuration) throws CoreException + { + String bindedLaunchConfigName = configuration.getAttribute(IDFLaunchConstants.ATTR_LAUNCH_CONFIGURATION_NAME, + StringUtil.EMPTY); + ILaunchConfiguration[] launchConfigurations = launchManager.getLaunchConfigurations(DebugPlugin.getDefault() + .getLaunchManager().getLaunchConfigurationType(IDFLaunchConstants.RUN_LAUNCH_CONFIG_TYPE)); + ILaunchConfiguration defaultConfiguration = launchConfigurations[0]; + return Stream.of(launchConfigurations).filter(config -> config.getName().contentEquals(bindedLaunchConfigName)) + .findFirst().orElse(defaultConfiguration); + + } + } diff --git a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/ui/TabGroupLaunchConfiguration.java b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/ui/TabGroupLaunchConfiguration.java index a69999fdc..f01a7b749 100644 --- a/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/ui/TabGroupLaunchConfiguration.java +++ b/bundles/com.espressif.idf.debug.gdbjtag.openocd/src/com/espressif/idf/debug/gdbjtag/openocd/ui/TabGroupLaunchConfiguration.java @@ -14,12 +14,19 @@ package com.espressif.idf.debug.gdbjtag.openocd.ui; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; import org.eclipse.debug.ui.CommonTab; import org.eclipse.debug.ui.ILaunchConfigurationDialog; import org.eclipse.debug.ui.ILaunchConfigurationTab; import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; +import com.espressif.idf.core.logging.Logger; +import com.espressif.idf.core.util.IDFUtil; +import com.espressif.idf.core.util.LaunchUtil; + public class TabGroupLaunchConfiguration extends AbstractLaunchConfigurationTabGroup { @@ -38,7 +45,7 @@ public void createTabs(ILaunchConfigurationDialog dialog, String mode) // we manually define the tabs here. TabStartup tabStartup = new TabStartup(); - + ILaunchConfigurationTab tabs[] = new ILaunchConfigurationTab[] { new TabMain(), new TabDebugger(tabStartup), tabStartup, new SourceLookupTab(), new CommonTab(), new TabSvdTarget() }; @@ -46,4 +53,20 @@ public void createTabs(ILaunchConfigurationDialog dialog, String mode) } + @Override + public void performApply(ILaunchConfigurationWorkingCopy configuration) + { + super.performApply(configuration); + try + { + IDFUtil.updateProjectBuildFolder(new LaunchUtil(DebugPlugin.getDefault().getLaunchManager()) + .getBoundConfiguration(configuration).getWorkingCopy()); + } + catch (CoreException e) + { + Logger.log(e); + } + + } + } diff --git a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/CMakeMainTab2.java b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/CMakeMainTab2.java index 7e6e6c658..5db1a0c77 100644 --- a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/CMakeMainTab2.java +++ b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/CMakeMainTab2.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.cdt.cmake.core.internal.CMakeBuildConfiguration; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; @@ -483,6 +484,13 @@ public boolean isValid(ILaunchConfiguration launchConfig) { hasProject = launchConfig.getMappedResources() != null && launchConfig.getMappedResources()[0].getProject().exists(); + // Manually check for "-B" in cmakeArgs here because CMakeBuildTab2's isValid() method is not being called + String cmakeArgs = launchConfig.getAttribute(CMakeBuildConfiguration.CMAKE_ARGUMENTS, StringUtil.EMPTY); + if (cmakeArgs.contains("-B")) //$NON-NLS-1$ + { + setErrorMessage(Messages.CMakeMainTab2_CmakeArgsDeprecatedBArgMessage); + return false; + } } catch (CoreException e) { diff --git a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/Messages.java b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/Messages.java index 48264b908..e9e5d57aa 100644 --- a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/Messages.java +++ b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/Messages.java @@ -30,6 +30,7 @@ public class Messages extends NLS public static String NewSerialFlashTargetWizardPage_Title; public static String CMakeMainTab2_FlashComboLbl; public static String CMakeMainTab2_Arguments; + public static String CMakeMainTab2_CmakeArgsDeprecatedBArgMessage; public static String CMakeMainTab2_NoDfuTargetSelectedError; public static String CMakeMainTab2_Note; public static String CMakeMainTab2_TargetsComboLbl; diff --git a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/SerialFlashLaunchConfigTabGroup.java b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/SerialFlashLaunchConfigTabGroup.java index d6aacdb97..1dd19e128 100644 --- a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/SerialFlashLaunchConfigTabGroup.java +++ b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/SerialFlashLaunchConfigTabGroup.java @@ -19,6 +19,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; import org.eclipse.debug.ui.CommonTab; import org.eclipse.debug.ui.EnvironmentTab; @@ -27,6 +28,7 @@ import org.eclipse.launchbar.ui.internal.LaunchBarLaunchConfigDialog; import com.espressif.idf.core.logging.Logger; +import com.espressif.idf.core.util.IDFUtil; @SuppressWarnings("restriction") public class SerialFlashLaunchConfigTabGroup extends AbstractLaunchConfigurationTabGroup @@ -47,6 +49,13 @@ public void createTabs(ILaunchConfigurationDialog dialog, String mode) } + @Override + public void performApply(ILaunchConfigurationWorkingCopy configuration) + { + super.performApply(configuration); + IDFUtil.updateProjectBuildFolder(configuration); + } + @Override public void initializeFrom(ILaunchConfiguration configuration) { diff --git a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/messages.properties b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/messages.properties index 8a620938f..2d3b430d0 100644 --- a/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/messages.properties +++ b/bundles/com.espressif.idf.launch.serial.ui/src/com/espressif/idf/launch/serial/ui/internal/messages.properties @@ -18,6 +18,7 @@ NewSerialFlashTargetWizardPage_SerialPort=Serial Port: NewSerialFlashTargetWizardPage_Title=ESP Target CMakeMainTab2_FlashComboLbl=Flash over: CMakeMainTab2_Arguments=Arguments: +CMakeMainTab2_CmakeArgsDeprecatedBArgMessage=The -B argument is deprecated and no longer supported. Specify the build path via the Build location setting. CMakeMainTab2_NoDfuTargetSelectedError=The active launch target {0} does not support DFU. The DFU is supported only by esp32s2 and esp32s3 CMakeMainTab2_Note=Note: Enclose an argument containing spaces using double-quotes (\\\\"). CMakeMainTab2_TargetsComboLbl=Targets with DFU support: diff --git a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/LaunchBarListener.java b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/LaunchBarListener.java index 5bc6d0c52..e74e653c7 100644 --- a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/LaunchBarListener.java +++ b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/LaunchBarListener.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.ILaunchMode; @@ -34,6 +35,7 @@ import com.espressif.idf.core.build.IDFLaunchConstants; import com.espressif.idf.core.logging.Logger; import com.espressif.idf.core.util.IDFUtil; +import com.espressif.idf.core.util.LaunchUtil; import com.espressif.idf.core.util.LspService; import com.espressif.idf.core.util.SDKConfigJsonReader; import com.espressif.idf.core.util.StringUtil; @@ -71,6 +73,7 @@ else if (IDFLaunchConstants.DEBUG_LAUNCH_CONFIG_TYPE.equals(configTypeIdentifier setMode(launchBarManager, ILaunchManager.RUN_MODE); setMode(launchBarManager, ILaunchManager.DEBUG_MODE); } + updateProjectBuildFolderBasedOnActiveConfig(activeLaunchConfiguration); } } catch (CoreException e) @@ -245,4 +248,26 @@ private void setMode(ILaunchBarManager launchBarManager, String mode) } } + private void updateProjectBuildFolderBasedOnActiveConfig(ILaunchConfiguration configuration) + { + if (configuration == null) + { + return; + } + try + { + if (configuration.getType().getIdentifier().equals(IDFLaunchConstants.DEBUG_LAUNCH_CONFIG_TYPE)) + { + configuration = new LaunchUtil(DebugPlugin.getDefault().getLaunchManager()) + .getBoundConfiguration(configuration); + } + IDFUtil.updateProjectBuildFolder(configuration.getWorkingCopy()); + + } + catch (CoreException e) + { + Logger.log(e); + } + } + } \ No newline at end of file diff --git a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/CMakeBuildTab2.java b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/CMakeBuildTab2.java index 700dad296..0cc5fe6c9 100644 --- a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/CMakeBuildTab2.java +++ b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/CMakeBuildTab2.java @@ -10,11 +10,11 @@ *******************************************************************************/ package com.espressif.idf.ui.dialogs; -import java.nio.file.Path; import java.util.Map; import org.eclipse.cdt.cmake.core.internal.CMakeBuildConfiguration; import org.eclipse.cdt.debug.core.launch.CoreBuildLaunchConfigDelegate; +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; import org.eclipse.cdt.launch.ui.corebuild.CommonBuildTab; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -31,12 +31,14 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import com.espressif.idf.core.IDFCorePlugin; import com.espressif.idf.core.build.IDFBuildConfigurationProvider; +import com.espressif.idf.core.build.IDFLaunchConstants; import com.espressif.idf.core.logging.Logger; import com.espressif.idf.core.util.LaunchTargetHelper; import com.espressif.idf.core.util.RecheckConfigsHelper; @@ -48,7 +50,7 @@ public class CMakeBuildTab2 extends CommonBuildTab private static final String LOCAL_CMAKE_ARGUMENTS = "local_cmake_arguments"; //$NON-NLS-1$ private static final String UNIX_MAKEFILES = "Unix Makefiles"; //$NON-NLS-1$ private static final String NINJA = "Ninja"; //$NON-NLS-1$ - private static final String DEFAULT_CMAKE_MSG = "-B customBuildFolder"; //$NON-NLS-1$ + private static final String DEFAULT_CMAKE_MSG = ""; //$NON-NLS-1$ private static final String DEFAULT_BUILD_MSG = "cmake --build ."; //$NON-NLS-1$ private static final String DEFAULT_CLEAN_MSG = "ninja clean"; //$NON-NLS-1$ private Button unixGenButton; @@ -56,6 +58,7 @@ public class CMakeBuildTab2 extends CommonBuildTab private Text cmakeArgsText; private Text buildCommandText; private Text cleanCommandText; + private Text buildFolderText; @Override protected String getBuildConfigProviderId() @@ -106,6 +109,37 @@ public void widgetSelected(SelectionEvent e) } }); + label = new Label(cmakeGroup, SWT.NONE); + label.setText(Messages.CMakeBuildTab2_BuildFolderTextLbl); + + // Create a composite to hold the text field and button + Composite buildFolderComp = new Composite(cmakeGroup, SWT.NONE); + buildFolderComp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + buildFolderComp.setLayout(new GridLayout(2, false)); // Two columns: Text field & Button + + // Text field for displaying the build folder path + buildFolderText = new Text(buildFolderComp, SWT.BORDER); + buildFolderText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + buildFolderText.setMessage(Messages.CMakeBuildTab2_BuildFolderTextMsg); + buildFolderText.setToolTipText(Messages.CMakeBuildTab2_BuildFolderTextToolTip); + + // Browse button to select a folder + Button browseButton = createPushButton(buildFolderComp, LaunchMessages.Launch_common_Browse_1, null); // $NON-NLS-1$ + browseButton.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + DirectoryDialog dialog = new DirectoryDialog(parent.getShell()); + dialog.setMessage(Messages.CMakeBuildTab2_SelectBuildFolderMsg); + String selectedDir = dialog.open(); + if (selectedDir != null) + { + buildFolderText.setText(selectedDir); + } + } + }); + label = new Label(cmakeGroup, SWT.NONE); label.setText(Messages.CMakeBuildTab2_AdditionalCMakeArgs); @@ -156,7 +190,6 @@ public void initializeFrom(ILaunchConfiguration configuration) { IProject project = CoreBuildLaunchConfigDelegate.getProject(configuration); RecheckConfigsHelper.revalidateToolchain(project); - } catch (CoreException e) { @@ -164,6 +197,9 @@ public void initializeFrom(ILaunchConfiguration configuration) } try { + String buildFolderPath = configuration.getAttribute(IDFLaunchConstants.BUILD_FOLDER_PATH, StringUtil.EMPTY); + buildFolderText.setText(buildFolderPath); + String generator = configuration.getAttribute(CMakeBuildConfiguration.CMAKE_GENERATOR, StringUtil.EMPTY); updateGeneratorButtons(generator); @@ -212,6 +248,8 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) Logger.log(e); } + configuration.setAttribute(IDFLaunchConstants.BUILD_FOLDER_PATH, buildFolderText.getText()); + configuration.setAttribute(CMakeBuildConfiguration.CMAKE_GENERATOR, ninjaGenButton.getSelection() ? NINJA : UNIX_MAKEFILES); @@ -220,8 +258,7 @@ public void performApply(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(LOCAL_CMAKE_ARGUMENTS, cmakeArgs); if (project != null) - configuration.setAttribute(CMakeBuildConfiguration.CMAKE_ARGUMENTS, - getCmakeArgumentsWithAbsProjectPath(project, cmakeArgs)); + configuration.setAttribute(CMakeBuildConfiguration.CMAKE_ARGUMENTS, cmakeArgs); } else { @@ -257,6 +294,7 @@ protected void saveProperties(Map properties) super.saveProperties(properties); properties.put(CMakeBuildConfiguration.CMAKE_GENERATOR, ninjaGenButton.getSelection() ? NINJA : UNIX_MAKEFILES); + properties.put(IDFLaunchConstants.BUILD_FOLDER_PATH, buildFolderText.getText().trim()); properties.put(LOCAL_CMAKE_ARGUMENTS, cmakeArgsText.getText().trim()); properties.put(CMakeBuildConfiguration.BUILD_COMMAND, buildCommandText.getText().trim()); properties.put(CMakeBuildConfiguration.CLEAN_COMMAND, cleanCommandText.getText().trim()); @@ -283,6 +321,11 @@ protected void restoreProperties(Map properties) } } + String buildFolderPath = properties.get(IDFLaunchConstants.BUILD_FOLDER_PATH); + if (buildFolderPath != null) + { + buildFolderText.setText(buildFolderPath); + } String cmakeArgs = properties.get(LOCAL_CMAKE_ARGUMENTS); if (cmakeArgs != null) { @@ -352,27 +395,4 @@ public String getName() return "CMake"; //$NON-NLS-1$ } - private String getCmakeArgumentsWithAbsProjectPath(IProject project, String cmakeArgumets) - { - String buildFolder = StringUtil.EMPTY; - String[] cmakeArgsArr = cmakeArgsText.getText().trim().split("\\s+"); // Split on any whitespace //$NON-NLS-1$ - - for (int i = 0; i < cmakeArgsArr.length - 1; i++) - { - if (cmakeArgsArr[i].equals("-B")) //$NON-NLS-1$ - { - buildFolder = cmakeArgsArr[i + 1]; - break; - } - } - - if (!Path.of(buildFolder).isAbsolute()) - { - // Getting the first argument after -B option - cmakeArgumets = cmakeArgumets.replaceFirst("(?<=-B)\\s+(\\S+)", //$NON-NLS-1$ - " " + project.getLocation().append(buildFolder)); //$NON-NLS-1$ - } - return cmakeArgumets; - } - } diff --git a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/Messages.java b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/Messages.java index 113455edb..8c635499c 100644 --- a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/Messages.java +++ b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/Messages.java @@ -11,10 +11,14 @@ public class Messages extends NLS public static String DeleteResourcesWizard_project_deleteConfigurations; public static String CMakeBuildTab2_AdditionalCMakeArgs; public static String CMakeBuildTab2_BuildCmd; + public static String CMakeBuildTab2_BuildFolderTextLbl; + public static String CMakeBuildTab2_BuildFolderTextMsg; + public static String CMakeBuildTab2_BuildFolderTextToolTip; public static String CMakeBuildTab2_CleanCmd; public static String CMakeBuildTab2_CMakeSettings; public static String CMakeBuildTab2_Generator; public static String CMakeBuildTab2_Ninja; + public static String CMakeBuildTab2_SelectBuildFolderMsg; public static String CMakeBuildTab2_UnixMakeFiles; public static String EraseFlashDialog_Title; public static String EraseFlashDialog_OkButton; diff --git a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/messages.properties b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/messages.properties index c8a637331..14fb9bfd5 100644 --- a/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/messages.properties +++ b/bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/dialogs/messages.properties @@ -3,10 +3,14 @@ BuildView_HintMsgLbl=Hint BuildView_NoAvailableHintsMsg=No available hints found CMakeBuildTab2_AdditionalCMakeArgs=Additional CMake arguments: CMakeBuildTab2_BuildCmd=Build command +CMakeBuildTab2_BuildFolderTextLbl=Build folder location: +CMakeBuildTab2_BuildFolderTextMsg=Enter a path or leave empty to use the default build folder. +CMakeBuildTab2_BuildFolderTextToolTip=Enter a path or leave empty to use the default build folder. CMakeBuildTab2_CleanCmd=Clean command CMakeBuildTab2_CMakeSettings=CMake Settings CMakeBuildTab2_Generator=Generator CMakeBuildTab2_Ninja=Ninja +CMakeBuildTab2_SelectBuildFolderMsg=Select a build folder: CMakeBuildTab2_UnixMakeFiles=Unix Makefiles EraseFlashDialog_Title=Erase Flash EraseFlashDialog_OkButton=Erase Flash diff --git a/docs/en/buildproject.rst b/docs/en/buildproject.rst index 504c2410d..6a2c26470 100644 --- a/docs/en/buildproject.rst +++ b/docs/en/buildproject.rst @@ -26,7 +26,7 @@ The IDE allows configuring a custom build directory for the project: 1. Select a project and click on the ``Edit`` button for the launch configuration in the top toolbar to open the ``Edit Configuration`` window. 2. Navigate to the ``Build Settings`` tab. -3. In the ``Additional CMake Arguments`` section, provide a custom build directory by adding arguments ``-B `` with an absolute path. The customized build directory path can be within the project or in any other location in the file system. For example: ``-B /Users/myUser/esp/generated``. +3. In the ``Build folder location`` section, provide a custom build directory. The customized build directory path can be within the project or in any other location in the file system. 4. Click on ``Ok`` and build the project. .. note:: diff --git a/media/custombuilddir.png b/media/custombuilddir.png index 6b4d18bf3..85df18616 100644 Binary files a/media/custombuilddir.png and b/media/custombuilddir.png differ