Eclipse Yoxos Services Downloads Blogs About
Home > Blogs >

Posts Tagged ‘tips’

on Mar 3rd, 2010Shared libraries with Eclipse CDT and cygwin on Windows

Can you help me use shared libraries with Eclipse CDT, managed make and cygwin?“, I was asked yesterday. Read on for a list of common pitfalls and detailed instructions.

The instructions are based on the latest CDT release (Galileo) and cygwin (make 3.81, gcc 3.4.4). They are applicable to CDT’s managed make projects (that means CDT generates a makefile to build project).

The Pitfalls

It turns out that using a shared library on Windows is not as straight forward as you think. There are several pitfalls waiting for the unaware to fall into:

1. Recent versions of cygwin’s make insist on cygwin-style paths instead of windows paths (/cygdrive/c/foo instead of c:\foo). CDT is not picky about this and will generate an incorrect makefile, if you use workspace relative paths:

make all
example.d:1: *** multiple target patterns.  Stop.

The solution is to use absolute cygwin paths, such as: /cygdrive/c/workspace/mymath

2. The compiler and linker will not find the header files / library unless you set the appropriate parameters. The compiler needs an include path (-I). The linker needs the library name (-l) and library search path (-L). These settings are scattered in two places in the project properties. Their location is not obvious for a first-time user (details below).

3. When launching, Windows will not find the shared library (.dll) and greet you with the error pictured below. Unix users might try to set the LD_LIBRARY_PATH, which has no effect on Windows. The solution is to append the directory containing the .dll to the PATH (MSDN Article). Restart Eclipse for the changed PATH to take effect.

example stopped working Shared libraries with Eclipse CDT and cygwin on Windows

The remainder of the post walks you through the process of creating and using a simple shared library with cygwin and CDT.

Creating a Shared Library with CDT

Follow these instructions to create a shared library project with CDT.

1. File > New > Project > C Project > Next. Project name: mymath. Ensure “use default location” is checked. Note the location: c:\workspace\mymath — we’ll need it later. Project type: Shared Library; Empty Project. Hit Finish.

02 lib project Shared libraries with Eclipse CDT and cygwin on Windows

2. Create a header file (mymath.h) and the corresponding implementation (mymath.c). The example below provides a trivial function that multiplies two integers:

03 mymath c Shared libraries with Eclipse CDT and cygwin on Windows

3. Afterwards save and hit Ctrl+B (or Project > Build All) to build the library. If cygwin is on your path, you should see a “Release” folder in your project containing the file “mymath.dll”.

04 mymath dll Shared libraries with Eclipse CDT and cygwin on Windows

4. For windows to find the shared library, you need to add the directory containing the .dll to your path. On Vista this can be done via: Control Panel > User Accounts > User Accounts > Change my environment variables.

05 change path Shared libraries with Eclipse CDT and cygwin on Windows

5. Exit and restart Eclipse after changing the PATH. Otherwise the changes will not be picked up.

Using a Shared Library with CDT

Follow these instructions to use a shared library in a “managed make” CDT project.

1. File > New > Project > C Project > Next. Project name: example. Project type: Executable; Empty Project. Hit Finish.

06 example project Shared libraries with Eclipse CDT and cygwin on Windows

2. In that project create a file named example.c with the following content:

07 example c Shared libraries with Eclipse CDT and cygwin on Windows

3. Save and hit Ctrl+B to build the project. The second line will have an error: “mymath.h: No such file or directory”. We now have to adjust the compiler and linker settings so that the mymath.h / mymath.dll files are found during the build.

4. Select the “example” folder in the Project Explorer. Select “Project > Properties” from the menu. A dialog comes up. In the tree on the left open: “C/C++ General > Paths and Symbols”. In the “Languages” list, pick “GNU C”. Then hit “Add”. Enter the cygwin-style path to the “mymath” project: /cygdrive/c/workspace/mymath

Caution: When entering the path, don’t use the “Workspace” or “File system” buttons because the resulting path will not be compatible with cygwin’s make.

09 include path Shared libraries with Eclipse CDT and cygwin on Windows

5. In the same dialog select: C/C++ Build > Settings in the tree on the left. In the “Tool Settings” tab find: “Cygwin C Linker > Libraries”. Hit the “+” icon in the “Libraries” section and add the name of the library: mymath

Caution: if your shared library starts with lib, omit the ‘lib’ prefix (i.e. libfoo becomes foo)

Hit the “+” icon in the “Library search path” section and add the path to the folder containing the shared library: /cygdrive/c/workspace/mymath/Debug

10 library path Shared libraries with Eclipse CDT and cygwin on Windows

Hit OK.

6. You will be asked to rebuild the project. Answer “Yes”, but for some reason this will not rebuild your project. Hit Ctrl+B to rebuild. The error will go away.

11 rebuild dialog Shared libraries with Eclipse CDT and cygwin on Windows

08 example c with warning Shared libraries with Eclipse CDT and cygwin on Windows

Note: ignore the “unresolved inclusion” warning. It seems that CDT has trouble resolving cygwin-style paths. The generated make-file however will work as expected.

7. Select “example” in the Project Explorer. Right-click > Run As > Local C/C++ Application. At this point you see the result of the multiplication on the console. That means that the shared library was found and used successfully:

12 console Shared libraries with Eclipse CDT and cygwin on Windows

Kind regards,
Elias.

on Jan 7th, 2010I See You — SWT Spy

I spent part of today trying to debug a Linux specific issue in which wizard pages are not being shown properly.  Actually, the content of some wizard pages are not showing up at all (Bug 298805 if you’re interested).

While thinking through the problem on IRC (yes, you should be on IRC), Susan McCourt had a great idea — install the SWT Spy and see what it shows.

spy I See You    SWT Spy

The SWT Spy is a small tool that allows you to place your mouse over a widget and get information about that widget, including:

  1. Layout information
  2. Bounds
  3. Siblings
  4. Parent Chain (back to the shell)

spy action I See You    SWT Spy

I hacked the tool a bit to add the visibility field.  The SPY is available from: http://www.eclipse.org/swt/tools.php. Once installed, you can toggle the spy using CTRL+ALT+SHIFT+”.”.

An oldie but a goodie.

on Dec 12th, 2009PDE Goodness: Project and Target Platform Templates

A nice thing about Eclipse PDE is that it has mechanisms to make it very easy for developers to get started consuming your frameworks. Here are two of them.

Target Platform Templates

For runtime projects, such as Riena, RAP and Equinox, the first hurdle a developer faces is to set-up the appropriate target platform. A target platform is the collection of bundles that are available during compilation. Obviously if you ship runtime components they must end up in there to be available for compilation.

You can make this much easier for others by contributing a target platform template to the “New Target Definition” wizard. A developer can then select an entry in the “Template” drop-down and will instantly receive a pre-configured target definition. Much easier and less error-prone that recreating the target definition manually from step-by-step instructions.

Since the target definition’s payload can be provisioned over http, the developer only has to click on “Set as Target Platform” and is done. For details refer to the org.eclipse.pde.core.targets extension point.

pde new target PDE Goodness: Project and Target Platform Templatestarget PDE Goodness: Project and Target Platform Templates

Project Templates

Another way to help developers with their first steps is to provide a project template. This hooks into the last page of “New Plug-in Project” Wizard and pre-populates a new project with source code, binary content and appropriate plugin.xml and MANIFEST.MF files.

The templating mechanism has a lot of depth as you can manipulate data-models to dynamically craft the MANIFEST.MF and plugin.xml files. You can also define placeholder variables, such as $pluginId$ and use them in source templates. There are mechanisms to tie these variables to UI elements in the wizard pages. The developer documentation on the matter is somewhat superficial. At the moment your best bet is to check out and study the org.eclipse.pde.ui.templates project from the Eclipse CVS (/cvsroot/eclipse/pde/ui/org.eclipse.pde.ui.templates). It contains the templates that ship with the IDE and therefore plenty of examples. Complement this by reading the specification of the org.eclipse.pde.ui.pluginContent extension point and this introductory article on developer works.

pde templates PDE Goodness: Project and Target Platform Templatesriena mail PDE Goodness: Project and Target Platform Templates


on Nov 18th, 2009Compile errors… I should have set my EE

Lately I have been working on (and committing) a repository analyzer tool for p2.  It is meant to help you validate your repository against known problems and common mistakes (missing version numbers, two IUs with the same ID/Version, etc…).  After cleaning up the code I finally committed it.  Within a few minutes of committing it, Andrew starting pinging me to let me know I introduced a compile error. (Thanks Andrew).

The offending lines where here:

ee1 Compile errors... I should have set my EE

and more precisely:

ee2 Compile errors... I should have set my EE

You see, while this may seem fine to all you Java 1.6 developers out there, p2 is set to run on CDC-1.1/Foundation-1.1 and JSE-1.4.  I know in the Java SE space, 1.4 is long past end of life, but in the embedded space, it is still very common.  (Remember, these embedded devices require much smaller VMs, otherwise we complain that our small devices are two slow /sluggish / expensive, etc…) — and p2 is a provisioning platform that operates just fine on embedded devices.

With Eclipse, you can set your Execution Environment (EE) and point to a variety of JDKs.  This allows you to “single source” your code so the same code can run on a server with Java 1.6 installed and a small device with a Foundation VM.  However, I don’t have a Foundation VM icon sad Compile errors... I should have set my EE .

Lucky for us, an EE description for several JDKs is available in the Eclipse CVS repository:

ee3 Compile errors... I should have set my EE

Once you checkout the project, you can add this to your list of known JREs

ee4 Compile errors... I should have set my EE
Now I get all the Java tooling (content assist, compile errors, etc…) for the Foundation 1.1 VMs.

ee5 Compile errors... I should have set my EE

on Nov 13th, 2009Where’s your project set? Getting Eclipse sources easily!

As you know, Eclipse can use “Team Project Set” files (.psf) to magically import code from various repositories. Thanks to Karl (294842), we committers can now set a project set url in our project’s metadata. This will link to a .psf-file from our project’s About page.

Here’s how this looks for Eclipse RAP:

project page Wheres your project set? Getting Eclipse sources easily!

After saving this file, you can use the “Team Project Set” wizard to download the latest RAP sources with a few clicks:

wizard 1 Wheres your project set? Getting Eclipse sources easily!

wizard 2 Wheres your project set? Getting Eclipse sources easily!

wizard 3 Wheres your project set? Getting Eclipse sources easily!

wizard 4 Wheres your project set? Getting Eclipse sources easily!

Now go and bug your favorite projects to provide a project set icon wink Wheres your project set? Getting Eclipse sources easily! .

Kind regards,
Elias.

(follow me on twitter)

on Oct 23rd, 2009Tip: Computing the difference of two collections

Sometimes you have two collections and want to know how they differ. It would also be useful to have a series of steps that transform collection ‘A’ into collection ‘B’ (or the reverse).

private static List list1 = Arrays.asList("a", "b", "c");
private static List list2 = Arrays.asList("a", "c", "d");
 
// Diff of list1 vs list2:
//  removed 'b' at 1
//  added 'd' at 2

With a little help from the class Diffs (found in the org.eclipse.core.databinding.observable bundle / package), it only takes a few lines, as shown in the snippet below. Thank you, Eclipse Databinding!

If you don’t see the snippet click here.

on Sep 11th, 2009Picasso paints the web with RAP

Whenever I’m working on UI stuff, something always goes terribly wrong icon wink Picasso paints the web with RAP Sometimes it’s only a margin or padding, other times it a composite that crosses my path. I was pretty happy that Chris Aniszczyk and Simon Archer hacked together Picasso, which helps you to identify some of these layout issues. As you may know, most of the time I work on the Rich Ajax Platform (RAP) and come across the same issues. As Picasso was originally intended to work for RCP, it’s not a long way to get it working for RAP.

picasso on rap 300x225 Picasso paints the web with RAP

In case you’re struggling with these issues too –  and working on RAP applications, please add your vote to bug 267975 so we can use Picasso on both runtimes.

on Jul 11th, 2009Testing hard to test code with EasyMock

hammock Testing hard to test code with EasyMock

If you are into unit testing, you may find EasyMock quite useful. It is very valuable for making hard-to-test-code testable.

For example I recently was adding tab-switching via keyboard to Riena. The state of each tab is kept in an interface named INavigationNode which has about 40 methods (!). Creating a mock by hand for such a big interface would not be fun at all. With EasyMock it just takes is a call to:

ISubApplicationNode nodeA = EasyMock.createMock(ISubApplicationNode.class);


The code for determining the next tab, depends strictly on the isSelected property. Manipulating the return value of this method takes just another EasyMock call:

EasyMock.expect(nodeA.isSelected()).andReturn(true);

This tells EasyMock that nodeA.isSelected() will be called once and should return true.

After everything is set-up I switch from ‘record’ to ‘play-back’ mode:

EasyMock.replay(nodeA);

Here’s a full example of a test case:

  protected void setUp() throws Exception {
    super.setUp();
    handler = new SwitchSubApplication();
    nodeA = EasyMock.createMock(ISubApplicationNode.class);
    nodeB = EasyMock.createMock(ISubApplicationNode.class);
    nodeC = EasyMock.createMock(ISubApplicationNode.class);
  }
 
  public void testFindNextSubApplicationAtoB() {
    EasyMock.expect(nodeA.isSelected()).andReturn(true);
    EasyMock.replay(nodeA);
 
    ISubApplicationNode[] nodes = { nodeA, nodeB, nodeC };
    assertSame(nodeB, handler.findNextNode(nodes));
  }

This post barely scratches the surface. Curious? Read this nice EasyMock introduction.

Image: (c) *Micky/flickr. Licensed under creative commons.

on Jul 10th, 2009PDE Build Compile Errors

Yesterday I spent the day working on examples of how PDE Build can be used to build OSGi bundles.  I was setting up builders, copying files from my workspace to my builder, and running builds.   Early in the morning I was faced with the follow:

The method disposeImageButtonImages(ImageButton) from the type
ScaledWidgetFactory refers to the missing type ImageButton

Ok, a compile error, no big deal… the better part of a day later I finally had this solved.  Just so nobody ever has to deal with this particular error again, I thought I would post a small debugging tip you can use.  But first, some background on my day (after I saw the error):

  1. Ensure export from the UI works… yes!
  2. PDE/Build defines a variable called pluginPath that you can use to point at additional plugin locations.  Since the missing type  –ImageButton in my case — was in a pre-compiled bundle that exists in my target, I assumed this variable was set wrong.  I tried different separators, bundle ordering and directory locations (with and without spaces in the name). I even tried putting the bundle in my baseLocation.  No dice.
  3. You can debug Ant scripts using PDE/Build.  There are a few things that you must setup first, but after I did this I was able to debug the script and ensure that the “so called ‘missing’” bundle was indeed in my classpath.
  4. At this point something hit me — the compile errors is on the method call, not the import statement. That means that the compiler found the type on import, but not when the method was called…. strange!
  5. In this particular example we are using Import-Package as opposed to Require-Bundle. Maybe I found a bug… I changed all the code to use Require-Bundle… No Dice.
  6. Because build can be finicky, and and a typo can cause all sorts of problems, I started again… Same problem.
  7. Read a story to my daughter. (Best part of the day, by far)
  8. Back to work… This time, I started making small changes in different bundles, copying them over, and trying again… At one point, IT WORKED!
  9. Revert the changes… IT WORKS! — Note: That’s not good
  10. Start over, .. IT FAILS… make the same changes I did above.. IT FAILS!
  11. Curse
  12. Notice something.. when I copy the directories over, I am copying a bin/ directory that may (or may not) have fully built .class files.
  13. Delete the bin/ directory .. IT WORKS!

In fact, the problem will happen very infrequently.  It only happened because I was copying bundles from my workspace (not fetching them from CVS), and in some cases, the bundles were not fully built.

So, the lesson: If you get strange compile errors using PDE Build, try deleting the bundles bin/ directory.

Thanks goes out to Andrew Niefer who once again came through with a much better way off structuring my build.

on Jul 8th, 2009Tracing Keybindings in Eclipse RCP

When adding keybindings to an existing Eclipse RCP application, it is extremelly helpful to get realtime information about which keybinding registered and to what command handlers it is mapped to. Why is that?  Because sometimes the operating system or another widget will consume the keyboard event before it gets to the command framework. Other times there are several handlers bound to the same key causing a conflict.

Enabling Tracing for Keybindigs

Fortunatelly, this information is easy to get, if you enable the right tracing options:

org.eclipse.ui/debug = true
org.eclipse.ui/trace/keyBindings = true
org.eclipse.ui/trace/keyBindings.verbose = true

trace keybindings Tracing Keybindings in Eclipse RCP

After that each keystroke will produce some output on the console:

KEYS --- WorkbenchKeyboard.press(potentialKeyStrokes = [CTRL+PAGE_UP, CTRL+])
KEYS --- WorkbenchKeyboard.executeCommand(commandId = 'org.eclipse.riena.navigation.ui.previousSubApplication', parameters = {})

In the above you can see that Ctrl+PageUp is mapped to the ‘previousSubApplication’ command.

Some times there is a conflict – i.e. one keybinding is mapped to two or more ‘active’ command handlers. This looks like this:

BINDINGS --- A conflict occurred for CTRL+SHIFT+W
BINDINGS ---     [Binding(CTRL+SHIFT+W,
	ParameterizedCommand(Command(org.eclipse.ui.file.closeAll,Close All,
		Close all editors,
		Category(org.eclipse.ui.category.file,File,null,true),
		org.eclipse.ui.internal.CloseAllHandler,
		,,true),null),
	org.eclipse.ui.defaultAcceleratorConfiguration,
	org.eclipse.ui.contexts.window,,,system), Binding(CTRL+SHIFT+W,
	ParameterizedCommand(Command(org.eclipse.riena.navigation.ui.closeModuleGroup,Close module group,
		,
		Category(org.eclipse.riena.navigation.ui.swt,Riena Navigation Commands,null,true),
		org.eclipse.riena.internal.navigation.ui.swt.handlers.CloseModuleGroup@39880a,
		,,true),null),
	org.eclipse.ui.defaultAcceleratorConfiguration,
	org.eclipse.ui.contexts.window,,,system)]

What happened here is that Ctrl+Shift+W was already bound to the CloseAllHandler via the ‘file.closeAll’ command. I was not aware of this initially, because it is defined in the org.eclipse.ui plugin. So I accidentally bound another command and handler to Ctrl+Shift+W. With the output I quickly realized what was going on. I ditched my own command and instead made ‘CloseModuleGroup’ a handler for the ‘file.closeAll’ command.

© EclipseSource 2008 - 2011