From 014da6087ef87e2ac92665f651d4a3080f501bfb Mon Sep 17 00:00:00 2001 From: Erwin Waterlander Date: Mon, 18 Nov 2024 15:44:09 +0000 Subject: [PATCH] New Main Tab for Core Build local launch configurations. A new Main Tab was created for Core Build local projects based on the Main Tab used for the classic Managed Build projects. It adds these features: * Option to select a different binary. * Option to control launch pre-builds. The default value for the binary is empty string. With empty string the behaviour for binary selection stays the same as it was. The project name is fixed and cannot be changed. A Core Build launch configuration is created with the project and tied to it. This change relates to #758. It affects all Core Build projects, including CMake projects. --- .../META-INF/MANIFEST.MF | 2 +- .../launch/CoreBuildLaunchConfigDelegate.java | 37 ++++++++++++++ .../CoreBuildLocalLaunchConfigProvider.java | 5 ++ .../CoreBuildLocalRunLaunchDelegate.java | 3 +- .../CoreBuildLocalDebugLaunchDelegate.java | 5 +- .../META-INF/MANIFEST.MF | 2 +- .../LocalLaunchConfigurationTabGroup.java | 4 +- .../launch/internal/ui/LaunchMessages.java | 1 + .../internal/ui/LaunchMessages.properties | 1 + .../org/eclipse/cdt/launch/ui/CMainTab2.java | 9 +++- .../ui/corebuild/CoreBuildMainTab2.java | 51 +++++++++++++++++++ 11 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/corebuild/CoreBuildMainTab2.java diff --git a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF index 0024a8029a6..2789f1a3945 100644 --- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.debug.core; singleton:=true -Bundle-Version: 8.8.600.qualifier +Bundle-Version: 8.8.700.qualifier Bundle-Activator: org.eclipse.cdt.debug.core.CDebugCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchConfigDelegate.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchConfigDelegate.java index 007c39fe546..5405b084778 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchConfigDelegate.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLaunchConfigDelegate.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.debug.core.launch; +import java.nio.file.Paths; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashSet; @@ -23,14 +24,18 @@ import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.internal.core.InternalDebugCoreMessages; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; +import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.launchbar.core.target.launch.LaunchConfigurationTargetedDelegate; @@ -121,6 +126,28 @@ protected IBinary getBinary(ICBuildConfiguration buildConfig) throws CoreExcepti return exeFile; } + /** + * @since 8.8 + */ + protected String getProgramPath(ILaunchConfiguration configuration, IBinary exeFile) throws CoreException { + String programName = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, ""); //$NON-NLS-1$ + + if (programName.isBlank()) { + return Paths.get(exeFile.getLocationURI()).toString(); + } else { + IPath path = new Path( + VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(programName)); + String fullPath; + if (path.isAbsolute()) { + fullPath = path.toOSString(); + } else { + IProject project = getProject(configuration); + fullPath = project.getFile(path).getLocation().toOSString(); + } + return fullPath; + } + } + @Override protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException { // 1. Extract project from configuration @@ -140,6 +167,16 @@ public static String getBuildAttributeName(String mode) { @Override public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target, IProgressMonitor monitor) throws CoreException { + + // We will never get here if "build before launching" is disabled in the Workspace settings, even if in the + // CDT launch configuration "Use workspace settings" is not selected. + // The workspace setting is already considered in org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(), + // before the settings in the CDT launch configuration. + int autoBuild = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_BUILD_BEFORE_LAUNCH, 2); + if (autoBuild == 0) { + return false; + } + ICBuildConfiguration buildConfig = getBuildConfiguration(configuration, mode, target, monitor); if (buildConfig != null) { IProject project = getProject(configuration); diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalLaunchConfigProvider.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalLaunchConfigProvider.java index 9f1a970d0a3..83217390a18 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalLaunchConfigProvider.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalLaunchConfigProvider.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Map.Entry; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; @@ -66,6 +67,10 @@ protected void populateLaunchConfiguration(ILaunchDescriptor descriptor, ILaunch // Set the project and the connection IProject project = descriptor.getAdapter(IProject.class); + // CMainTab2 expects these attributes when calling CLaunchConfigurationTab.getContext() + // Using empty string for default Core Build program. + workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName()); + workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, ""); //$NON-NLS-1$ workingCopy.setMappedResources(new IResource[] { project }); } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalRunLaunchDelegate.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalRunLaunchDelegate.java index ffcfcd597ad..f9b8b4589f4 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalRunLaunchDelegate.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/launch/CoreBuildLocalRunLaunchDelegate.java @@ -12,7 +12,6 @@ import java.io.File; import java.io.IOException; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -55,7 +54,7 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun String[] arguments = CommandLineUtil.argumentsToArray(args); List command = new ArrayList<>(1 + arguments.length); - command.add(Paths.get(exeFile.getLocationURI()).toString()); + command.add(getProgramPath(configuration, exeFile)); command.addAll(Arrays.asList(arguments)); ProcessBuilder builder = new ProcessBuilder(command); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/launching/CoreBuildLocalDebugLaunchDelegate.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/launching/CoreBuildLocalDebugLaunchDelegate.java index 24877b3c275..5c66df142ea 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/launching/CoreBuildLocalDebugLaunchDelegate.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/launching/CoreBuildLocalDebugLaunchDelegate.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.debug.core.launch.CoreBuildLaunchConfigDelegate; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; @@ -86,8 +87,8 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun gdbLaunch.setGDBPath(gdbPath != null ? gdbPath.toString() : "gdb"); //$NON-NLS-1$ String gdbVersion = gdbLaunch.getGDBVersion(); - Path exeFile = Paths.get(getBinary(buildConfig).getLocationURI()); - gdbLaunch.setProgramPath(exeFile.toString()); + IBinary exeFile = getBinary(buildConfig); + gdbLaunch.setProgramPath(getProgramPath(configuration, exeFile)); gdbLaunch.setServiceFactory(new GdbDebugServicesFactory(gdbVersion, configuration)); diff --git a/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF b/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF index 02b137933b9..9913822226b 100644 --- a/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF +++ b/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.launch; singleton:=true -Bundle-Version: 10.4.600.qualifier +Bundle-Version: 10.4.700.qualifier Bundle-Activator: org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/corebuild/LocalLaunchConfigurationTabGroup.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/corebuild/LocalLaunchConfigurationTabGroup.java index a77fe952a98..3636caa3d49 100644 --- a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/corebuild/LocalLaunchConfigurationTabGroup.java +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/corebuild/LocalLaunchConfigurationTabGroup.java @@ -11,7 +11,7 @@ package org.eclipse.cdt.launch.internal.corebuild; import org.eclipse.cdt.launch.ui.CArgumentsTab; -import org.eclipse.cdt.launch.ui.corebuild.CoreBuildMainTab; +import org.eclipse.cdt.launch.ui.corebuild.CoreBuildMainTab2; import org.eclipse.cdt.launch.ui.corebuild.CoreBuildTab; import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; import org.eclipse.debug.ui.EnvironmentTab; @@ -22,7 +22,7 @@ public class LocalLaunchConfigurationTabGroup extends AbstractLaunchConfiguratio @Override public void createTabs(ILaunchConfigurationDialog dialog, String mode) { - ILaunchConfigurationTab mainTab = new CoreBuildMainTab(); + ILaunchConfigurationTab mainTab = new CoreBuildMainTab2(); ILaunchConfigurationTab buildTab = new CoreBuildTab(); ILaunchConfigurationTab argumentsTab = new CArgumentsTab(); ILaunchConfigurationTab environmentTab = new EnvironmentTab(); diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.java index 945f83e21c2..43072c93477 100644 --- a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.java +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.java @@ -52,6 +52,7 @@ public class LaunchMessages extends NLS { public static String CommonBuildTab_Default; public static String CommonBuildTab_NotFound; public static String CommonBuildTab_Toolchain; + public static String CoreBuildMainTab_Keep_empty_for_auto_selection; public static String CoreBuildTab_Build; public static String CoreBuildTab_NoOptions; public static String CoreFileLaunchDelegate_Launching_postmortem_debugger; diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties index cd420e37c48..2f9d5e7c33d 100644 --- a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties @@ -55,6 +55,7 @@ LocalAttachLaunchDelegate_CDT_Launch_Error=CDT Launch Error CommonBuildTab_Default=Default (%s) CommonBuildTab_NotFound=No suitable toolchains found CommonBuildTab_Toolchain=Toolchain +CoreBuildMainTab_Keep_empty_for_auto_selection=keep empty for automatic selection CoreBuildTab_Build=Build Settings CoreBuildTab_NoOptions=No build options required. CoreFileLaunchDelegate_Launching_postmortem_debugger=Launching postmortem debugger diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab2.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab2.java index 44c90a15bdf..ba7f9cda8e8 100644 --- a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab2.java +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab2.java @@ -93,7 +93,7 @@ public class CMainTab2 extends CAbstractMainTab { */ protected Combo fCoreTypeCombo; - private final boolean fDontCheckProgram; + private boolean fDontCheckProgram; private final boolean fSpecifyCoreFile; private final boolean fIncludeBuildSettings; @@ -111,6 +111,13 @@ public CMainTab2(int flags) { fIncludeBuildSettings = (flags & INCLUDE_BUILD_SETTINGS) != 0; } + /** + * @since 10.4 + */ + protected void setDontCheckProgram(boolean dontCheck) { + fDontCheckProgram = dontCheck; + } + @Override public void createControl(Composite parent) { Composite comp = new Composite(parent, SWT.NONE); diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/corebuild/CoreBuildMainTab2.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/corebuild/CoreBuildMainTab2.java new file mode 100644 index 00000000000..52bcc7d55f9 --- /dev/null +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/corebuild/CoreBuildMainTab2.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2024 Intel Corporation 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 + *******************************************************************************/ +package org.eclipse.cdt.launch.ui.corebuild; + +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.cdt.launch.ui.CMainTab2; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.swt.widgets.Composite; + +/** + * @since 10.4 + */ +public class CoreBuildMainTab2 extends CMainTab2 { + + /* + * A Core Build launch configuration is created immediately upon the Core Build project creation. + * It cannot be created by hand and it is not duplicatable and can't be renamed. + * The launch configuration is tied to the project. The project name may not be changed. + */ + @Override + protected void createProjectGroup(Composite parent, int colSpan) { + super.createProjectGroup(parent, colSpan); + fProjText.setEnabled(false); + fProjButton.setVisible(false); + } + + @Override + protected void createExeFileGroup(Composite parent, int colSpan) { + super.createExeFileGroup(parent, colSpan); + fProgText.setMessage(LaunchMessages.CoreBuildMainTab_Keep_empty_for_auto_selection); + } + + /* + * Don't check the program name if it is empty. When the program name is empty the default + * CoreBuild binary is used. + */ + @Override + public boolean isValid(ILaunchConfiguration config) { + String programName = fProgText.getText().trim(); + setDontCheckProgram(programName.isEmpty()); + return super.isValid(config); + } +}