[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-dev] Remote C/C++ Project Support Prototype
|
I have recently been working on Remote Project support for Autotools
projects and wanted to start a discussion on what changes I made in the
CDT and Autotools and whether this would be something the CDT would want
to pursue.
To start with, my goal was to eliminate the need for separate Project
types or wizards which IMO there are lots to confuse the user as-is. To
create the remote project, I simply wanted to specify the location of a
C or C++ project as being remote. To do this, in the C/C++ Project
Wizards, one can specify a non-default location outside of the workspace
and there is a file-system pull-down where one can choose the rse
filesystem. From there, there is a browser to look at existing remote
connections and select an existing remote directory. Trying this out
was relatively easy, but as it turns out the RSE adds the connection
name at the end of the URI it creates for the locaion, but does not add
the project name. So, to create the project name directory, one has to
add the name of new project ahead of the connection query portion of the
URI. This obviously could be improved in the future so that the editing
step would not be needed.
For my design, I chose to use RDT. The beauty of RDT is that it allows
conversion between paths and URIs. This is an important feature in that
it is possible to leave existing UI elements as-is and there is no real
learning curve for the end-user. The context of paths can be implied by
the project location. If the project is remote, the paths are on the
same remote machine and no need to specify the full URI all over the
place. The user doesn't really need to see the remote machine URI all
over the place and by supporting paths, the data formats do not require
changing (e.g. paths occur in many classes in the CDT and there would be
no need to switch to URIs).
So, the first thing was for me to create the framework.
In my particular experiment, I created a RemoteProxyManager in
org.eclipse.cdt.core.internal.remoteproxy that implemented
IRemoteProxyManager:
public interface IRemoteProxyManager {
String EXTENSION_POINT_ID = "RemoteProxyManager"; //$NON-NLS-1$
String MANAGER_NAME = "manager"; //$NON-NLS-1$
String SCHEME_ID = "scheme"; //$NON-NLS-1$
public IRemoteFileProxy getFileProxy(IProject project) throws
CoreException;
public IRemoteCommandLauncher getLauncher(IProject project)
throws CoreException;
public String getOS(IProject project) throws CoreException;
}
The job of the proxy manager was to fish out proxies for file and
command access as well as to identify the remote OS.
For file access, there is the IRemoteFileProxy interface:
public interface IRemoteFileProxy {
public URI toURI(IPath path);
public URI toURI(String path);
public String toPath(URI uri);
public String getDirectorySeparator();
public IFileStore getResource(String path);
}
When accessing a path, one uses the project to get the IRemoteFileProxy
and then paths can be converted to URIs or IFileStore objects directly.
A path for storing or displaying in the UI can be obtained from the
URI via the API.
The IRemoteCommandLauncher interface allows one to run commands on the
same system as the project:
public interface IRemoteCommandLauncher {
public final static int OK = 0;
public final static int COMMAND_CANCELED = 1;
public final static int ILLEGAL_COMMAND = -1;
public Process execute(String commandPath, String[] args,
String[] env, String changeToDirectory, IProgressMonitor monitor) throws
CoreException;
public Process execute(String commandPath, String[] args,
String[] env, String changeToDirectory, boolean usePTY, IProgressMonitor
monitor) throws CoreException;
public int waitAndRead(OutputStream output, OutputStream err,
IProgressMonitor monitor);
public String getErrorMessage();
public String getCommandLine();
}
In my implementation, I also created a plug-in extension that would
allow specification of an IRemoteProxyManager. The remote proxy manager
would register itself to handle certain URI schema. The default
RemoteProxyManager class only handles local references and then if not
local, looks for an extension to handle the URI schema. It then punts
what ever method call was requested to the IRemoteProxyManager extension
class. For example, I created a remote proxy manager that uses RDT and
handles URIs starting with rse:// and remotetools:// which handles
projects set up via RSE or RDT.
I created the separate extension because my experiment started by
altering the Autotools plug-ins in Linux Tools. I did not want to make
Autotools force RDT to be required so I used the extension. The plug-in
that implements the extension for RSE and RDT connections using RDT is
not required for local project users. For the CDT, I copied over the
code from Linux Tools for the most part so I also copied over the
extension. The extension has the benefit that other systems could be
used to plug in and handle other remote system types (e.g. IIRC, RDT
doesn't support Windows as a target).
The design could easily be altered to use RDT directly and the CDT would
then have a dependency on RDT.
Once the framework was in place, I started converting the Autotools and
CDT code to use the proxies and found a few things that needed changing
as a rule:
1. All path accesses that are project located can not use java.io.File.
Instead, the project is used to get the IRemoteFileProxy and then
a path can be used to get an IFileStore (EFS file).
2. The getLocation() method can not be used for a resource. This
returns null for a remote object. Instead, one must use
getLocationURI(), then use the IRemoteFileProxy to convert to a path
which is what getLocation() returns.
3. Checking for existence requires getting the IFileStore as in 1), then
using the fetchInfo() method to get the IFileInfo exists()
method.
4. Running a command requires using a IRemoteCommandLauncher grabbed by
using the project rather than a ICommandLauncher.
Once my changes were in place, I was able to create a remote Autotools
Hello world project using the C Project Wizard (all I did was specify a
remote location). The remote project configures and builds on the
remote machine. I made a change so that the Binaries folder shows up
and I am able to execute the binary on the remote system and have the
results show up in the Console. In addition, I was able to invoke
Autotools commands remotely.
I did not change all code in the CDT as this was a proof of concept. I
added support to the TranslationUnit so the indexer appears to work but
while it uses the correct remote source file, I did not make it use
external headers so that would require further changes. There is a
remote indexer and if the indexer changes are not desired, the remote
indexer could be defaulted for the end-user by the C Project wizard.
I didn't actually have to change too much in the Autotools plug-ins nor
the CDT to get all of this to work.
If someone would like to see the changes I made, I have a fork of the
CDT with a branch called "rdt" which you can access read-only here:
git://github.com/jjohnstn/cdt.git
The Linux Tools changes for Autotools can be found in the RDT branch of
the org.eclipse.linuxtools git repository.
The Autotool changes are not in the master branch and are not part of
the code move currently under way.
Would there be interest in pursuing this further? I'm sure there are
things I haven't thought of.
I could also look into posting a screen-cast somewhere so you could see
how it all works.
-- Jeff J.