mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 317796 - Build before launch should be cleverer about which configuration is built.
Add option to LaunchConfig Main Tab to automatically choose a build configuration appropriate to the binary being debugged.
This commit is contained in:
parent
97c334a819
commit
5294511318
9 changed files with 176 additions and 14 deletions
|
@ -9,6 +9,7 @@
|
|||
* QNX Software Systems - initial API and implementation
|
||||
* Ken Ryall (Nokia) - bug 118894
|
||||
* Ken Ryall (Nokia) - bug 178731
|
||||
* Alex Collins (Broadcom Corp.) - choose build config automatically
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.debug.core;
|
||||
|
||||
|
@ -120,6 +121,13 @@ public interface ICDTLaunchConfigurationConstants {
|
|||
*/
|
||||
public static final String ATTR_PROJECT_BUILD_CONFIG_ID = CDT_LAUNCH_ID + ".PROJECT_BUILD_CONFIG_ID_ATTR"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Automatically choose build configuration for launch key. The value indicates whether the ID of the build configuration
|
||||
* to be built before launch should be calculated based on the path to the application being launched.
|
||||
* @since 7.1
|
||||
*/
|
||||
public static final String ATTR_PROJECT_BUILD_CONFIG_AUTO = CDT_LAUNCH_ID + ".PROJECT_BUILD_CONFIG_AUTO_ATTR"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Launch configuration attribute key. The value is a string specifying
|
||||
* application a C/C++ launch configuration.
|
||||
|
|
|
@ -522,6 +522,10 @@ public class CMainTab extends CAbstractMainTab {
|
|||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, EMPTY_STRING);
|
||||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, EMPTY_STRING);
|
||||
|
||||
// Set the auto choose build configuration to true for new configurations.
|
||||
// Existing configurations created before this setting was introduced will have this disabled.
|
||||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_AUTO, true);
|
||||
|
||||
ICElement cElement = null;
|
||||
cElement = getContext(config, getPlatform(config));
|
||||
if (cElement != null) {
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.launch; singleton:=true
|
||||
Bundle-Version: 6.1.0.qualifier
|
||||
Bundle-Version: 6.2.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* Andrew Ferguson (andrew.ferguson@arm.com) - bug 123997
|
||||
* Ken Ryall (Nokia) - bug 178731
|
||||
* Anton Leherbauer (Wind River Systems) - bug 224187
|
||||
* Alex Collins (Broadcom Corp.) - choose build config automatically
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.launch;
|
||||
|
||||
|
@ -126,6 +127,7 @@ abstract public class AbstractCLaunchDelegate extends LaunchConfigurationDelegat
|
|||
}
|
||||
}
|
||||
|
||||
private static final String EMPTY_STR = ""; //$NON-NLS-1$
|
||||
|
||||
public AbstractCLaunchDelegate() {
|
||||
super();
|
||||
|
@ -619,18 +621,29 @@ abstract public class AbstractCLaunchDelegate extends LaunchConfigurationDelegat
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets up a project for building by making sure the active configuration is the one used
|
||||
* when the launch was created.
|
||||
* @param configuration
|
||||
* @param buildProject
|
||||
* Sets up a project for building by making sure the active configuration is set to the configuration chosen to
|
||||
* be built before the launch.
|
||||
*
|
||||
* If the configuration to be built before launch was set to be automatically discovered, it is set to the unique
|
||||
* build configuration for the project that outputs to the directory containing the program to be launched.
|
||||
*
|
||||
* @param configuration The launch configuration being launched.
|
||||
* @param buildProject The project to be build before the launch configuration is launched.
|
||||
*/
|
||||
private void setBuildConfiguration(ILaunchConfiguration configuration, IProject buildProject) {
|
||||
|
||||
try {
|
||||
String buildConfigID = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, ""); //$NON-NLS-1$
|
||||
ICProjectDescription projDes = CDTPropertyManager.getProjectDescription(buildProject);
|
||||
String buildConfigID = null;
|
||||
|
||||
if (buildConfigID.length() > 0 && projDes != null)
|
||||
if (configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_AUTO, false)) {
|
||||
String programPath = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, EMPTY_STR);
|
||||
ICConfigurationDescription buildConfig = LaunchUtils.getBuildConfigByProgramPath(buildProject, programPath);
|
||||
if (buildConfig != null)
|
||||
buildConfigID = buildConfig.getId();
|
||||
} else
|
||||
buildConfigID = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, EMPTY_STR);
|
||||
|
||||
if (buildConfigID != null && buildConfigID.length() > 0 && projDes != null)
|
||||
{
|
||||
ICConfigurationDescription buildConfiguration = projDes.getConfigurationById(buildConfigID);
|
||||
if (buildConfiguration != null) {
|
||||
|
|
|
@ -243,11 +243,23 @@ public abstract class AbstractCLaunchDelegate2 extends LaunchConfigurationDelega
|
|||
return false;
|
||||
}
|
||||
|
||||
String buildConfigID = null;
|
||||
|
||||
// If automatic configuration detection then discover the build config corresponding to the executable
|
||||
if (configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_AUTO, false)) {
|
||||
String programPath = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, ""); //$NON-NLS-1$
|
||||
ICConfigurationDescription buildConfig = LaunchUtils.getBuildConfigByProgramPath(project, programPath);
|
||||
if (buildConfig != null)
|
||||
buildConfigID = buildConfig.getId();
|
||||
}
|
||||
|
||||
// The attribute value will be "" if 'Use Active' is selected
|
||||
String buildConfigID = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, ""); //$NON-NLS-1$
|
||||
if (buildConfigID == null) {
|
||||
buildConfigID = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, ""); //$NON-NLS-1$
|
||||
if (buildConfigID.length() == 0) {
|
||||
buildConfigID = null;
|
||||
}
|
||||
}
|
||||
|
||||
// There's no guarantee the ID stored in the launch config is valid.
|
||||
// The user may have deleted the build configuration.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Alex Collins (Broadcom Corp.) - choose build config automatically
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.launch;
|
||||
|
||||
|
@ -18,8 +19,17 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.IBinaryParser;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.core.ICExtensionReference;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICOutputEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.core.settings.model.extension.CBuildData;
|
||||
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
|
||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
||||
import org.eclipse.cdt.utils.CommandLineUtil;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -141,4 +151,63 @@ public class LaunchUtils {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the build configuration that most likely builds the given program path.
|
||||
* The build configuration is chosen as the one that outputs to a directory that contains
|
||||
* the given program.
|
||||
*
|
||||
* @param projectDesc The description for the project in which to search for the configuration.
|
||||
* @param programPath The path to the program to search the build configurations for
|
||||
* @return The build configuration that builds programName; or null if none or more than one were found.
|
||||
* @since 6.2
|
||||
*/
|
||||
public static ICConfigurationDescription getBuildConfigByProgramPath(IProject project, String programPath) {
|
||||
if (project == null || programPath == null)
|
||||
return null;
|
||||
ICProjectDescription projectDesc = CoreModel.getDefault().getProjectDescription(project, false);
|
||||
if (projectDesc == null)
|
||||
return null;
|
||||
|
||||
// If the program path is relative, it must be relative to the projects root
|
||||
IPath path = new Path(programPath);
|
||||
if (!path.isAbsolute()) {
|
||||
IPath projLocation = project.getLocation();
|
||||
if (projLocation == null)
|
||||
return null;
|
||||
path = projLocation.append(path);
|
||||
}
|
||||
|
||||
// Get all possible files that the program path could refer to
|
||||
IFile[] files = ResourceLookup.findFilesForLocation(path);
|
||||
|
||||
// Find the build config whose output directory matches one of the possible files
|
||||
ICConfigurationDescription buildConfig = null;
|
||||
findCfg: for (ICConfigurationDescription cfgDes : projectDesc.getConfigurations()) {
|
||||
CConfigurationData cfgData = cfgDes.getConfigurationData();
|
||||
if (cfgData == null)
|
||||
continue;
|
||||
CBuildData buildData = cfgData.getBuildData();
|
||||
if (buildData == null)
|
||||
continue;
|
||||
for (ICOutputEntry dir : buildData.getOutputDirectories()) {
|
||||
ICOutputEntry absoluteDir = CDataUtil.makeAbsolute(project, dir);
|
||||
if (absoluteDir == null)
|
||||
continue;
|
||||
IPath dirLocation = absoluteDir.getLocation();
|
||||
if (dirLocation == null)
|
||||
continue;
|
||||
for (IFile file : files) {
|
||||
if (dirLocation.isPrefixOf(file.getLocation())) {
|
||||
if (buildConfig != null && buildConfig != cfgDes) {
|
||||
// Matched more than one, so use the active configuration
|
||||
buildConfig = null;
|
||||
break findCfg;
|
||||
}
|
||||
buildConfig = cfgDes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return buildConfig;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ CMainTab.Program_is_not_a_recongnized_executable=Program is not a recognized exe
|
|||
CMainTab.Program_invalid_proj_path=Program specification is not a valid project-relative path.
|
||||
CMainTab.Build_Config=Build configuration:
|
||||
CMainTab.Use_Active=Use Active
|
||||
CMainTab.Build_Config_Auto=Select configuration using 'C/C++ Application'
|
||||
#For CMainTab.Configuration_name: {0} - project name; {1} - configuration name
|
||||
CMainTab.Configuration_name={0} {1}
|
||||
CMainTab.Build_options=Build (if required) before launching
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Ken Ryall (Nokia) - initial API and implementation
|
||||
* IBM Corporation
|
||||
* Alex Collins (Broadcom Corp.) - choose build config automatically
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.launch.ui;
|
||||
|
||||
|
@ -16,8 +17,8 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.ICDescriptor;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.core.ICDescriptor;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.IBinary;
|
||||
|
@ -72,6 +73,12 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
* @since 6.0
|
||||
*/
|
||||
protected Combo fBuildConfigCombo;
|
||||
/** @since 6.2 */
|
||||
protected Button fBuildConfigAuto;
|
||||
/** Indicates whether the user has clicked on the build config auto button
|
||||
* Prevents causing a delta to the underlying launch configuration if the user hasn't touched this setting.
|
||||
* @since 6.2 */
|
||||
protected boolean fBuildConfigAutoChanged;
|
||||
/** @since 6.1 */
|
||||
protected Button fDisableBuildButton;
|
||||
/** @since 6.1 */
|
||||
|
@ -262,6 +269,7 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
protected void updateBuildConfigCombo(String selectedConfigID) {
|
||||
if (fBuildConfigCombo != null)
|
||||
{
|
||||
fBuildConfigCombo.setEnabled(!fBuildConfigAuto.getSelection());
|
||||
fBuildConfigCombo.removeAll();
|
||||
fBuildConfigCombo.add(LaunchMessages.getString("CMainTab.Use_Active")); //$NON-NLS-1$
|
||||
fBuildConfigCombo.setData("0", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
@ -272,6 +280,14 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
ICProjectDescription projDes = CDTPropertyManager.getProjectDescription(cproject.getProject());
|
||||
if (projDes != null)
|
||||
{
|
||||
// Find the config that should be automatically selected
|
||||
String autoConfigId = null;
|
||||
if (fBuildConfigAuto.getSelection()) {
|
||||
ICConfigurationDescription autoConfig = LaunchUtils.getBuildConfigByProgramPath(cproject.getProject(), fProgText.getText());
|
||||
if (autoConfig != null)
|
||||
autoConfigId = autoConfig.getId();
|
||||
}
|
||||
|
||||
int selIndex = 0;
|
||||
ICConfigurationDescription[] configurations = projDes.getConfigurations();
|
||||
ICConfigurationDescription selectedConfig = projDes.getConfigurationById(selectedConfigID);
|
||||
|
@ -279,9 +295,11 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
String configName = configurations[i].getName();
|
||||
fBuildConfigCombo.add(configName);
|
||||
fBuildConfigCombo.setData(Integer.toString(i + 1), configurations[i].getId());
|
||||
if (selectedConfig != null && selectedConfigID.equals(configurations[i].getId()))
|
||||
if (selectedConfig != null && selectedConfigID.equals(configurations[i].getId()) ||
|
||||
fBuildConfigAuto.getSelection() && configurations[i].getId().equals(autoConfigId)) {
|
||||
selIndex = i + 1;
|
||||
}
|
||||
}
|
||||
fBuildConfigCombo.select(selIndex);
|
||||
}
|
||||
|
||||
|
@ -313,6 +331,26 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
updateLaunchConfigurationDialog();
|
||||
}
|
||||
});
|
||||
|
||||
new Label(comboComp, SWT.NONE).setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
|
||||
fBuildConfigAuto = new Button(comboComp, SWT.CHECK);
|
||||
fBuildConfigAuto.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
fBuildConfigAuto.setText(LaunchMessages.getString("CMainTab.Build_Config_Auto")); //$NON-NLS-1$
|
||||
fBuildConfigAuto.addSelectionListener(new SelectionListener() {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
fBuildConfigAutoChanged = true;
|
||||
fBuildConfigCombo.setEnabled(false);
|
||||
updateBuildConfigCombo(""); //$NON-NLS-1$
|
||||
updateLaunchConfigurationDialog();
|
||||
}
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
fBuildConfigAutoChanged = true;
|
||||
fBuildConfigCombo.setEnabled(true);
|
||||
updateBuildConfigCombo(""); //$NON-NLS-1$
|
||||
updateLaunchConfigurationDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @since 6.1 */
|
||||
|
@ -377,13 +415,20 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
|
||||
/** @since 6.1 */
|
||||
protected void updateBuildOptionFromConfig(ILaunchConfiguration config) {
|
||||
boolean configAuto = false;
|
||||
int buildBeforeLaunchValue = ICDTLaunchConfigurationConstants.BUILD_BEFORE_LAUNCH_USE_WORKSPACE_SETTING;
|
||||
try {
|
||||
buildBeforeLaunchValue = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_BUILD_BEFORE_LAUNCH, buildBeforeLaunchValue);
|
||||
configAuto = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_AUTO, false);
|
||||
} catch (CoreException e) {
|
||||
LaunchUIPlugin.log(e);
|
||||
}
|
||||
|
||||
if (fBuildConfigAuto != null) {
|
||||
fBuildConfigAuto.setSelection(configAuto);
|
||||
if (configAuto)
|
||||
updateBuildConfigCombo(""); //$NON-NLS-1$
|
||||
}
|
||||
if (fDisableBuildButton != null)
|
||||
fDisableBuildButton.setSelection(buildBeforeLaunchValue == ICDTLaunchConfigurationConstants.BUILD_BEFORE_LAUNCH_DISABLED);
|
||||
if (fEnableBuildButton != null)
|
||||
|
@ -501,6 +546,10 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, (String)fBuildConfigCombo.getData(Integer.toString(fBuildConfigCombo.getSelectionIndex())));
|
||||
}
|
||||
|
||||
if (fBuildConfigAutoChanged && fBuildConfigAuto != null) {
|
||||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_AUTO, fBuildConfigAuto.getSelection());
|
||||
}
|
||||
|
||||
if (fDisableBuildButton != null) {
|
||||
int buildBeforeLaunchValue = ICDTLaunchConfigurationConstants.BUILD_BEFORE_LAUNCH_USE_WORKSPACE_SETTING;
|
||||
if (fDisableBuildButton.getSelection()) {
|
||||
|
@ -545,6 +594,8 @@ public abstract class CAbstractMainTab extends CLaunchConfigurationTab {
|
|||
*/
|
||||
@Override
|
||||
protected void updateLaunchConfigurationDialog() {
|
||||
if (fBuildConfigAuto.getSelection())
|
||||
updateBuildConfigCombo(""); //$NON-NLS-1$
|
||||
super.updateLaunchConfigurationDialog();
|
||||
}
|
||||
|
||||
|
|
|
@ -535,6 +535,10 @@ public class CMainTab extends CAbstractMainTab {
|
|||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, EMPTY_STRING);
|
||||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, EMPTY_STRING);
|
||||
|
||||
// Set the auto choose build configuration to true for new configurations.
|
||||
// Existing configurations created before this setting was introduced will have this disabled.
|
||||
config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_AUTO, true);
|
||||
|
||||
ICElement cElement = null;
|
||||
cElement = getContext(config, getPlatform(config));
|
||||
if (cElement != null) {
|
||||
|
|
Loading…
Add table
Reference in a new issue