mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Add remotecdt example - bug 137839
This commit is contained in:
parent
0e4a40ba00
commit
307a85d9ac
14 changed files with 885 additions and 0 deletions
7
rse/examples/org.eclipse.rse.remotecdt/.classpath
Normal file
7
rse/examples/org.eclipse.rse.remotecdt/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
rse/examples/org.eclipse.rse.remotecdt/.project
Normal file
28
rse/examples/org.eclipse.rse.remotecdt/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.rse.remotecdt</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
27
rse/examples/org.eclipse.rse.remotecdt/META-INF/MANIFEST.MF
Normal file
27
rse/examples/org.eclipse.rse.remotecdt/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,27 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Remote CDT Plug-in
|
||||
Bundle-SymbolicName: org.eclipse.rse.remotecdt;singleton:=true
|
||||
Bundle-Version: 1.0.0
|
||||
Bundle-Activator: org.eclipse.rse.remotecdt.Activator
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: org.eclipse.core.runtime,
|
||||
org.eclipse.rse.ui,
|
||||
org.eclipse.rse.files.ui,
|
||||
org.eclipse.rse.subsystems.files.ftp,
|
||||
org.eclipse.debug.ui,
|
||||
org.eclipse.cdt.launch,
|
||||
org.eclipse.swt,
|
||||
org.eclipse.ui,
|
||||
org.eclipse.rse.subsystems.shells.dstore,
|
||||
org.eclipse.rse.subsystems.shells.local,
|
||||
org.eclipse.debug.core,
|
||||
org.eclipse.core.resources,
|
||||
org.eclipse.cdt.core,
|
||||
org.eclipse.cdt.debug.mi.core,
|
||||
org.eclipse.rse.subsystems.shells.core,
|
||||
org.eclipse.rse.services,
|
||||
org.eclipse.cdt.debug.core,
|
||||
org.eclipse.cdt.debug.mi.ui
|
||||
Eclipse-LazyStart: true
|
||||
Bundle-Vendor: Eclipse.org
|
12
rse/examples/org.eclipse.rse.remotecdt/build.properties
Normal file
12
rse/examples/org.eclipse.rse.remotecdt/build.properties
Normal file
|
@ -0,0 +1,12 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
plugin.xml
|
||||
src.includes = .classpath,\
|
||||
.project,\
|
||||
META-INF/,\
|
||||
build.properties,\
|
||||
icons/,\
|
||||
plugin.xml,\
|
||||
src/
|
Binary file not shown.
After Width: | Height: | Size: 606 B |
Binary file not shown.
After Width: | Height: | Size: 580 B |
Binary file not shown.
After Width: | Height: | Size: 592 B |
39
rse/examples/org.eclipse.rse.remotecdt/instructions.txt
Normal file
39
rse/examples/org.eclipse.rse.remotecdt/instructions.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
Introduction
|
||||
--------------
|
||||
The attached plugin (org.eclipse.rse.remotecdt) builds on top of CDT and integrates with RSE to introduce a "Remote C++ Application" launch configuration (see screenshot1 attached). This launch configuration shows RSE connections of type "Ssh\Gdbserver" in a pulldown. The "Ssh\Gdbserver" connection type is introduced to RSE with this plugin (screenshot2). The host details from that selected connection are used to establish an ssh/sftp connection to the target. For a debug configuration, the binary is downloaded to the remote (using sftp), gdbserver is automatically started on the remote (using ssh) and a gdb debug connection is establised. For a run configuration, the binary is downloaded to the remote (using sftp) and then it is invoked (using ssh.)
|
||||
|
||||
|
||||
|
||||
The extent of the current RSE integration with this launch configuration is the pulldown of connections. An important thing to note is that ssh and sftp are invoked directly by the plugin, without going through RSE. These are prime candidates for further integration. Also an RSE file service could be used in the future to select where the remote download should take place.
|
||||
|
||||
|
||||
System Prerequisites
|
||||
------------------
|
||||
Local Host
|
||||
A. ssh, sftp, gdb are on the path.
|
||||
B. ssh and sftp are setup to connect to the desired remote without prompting.
|
||||
|
||||
Remote Host
|
||||
A. gdbserver is on the path.
|
||||
B. port 2345 is available to use. gdbserver will use this port.
|
||||
|
||||
|
||||
Installation of Necessary Eclipse Components
|
||||
---------------------------------
|
||||
|
||||
1. Install Eclipse Platform M6.
|
||||
2. Install CDT Runtime compatible with Eclipse M6.
|
||||
From: http://cdt.eclipse.org/builds/3.1.0/index.html
|
||||
I used the following build: I200604141755
|
||||
|
||||
3. Install RSE. This is the procedure I followed.
|
||||
A. Checkout RSE from the repository using anonymous username.
|
||||
B. Import the plugin directory and build all the RSE plugins.
|
||||
|
||||
4. Import the Remote CDT plugin attached to this bugzilla and build that as well.
|
||||
|
||||
|
||||
Using
|
||||
----------
|
||||
|
||||
A "Remote C++ Application" launch configuration will be available. After building a binary which will run on your remote, try using this configuration to run or debug it.
|
42
rse/examples/org.eclipse.rse.remotecdt/plugin.xml
Normal file
42
rse/examples/org.eclipse.rse.remotecdt/plugin.xml
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.0"?>
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.rse.core.systemTypes">
|
||||
<systemType id="org.eclipse.rse.remotecdt.sshgdbserver"
|
||||
name="Ssh/Gdbserver"
|
||||
description="Place holder for host information used by the Remote C++ Application launch configuration.">
|
||||
<property name="icon" value="icons/full/obj16/systemlocal_obj.gif"/>
|
||||
<property name="iconLive" value="icons/full/obj16/systemlocallive_obj.gif"/>
|
||||
</systemType>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.core.launchConfigurationTypes">
|
||||
<launchConfigurationType
|
||||
sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator"
|
||||
delegate="org.eclipse.rse.remotecdt.RemoteRunLaunchDelegate"
|
||||
public="true"
|
||||
sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"
|
||||
name="C/C++ Remote Application"
|
||||
id="org.eclipse.rse.remotecdt.RemoteApplicationLaunch"
|
||||
modes="debug,run">
|
||||
</launchConfigurationType>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchConfigurationTypeImages">
|
||||
<launchConfigurationTypeImage
|
||||
icon="icons/full/obj16/c_app.gif"
|
||||
configTypeID="org.eclipse.rse.remotecdt.RemoteApplicationLaunch"
|
||||
id="org.eclipse.cdt.launch.localRunLaunchImagefff">
|
||||
</launchConfigurationTypeImage>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
|
||||
<launchConfigurationTabGroup
|
||||
type="org.eclipse.rse.remotecdt.RemoteApplicationLaunch"
|
||||
class="org.eclipse.rse.remotecdt.RemoteLaunchConfigurationTabGroup"
|
||||
id="org.eclipse.rse.remotecdt.RemoteLaunchTabGroup">
|
||||
</launchConfigurationTabGroup>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 PalmSource, Inc.
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Ewa Matejska (PalmSource)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.remotecdt;
|
||||
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The main plugin class to be used in the desktop.
|
||||
*/
|
||||
public class Activator extends Plugin {
|
||||
|
||||
//The shared instance.
|
||||
private static Activator plugin;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public Activator() {
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called upon plug-in activation
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the plug-in is stopped
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
super.stop(context);
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance.
|
||||
*
|
||||
* @return the shared instance.
|
||||
*/
|
||||
public static Activator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 PalmSource, Inc.
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Ewa Matejska (PalmSource) - Adapted from IGDBServerMILaunchConfigurationConstants
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
package org.eclipse.rse.remotecdt;
|
||||
|
||||
import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
|
||||
public interface IRemoteConnectionConfigurationConstants extends
|
||||
IMILaunchConfigurationConstants {
|
||||
|
||||
public static final String ATTR_REMOTE_CONNECTION =
|
||||
DebugPlugin.getUniqueIdentifier() + ".REMOTE_TCP";
|
||||
|
||||
/*
|
||||
* ATTR_TCP_PORT: gdbserver port.
|
||||
*/
|
||||
public static final String ATTR_TCP_PORT = "2345";
|
||||
|
||||
/*
|
||||
* Generic Remote Path and Download options
|
||||
* ATTR_REMOTE_PATH: Path of the binary on the remote.
|
||||
* ATTR_SKIP_DOWNLOAD_TO_TARGET: true if download to remote is not desired.
|
||||
*/
|
||||
public static final String ATTR_REMOTE_PATH =
|
||||
DebugPlugin.getUniqueIdentifier() + ".ATTR_TARGET_PATH";
|
||||
public static final String ATTR_SKIP_DOWNLOAD_TO_TARGET =
|
||||
DebugPlugin.getUniqueIdentifier() + ".ATTR_SKIP_DOWNLOAD_TO_TARGET";
|
||||
|
||||
}
|
|
@ -0,0 +1,331 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 PalmSource, Inc.
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Ewa Matejska (PalmSource)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.remotecdt;
|
||||
|
||||
import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin;
|
||||
import org.eclipse.cdt.launch.ui.CMainTab;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.rse.model.IHost;
|
||||
import org.eclipse.rse.ui.RSEUIPlugin;
|
||||
import org.eclipse.rse.ui.actions.SystemNewConnectionAction;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
|
||||
public class RemoteCMainTab extends CMainTab {
|
||||
|
||||
private static final String[] SYSTEM_TYPE = {"Ssh/Gdbserver"};
|
||||
/* Labels and Error Messages */
|
||||
private static final String REMOTE_PROG_LABEL_TEXT = "Remote Path for C/C++ Application:";
|
||||
private static final String SKIP_DOWNLOAD_BUTTON_TEXT = "Skip download to target path.";
|
||||
private static final String REMOTE_PROG_TEXT_ERROR = "Remote executable path is not specified.";
|
||||
private static final String CONNECTION_TEXT_ERROR = "Remote Connection must be selected.";
|
||||
|
||||
/* Defaults */
|
||||
private static final String REMOTE_PATH_DEFAULT = EMPTY_STRING;
|
||||
private static final boolean SKIP_DOWNLOAD_TO_REMOTE_DEFAULT = false;
|
||||
|
||||
protected Button newRemoteConnectionButton;
|
||||
protected Label connectionLabel;
|
||||
protected Combo connectionCombo;
|
||||
protected Label remoteProgLabel;
|
||||
protected Text remoteProgText;
|
||||
protected Button skipDownloadButton;
|
||||
protected Button useLocalPathButton;
|
||||
|
||||
private boolean initialized = false;
|
||||
SystemNewConnectionAction action = null;
|
||||
|
||||
public RemoteCMainTab(boolean terminalOption) {
|
||||
super(terminalOption);
|
||||
}
|
||||
|
||||
/*
|
||||
* createControl
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl
|
||||
*/
|
||||
public void createControl(Composite parent) {
|
||||
Composite comp = new Composite(parent, SWT.NONE);
|
||||
GridLayout topLayout = new GridLayout();
|
||||
setControl(comp);
|
||||
comp.setLayout(topLayout);
|
||||
|
||||
/* The RSE Connection dropdown with New button. */
|
||||
createVerticalSpacer(comp, 1);
|
||||
createRemoteConnectionGroup(comp, 3);
|
||||
|
||||
/* The Project and local binary location */
|
||||
createVerticalSpacer(comp, 1);
|
||||
createProjectGroup(comp, 1);
|
||||
createExeFileGroup(comp, 1);
|
||||
|
||||
/* The remote binary location and skip download option */
|
||||
createVerticalSpacer(comp, 1);
|
||||
createTargetExePath(comp);
|
||||
createDownloadOption(comp);
|
||||
|
||||
/* If the local binary path changes, modify the remote binary location */
|
||||
fProgText.addModifyListener(new ModifyListener() {
|
||||
|
||||
public void modifyText(ModifyEvent evt) {
|
||||
if(initialized)
|
||||
setLocalPathForRemotePath();
|
||||
else
|
||||
initialized = true;
|
||||
}
|
||||
});
|
||||
|
||||
LaunchUIPlugin.setDialogShell(parent.getShell());
|
||||
}
|
||||
|
||||
/*
|
||||
* isValid
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid
|
||||
*/
|
||||
public boolean isValid(ILaunchConfiguration config) {
|
||||
boolean retVal = super.isValid(config);
|
||||
if(retVal == true) {
|
||||
setErrorMessage(null);
|
||||
int currentSelection = connectionCombo.getSelectionIndex();
|
||||
String connection_name = currentSelection >= 0 ? connectionCombo.getItem(currentSelection) : "";
|
||||
if(connection_name.equals("")) {
|
||||
setErrorMessage(CONNECTION_TEXT_ERROR);
|
||||
retVal = false;
|
||||
}
|
||||
if(retVal) {
|
||||
String name = remoteProgText.getText().trim();
|
||||
if (name.length() == 0) {
|
||||
setErrorMessage(REMOTE_PROG_TEXT_ERROR);
|
||||
retVal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
protected void createRemoteConnectionGroup(Composite parent, int colSpan) {
|
||||
Composite projComp = new Composite(parent, SWT.NONE);
|
||||
GridLayout projLayout = new GridLayout();
|
||||
projLayout.numColumns = 3;
|
||||
projLayout.marginHeight = 0;
|
||||
projLayout.marginWidth = 0;
|
||||
projComp.setLayout(projLayout);
|
||||
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.horizontalSpan = colSpan;
|
||||
projComp.setLayoutData(gd);
|
||||
|
||||
connectionLabel = new Label(projComp, SWT.NONE);
|
||||
connectionLabel.setText("Connection:");
|
||||
gd = new GridData();
|
||||
gd.horizontalSpan = 1;
|
||||
connectionLabel.setLayoutData(gd);
|
||||
|
||||
connectionCombo = new Combo(projComp, SWT.DROP_DOWN | SWT.READ_ONLY);
|
||||
gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
gd.horizontalSpan = 1;
|
||||
connectionCombo.setLayoutData(gd);
|
||||
connectionCombo.addModifyListener(new ModifyListener() {
|
||||
|
||||
public void modifyText(ModifyEvent e) {
|
||||
setDirty(true);
|
||||
updateLaunchConfigurationDialog();
|
||||
}
|
||||
});
|
||||
updateConnectionPulldown();
|
||||
|
||||
newRemoteConnectionButton = createPushButton(projComp, "New", null);
|
||||
newRemoteConnectionButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
public void widgetSelected(SelectionEvent evt) {
|
||||
handleNewRemoteConnectionSelected();
|
||||
updateLaunchConfigurationDialog();
|
||||
updateConnectionPulldown();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* createTargetExePath
|
||||
* This creates the remote path user-editable textfield on the Main Tab.
|
||||
*/
|
||||
protected void createTargetExePath(Composite parent) {
|
||||
Composite mainComp = new Composite(parent, SWT.NONE);
|
||||
GridLayout mainLayout = new GridLayout();
|
||||
mainLayout.marginHeight = 0;
|
||||
mainLayout.marginWidth = 0;
|
||||
mainComp.setLayout(mainLayout);
|
||||
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
mainComp.setLayoutData(gd);
|
||||
remoteProgLabel = new Label(mainComp, SWT.NONE);
|
||||
remoteProgLabel.setText(REMOTE_PROG_LABEL_TEXT);
|
||||
gd = new GridData();
|
||||
remoteProgLabel.setLayoutData(gd);
|
||||
remoteProgText = new Text(mainComp, SWT.SINGLE | SWT.BORDER);
|
||||
gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
remoteProgText.setLayoutData(gd);
|
||||
remoteProgText.addModifyListener(new ModifyListener() {
|
||||
|
||||
public void modifyText(ModifyEvent evt) {
|
||||
updateLaunchConfigurationDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* createDownloadOption
|
||||
* This creates the skip download check button.
|
||||
*/
|
||||
protected void createDownloadOption(Composite parent) {
|
||||
Composite mainComp = new Composite(parent, SWT.NONE);
|
||||
GridLayout mainLayout = new GridLayout();
|
||||
mainLayout.marginHeight = 0;
|
||||
mainLayout.marginWidth = 0;
|
||||
mainComp.setLayout(mainLayout);
|
||||
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||
mainComp.setLayoutData(gd);
|
||||
|
||||
skipDownloadButton = createCheckButton(mainComp, SKIP_DOWNLOAD_BUTTON_TEXT);
|
||||
skipDownloadButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
public void widgetSelected(SelectionEvent evt) {
|
||||
updateLaunchConfigurationDialog();
|
||||
}
|
||||
});
|
||||
skipDownloadButton.setEnabled(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* performApply
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply
|
||||
*/
|
||||
public void performApply(ILaunchConfigurationWorkingCopy config) {
|
||||
|
||||
int currentSelection = connectionCombo.getSelectionIndex();
|
||||
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION,
|
||||
currentSelection >= 0 ? connectionCombo.getItem(currentSelection) : null);
|
||||
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH,
|
||||
remoteProgText.getText());
|
||||
config.setAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET,
|
||||
skipDownloadButton.getSelection());
|
||||
super.performApply(config);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom
|
||||
*/
|
||||
public void initializeFrom(ILaunchConfiguration config) {
|
||||
String remoteConnection = null;
|
||||
try {
|
||||
remoteConnection = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION,
|
||||
"");
|
||||
} catch (CoreException ce) {
|
||||
/* default to doing nothing */
|
||||
}
|
||||
|
||||
String[] items = connectionCombo.getItems();
|
||||
int i = 0;
|
||||
for(i = 0; i < items.length; i++)
|
||||
if(items[i].equals(remoteConnection))
|
||||
break;
|
||||
/* Select the last used connection in the connecion pulldown if it still exists. */
|
||||
if(i < items.length)
|
||||
connectionCombo.select(i);
|
||||
else if(items.length > 0)
|
||||
connectionCombo.select(0);
|
||||
|
||||
super.initializeFrom(config);
|
||||
|
||||
updateTargetProgFromConfig(config);
|
||||
updateSkipDownloadFromConfig(config);
|
||||
}
|
||||
|
||||
protected void handleNewRemoteConnectionSelected() {
|
||||
if (action == null)
|
||||
{
|
||||
action = new SystemNewConnectionAction(getControl().getShell(), false, false, null);
|
||||
}
|
||||
action.restrictSystemTypes(SYSTEM_TYPE);
|
||||
|
||||
try
|
||||
{
|
||||
action.run();
|
||||
} catch (Exception exc)
|
||||
{
|
||||
/* Ignore for now */
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateConnectionPulldown() {
|
||||
connectionCombo.removeAll();
|
||||
IHost[] connections = RSEUIPlugin.getTheSystemRegistry().getHostsBySystemType(SYSTEM_TYPE[0]);
|
||||
for(int i = 0; i < connections.length; i++)
|
||||
connectionCombo.add(connections[i].getAliasName());
|
||||
if(connections.length > 0)
|
||||
connectionCombo.select(0);
|
||||
}
|
||||
|
||||
protected void updateTargetProgFromConfig(ILaunchConfiguration config) {
|
||||
String targetPath = null;
|
||||
try {
|
||||
targetPath = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH,
|
||||
REMOTE_PATH_DEFAULT);
|
||||
} catch (CoreException ce) {
|
||||
/* Ignore for now */
|
||||
}
|
||||
remoteProgText.setText(targetPath);
|
||||
}
|
||||
|
||||
protected void updateSkipDownloadFromConfig(ILaunchConfiguration config) {
|
||||
boolean downloadToTarget = true;
|
||||
try {
|
||||
downloadToTarget = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET,
|
||||
SKIP_DOWNLOAD_TO_REMOTE_DEFAULT);
|
||||
} catch (CoreException e) {
|
||||
/* Ignore for now */
|
||||
}
|
||||
skipDownloadButton.setSelection(downloadToTarget);
|
||||
}
|
||||
|
||||
/*
|
||||
* setLocalPathForRemotePath
|
||||
* This function sets the remote path text field with the value of the
|
||||
* local executable path.
|
||||
*/
|
||||
private void setLocalPathForRemotePath() {
|
||||
String name = fProgText.getText().trim();
|
||||
if (name.length() != 0) {
|
||||
IProject project = getCProject().getProject();
|
||||
IPath exePath = new Path(name);
|
||||
if (!exePath.isAbsolute()) {
|
||||
exePath = project.getFile(name).getLocation();
|
||||
}
|
||||
String path = exePath.toString();
|
||||
remoteProgText.setText(path);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 PalmSource, Inc.
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Ewa Matejska (PalmSource) - Adapted from LocalRunLaunchConfigurationTabGroup
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
package org.eclipse.rse.remotecdt;
|
||||
import org.eclipse.cdt.launch.ui.CArgumentsTab;
|
||||
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;
|
||||
|
||||
/**
|
||||
* This class defines the tab group for the Remote C++ Launch
|
||||
* Configuration.
|
||||
*/
|
||||
public class RemoteLaunchConfigurationTabGroup extends
|
||||
AbstractLaunchConfigurationTabGroup {
|
||||
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
|
||||
ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
|
||||
new RemoteCMainTab(true),
|
||||
new CArgumentsTab(),
|
||||
new SourceLookupTab(),
|
||||
new CommonTab()
|
||||
};
|
||||
setTabs(tabs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 PalmSource, Inc.
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Ewa Matejska (PalmSource) - Adapted from LocalRunLaunchDelegate
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
|
||||
package org.eclipse.rse.remotecdt;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.debug.core.CDIDebugModel;
|
||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.debug.core.cdi.CDIException;
|
||||
import org.eclipse.cdt.debug.core.cdi.ICDISession;
|
||||
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
|
||||
import org.eclipse.cdt.debug.mi.core.GDBServerCDIDebugger;
|
||||
import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.launch.AbstractCLaunchDelegate;
|
||||
import org.eclipse.cdt.utils.spawner.Spawner;
|
||||
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.Status;
|
||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.core.ILaunchManager;
|
||||
import org.eclipse.debug.core.model.IProcess;
|
||||
import org.eclipse.rse.model.IHost;
|
||||
import org.eclipse.rse.ui.RSEUIPlugin;
|
||||
|
||||
|
||||
public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
||||
|
||||
private final static String REMOTE_GDBSERVER_COMMAND = "gdbserver";
|
||||
private final static String SFTP_COMMAND = "sftp";
|
||||
private final static String SFTP_COMMAND_ARGS = "-b -";
|
||||
private final static String SSH_COMMAND = "ssh";
|
||||
private final static String SYSTEM_TYPE = "Ssh/Gdbserver";
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch
|
||||
*/
|
||||
public void launch(ILaunchConfiguration config, String mode, ILaunch launch,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
IBinaryObject exeFile = null;
|
||||
IPath exePath = verifyProgramPath(config);
|
||||
ICProject project = verifyCProject(config);
|
||||
if (exePath != null) {
|
||||
exeFile = verifyBinary(project, exePath);
|
||||
}
|
||||
|
||||
String arguments = getProgramArguments(config);
|
||||
String remoteExePath = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH,
|
||||
"");
|
||||
|
||||
if(mode.equals(ILaunchManager.DEBUG_MODE)){
|
||||
setDefaultSourceLocator(launch, config);
|
||||
ICDISession dsession = null;
|
||||
String debugMode = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE,
|
||||
ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN);
|
||||
if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) {
|
||||
/* Download the binary to the remote before debugging using the scp program*/
|
||||
remoteSftpDownload(config, launch, exePath.toString(), remoteExePath);
|
||||
|
||||
/* Default to using the GDBServerCDIDebugger. */
|
||||
GDBServerCDIDebugger debugger = new GDBServerCDIDebugger();
|
||||
|
||||
/* Automatically start up the gdbserver to be used by the GDBServerCDIDebugger on the remote
|
||||
* using ssh.
|
||||
*/
|
||||
String command_arguments = ":" + IRemoteConnectionConfigurationConstants.ATTR_TCP_PORT + " " + remoteExePath;
|
||||
if(arguments != null && !arguments.equals(""))
|
||||
command_arguments += " " + arguments;
|
||||
Process sshProcess = remoteSshExec(config, REMOTE_GDBSERVER_COMMAND, command_arguments);
|
||||
DebugPlugin.newProcess(launch, sshProcess, renderProcessLabel(REMOTE_GDBSERVER_COMMAND));
|
||||
/* Pre-set configuration constants for the GDBSERVERCDIDebugger to indicate how the gdbserver
|
||||
* was automatically started on the remote. GDBServerCDIDebugger uses these to figure out how
|
||||
* to connect to the remote gdbserver.
|
||||
*/
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_REMOTE_TCP, true);
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_HOST, getRemoteHostname(config));
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_PORT,
|
||||
IRemoteConnectionConfigurationConstants.ATTR_TCP_PORT);
|
||||
|
||||
dsession = debugger.createLaunchSession(wc.doSave(), exeFile, new SubProgressMonitor(monitor, 8));
|
||||
|
||||
try {
|
||||
/* Assume that stopInMain is true until the Debugger tab is added */
|
||||
boolean stopInMain = true;
|
||||
String stopSymbol = null;
|
||||
if ( stopInMain )
|
||||
stopSymbol = launch.getLaunchConfiguration().
|
||||
getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL,
|
||||
ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT );
|
||||
|
||||
ICDITarget[] targets = dsession.getTargets();
|
||||
for (int i = 0; i < targets.length; i++) {
|
||||
Process process = targets[i].getProcess();
|
||||
IProcess iprocess = null;
|
||||
if (process != null) {
|
||||
iprocess = DebugPlugin.newProcess(launch, process,
|
||||
renderProcessLabel(exePath.toOSString()), getDefaultProcessMap());
|
||||
}
|
||||
CDIDebugModel.newDebugTarget(launch, project.getProject(), targets[i],
|
||||
renderProcessLabel("gdbserver debugger"),
|
||||
iprocess, exeFile, true, false, stopSymbol, true);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
try {
|
||||
dsession.terminate();
|
||||
} catch (CDIException e1) {
|
||||
// ignore
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
} else if(mode.equals(ILaunchManager.RUN_MODE)) {
|
||||
/* Download the binary to the remote before debugging */
|
||||
remoteSftpDownload(config, launch, exePath.toString(),remoteExePath );
|
||||
|
||||
/* Use ssh to launch the binary on the remote */
|
||||
Process process = remoteSshExec(config, remoteExePath, arguments);
|
||||
DebugPlugin.newProcess(launch, process, renderProcessLabel(exePath.toOSString()));
|
||||
|
||||
} else {
|
||||
IStatus status = new Status(IStatus.ERROR, getPluginID(),
|
||||
IStatus.OK, "Unidentified mode " + mode + " passed to RemoteRunLaunchDelegate", null);
|
||||
throw new CoreException(status);
|
||||
}
|
||||
}
|
||||
|
||||
private String quotify(String inputString) {
|
||||
if(inputString == null)
|
||||
return null;
|
||||
return '"' + inputString + '"';
|
||||
}
|
||||
|
||||
private String spaceEscapify(String inputString) {
|
||||
if(inputString == null)
|
||||
return null;
|
||||
|
||||
return inputString.replaceAll(" ", "\\\\ ");
|
||||
}
|
||||
|
||||
protected Process remoteSftpDownload(ILaunchConfiguration config, ILaunch launch, String localExePath, String remoteExePath)
|
||||
throws CoreException {
|
||||
boolean skipDownload = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET,
|
||||
false);
|
||||
|
||||
if(skipDownload)
|
||||
//Nothing to do. Download is skipped.
|
||||
return null;
|
||||
|
||||
String arguments = SFTP_COMMAND_ARGS + " " + getRemoteHostname(config);
|
||||
Process p = null;
|
||||
try {
|
||||
p = execLocal(SFTP_COMMAND, arguments);
|
||||
DebugPlugin.newProcess(launch, p, renderProcessLabel(SFTP_COMMAND));
|
||||
OutputStream outStream = p.getOutputStream();
|
||||
String putCommand = "put " + quotify(localExePath) + " " + quotify(remoteExePath) + "\n";
|
||||
String exitCommand = "exit\n";
|
||||
// Execute the put and then the exit command.
|
||||
outStream.write(putCommand.getBytes());
|
||||
outStream.write(exitCommand.getBytes());
|
||||
if(p.waitFor() != 0) {
|
||||
IStatus status = new Status(IStatus.ERROR, getPluginID(),
|
||||
IStatus.OK, "Couldn't download program to remote. See console for reason.", null);
|
||||
throw new CoreException(status);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getRemoteHostname(ILaunchConfiguration config) throws CoreException{
|
||||
String remoteConnection = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION,
|
||||
"");
|
||||
|
||||
IHost[] connections = RSEUIPlugin.getTheSystemRegistry().getHostsBySystemType(SYSTEM_TYPE);
|
||||
int i = 0;
|
||||
for(i = 0; i < connections.length; i++)
|
||||
if(connections[i].getAliasName().equals(remoteConnection))
|
||||
break;
|
||||
if(i >= connections.length) {
|
||||
IStatus status = new Status(IStatus.ERROR, getPluginID(),
|
||||
IStatus.OK, "Internal Error: Could not find the remote connection.\n", null);
|
||||
throw new CoreException(status);
|
||||
}
|
||||
return connections[i].getHostName();
|
||||
}
|
||||
|
||||
protected Process remoteSshExec(ILaunchConfiguration config, String remoteCommandPath,
|
||||
String arguments) throws CoreException {
|
||||
String remote_command = arguments == null ? spaceEscapify(remoteCommandPath) :
|
||||
spaceEscapify(remoteCommandPath) + " " + arguments;
|
||||
String ssh_arguments = getRemoteHostname(config) + " " + remote_command;
|
||||
|
||||
Process p = execLocal(SSH_COMMAND, ssh_arguments);
|
||||
return p;
|
||||
|
||||
/* In the future the Shell subsystem from RSE should be used instead of invoking ssh and scp
|
||||
* directly. The code to accomplish this might look like below.
|
||||
*/
|
||||
|
||||
/*ISubSystem[] subSystems = connections[i].getSubSystems();
|
||||
for(i = 0; i < subSystems.length; i++)
|
||||
if(subSystems[i] instanceof IShellServiceSubSystem)
|
||||
break;
|
||||
if(i >= subSystems.length)
|
||||
abort("Internal Error: No shell subsystem found.\n", null, 0);
|
||||
IShellServiceSubSystem shellSubSystem = (IShellServiceSubSystem) subSystems[i];
|
||||
IShellService shellService = shellSubSystem.getShellService();
|
||||
String command = arguments == null ? file.toOSString() : file.toOSString() + " " + arguments;
|
||||
|
||||
IHostShell hostShell = shellService.runCommand(null, file.removeLastSegments(1).toOSString(),command, null);
|
||||
|
||||
Process p = null;
|
||||
try {
|
||||
p = new HostShellProcess(hostShell);
|
||||
} catch (Exception e) {
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
abort("Internal Error: Could not create the hostShellProcess.\n", null, 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
protected Process execLocal(String file, String arguments) throws CoreException {
|
||||
Process p = null;
|
||||
String command = file + " " + arguments;
|
||||
try {
|
||||
p = new Spawner(command, false);
|
||||
} catch (Exception e) {
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
IStatus status = new Status(IStatus.ERROR, getPluginID(),
|
||||
IStatus.OK, "Internal Error: Could not execute command.\n", null);
|
||||
throw new CoreException(status);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
protected String getPluginID() {
|
||||
return "org.eclipse.rse.remotecdt";
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue