Mica Architecture Guide








Ed Swartz

initial version



Ed Swartz

add sections about project model, build model, launch model



Ed Swartz

add launch protocol and templates/project wizards section



Ed Swartz

update for recent process launcher API changes

Table of Contents


This document describes the architecture of Mica (Maemo IDE Common Architecture). It describes the essential interfaces and concepts and also serves as a bit of a porting guide.

Mica was not designed in an ivory tower and is a real evolving framework, so chunks of documentation are missing. Watch this space for updates and ask questions on mica-devel@garage.maemo.org in the meantime! Also, consult the ESbox and PluThon sources for real-world examples of Mica usage.

Mica is intended to serve as a common basis for Eclipse-based IDEs targeting Maemo build and/or runtime environments. With the basic assumption that the development and runtime environments will be command-line based, Mica provides a set of interfaces and extension points that serve to insulate client code from build and runtime specific dependencies. You can target the local machine, a Maemo device, a sandbox (with either or both command line rewriting or file system remapping), with one piece of code.

While Mica had its roots in the ESbox project, it has no dependencies or assumptions that Scratchbox will be used. On the other hand, Mica provides the essential abstractions that allow ESbox to exist.

(Mica actually isn't all that dependent on Maemo either – the Maemo-specific functionality is in the “maemosdk” feature. Someday we may have to bite the bullet and rename the project.)

For example, Mica isolates the Make builder logic so that Make can be executed in an aribtrary way – under Scratchbox, on the host, or even on a device (though no one has seen fit to test this, due to device disk space limitations and an aversion to pain). Mica has no idea where the program will run; it calls through the interfaces ISDKTarget, IProcessLauncher, etc. to do the job. The Scratchbox support in ESbox provides the implementations of these interfaces, which create the actual command line (e.g. “/scratchbox/login ...... make”) and convert filesystem references to the project to point into the current rootstrap. This abstraction is so clean, in fact, that ESbox was ported to Windows and MacOS X, redirecting all its output through an SSH connection to a virtual machine, without any impact whatsoever on the builder.

You may ask, why use Mica if your needs are simple, such as launching locally? Well, do you really want to rewrite process launching behavior from scratch? Mica provides tested and useful utilities around the interfaces described above. Do you really want to have assumptions that all your files are on the local host, or write it twice, for local and remote usage? Mica uses the EFS filesystem abstractions in its IFileSystemAccess wrapper, allowing your code to target either. Also, do you want to rewrite support for Make, Autotools, run/debug/profile support on host and device, device flashing, string externalization, Maemo SDK platform detection, apt packge installation, Debian package creation/deployment, etc...? All of these code is built on Mica and is easily reusable.

Machines and Targets


The primary architectural basis of Mica is a set of abstractions allowing a “machine” and its resources are accessed in a consistent way in order to allow tools to work the same no matter where the machine is, and also to abstract the way that SDKs and targets are defined on that machine, so that tools may be written against them in a generic way.

A machine (IMachine) is defined by:

/scratchbox/login -d /scratchbox/users/devel/home/devel/.esbox/ "./run.sh /home/devel/shared/workspace/myproject \\\"CWD=/home/devel/shared/workspace/cppsocketexampleproject,DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/session_bus_socket,DISPLAY=,PWD=/home/devel/shared/workspace/myproject\\\" \\\"make all\\\""

Machines are provided by the IMachineFactory extension point and by the IBuildMachineFactory extension point, or by direct instantiation.

Currently, IMachineFactory extensions create SSH and SBRSH machines as well as virtual machines for QEMU and VMware. These use URIs to encode the host address, the username and password, and configuration options for the machine. You will see these used in TestMachineFactory to generate IMachine instances used for unit testing.

There is also the notion of a “host machine”, accessible via MachineRegistry#getLocalMachine().

A build machine is a specific kind of machine which allows programs to be built on it (as opposed to just being a host for launched applications).

Currently, this primarily indicates that C/C++ building is possible. Scripted languages, for instance, are assumed to not be “built”.

Build machines may provide a property page visible in ESbox > Build Machines. Currently, the only build machines are a host Linux/x86 machine (if that is the host) or a virtual machine hosting a Linux/x86 image.

Current build machines are implemented by a Linux/x86 host, if available, or one of the virtual machines.

SDKs and targets

An SDK (ISDK) is defined as an agent which can locate and provide a collection of SDK targets. Machines host SDKs.

An SDK target (ISDKTarget) is defined as a view onto a machine through another layer of process launching, filesystem mapping, and filesystem access. The primary example and driving motivation for Mica and ESbox are, of course, Scratchbox 1 and 2. While processes run on the local machine (or under a VM when cross-developing), those processes are launched with specific transformations of a general command line, and the files these processes “see” are mapped into a union of a development toolkit and a target rootstrap.

There are SDKs for Scratchbox 1 and 2, each instance of which corresponds to one installation of the respective environment. Their SDK targets correspond to the targets in Scratchbox.

Recently, we brought the Eclipse Remote System Explorer framework into Mica as a core dependency. This provides the preferred mechanism for enumerating devices like Nokia Internet Tablets. There is a single RSE SDK instance which provides RSE SDK targets for all the registered connections that match Mica's needs (currently, SSH process launching and SFTP file access).

Note, however, that generic ISSHMachine exists, and can be used to contact devices not otherwise registered through RSE.

The intent of these interfaces is to remove all the burden from client code for deciding how to launch and manage a process. You should be able to construct a generic command line, a set of environment variable changes, and a working directory, and get the same result whether you launch on the host, under Scratchbox 1 or 2, or on a remote machine.

Process launching


In Mica, to launch a process, we need the command line, the environment variable changes, and the working directory.


Machines and SDK targets provide IProcessLauncherFactory instances with #getProcessLauncherFactory(), with which you construct a process launcher. The factory instance is used to create IProcessLauncher instances and to provide a starting point for modifying the environment for a launch.

If you need to modify the environment, always start with IProcessLauncherFactory#getDefaultEnvironmentModifierBlock() to get a copy of the IEnvironmentModifierBlock instance derived from the Maemo > Environment preferences. You may modify this instance by adding or removing definitions.

Then, construct a ProcessLauncherParameters block using one of the #create(...) methods in that class. A variety of forms is accepted here.

Create an IProcessLauncher from the process launcher factory using that parameter block. This launcher controls the lifetime of the process.

Process launching

This process launcher is the engine for starting, monitoring, and retrieving results from a launched process. You may query the original launch parameters if needed (e.g. for logging errors).

Launch the process with #createProcess(). This asynchronously creates the process and returns a Process object appropriate for the launcher (usually a host JRE process implementation or an SSHProcess).

You may then monitor the process. You may track the Process directly, using Process APIs – but this is not recommended. It is a tricky task to properly manage external Processes, given that they may block until output is consumed, and your program will block unless output is available. Plus, you have to allow for cancellation somewhere!

Instead, for new code, queue IStreamMonitor listeners and then let an IProcessMonitor object handle the process for you.

Before launching a process, create and queue IStreamMonitor instances with IProcessLauncher#queueStreamMonitor(). These instances will incrementally receive stdout and stderr text from a process. All the stream monitors receive the same output, formatted either as blocks of raw text (for IStreamTextMonitor-derived instances) or as lines (for IStreamLineMonitor-derived instances). A monitor can have custom behavior on process creation or termination. It can also choose to interrupt the process as a whole by throwing InterruptedException in response to text it has received.

See StreamTextMonitorAdapter and StreamLineMonitorAdapter for versions that handle all the default behavior except for text processing, and various subclasses of these to collect text (StringBuilderStreamTextMonitor) or send output to a console (ConsoleStreamMonitor).

When a process is created, then you may create the IProcessMonitor instance with IProcessLauncher#createProcessMonitor(), and then monitor the process with #runBlocking() or #runNonBlocking(). You may prefer to use the ProcessLauncherUtils class to handle the monitoring step, though, since it can also handle progress monitors and cancellation.

Example uses of machine and process launcher APIs

An example of process launching:

String[] getHomeDirectoryTextListing(IMachine machine, IProgressMonitor monitor) throws MicaException {
    List<String> cmdLine = CommandLineArguments.createFromVarArgs("ls", "-l");
    cmdLine = CommandLineArguments.wrapCommandLineForShell(cmdLine);  // since we use a wildcard

    final IProcessLauncher processLauncher = machine.getProcessLauncherFactory().createProcessLauncher(
                ProcessLauncherParameters.create(machine.getUserHome(), cmdLine));

    StringBuilderStreamTextMonitor textMonitor = new StringBuilderStreamTextMonitor(false);  // don't interleave

    int exit = ProcessLauncherUtils.launchAndMonitorStandardStreams(
                new IStreamMonitor[] { new ConsoleStreamMonitor(console) },

    if (exit != 0) 
        throw new MicaException("Process listing failed with exit " + exit);
    return textMonitor.stdout.split("\n");

This makes use of some useful utility classes – ProcessLauncherUtils has a variety of useful shorthands for common tasks.

This example does the same but dumps output to a console:

void showHomeDirectoryTextFiles(IMachine machine, IProgressMonitor monitor) throws MicaException {
    List<String> cmdLine = CommandLineArguments.createFromVarArgs("ls", "-l");
    cmdLine = CommandLineArguments.wrapCommandLineForShell(cmdLine);  // since we use a wildcard

    final IProcessLauncher processLauncher = machine.getProcessLauncherFactory().createProcessLauncher(
                ProcessLauncherParameters.create(machine.getUserHome(), cmdLine));

    IStreamMonitor consoleMonitor = new ConsoleStreamMonitor(CoreConsoleManager.createConsole(
                true, null, "System Output")); //$NON-NLS-1$

    /*int exit =*/ ProcessLauncherUtils.launchAndMonitorStandardStreams(
                new IStreamMonitor[] { new ConsoleStreamMonitor(console) },

    if (exit != 0) 
        throw new MicaException("Process listing failed with exit " + exit);

Note that the only difference is in which IStreamMonitor instance was passed. This could be even shorter, using:

                true, null, "System Output");//$NON-NLS-1$

which creates a MessageConsole and a ConsoleStreamMonitor and queues them for you, which means no IStreamMonitor array needs to be passed.

The ProcessLauncherUtils methods do all the work of properly tracking the streams for the process, tracking the process lifetime, allowing cancellation, and allowing for arbitrary client-side handling of the streams.

Filesystem Mapping and Access

A vitally important part of Mica is understanding how to reference files which may be embedded inside sandboxes (like Scratchbox targets or rootstraps) or on other machines, in a generic way that doesn't require special casing. Fortunately the APIs hide all the ugly details, but you must use them properly, or they won't help you at all :)

The filesystem mapping (IFileSystemMapping) is used to convert paths from one context to another. Such conversion maps a path for the same file, e.g., to find the local filesystem path for a file embedded in a rootstrap or for a file on another machine whose shared filesystem is mounted on the host. Any file which cannot be accessed from one context or the other cannot be mapped.

The contexts between which you convert may be on the same machine or on different machines. You must know these contexts to call the correct mapping routines.

Machine to machine mapping

One example is to find the location of a project in the build machine, in order to do operations on the project with commands launched on that machine. So, on Mac OS X, the project may live at “/Users/me/Public/workspace/project”, or in Windows at “c:\maemo\shared\workspace\project”, while in a Virtualbox virtual machine, it is seen at “/home/maemo/shared/workspace/project”.

For this case, use:

IMachine buildMachine;
IProject project;
IPath buildMachinePath = buildMachine.getFileSystemMapping().convertHostToTargetPath(project.getLocation());

This may return “null” to indicate there is no mapping.

In such machine to machine mappings, a shared folder must be configured so that the machines can see the same subtree of a filesystem. In the UI, ESbox > Build Machines > Shared Folders contains this configuration. In the APIs, IMachine#getSharedFilesystemProvider provides this information – this data is incorporated into IMachine#getFilesystemMapping().

To map a path on the other machine back to your machine, use #convertTargetToHostPath() instead.

ISDKTarget also provides access to this mapping with #getHostToMachineFileSystemMapping().

Machine to target mapping

Another example is to convert from a path in a project to a path in a Scratchbox target. In a project on Linux/x86, the path may be “/home/maemo/workspace/project/file.cpp”, while under Scratchbox 1 in a virtual machine, the path to the same file is “/scratchbox/users/maemo/home/maemo/workspace/project/file.cpp”.

For this case, use:

IPath projectPath = project.getLocation().append("file.cpp");
try {
    IPath targetPath = sdkTarget.convertHostToTargetPath(projectPath);
} catch (MicaException e) {

When a build machine is inside a virtual machine, the same routine is used. The conversion first maps through the shares exposed between the host and the build machine, then maps into the target. This is why this version throws an exception (more complexity leading to different failures)... plus that's the way the existing code did it, and it was easier not to deal with nulls. :)

As an example of cross-machine mapping: an include file used by C/C++ may be “/usr/include/gtk/gtk-2.0/gtk.h” from a given Scratchbox target. But on a Windows host, this file will not be mapped unless there is a file mapping from the virtual machine's “/scratchbox” or “/home/maemo” directory to a shared drive on that host. (This is not configured by default.) If “s:\” is mapped to “/scratchbox” in the VM, then such a mapping from target to host would produce “s:\users\maemo\targets\DIABLO_ARMEL\usr\include\gtk\gtk-2.0\gtk.h”.

Cross-hosting Considerations

With Mica's architecture, we were able to easily migrate from a system where Scratchbox was hosted locally (on the same host Linux/x86 machine) to one where it is hosted “remotely” through a virtual machine running on a host Windows or MacOS X or Linux/x64 machine. This required only that there be some way to designate a virtual machine as the build machine (versus assuming it is always the host machine).

There is virtually no client code that cares what the “real” host is. But the structure of the code is vitally important. Processes and files should be handled through the APIs described above to ensure portability.

Project Model

Mica provides a project model that abstracts the differences between various third-party language or project features, so that Mica features and clients can use uniform code and UI to interact with such projects.

This allows for a unified project creation wizard, project conversion wizard, Debian apt package import wizard, build configuration property page hierarchy, etc. which in themselves have little or no dependencies on specific CDT or Pydev (or whatever else) plugins.

This also allows Mica to provide custom builders and a launch framework for these projects which can operate with ISDKTarget and IMachine rather than using the default implementations that typically only work with host-only launching. Thus, if you implement ISDKTarget for a new build environment, the Mica-provided project model will support it for free.

Project handles and build configurations

In Mica, the core project model and UI provide a framework for accessing projects (IProjectHandle) with build configurations (IBuildConfiguration). Get project handles from the ProjectManager singleton and build configurations from the project handle.

A project handle is created from an existing Eclipse project and allows manipulating its build configurations and setting its active build configuration. Project handles encapsulate access to the vendor-specific method of manipulating the project.

A build configuration is a set of settings, such as SDK and SDK target and execution environment and project-type-specific metadata. It can map directly to a similar concept in the concrete project model (like CDT's build configurations) or to a Mica-specific build configuration model for project models that don't use configurations (like for Pydev).

A project has an active build configuration for performing builds and launches. In Mica build selection UI, the active configuration is presented in boldface. (Note: build” configuration is a slight misnomer since it applies to more than builds...)

While a build configuration is an actual live configuration, build configuration data (IBuildConfigurationData), on the other hand, represents only the data behind a configuration. It is used to create projects, modify the configurations, and provide UI for stock configurations the user may wish to select.

Project handle and build configuration/data implementations are associated with project types (see below).

Build configuration providers

When configuring a new project or editing build configurations in an existing project, the stock Mica build configuration UI (e.g. BuildConfigSelectionUI) uses IBuildConfigurationProvider to generate a tree of build configuration data either for SDKs or for SDK targets, depending on the style of the project.

Currently there are two primary styles of configurations assigned to projects:

In Pydev projects, for example, configurations are directly based on ISDKTarget, so SDKTargetBuildConfigurationProvider provides a build configuration for each ISDKTarget child of ISDK.

In C/C++ projects, there may be several configurations per ISDKTarget, so StockTargetBuildConfigurationProvider provides a set of stock configurations, like Debug/Optimized, for each ISDKTarget child of an eligible ISDK.

The IStockBuildConfigurationProvider interface is provided by a project builder type to provide the specific build configuration data of stock configurations according to the builder. For example, Make projects usually control a build using CFLAGS, LDFLAGS, etc. environment variables. Debian Make projects, on the other hand, use the DEB_BUILD_OPTIONS environment variable to control the build.

Note: while the style of build configuration is presented here as being specific to a project type, it's up to the client-implemented wizards to provide the IBuildConfigurationProvider. This is because the project handle only cares about build configurations, not how they are generated. For example, the Debian project import wizard uses the StockTargetBuildConfigurationProvider in its build configuration tree, because the project type is not yet known before sources are extracted and analyzed.

Project and builder types

A project is identified in Mica by a project type (IProjectType). The project type is used in various Mica project creation, conversion, and import wizards to abstract out the way that the Eclipse project will be realized as a vendor-specific project. Mica provides CDT C, CDT C++, and Pydev project types. Get access to the project types from the ProjectManager singleton.

For instance, the project type is used to determine whether a given project is a C/C++/Python project. It can detect types for currently configured projects (by nature, usually) or arbitrary file trees (by contents). It can also provide a list of build artifacts in a project from the perspective of the type (e.g. in C/C++ projects, the IBinary model objects obtained by CDT through the use of binary parsers; in Python, all *.py[w] scripts).

Also associated with a project at creation and conversion time is the project builder type (IProjectBuilderType). This identifies the build system which transforms sources into programs. Mica provides Make, Autotools, and Debian Make (e.g. debian/rules) builders. Get access to the project builder types from the ProjectManager singleton.

As with project types, the builder type can be detected in existing projects (usually by nature) and in arbitrary file trees (by identifying specific files). Project builder types can also provide information about the build artifacts expected to be generated by the builder (e.g., before a project is built). (Note: this support is not implemented for any builder types yet.)

Typically, clients should not need to write their own project types or project builder types. Configuration of specific projects should be done by project templates, adjustments to the build configuration provider, etc.

Mica and product project natures

In order for Mica to provide support for ISDKTarget/IMachine based builders and launchers, it needs to add or replace its own project natures on top of vendor-specific natures. As described above, IProjectType and IProjectBuilderType handle most of this work already.

Products themselves (like ESbox, PluThon) should add their own natures, for example via AbstractProjectWizard#configureProjectConfigHandler(), to associate projects with their products for use in UI filtering. For example, the Maemo Build Configuration property page must be provided and instantiated by a product, as well as all the new project and project conversion wizards.

Thus, an ESbox C/C++ make project has these natures:


In boldface, the Mica cppNature identifies the project as “recognized by Mica” and allows the project type and handle to be created. The makeNature replaces the CDT make nature, which only builds locally. The remaining nature is used by ESbox to distinguish this project as an ESbox project.

Templates and Project Wizards

Template model

The org.maemo.mica.common.project.core.ITemplate[Provider] interface and the org.maemo.mica.common.project.core.templateProvider extension provides the basis of an extensible model for handling templates. Currently, only project-generating templates are supported, but these can easily be used for New File or New Class (or anything else) wizards.

A template is essentially metadata plus “processing”. The implementation of “processing” is completely up to the implementor, but it should not include work handled by the a given wizard (for example, Mica's template project wizard creates and configures the project using the project type and project builder type, so the template just handles creating initial project content and validating the installation).

The provided implementation of ITemplateProvider uses the Nokia Carbide template engine (com.nokia.carbide.templatewizard and the wizardTemplate extension). In this model, a plugin publishes wizardTemplate extensions to register one or more templates. The extension includes metadata that provide most of the information in the ITemplate implementation. The actual guts of the template are in a separate directory along with a template.xml file. The template.xml file publishes a list of pages with fields which may be edited in UI, and a list of processes (implementing com.nokia.carbide.templatewizard.IProcess) which do the work of the template using the variables defined by those fields.

The Carbide template engine and Mica provide several useful Carbide template processes for generating a project, especially the sticky aspects of copying and expanding variables in a tree of sources, registering C/C++ indexer metadata, and checking the user's SDK installation for compatibility with the template (and offering to upgrade). You may provide your own ITemplateProvider and ITemplate implementations, but for ease of integration, you may want to implement a hybrid approach that combines whatever custom template expansion engine with the Carbide processes, so you can make use of pre-written support.

Project wizards

Mica provides a hierarchy of abstract classes useful in generating “New project” wizards. org.maemo.mica.common.project.ui.wizards.AbstractTemplateWizard is the basis of the tree, with AbstractTemplateProjectWizard built on top of that.

The AbstractTemplateProjectWizard provides complete wizard logic, showing pages with the list of templates, the initial build configurations, and integrates additional pages through the ITemplateWizardUIAdapter of ITemplate for any template-specific configuration. The wizard will create the project and configure it using the project type, builder type, and execution environment referenced in the ITemplate. All you need to do in an end-user product is implement a wizard class and provide the title, description, icon, ISDKTarget filter, and template filter.

Template Filtering

By default, in AbstractTemplateWizard, every available template in the installation (from org.maemo.mica.common.project.core.TemplateProviderManager) is available. This is a whole lot of templates, and few of them may apply to your particular wizard. There are several levels of filtering provided to handle this.

First, the wizard will pre-filter non-project templates or templates whose published project type, builder type, or execution environment are not installed.

Then, the template selection page additionally filters templates based on platform (see ITemplate#getPlatformFilterPattern()). Since Mica is ostensibly for Maemo, the platform filter is a case-insensitive regular expression over platform names (Diablo, Fremantle, etc.). Also, the wizard implementor provides an IBuildTargetFilter to limit the supported ISDKTargets allowed for build configurations. (In practice, this is limited to “build machine” vs. “on-device” target filtering.)

Working together, these two pages provide mutual filtering so that (1) templates for unsupported platforms are not displayed and (2) targets not supported by a selected template are not displayed.

Finally, you can additionally pre-filter templates based on any of the attributes or metadata in ITemplate, or any other necessary logic. Be careful how strict your filtering is, though, and don't unnecessarily limit your wizard's power. Remember that various products may be installed together, and it may be perfectly fine for your product to use templates from another product, since other extensions to Mica are handling most of the work. For example, ESbox and PluThon wizards only exclude templates by C/C++ or Python project types.

Launching model

Mica provides a unified framework for running, debugging, and profiling programs for C/C++ and Python. This is the Eclipse debug framework for launching, which is distinct from, but which uses, the Mica process launcher.

Launching architecture

Most of the work of producing a launch consists of boringly repetitive code. Mica provides several trees of classes to make this simple. Also, of course, Mica implements these classes using the IMachine, ISDKTarget, and IFilesystemMapping/Access interfaces, ensuring that new build environments can easily be supported without rewriting.


For launch delegates, Mica provides a tree of AbstractLaunchDelegates terminating in directly usable classes for all the currently supported combinations of launches: C/C++, local/remote, and run/debug/profile. These are not intended to be extended (except where new major variations arise).

Tab groups

For launch configuration tab groups, Mica provides a tree rooted at AbstractMicaLaunchConfigurationTabGroup. This is a tree of abstract classes for all the currently supported combinations of launches: C/C++, local/remote, and run/debug/profile. To make a specific launch type for a product, you subclass and make a non-abstract class from the nearest abstract class. You may customize which tab groups are defined, though probably you should only add groups, not modify or remove them. You must provide an implementation of a method to create the launch shortcut instance corresponding to the launch tab group.


For launch shortcuts, Mica also provides a tree of AbstractMicaLaunchShortcut (and AbstractCppLaunchShortcut, since we need to use a CDT base class), again a tree of abstract classes, one of which you must instantiate for your needs. The shortcut provides the id of the launch configuration type created by the launch shortcut. Additionally, the shortcut implementation may provide different or extended default settings.

All launch shortcut classes implement IMicaLaunchShortcut, which has methods to configure the vendor-specific defaults, provide the launch configuration type, and provide the launch configuration's name.

In Mica, the launch shortcut takes the task of providing defaults for itself and for the launch configuration tab group. This ensures that the user experience is identical whichever path the user takes to create a configuration. (This means that if using the Run/Debug/Profile Configurations dialog, creating a new configuration may result in some dialog popups, but this is a small price to pay.)

The launch configuration name is provided through pattern expansion. Since we want to ensure that launch configurations have the same pattern, subclasses actually only provide information used to construct the name. MicaLaunchUtils#createLaunchConfigurationName actually handles this work, and subclasses override IMicaLaunchShortcut#setLaunchConfigurationNameKeys to add additional metadata keyed by MicaLaunchUtils#ELaunchConfigNameKey to a map.

Other glue classes

Under the covers, the real Mica-dependent APIs are used in a tree of classes based on ILaunchProxy / AbstractLaunchProxy. This class hierarchy takes care of the major functional differences between launches by constructing the command lines, hooking up debuggers or backend services, etc.

The ILaunchParameterAccessor / AbstractLaunchParameterAccessor class hierarchy provides the translation between the launch configuration data and the actual paths and files used for process launching, such as the program name, configured target, the current directory, and the environment. This is intended to ease the task of testing and documenting the behavior of the various launch configuration tabs shared among this forest of launches. (For example, a “working directory” for a launch should be ISDKTarget-relative or machine-relative depending on whether it's a local or remote launch. There are some rough edges in this area, still, because we use stock UI that assumes everything is on the local filesystem, so occasionally we have to allow either a local or an ISDKTarget-relative path.)

Adding launch support

From a client perspective, you only need to provide standard Eclipse launch configuration extensions and minimally instantiate some abstract classes.

This table shows the provided classes to be used for the respective extension points.

Language / Plugin

Local Launches(current ISDKTarget performs launch):

org.eclipse.debug.core.launchConfigurationTypes, org.eclipse.debug.ui.launchConfigurationTabGroups, org.eclipse.debug.ui.launchShortcuts

Remote Launches(user chooses a download method and remote connection for launch):

org.eclipse.debug.core.launchConfigurationTypes, org.eclipse.debug.ui.launchConfigurationTabGroups, org.eclipse.debug.ui.launchShortcuts

Launch shortcut filtering recommendation

Place this inside the <contextualLaunch> element for the launchShort, and in the top-level <and> block, edit the test to match your project appropriately. See below.

CDI (old-style CDT debugger interface)


CDILocalLaunchDelegate AbstractCDILocalLaunchConfigurationTabGroup AbstractCDILocalLaunchShortcut


CDIRemoteLaunchDelegate AbstractCDIRemoteLaunchConfigurationTabGroup AbstractCDIRemoteLaunchShortcut

   <with variable="selection">
      <count value="1"/>
             <!-- insert product check; see below -->




DSF (new-style CDT debugger interface)


DSFGDBLocalLaunchDelegate AbstractDSFGDBLocalLaunchConfigurationTabGroup AbstractDSFGDBLocalLaunchShortcut


DSFGDBRemoteLaunchDelegate AbstractDSFGDBRemoteLaunchConfigurationTabGroup AbstractDSFGDBRemoteLaunchShortcut

(Enablement same as for CDI)

C/C++ OProfile + Valgrind (note: valgrind is only "local", i.e. X86, and oprofile is only "remote", i.e. ARMEL and device)




OProfileRemoteLaunchDelegate AbstractOProfileRemoteLaunchConfigurationTabGroup AbstractOProfileRemoteLaunchShortcut

Enablement same as for CDI/DSF, but add one of: For Valgrind:


and for OProfile:





Note: The shortcut has mode "profile"


PythonRemoteLaunchDelegate AbstractPythonRemoteLaunchConfigurationTabGroup AbstractPythonRemoteLaunchShortcut

Note: The shortcut has mode "profile"

             <!-- insert product check; see below -->




Pydev OProfile + Valgrind



Note: The shortcut has mode "profile"


PythonOProfileRemoteLaunchDelegate AbstractPythonOProfileRemoteLaunchConfigurationTabGroup AbstractPythonOProfileRemoteLaunchShortcut

Note: The shortcut has mode "profile"

Same as for C/C++ enablement, but with org.maemo.mica.python.isPythonLaunchable

As described above, the launch shortcuts need to have a filter so they don't show up inappropriately. The enablement checks use Mica property testers to perform the tests that apply to the basic launch configuration implementations (previously a very long series of nested and/or/test elements).

Your product should also check for a product-specific project nature so your shortcuts don't pollute unrelated projects. Note that in order for Run/Debug/Profile As... to work with file or editor selections, you cannot use the built-in Eclipse project nature check. Instead, use the Mica version, which can find the project from the current selection, for example:


In the tables above, launches are also filtered on the kinds of targets the launch is known to work with (e.g., isX86Target, isRemoteTarget, etc). This uses the platform detected for the target of the active build configuration to make its assessment. Check the "propertyTester" extension in org.maemo.mica.maemosdk.core for a list of the properties you can test.

Also, take note of the configurationType element in the launchShortcut, as shown here in an ESbox Python Remote launch:

<!-- this maps the shortcut back to the launch configuration type,
    allowing the Run/Debug Settings UI in the Resource properties view 
    to show associated launch configs -->

For complete examples of a launch extension set, see the ESbox or PluThon *.launch plugins.

Launch protocols

For remote run/debug/profile launches, Mica provides an extension mechanism for configuring and deploying such a launch. For example, files may be copied, directories may be mounted, packages may be built and installed, etc.

Mica uses the extensions org.maemo.mica.common.launch: launchProtocolType and launchProtocolPage to provide the “Download methods” for remote launches. These handle the model and the UI for deploying artifacts from a project to the remote device for run, debug, and profiling launches. The remote launch configuration tab groups and shortcuts automatically integrate support for selecting and initializing the launch configuration data for these protocols.

ILaunchProtocolType is the model interface. It provides the metadata to display and record the protocol type, provides the implementation of ILaunchProtocol for an actual launch, and provides support for interactively configuring a launch configuration for that type.

ILaunchProtocolPage is the UI interface. It is a simple extension of the Eclipse debug UI ILaunchConfigurationTab interface.

ILaunchProtocol is the actual engine behind the launch protocol. It handles remapping and copying files to the device, creating the IMachine that provides the process launcher, and validating the connection before launch.

Provided implementations

Mica provides implementations for two essential protocols: SSH and SBRSH, labeled as “Copy programs (SSH)” and “Mount project (SBRSH)”.

Both will prompt the user for an RSE connection (more specifically, an IDeviceSDKTarget, which an SDK provider can create as well) through their interactive configuration methods, and use this connection name to resolve the address of the device dynamically at launch time. The launch configuration stores only the name of the connection, not the addresses. Thus, the user can edit the connection later and continue to use the same launch configuration. ILaunchProtocolType#syncLaunchParameters allows the protocol to update other parameters during a launch which (for historical or integration reasons) still rely on literal addresses.

The SSH method cooperates with the IProjectType and IProjectBuilderType to discover what files need to be copied to the device for a launch. (The user can edit the list of files in the launch configuration's “Download” page.) The SSHLaunchProtocol then generates an SSHMachine to handle launching and mapping files to the device.

The SBRSH method defaults to generating an .sbrsh configuration file automatically, which will mount the project on the device using sshfs. The org.maemo.mica.internal.api.protocol.launch.sbrsh.ISBRSHLaunchAdapter adapter provided on an ISDKTarget will provide target-specific initialization behavior. (For example, in ESbox, the “Sandbox mode” is used, substituting the target's rootstrap for the device's root directory, while this is disabled in PluThon, which doesn't use rootstraps.) Then the SBRSHLaunchProtocol generates an SBRSHMachine to handle the work of launching and mapping files to the device under an SBRSH configuration and target.