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 d2ca74a2f45..854112f49e0 100644 --- a/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF +++ b/debug/org.eclipse.cdt.debug.core/META-INF/MANIFEST.MF @@ -11,6 +11,7 @@ Export-Package: org.eclipse.cdt.debug.core, org.eclipse.cdt.debug.core.command, org.eclipse.cdt.debug.core.disassembly, org.eclipse.cdt.debug.core.executables, + org.eclipse.cdt.debug.core.launch, org.eclipse.cdt.debug.core.model, org.eclipse.cdt.debug.core.model.provisional; x-friends:="org.eclipse.cdt.dsf, @@ -27,6 +28,7 @@ Export-Package: org.eclipse.cdt.debug.core, org.eclipse.cdt.debug.internal.core.breakpoints;x-friends:="org.eclipse.cdt.debug.edc,org.eclipse.cdt.dsf.gdb", org.eclipse.cdt.debug.internal.core.disassembly;x-internal:=true, org.eclipse.cdt.debug.internal.core.executables;x-internal:=true, + org.eclipse.cdt.debug.internal.core.launch;x-internal:=true, org.eclipse.cdt.debug.internal.core.model;x-friends:="org.eclipse.cdt.dsf.ui,org.eclipse.cdt.dsf.gdb", org.eclipse.cdt.debug.internal.core.sourcelookup; x-friends:="org.eclipse.cdt.debug.edc, diff --git a/debug/org.eclipse.cdt.debug.core/plugin.xml b/debug/org.eclipse.cdt.debug.core/plugin.xml index 51fa9e3f419..f24d8b3bd14 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.xml +++ b/debug/org.eclipse.cdt.debug.core/plugin.xml @@ -465,7 +465,7 @@ point="org.eclipse.debug.core.launchConfigurationTypes"> diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLocalLaunchConfigDelegate.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLocalLaunchConfigDelegate.java new file mode 100644 index 00000000000..d66bcb7844f --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/launch/CoreBuildLocalLaunchConfigDelegate.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.debug.core.launch; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.build.IToolChainManager; +import org.eclipse.cdt.core.model.IBinary; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.utils.Platform; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.launchbar.core.target.ILaunchTarget; +import org.eclipse.launchbar.core.target.launch.LaunchConfigurationTargetedDelegate; + +/** + * Common launch delegate code for core build launches. + * + * @since 8.1 + */ +public abstract class CoreBuildLocalLaunchConfigDelegate extends LaunchConfigurationTargetedDelegate { + + protected ICBuildConfigurationManager configManager = CDebugCorePlugin + .getService(ICBuildConfigurationManager.class); + protected IToolChainManager toolChainManager = CDebugCorePlugin.getService(IToolChainManager.class); + + protected IProject getProject(ILaunchConfiguration configuration) throws CoreException { + // TODO - make sure this is really the correct project + return configuration.getMappedResources()[0].getProject(); + } + + protected ICBuildConfiguration getBuildConfiguration(IProject project, String mode, ILaunchTarget target, + IProgressMonitor monitor) throws CoreException { + // Pick build config based on toolchain for target + Map properties = new HashMap<>(); + properties.put(IToolChain.ATTR_OS, Platform.getOS()); + properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); + Collection tcs = toolChainManager.getToolChainsMatching(properties); + if (!tcs.isEmpty()) { + IToolChain toolChain = tcs.iterator().next(); + return configManager.getBuildConfiguration(project, toolChain, mode, monitor); + } else { + return null; + } + } + + protected IBinary getBinary(ICBuildConfiguration buildConfig) throws CoreException { + IBinary[] binaries = buildConfig.getBuildOutput(); + IBinary exeFile = null; + for (IBinary binary : binaries) { + if (binary.isExecutable()) { + exeFile = binary; + break; + } + } + if (exeFile == null) { + throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.PLUGIN_ID, "No binaries")); + } + return exeFile; + } + + @Override + protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException { + // 1. Extract project from configuration + // TODO dependencies too. + IProject project = getProject(configuration); + return new IProject[] { project }; + } + + @Override + public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target, + IProgressMonitor monitor) throws CoreException { + IProject project = getProject(configuration); + ICBuildConfiguration buildConfig = getBuildConfiguration(project, mode, target, monitor); + if (buildConfig != null) { + IProjectDescription desc = project.getDescription(); + desc.setActiveBuildConfig(buildConfig.getBuildConfiguration().getName()); + project.setDescription(desc, monitor); + + Map buildProps = configuration.getAttribute("COREBUILD_" + mode, new HashMap<>()); //$NON-NLS-1$ + if (!buildProps.isEmpty()) { + buildConfig.setProperties(buildProps); + } + } + + // proceed with the build + return superBuildForLaunch(configuration, mode, monitor); + } + +} 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 609bfa3e342..fd8cd1771d3 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 @@ -25,7 +25,7 @@ import org.eclipse.launchbar.core.target.ILaunchTargetManager; public class CoreBuildLocalLaunchConfigProvider extends AbstractLaunchConfigProvider { - private static final String TYPE_ID = "org.eclipse.cdt.debug.core.localLaunchConfigurationType"; //$NON-NLS-1$ + private static final String TYPE_ID = "org.eclipse.cdt.debug.core.localCoreBuildLaunchConfigType"; //$NON-NLS-1$ private Map configs = new HashMap<>(); 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 51d53494c22..e67fa6d96a9 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 @@ -9,19 +9,12 @@ package org.eclipse.cdt.debug.internal.core.launch; import java.io.IOException; import java.nio.file.Paths; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; import org.eclipse.cdt.core.build.ICBuildConfiguration; -import org.eclipse.cdt.core.build.ICBuildConfigurationManager; -import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.debug.core.CDebugCorePlugin; -import org.eclipse.cdt.utils.Platform; +import org.eclipse.cdt.debug.core.launch.CoreBuildLocalLaunchConfigDelegate; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -31,50 +24,8 @@ import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.launchbar.core.target.launch.ITargetedLaunch; -import org.eclipse.launchbar.core.target.launch.LaunchConfigurationTargetedDelegate; -public class CoreBuildLocalRunLaunchDelegate extends LaunchConfigurationTargetedDelegate { - - public static final String TYPE_ID = "org.eclipse.cdt.cmake.core.launchConfigurationType"; //$NON-NLS-1$ - - private ICBuildConfigurationManager configManager = CDebugCorePlugin.getService(ICBuildConfigurationManager.class); - private IToolChainManager tcManager = CDebugCorePlugin.getService(IToolChainManager.class); - - private IProject getProject(ILaunchConfiguration configuration) throws CoreException { - return configuration.getMappedResources()[0].getProject(); - } - - @Override - public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target, - IProgressMonitor monitor) throws CoreException { - // Set active build config based on toolchain for target - Map properties = new HashMap<>(); - properties.put(IToolChain.ATTR_OS, Platform.getOS()); - properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); - // TODO should really use real architecture of platform, not what Eclipse is using. - // Also on 64-bit platforms, try 32-bit if toolchains not found - Collection tcs = tcManager.getToolChainsMatching(properties); - if (!tcs.isEmpty()) { - IToolChain toolChain = tcs.iterator().next(); - - IProject project = getProject(configuration); - ICBuildConfiguration config = configManager.getBuildConfiguration(project, toolChain, "run", monitor); //$NON-NLS-1$ - - if (config != null) { - IProjectDescription desc = project.getDescription(); - desc.setActiveBuildConfig(config.getBuildConfiguration().getName()); - project.setDescription(desc, monitor); - - Map buildProps = configuration.getAttribute("COREBUILD_" + mode, new HashMap<>()); //$NON-NLS-1$ - if (!buildProps.isEmpty()) { - config.setProperties(buildProps); - } - } - } - - // proceed with the build - return superBuildForLaunch(configuration, mode, monitor); - } +public class CoreBuildLocalRunLaunchDelegate extends CoreBuildLocalLaunchConfigDelegate { @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) @@ -83,17 +34,7 @@ public class CoreBuildLocalRunLaunchDelegate extends LaunchConfigurationTargeted ILaunchTarget target = ((ITargetedLaunch) launch).getLaunchTarget(); ICBuildConfiguration buildConfig = getBuildConfiguration(project, mode, target, monitor); - IBinary[] binaries = buildConfig.getBuildOutput(); - IBinary exeFile = null; - for (IBinary binary : binaries) { - if (binary.isExecutable()) { - exeFile = binary; - break; - } - } - if (exeFile == null) { - throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.PLUGIN_ID, "No binaries")); - } + IBinary exeFile = getBinary(buildConfig); try { ProcessBuilder builder = new ProcessBuilder(Paths.get(exeFile.getLocationURI()).toString()); @@ -105,27 +46,4 @@ public class CoreBuildLocalRunLaunchDelegate extends LaunchConfigurationTargeted } } - @Override - protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException { - // 1. Extract project from configuration - // TODO dependencies too. - IProject project = getProject(configuration); - return new IProject[] { project }; - } - - private ICBuildConfiguration getBuildConfiguration(IProject project, String mode, ILaunchTarget target, - IProgressMonitor monitor) throws CoreException { - // Set active build config based on toolchain for target - Map properties = new HashMap<>(); - properties.put(IToolChain.ATTR_OS, Platform.getOS()); - properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); - Collection tcs = tcManager.getToolChainsMatching(properties); - if (!tcs.isEmpty()) { - IToolChain toolChain = tcs.iterator().next(); - return configManager.getBuildConfiguration(project, toolChain, "run", monitor); //$NON-NLS-1$ - } else { - return null; - } - } - } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb/plugin.xml index da205ebd521..ea9c3a68a7c 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/plugin.xml +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/plugin.xml @@ -85,4 +85,20 @@ + + + + + + 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 new file mode 100644 index 00000000000..4ccc09812cf --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/launching/CoreBuildLocalDebugLaunchDelegate.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2016 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.launching; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.debug.core.launch.CoreBuildLocalLaunchConfigDelegate; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; +import org.eclipse.cdt.dsf.gdb.launching.GdbSourceLookupDirector; +import org.eclipse.cdt.dsf.gdb.launching.ServicesLaunchSequence; +import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory; +import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.launchbar.core.target.ILaunchTarget; +import org.eclipse.launchbar.core.target.launch.ITargetedLaunch; + +public class CoreBuildLocalDebugLaunchDelegate extends CoreBuildLocalLaunchConfigDelegate { + + @Override + public ITargetedLaunch getLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target) + throws CoreException { + GdbLaunch launch = new GdbLaunch(configuration, mode, null); + launch.setLaunchTarget(target); + launch.initialize(); + + GdbSourceLookupDirector locator = new GdbSourceLookupDirector(launch.getSession()); + String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String) null); + if (memento == null) { + locator.initializeDefaults(configuration); + } else { + locator.initializeFromMemento(memento, configuration); + } + + launch.setSourceLocator(locator); + return launch; + } + + @Override + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) + throws CoreException { + GdbLaunch gdbLaunch = (GdbLaunch) launch; + ILaunchTarget target = ((ITargetedLaunch) launch).getLaunchTarget(); + IProject project = getProject(configuration); + ICBuildConfiguration buildConfig = getBuildConfiguration(project, mode, target, monitor); + + Map buildEnv = new HashMap<>(); + buildConfig.setBuildEnvironment(buildEnv); + Properties envProps = new Properties(); + envProps.putAll(buildEnv); + gdbLaunch.setInitialEnvironment(envProps); + + IToolChain toolChain = buildConfig.getToolChain(); + gdbLaunch.setGDBPath(toolChain.getCommandPath(Paths.get("gdb")).toString()); //$NON-NLS-1$ + String gdbVersion = gdbLaunch.getGDBVersion(); + + Path exeFile = Paths.get(getBinary(buildConfig).getLocationURI()); + gdbLaunch.setProgramPath(exeFile.toString()); + + gdbLaunch.setServiceFactory(new GdbDebugServicesFactory(gdbVersion, configuration)); + + Sequence servicesLaunchSequence = new ServicesLaunchSequence(gdbLaunch.getSession(), gdbLaunch, monitor); + gdbLaunch.getSession().getExecutor().execute(servicesLaunchSequence); + try { + servicesLaunchSequence.get(); + } catch (InterruptedException | ExecutionException e) { + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Failure launching with gdb", e)); + } + + gdbLaunch.initializeControl(); + + gdbLaunch.addCLIProcess(gdbLaunch.getGDBPath().toOSString() + " (" + gdbVersion + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + + Query ready = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + DsfServicesTracker tracker = new DsfServicesTracker( + GdbPlugin.getDefault().getBundle().getBundleContext(), gdbLaunch.getSession().getId()); + IGDBControl control = tracker.getService(IGDBControl.class); + tracker.dispose(); + control.completeInitialization( + new RequestMonitorWithProgress(ImmediateExecutor.getInstance(), monitor) { + @Override + protected void handleCompleted() { + if (isCanceled()) { + rm.cancel(); + } else { + rm.setStatus(getStatus()); + } + rm.done(); + } + }); + } + }; + + // Start it up + gdbLaunch.getSession().getExecutor().execute(ready); + try { + ready.get(); + } catch (ExecutionException | InterruptedException e) { + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Failure to start debug session", e)); + } + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java index 48ec7751db1..2bf27f35e82 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java @@ -113,6 +113,7 @@ public class GdbLaunch extends DsfLaunch implements ITerminate, IDisconnect, ITr private IMemoryBlockRetrievalManager fMemRetrievalManager; private IDsfDebugServicesFactory fServiceFactory; private ILaunchTarget fLaunchTarget; + private Properties fInitialEnv; private String fGdbVersion; @@ -897,6 +898,9 @@ public class GdbLaunch extends DsfLaunch implements ITerminate, IDisconnect, ITr */ public Properties getEnvironmentVariables() throws CoreException { Properties envVariables = new Properties(); + if (fInitialEnv != null) { + envVariables.putAll(fInitialEnv); + } // if the attribute ATTR_APPEND_ENVIRONMENT_VARIABLES is set, // the LaunchManager will return both the new variables and the @@ -984,4 +988,13 @@ public class GdbLaunch extends DsfLaunch implements ITerminate, IDisconnect, ITr return fLaunchTarget; } + /** + * Set the initial environment variables. These can then be overriden + * by launch configuration attributes. + * + * @since 5.2 + */ + public void setInitialEnvironment(Properties initialEnv) { + this.fInitialEnv = initialEnv; + } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java index 3236ea2af0e..81ca2ccd005 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java @@ -60,6 +60,28 @@ public class QtBuildConfiguration extends CBuildConfiguration private final String qtInstallSpec; private IQtInstall qtInstall; private Map properties; + + private IEnvironmentVariable pathVar = new IEnvironmentVariable() { + @Override + public String getValue() { + return getQmakeCommand().getParent().toString(); + } + + @Override + public int getOperation() { + return IEnvironmentVariable.ENVVAR_PREPEND; + } + + @Override + public String getName() { + return "PATH"; + } + + @Override + public String getDelimiter() { + return File.pathSeparator; + } + }; public QtBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { super(config, name); @@ -236,14 +258,16 @@ public class QtBuildConfiguration extends CBuildConfiguration @Override public IEnvironmentVariable getVariable(String name) { - // TODO Auto-generated method stub - return null; + if ("PATH".equals(name)) { + return pathVar; + } else { + return null; + } } @Override public IEnvironmentVariable[] getVariables() { - // TODO - return new IEnvironmentVariable[0]; + return new IEnvironmentVariable[] { pathVar }; } @Override