diff options
Diffstat (limited to 'cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt')
10 files changed, 1567 insertions, 0 deletions
diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/Activator.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/Activator.java new file mode 100644 index 00000000000..bca462bd694 --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/Activator.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.cdt.launch.remote; + +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; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + 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; + } + +} diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/IRemoteConnectionConfigurationConstants.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/IRemoteConnectionConfigurationConstants.java new file mode 100644 index 00000000000..e86581f185b --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/IRemoteConnectionConfigurationConstants.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006, 2009 PalmSource, Inc. 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 + * + * Contributors: + * Ewa Matejska (PalmSource) - Adapted from IGDBServerMILaunchConfigurationConstants + * Anna Dushistova (MontaVista) - [181517][usability] Specify commands to be run before remote application launch + *******************************************************************************/ + + +package org.eclipse.cdt.launch.remote; + +import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; +import org.eclipse.debug.core.DebugPlugin; + +public interface IRemoteConnectionConfigurationConstants extends + IGDBServerMILaunchConfigurationConstants { + + public static final String ATTR_REMOTE_CONNECTION = + DebugPlugin.getUniqueIdentifier() + ".REMOTE_TCP"; //$NON-NLS-1$ + + + public static final String ATTR_GDBSERVER_PORT = + DebugPlugin.getUniqueIdentifier() + ".ATTR_GDBSERVER_PORT"; //$NON-NLS-1$ + public static final String ATTR_GDBSERVER_COMMAND = + DebugPlugin.getUniqueIdentifier() + ".ATTR_GDBSERVER_COMMAND"; //$NON-NLS-1$ + + public static final String ATTR_GDBSERVER_PORT_DEFAULT = "2345"; //$NON-NLS-1$ + public static final String ATTR_GDBSERVER_COMMAND_DEFAULT = "gdbserver"; //$NON-NLS-1$ + + /* + * 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"; //$NON-NLS-1$ + public static final String ATTR_SKIP_DOWNLOAD_TO_TARGET = + DebugPlugin.getUniqueIdentifier() + ".ATTR_SKIP_DOWNLOAD_TO_TARGET"; //$NON-NLS-1$ + + + public static final String ATTR_PRERUN_COMMANDS = DebugPlugin.getUniqueIdentifier() + ".ATTR_PRERUN_CMDS"; //$NON-NLS-1$ + +} diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/IRemoteConnectionHostConstants.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/IRemoteConnectionHostConstants.java new file mode 100644 index 00000000000..1d7fdc6aac5 --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/IRemoteConnectionHostConstants.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2008, 2009 Wind River Systems, 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: + * Johann Draschwandtner (Wind River) - initial API and implementation + * Martin Oberhuber (Wind River) - [261486][api][cleanup] Mark @noimplement interfaces as @noextend + *******************************************************************************/ +package org.eclipse.cdt.launch.remote; + +/** + * Constants used for Remote CDT connection properties. + * + * <strong>EXPERIMENTAL</strong>. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. Please do not use this API without consulting with + * the <a href="http://www.eclipse.org/dsdp/tm/">Target Management</a> team. + * </p> + * + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + * @since org.eclipse.rse.remotecdt 2.1 + */ +public interface IRemoteConnectionHostConstants { + + public static final String PI_REMOTE_CDT = "org.eclipse.rse.remotecdt"; //$NON-NLS-1$ + + public static final String REMOTE_WS_ROOT = "remoteWsRoot"; //$NON-NLS-1$ + public static final String DEFAULT_SKIP_DOWNLOAD = "defaultSkipDownload"; //$NON-NLS-1$ +} diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/Messages.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/Messages.java new file mode 100644 index 00000000000..4d245044291 --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/Messages.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2006, 2009 Wind River Systems, Inc. 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 + * + * Contributors: + * Martin Oberhuber (Wind River) - initial API and implementation + * Ewa Matejska (PalmSource) - [158783] browse button for cdt remote path + * Johann Draschwandtner (Wind River) - [231827][remotecdt]Auto-compute default for Remote path + * Anna Dushistova (MontaVista) - [244173][remotecdt][nls] Externalize Strings in RemoteRunLaunchDelegate + * Anna Dushistova (MontaVista) - [181517][usability] Specify commands to be run before remote application launch + * Nikita Shulga (EmbeddedAlley) - [265236][remotecdt] Wait for RSE to initialize before querying it for host list + *******************************************************************************/ +package org.eclipse.cdt.launch.remote; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.rse.internal.remotecdt.messages"; //$NON-NLS-1$ + + public static String Gdbserver_name_textfield_label; + + public static String Gdbserver_Settings_Tab_Name; + + public static String Port_number_textfield_label; + + public static String Remote_GDB_Debugger_Options; + + public static String RemoteCMainTab_Prerun; + + public static String RemoteCMainTab_Program; + + public static String RemoteCMainTab_Remote_Path_Browse_Button; + + public static String RemoteCMainTab_Remote_Path_Browse_Button_Title; + public static String RemoteCMainTab_SkipDownload; + public static String RemoteCMainTab_ErrorNoProgram; + public static String RemoteCMainTab_ErrorNoConnection; + public static String RemoteCMainTab_Connection; + public static String RemoteCMainTab_New; + public static String RemoteCMainTab_Properties; + public static String RemoteCMainTab_Properties_title; + public static String RemoteCMainTab_Properties_Location; + public static String RemoteCMainTab_Properties_Skip_default; + + public static String RemoteRunLaunchDelegate_0; + + public static String RemoteRunLaunchDelegate_RemoteShell; + public static String RemoteRunLaunchDelegate_1; + + public static String RemoteRunLaunchDelegate_10; + + public static String RemoteRunLaunchDelegate_12; + + public static String RemoteRunLaunchDelegate_13; + + public static String RemoteRunLaunchDelegate_2; + public static String RemoteRunLaunchDelegate_3; + public static String RemoteRunLaunchDelegate_4; + public static String RemoteRunLaunchDelegate_5; + public static String RemoteRunLaunchDelegate_6; + public static String RemoteRunLaunchDelegate_7; + public static String RemoteRunLaunchDelegate_8; + + public static String RemoteRunLaunchDelegate_9; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteCDebuggerTab.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteCDebuggerTab.java new file mode 100644 index 00000000000..acb9458b282 --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteCDebuggerTab.java @@ -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.cdt.launch.remote; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.ICDebugConfiguration; +import org.eclipse.cdt.launch.ui.CDebuggerTab; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PlatformUI; + +public class RemoteCDebuggerTab extends CDebuggerTab { + + public void createControl(Composite parent) { + super.createControl(parent); + PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), + "org.eclipse.rse.internal.remotecdt.launchgroup"); //$NON-NLS-1$ + } + + static final private String REMOTE_GDB_DEBUGGER_NAME = "remote gdb/mi"; //$NON-NLS-1$ + + public RemoteCDebuggerTab(boolean attachMode) { + super(attachMode); + } + + protected void loadDebuggerComboBox(ILaunchConfiguration config, String selection) { + ICDebugConfiguration[] debugConfigs = CDebugCorePlugin.getDefault().getDebugConfigurations(); + String defaultSelection = selection; + List list = new ArrayList(); + for(int i = 0; i < debugConfigs.length; i++) { + ICDebugConfiguration configuration = debugConfigs[i]; + if(configuration.getName().equals(REMOTE_GDB_DEBUGGER_NAME)) { + list.add(configuration); + // Select as default selection + defaultSelection = configuration.getID(); + break; + } + } + setInitializeDefault(defaultSelection.equals("") ? true : false); //$NON-NLS-1$ + loadDebuggerCombo((ICDebugConfiguration[])list.toArray( + new ICDebugConfiguration[list.size()]), defaultSelection); + } + +} diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteCMainTab.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteCMainTab.java new file mode 100644 index 00000000000..eed3c1ad8ad --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteCMainTab.java @@ -0,0 +1,659 @@ +/******************************************************************************* + * Copyright (c) 2006, 2009 PalmSource, Inc. 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 + * + * Contributors: + * Ewa Matejska (PalmSource) - initial API and implementation + * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry + * Martin Oberhuber (Wind River) - [196934] hide disabled system types in remotecdt combo + * Yu-Fen Kuo (MontaVista) - [190613] Fix NPE in Remotecdt when RSEUIPlugin has not been loaded + * Martin Oberhuber (Wind River) - [cleanup] Avoid using SystemStartHere in production code + * Johann Draschwandtner (Wind River) - [231827][remotecdt]Auto-compute default for Remote path + * Johann Draschwandtner (Wind River) - [233057][remotecdt]Fix button enablement + * Anna Dushistova (MontaVista) - [181517][usability] Specify commands to be run before remote application launch + * Anna Dushistova (MontaVista) - [223728] [remotecdt] connection combo is not populated until RSE is activated + *******************************************************************************/ + +package org.eclipse.cdt.launch.remote; + +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.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.window.Window; +import org.eclipse.rse.core.IRSESystemType; +import org.eclipse.rse.core.RSECorePlugin; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.core.model.IPropertySet; +import org.eclipse.rse.files.ui.dialogs.SystemRemoteFileDialog; +import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile; +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.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + +public class RemoteCMainTab extends CMainTab { + + /* Labels and Error Messages */ + private static final String REMOTE_PROG_LABEL_TEXT = Messages.RemoteCMainTab_Program; + private static final String SKIP_DOWNLOAD_BUTTON_TEXT = Messages.RemoteCMainTab_SkipDownload; + private static final String REMOTE_PROG_TEXT_ERROR = Messages.RemoteCMainTab_ErrorNoProgram; + private static final String CONNECTION_TEXT_ERROR = Messages.RemoteCMainTab_ErrorNoConnection; + private static final String PRE_RUN_LABEL_TEXT = Messages.RemoteCMainTab_Prerun; + + /* Defaults */ + private static final String REMOTE_PATH_DEFAULT = EMPTY_STRING; + private static final boolean SKIP_DOWNLOAD_TO_REMOTE_DEFAULT = false; + + protected Button newRemoteConnectionButton; + protected Button remoteConnectionPropertiesButton; + protected Button remoteBrowseButton; + protected Label connectionLabel; + protected Combo connectionCombo; + protected Label remoteProgLabel; + protected Text remoteProgText; + protected Button skipDownloadButton; + protected Button useLocalPathButton; + + SystemNewConnectionAction action = null; + private Text preRunText; + private Label preRunLabel; + + 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, 4); + + /* The Project and local binary location */ + createVerticalSpacer(comp, 1); + createProjectGroup(comp, 1); + createBuildConfigCombo(comp, 1); + createExeFileGroup(comp, 1); + + /* The remote binary location and skip download option */ + createVerticalSpacer(comp, 1); + createTargetExePathGroup(comp); + createDownloadOption(comp); + + /* If the local binary path changes, modify the remote binary location */ + fProgText.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent evt) { + setLocalPathForRemotePath(); + } + }); + + PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), + "org.eclipse.rse.internal.remotecdt.launchgroup"); //$NON-NLS-1$ + + // //No more needed according to + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=178832 + // 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) : ""; //$NON-NLS-1$ + if (connection_name.equals("")) { //$NON-NLS-1$ + 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 = 4; + 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(Messages.RemoteCMainTab_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(); + useDefaultsFromConnection(); + updatePropertiesButton(); + } + }); + + newRemoteConnectionButton = createPushButton(projComp, + Messages.RemoteCMainTab_New, null); + newRemoteConnectionButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) { + handleNewRemoteConnectionSelected(); + updateLaunchConfigurationDialog(); + updateConnectionPulldown(); + } + }); + + remoteConnectionPropertiesButton = createPushButton(projComp, + Messages.RemoteCMainTab_Properties, null); + remoteConnectionPropertiesButton + .addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) { + handleRemoteConnectionPropertiesSelected(); + } + }); + + updateConnectionPulldown(); + } + + /* + * createTargetExePath This creates the remote path user-editable textfield + * on the Main Tab. + */ + protected void createTargetExePathGroup(Composite parent) { + Composite mainComp = new Composite(parent, SWT.NONE); + GridLayout mainLayout = new GridLayout(); + mainLayout.numColumns = 2; + 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(); + gd.horizontalSpan = 2; + remoteProgLabel.setLayoutData(gd); + + remoteProgText = new Text(mainComp, SWT.SINGLE | SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 1; + remoteProgText.setLayoutData(gd); + remoteProgText.addModifyListener(new ModifyListener() { + + public void modifyText(ModifyEvent evt) { + updateLaunchConfigurationDialog(); + } + }); + + remoteBrowseButton = createPushButton(mainComp, + Messages.RemoteCMainTab_Remote_Path_Browse_Button, null); + remoteBrowseButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) { + handleRemoteBrowseSelected(); + updateLaunchConfigurationDialog(); + } + }); + + // Commands to run before execution + preRunLabel = new Label(mainComp, SWT.NONE); + preRunLabel.setText(PRE_RUN_LABEL_TEXT); + gd = new GridData(); + gd.horizontalSpan = 2; + preRunLabel.setLayoutData(gd); + + preRunText = new Text(mainComp, SWT.MULTI | SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + preRunText.setLayoutData(gd); + preRunText.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()); + config.setAttribute( + IRemoteConnectionConfigurationConstants.ATTR_PRERUN_COMMANDS, + preRunText.getText()); + 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, + ""); //$NON-NLS-1$ + } catch (CoreException ce) { + // Ignore + } + + 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); + updatePropertiesButton(); + } + + protected void handleNewRemoteConnectionSelected() { + if (action == null) { + action = new SystemNewConnectionAction(getControl().getShell(), + false, false, null); + } + + try { + action.run(); + } catch (Exception e) { + // Ignore + } + } + + protected IHost getCurrentConnection() { + int currentSelection = connectionCombo.getSelectionIndex(); + String remoteConnection = currentSelection >= 0 ? connectionCombo + .getItem(currentSelection) : null; + if (remoteConnection == null) + return null; + IHost[] connections = RSECorePlugin.getTheSystemRegistry().getHosts(); + int i = 0; + for (i = 0; i < connections.length; i++) + if (connections[i].getAliasName().equals(remoteConnection)) + break; + return connections[i]; + } + + protected void handleRemoteBrowseSelected() { + IHost currentConnectionSelected = getCurrentConnection(); + SystemRemoteFileDialog dlg = new SystemRemoteFileDialog(getControl() + .getShell(), + Messages.RemoteCMainTab_Remote_Path_Browse_Button_Title, + currentConnectionSelected); + dlg.setBlockOnOpen(true); + if (dlg.open() == Window.OK) { + Object retObj = dlg.getSelectedObject(); + if (retObj instanceof IRemoteFile) { + IRemoteFile selectedFile = (IRemoteFile) retObj; + remoteProgText.setText(selectedFile.getAbsolutePath()); + } + + } + } + + protected void handleRemoteConnectionPropertiesSelected() { + class RemoteConnectionPropertyDialog extends Dialog { + private IHost fHost; + boolean fbLocalHost; + private Button fSkipDownloadBtn; + private Text fWSRoot; + + public RemoteConnectionPropertyDialog(Shell parentShell, + String dialogTitle, IHost host) { + super(parentShell); + parentShell.setText(dialogTitle); + fHost = host; + fbLocalHost = fHost.getSystemType().isLocal(); + } + + protected Control createDialogArea(Composite parent) { + // create composite + Composite composite = (Composite) super + .createDialogArea(parent); + + Label label = new Label(composite, SWT.WRAP); + label.setText(Messages.RemoteCMainTab_Properties_Location); + GridData data = new GridData(GridData.GRAB_HORIZONTAL + | GridData.GRAB_VERTICAL + | GridData.HORIZONTAL_ALIGN_FILL + | GridData.VERTICAL_ALIGN_CENTER); + data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); + label.setLayoutData(data); + label.setFont(parent.getFont()); + fWSRoot = new Text(composite, SWT.SINGLE | SWT.BORDER); + fWSRoot.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL + | GridData.HORIZONTAL_ALIGN_FILL)); + + fSkipDownloadBtn = new Button(composite, SWT.CHECK); + fSkipDownloadBtn + .setText(Messages.RemoteCMainTab_Properties_Skip_default); + if (!fbLocalHost) { + IPropertySet propertySet = fHost + .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); + if (propertySet != null) { + String value = propertySet + .getPropertyValue(IRemoteConnectionHostConstants.REMOTE_WS_ROOT); + if (value != null) { + fWSRoot.setText(value); + } + fSkipDownloadBtn + .setSelection(Boolean + .valueOf( + propertySet + .getPropertyValue(IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD)) + .booleanValue()); + } + } else { + fSkipDownloadBtn.setEnabled(false); + fWSRoot.setEnabled(false); + } + applyDialogFont(composite); + return composite; + } + + protected void buttonPressed(int buttonId) { + if (!fbLocalHost && (buttonId == IDialogConstants.OK_ID)) { + IPropertySet propertySet = fHost + .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); + if (propertySet == null) { + propertySet = fHost + .createPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); + } + propertySet.addProperty( + IRemoteConnectionHostConstants.REMOTE_WS_ROOT, + fWSRoot.getText()); + propertySet + .addProperty( + IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD, + Boolean.toString(fSkipDownloadBtn + .getSelection())); + fHost.commit(); + } + super.buttonPressed(buttonId); + } + } + IHost currentConnectionSelected = getCurrentConnection(); + RemoteConnectionPropertyDialog dlg = new RemoteConnectionPropertyDialog( + getControl().getShell(), + Messages.RemoteCMainTab_Properties_title, + currentConnectionSelected); + dlg.setBlockOnOpen(true); + dlg.open(); + } + + protected void updateConnectionPulldown() { + if (!RSECorePlugin.isInitComplete(RSECorePlugin.INIT_MODEL)) + try { + RSECorePlugin.waitForInitCompletion(RSECorePlugin.INIT_MODEL); + } catch (InterruptedException e) { + return; + } + // already initialized + connectionCombo.removeAll(); + IHost[] connections = RSECorePlugin.getTheSystemRegistry() + .getHostsBySubSystemConfigurationCategory("shells"); //$NON-NLS-1$ + for (int i = 0; i < connections.length; i++) { + IRSESystemType sysType = connections[i].getSystemType(); + if (sysType != null && sysType.isEnabled()) { + connectionCombo.add(connections[i].getAliasName()); + } + } + + if (connections.length > 0) { + connectionCombo.select(connections.length - 1); + } + updatePropertiesButton(); + } + + private void updatePropertiesButton() { + if ((remoteConnectionPropertiesButton == null) + || remoteConnectionPropertiesButton.isDisposed()) { + return; + } + boolean bEnableProperties = false; + IHost currentConnectionSelected = getCurrentConnection(); + if (currentConnectionSelected != null) { + IRSESystemType sysType = currentConnectionSelected.getSystemType(); + if (sysType != null && sysType.isEnabled() && !sysType.isLocal()) { + bEnableProperties = true; + } + } + remoteConnectionPropertiesButton.setEnabled(bEnableProperties); + } + + protected void updateTargetProgFromConfig(ILaunchConfiguration config) { + String targetPath = null; + try { + targetPath = config.getAttribute( + IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, + REMOTE_PATH_DEFAULT); + } catch (CoreException e) { + // Ignore + } + remoteProgText.setText(targetPath); + + String prelaunchCmd = null; + try { + prelaunchCmd = config + .getAttribute( + IRemoteConnectionConfigurationConstants.ATTR_PRERUN_COMMANDS, + ""); //$NON-NLS-1$ + } catch (CoreException e) { + // Ignore + } + preRunText.setText(prelaunchCmd); + } + + 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 programName = fProgText.getText().trim(); + boolean bUpdateRemote = false; + + String remoteName = remoteProgText.getText().trim(); + String remoteWsRoot = getRemoteWSRoot(); + if (remoteName.length() == 0) { + bUpdateRemote = true; + } else if (remoteWsRoot.length() != 0) { + bUpdateRemote = remoteName.equals(remoteWsRoot); + } + + if (programName.length() != 0 && bUpdateRemote) { + IProject project = getCProject().getProject(); + IPath exePath = new Path(programName); + if (!exePath.isAbsolute()) { + exePath = project.getFile(programName).getLocation(); + + IPath wsRoot = project.getWorkspace().getRoot().getLocation(); + exePath = makeRelativeToWSRootLocation(exePath, remoteWsRoot, + wsRoot); + } + String path = exePath.toString(); + remoteProgText.setText(path); + } + } + + private void useDefaultsFromConnection() { + if ((remoteProgText != null) && !remoteProgText.isDisposed()) { + String remoteName = remoteProgText.getText().trim(); + String remoteWsRoot = getRemoteWSRoot(); + if (remoteName.length() == 0) { + remoteProgText.setText(remoteWsRoot); + } else { + // try to use remote path + IPath wsRoot = getCProject().getProject().getWorkspace() + .getRoot().getLocation(); + IPath remotePath = makeRelativeToWSRootLocation(new Path( + remoteName), remoteWsRoot, wsRoot); + remoteProgText.setText(remotePath.toString()); + } + } + if ((skipDownloadButton != null) && !skipDownloadButton.isDisposed()) { + skipDownloadButton.setSelection(getDefaultSkipDownload()); + } + } + + private IPath makeRelativeToWSRootLocation(IPath exePath, + String remoteWsRoot, IPath wsRoot) { + if (remoteWsRoot.length() != 0) { + // use remoteWSRoot instead of Workspace Root + if (wsRoot.isPrefixOf(exePath)) { + return new Path(remoteWsRoot).append(exePath + .removeFirstSegments(wsRoot.segmentCount()).setDevice( + null)); + } + } + return exePath; + } + + private String getRemoteWSRoot() { + IHost host = getCurrentConnection(); + if (host != null) { + IPropertySet propertySet = host + .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); + if (propertySet != null) { + String value = propertySet + .getPropertyValue(IRemoteConnectionHostConstants.REMOTE_WS_ROOT); + if (value != null) { + return value; + } + } + } + return ""; //$NON-NLS-1$ + } + + private boolean getDefaultSkipDownload() { + IHost host = getCurrentConnection(); + if (host != null) { + IPropertySet propertySet = host + .getPropertySet(IRemoteConnectionHostConstants.PI_REMOTE_CDT); + if (propertySet != null) { + return Boolean + .valueOf( + propertySet + .getPropertyValue(IRemoteConnectionHostConstants.DEFAULT_SKIP_DOWNLOAD)) + .booleanValue(); + } + } + return SKIP_DOWNLOAD_TO_REMOTE_DEFAULT; + } +} diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteGDBDebuggerPage.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteGDBDebuggerPage.java new file mode 100644 index 00000000000..6162b92a7c2 --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteGDBDebuggerPage.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * 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) + * + * Referenced GDBDebuggerPage code to write this. + *******************************************************************************/ + +package org.eclipse.cdt.launch.remote; + +import org.eclipse.cdt.debug.mi.internal.ui.GDBDebuggerPage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.Text; + +/** + * The dynamic debugger tab for remote launches using gdb server. + * The gdbserver settings are used to start a gdbserver session on the + * remote and then to connect to it from the host. The DSDP-TM project is + * used to accomplish this. + */ +public class RemoteGDBDebuggerPage extends GDBDebuggerPage { + + protected Text fGDBServerCommandText; + + protected Text fGDBServerPortNumberText; + + public String getName() { + return Messages.Remote_GDB_Debugger_Options; + } + + public void setDefaults( ILaunchConfigurationWorkingCopy configuration ) { + super.setDefaults(configuration); + configuration.setAttribute( IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND, + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND_DEFAULT ); + configuration.setAttribute( IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT, + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT_DEFAULT ); + } + + public void initializeFrom( ILaunchConfiguration configuration ) { + super.initializeFrom(configuration); + String gdbserverCommand = null; + String gdbserverPortNumber = null; + try { + gdbserverCommand = configuration.getAttribute( IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND, + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND_DEFAULT); + } + catch( CoreException e ) { + } + try { + gdbserverPortNumber = configuration.getAttribute( IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT, + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT_DEFAULT ); + } + catch( CoreException e ) { + } + fGDBServerCommandText.setText( gdbserverCommand ); + fGDBServerPortNumberText.setText( gdbserverPortNumber ); + } + + public void performApply( ILaunchConfigurationWorkingCopy configuration ) { + super.performApply(configuration); + String str = fGDBServerCommandText.getText(); + str.trim(); + configuration.setAttribute( IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND, str ); + str = fGDBServerPortNumberText.getText(); + str.trim(); + configuration.setAttribute( IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT, str ); + } + + protected void createGdbserverSettingsTab( TabFolder tabFolder ) { + TabItem tabItem = new TabItem( tabFolder, SWT.NONE ); + tabItem.setText( Messages.Gdbserver_Settings_Tab_Name ); + + Composite comp = new Composite(tabFolder, SWT.NULL); + comp.setLayout(new GridLayout(1, true)); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + ((GridLayout)comp.getLayout()).makeColumnsEqualWidth = false; + comp.setFont( tabFolder.getFont() ); + tabItem.setControl( comp ); + + Composite subComp = new Composite(comp, SWT.NULL); + subComp.setLayout(new GridLayout(2, true)); + subComp.setLayoutData(new GridData(GridData.FILL_BOTH)); + ((GridLayout)subComp.getLayout()).makeColumnsEqualWidth = false; + subComp.setFont( tabFolder.getFont() ); + + Label label = new Label(subComp, SWT.LEFT); + label.setText(Messages.Gdbserver_name_textfield_label); + GridData gd = new GridData(); + label.setLayoutData( gd ); + + + fGDBServerCommandText = new Text(subComp, SWT.SINGLE | SWT.BORDER); + GridData data = new GridData(); + fGDBServerCommandText.setLayoutData(data); + fGDBServerCommandText.addModifyListener( new ModifyListener() { + + public void modifyText( ModifyEvent evt ) { + updateLaunchConfigurationDialog(); + } + } ); + label = new Label(subComp, SWT.LEFT); + label.setText(Messages.Port_number_textfield_label); + gd = new GridData(); + label.setLayoutData( gd ); + + fGDBServerPortNumberText = new Text(subComp, SWT.SINGLE | SWT.BORDER); + data = new GridData(); + fGDBServerPortNumberText.setLayoutData(data); + fGDBServerPortNumberText.addModifyListener( new ModifyListener() { + + public void modifyText( ModifyEvent evt ) { + updateLaunchConfigurationDialog(); + } + } ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.mi.internal.ui.GDBDebuggerPage#createTabs(org.eclipse.swt.widgets.TabFolder) + */ + public void createTabs( TabFolder tabFolder ) { + super.createTabs( tabFolder ); + createGdbserverSettingsTab( tabFolder ); + } +} + diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteLaunchConfigurationTabGroup.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteLaunchConfigurationTabGroup.java new file mode 100644 index 00000000000..8fe70b7166d --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteLaunchConfigurationTabGroup.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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.cdt.launch.remote; +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 RemoteCDebuggerTab(false), + new SourceLookupTab(), + new CommonTab() + }; + setTabs(tabs); + } +}
\ No newline at end of file diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteRunLaunchDelegate.java b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteRunLaunchDelegate.java new file mode 100644 index 00000000000..f61daf31299 --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/RemoteRunLaunchDelegate.java @@ -0,0 +1,409 @@ +/******************************************************************************* + * Copyright (c) 2006, 2009 PalmSource, Inc. 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 + * + * Contributors: + * Ewa Matejska (PalmSource) - Adapted from LocalRunLaunchDelegate + * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API + * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry + * Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error + * Anna Dushistova (MontaVista) - [234490][remotecdt] Launching with disconnected target fails + * Anna Dushistova (MontaVista) - [235298][remotecdt] Further improve progress reporting and cancellation of Remote CDT Launch + * Anna Dushistova (MontaVista) - [244173][remotecdt][nls] Externalize Strings in RemoteRunLaunchDelegate + * Anna Dushistova (MontaVista) - [181517][usability] Specify commands to be run before remote application launch + * Nikita Shulga (EmbeddedAlley) - [265236][remotecdt] Wait for RSE to initialize before querying it for host list + *******************************************************************************/ + +package org.eclipse.cdt.launch.remote; + +import java.io.File; + +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.ICDIDebugger2; +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.GDBServerCDIDebugger2; +import org.eclipse.cdt.debug.mi.core.IGDBServerMILaunchConfigurationConstants; +import org.eclipse.cdt.launch.AbstractCLaunchDelegate; +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.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +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.osgi.util.NLS; +import org.eclipse.rse.core.RSECorePlugin; +import org.eclipse.rse.core.model.IHost; +import org.eclipse.rse.core.subsystems.ISubSystem; +import org.eclipse.rse.services.IService; +import org.eclipse.rse.services.clientserver.messages.SystemOperationCancelledException; +import org.eclipse.rse.services.files.IFileService; +import org.eclipse.rse.services.shells.HostShellProcessAdapter; +import org.eclipse.rse.services.shells.IHostShell; +import org.eclipse.rse.services.shells.IShellService; +import org.eclipse.rse.subsystems.files.core.servicesubsystem.IFileServiceSubSystem; +import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IShellServiceSubSystem; + +public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate { + + private final static String SHELL_SERVICE = "shell.service"; //$NON-NLS-1$ + private final static String FILE_SERVICE = "file.service"; //$NON-NLS-1$ + private final static String EXIT_CMD = "exit"; //$NON-NLS-1$ + private final static String CMD_DELIMITER = ";"; //$NON-NLS-1$ + + /* + * (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, + ""); //$NON-NLS-1$ + String prelaunchCmd = config + .getAttribute( + IRemoteConnectionConfigurationConstants.ATTR_PRERUN_COMMANDS, + ""); //$NON-NLS-1$ + + if (monitor == null) + monitor = new NullProgressMonitor(); + + if (!RSECorePlugin.isInitComplete(RSECorePlugin.INIT_MODEL)) { + monitor.subTask(Messages.RemoteRunLaunchDelegate_10); + try { + RSECorePlugin.waitForInitCompletion(RSECorePlugin.INIT_MODEL); + } catch (InterruptedException e) { + throw new CoreException(new Status(IStatus.ERROR, getPluginID(), + IStatus.OK, e.getLocalizedMessage(), e)); + } + } + if (mode.equals(ILaunchManager.DEBUG_MODE)) { + monitor.beginTask(Messages.RemoteRunLaunchDelegate_0, 100); + setDefaultSourceLocator(launch, config); + String debugMode = config + .getAttribute( + ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, + ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN); + if (debugMode + .equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) { + Process remoteShellProcess = null; + ICDISession dsession = null; + try { + // Download the binary to the remote before debugging. + monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2); + remoteFileDownload(config, launch, exePath.toString(), + remoteExePath, new SubProgressMonitor(monitor, + 80)); + + // Automatically start up the gdbserver. In the future + // this should be expanded to launch + // an arbitrary remote daemon. + String gdbserver_port_number = config + .getAttribute( + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT, + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT_DEFAULT); + String gdbserver_command = config + .getAttribute( + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND, + IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_COMMAND_DEFAULT); + String command_arguments = ":" + gdbserver_port_number + " " //$NON-NLS-1$ //$NON-NLS-2$ + + spaceEscapify(remoteExePath); + if (arguments != null && !arguments.equals("")) //$NON-NLS-1$ + command_arguments += " " + arguments; //$NON-NLS-1$ + monitor.setTaskName(Messages.RemoteRunLaunchDelegate_9); + remoteShellProcess = remoteShellExec(config, + prelaunchCmd, gdbserver_command, + command_arguments, new SubProgressMonitor( + monitor, 5)); + DebugPlugin.newProcess(launch, remoteShellProcess, + Messages.RemoteRunLaunchDelegate_RemoteShell); + + // 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, + gdbserver_port_number); + wc.doSave(); + + // Default to using the GDBServerCDIDebugger. + GDBServerCDIDebugger2 debugger = new GDBServerCDIDebugger2(); + dsession = ((ICDIDebugger2) debugger).createSession( + launch, exePath.toFile(), + new SubProgressMonitor(monitor, 15)); + + boolean stopInMain = config + .getAttribute( + ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, + false); + 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"), //$NON-NLS-1$ + iprocess, exeFile, true, false, stopSymbol, + true); + } + } catch (CoreException e) { + try { + if (dsession != null) + dsession.terminate(); + if (remoteShellProcess != null) + remoteShellProcess.destroy(); + } catch (CDIException e1) { + // ignore + } + throw e; + } finally { + monitor.done(); + } + } + + } else if (mode.equals(ILaunchManager.RUN_MODE)) { + monitor.beginTask(Messages.RemoteRunLaunchDelegate_0, 100); + Process remoteProcess = null; + try { + // Download the binary to the remote before debugging. + monitor.setTaskName(Messages.RemoteRunLaunchDelegate_2); + remoteFileDownload(config, launch, exePath.toString(), + remoteExePath, new SubProgressMonitor(monitor, 80)); + // Use a remote shell to launch the binary. + monitor.setTaskName(Messages.RemoteRunLaunchDelegate_12); + remoteProcess = remoteShellExec(config, prelaunchCmd, + remoteExePath, arguments, new SubProgressMonitor( + monitor, 20)); + DebugPlugin.newProcess(launch, remoteProcess, + renderProcessLabel(exePath.toOSString())); + } catch (CoreException e) { + throw e; + } finally { + monitor.done(); + } + + } else { + IStatus status = new Status(IStatus.ERROR, getPluginID(), + IStatus.OK, NLS.bind( + Messages.RemoteRunLaunchDelegate_1, mode), null); + throw new CoreException(status); + } + } + } + + private String spaceEscapify(String inputString) { + if (inputString == null) + return null; + + return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$ + } + + protected IHost getCurrentConnection(ILaunchConfiguration config) + throws CoreException { + String remoteConnection = config.getAttribute( + IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, + ""); //$NON-NLS-1$ + + IHost[] connections = RSECorePlugin.getTheSystemRegistry().getHosts(); + int i = 0; + for (i = 0; i < connections.length; i++) + if (connections[i].getAliasName().equals(remoteConnection)) + break; + if (i >= connections.length) { + abort(Messages.RemoteRunLaunchDelegate_13, null, + ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + } + return connections[i]; + } + + protected IService getConnectedRemoteService(ILaunchConfiguration config, + String kindOfService, IProgressMonitor monitor) + throws CoreException { + + // Check that the service requested is file or shell. + if (!kindOfService.equals(SHELL_SERVICE) + && !kindOfService.equals(FILE_SERVICE)) + abort(Messages.RemoteRunLaunchDelegate_3, null, + ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + + IHost currentConnection = getCurrentConnection(config); + + ISubSystem[] subSystems = currentConnection.getSubSystems(); + int i = 0; + for (i = 0; i < subSystems.length; i++) { + if (subSystems[i] instanceof IShellServiceSubSystem + && kindOfService.equals(SHELL_SERVICE)) + break; + if (subSystems[i] instanceof IFileServiceSubSystem + && kindOfService.equals(FILE_SERVICE)) + break; + } + if (i >= subSystems.length) + abort(Messages.RemoteRunLaunchDelegate_4, null, + ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + + final ISubSystem subsystem = subSystems[i]; + try { + subsystem.connect(monitor, false); + } catch (CoreException e) { + throw e; + } catch (OperationCanceledException e) { + throw new CoreException(Status.CANCEL_STATUS); + } catch (Exception e) { + throw new CoreException(new Status(IStatus.ERROR, getPluginID(), + IStatus.OK, e.getLocalizedMessage(), e)); + } + + if (!subsystem.isConnected()) + abort(Messages.RemoteRunLaunchDelegate_5, null, + ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + + if (kindOfService.equals(SHELL_SERVICE)) + return ((IShellServiceSubSystem) subsystem).getShellService(); + else + return ((IFileServiceSubSystem) subsystem).getFileService(); + } + + protected Process remoteFileDownload(ILaunchConfiguration config, + ILaunch launch, String localExePath, String remoteExePath, + IProgressMonitor monitor) throws CoreException { + + boolean skipDownload = config + .getAttribute( + IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, + false); + + if (skipDownload) + // Nothing to do. Download is skipped. + return null; + monitor.beginTask(Messages.RemoteRunLaunchDelegate_2, 100); + IFileService fileService = (IFileService) getConnectedRemoteService( + config, FILE_SERVICE, new SubProgressMonitor(monitor, 10)); + File file = new File(localExePath); + Path remotePath = new Path(remoteExePath); + try { + fileService.upload(file, remotePath.removeLastSegments(1) + .toString(), remotePath.lastSegment(), true, null, null, + new SubProgressMonitor(monitor, 85)); + // Need to change the permissions to match the original file + // permissions because of a bug in upload + Process p = remoteShellExec( + config, + "", "chmod", "+x " + spaceEscapify(remotePath.toString()), new SubProgressMonitor(monitor, 5)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Thread.sleep(500); + p.destroy(); + } catch (SystemOperationCancelledException e) { + cancel(e.getLocalizedMessage(), IStatus.CANCEL); + } catch (Exception e) { + abort(Messages.RemoteRunLaunchDelegate_6, e, + ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + } finally { + monitor.done(); + } + return null; + } + + protected String getRemoteHostname(ILaunchConfiguration config) + throws CoreException { + IHost currentConnection = getCurrentConnection(config); + return currentConnection.getHostName(); + } + + protected Process remoteShellExec(ILaunchConfiguration config, + String prelaunchCmd, String remoteCommandPath, String arguments, + IProgressMonitor monitor) throws CoreException { + // The exit command is called to force the remote shell to close after + // our command + // is executed. This is to prevent a running process at the end of the + // debug session. + // See Bug 158786. + monitor.beginTask(NLS.bind(Messages.RemoteRunLaunchDelegate_8, + remoteCommandPath, arguments), 10); + String real_remote_command = arguments == null ? spaceEscapify(remoteCommandPath) + : spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$ + + String remote_command = real_remote_command + CMD_DELIMITER + EXIT_CMD; + + if (!prelaunchCmd.trim().equals("")) //$NON-NLS-1$ + remote_command = prelaunchCmd + CMD_DELIMITER + remote_command; + + IShellService shellService = (IShellService) getConnectedRemoteService( + config, SHELL_SERVICE, new SubProgressMonitor(monitor, 7)); + + // This is necessary because runCommand does not actually run the + // command right now. + String env[] = new String[0]; + Process p = null; + try { + IHostShell hostShell = shellService.launchShell( + "", env, new SubProgressMonitor(monitor, 3)); //$NON-NLS-1$ + hostShell.writeToShell(remote_command); + p = new HostShellProcessAdapter(hostShell); + } catch (Exception e) { + if (p != null) { + p.destroy(); + } + abort(Messages.RemoteRunLaunchDelegate_7, e, + ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR); + } + monitor.done(); + return p; + + } + + protected String getPluginID() { + return "org.eclipse.rse.internal.remotecdt"; //$NON-NLS-1$ + } +} diff --git a/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/messages.properties b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/messages.properties new file mode 100644 index 00000000000..326545073b0 --- /dev/null +++ b/cross/org.eclipse.cdt.launch.remote/src/org/eclipse/cdt/launch/remote/messages.properties @@ -0,0 +1,51 @@ +################################################################################ +# Copyright (c) 2006, 2009 Wind River Systems, Inc. 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 +# +# Contributors: +# Martin Oberhuber (Wind River) - externalized strings +# Ewa Matejska (PalmSource) - [158783] browse button for cdt remote path +# Johann Draschwandtner (Wind River) - [231827][remotecdt]Auto-compute default for Remote path +# Anna Dushistova (MontaVista) - [244173][remotecdt][nls] Externalize Strings in RemoteRunLaunchDelegate +# Anna Dushistova (MontaVista) - [181517][usability] Specify commands to be run before remote application launch +# Nikita Shulga (EmbeddedAlley) - [265236][remotecdt] Wait for RSE to initialize before querying it for host list +################################################################################ + +# NLS_MESSAGEFORMAT_VAR +# NLS_ENCODING=UTF-8 + +RemoteRunLaunchDelegate_0=Launching +RemoteRunLaunchDelegate_RemoteShell=Remote Shell +RemoteRunLaunchDelegate_1=Unidentified mode {0} passed to RemoteRunLaunchDelegate +RemoteRunLaunchDelegate_10=Initializing RSE +RemoteRunLaunchDelegate_12=Starting Debugger +RemoteRunLaunchDelegate_13=Could not find the remote connection. +RemoteRunLaunchDelegate_2=Downloading +RemoteRunLaunchDelegate_3=Wrong service requested. +RemoteRunLaunchDelegate_4=No subsystem found.\n +RemoteRunLaunchDelegate_5=Could not connect to the remote system. +RemoteRunLaunchDelegate_6=Error during file upload. +RemoteRunLaunchDelegate_7=Could not create the hostShellProcess.\n +RemoteRunLaunchDelegate_8=Executing {0} {1} +RemoteRunLaunchDelegate_9=Starting Program + +RemoteCMainTab_Prerun=Commands to execute before application +RemoteCMainTab_Program=Remote Absolute File Path for C/C++ Application: +RemoteCMainTab_SkipDownload=Skip download to target path. +Remote_GDB_Debugger_Options=Remote GDB Debugger Options +RemoteCMainTab_ErrorNoProgram=Remote executable path is not specified. +RemoteCMainTab_ErrorNoConnection=Remote Connection must be selected. +RemoteCMainTab_Remote_Path_Browse_Button=Browse... +RemoteCMainTab_Connection=Connection: +RemoteCMainTab_New=New... +Gdbserver_Settings_Tab_Name=Gdbserver Settings +Gdbserver_name_textfield_label=Gdbserver name: +Port_number_textfield_label=Port number: +RemoteCMainTab_Remote_Path_Browse_Button_Title=Select Remote C/C++ Application File +RemoteCMainTab_Properties=Properties... +RemoteCMainTab_Properties_title=Properties +RemoteCMainTab_Properties_Location=Remote workspace location: +RemoteCMainTab_Properties_Skip_default=Skip download to target path by default |