Sunday, September 26, 2010

Building Static Libraries and Test Program with Eclipse CDT

Based on sample code from a book, GNU/Linux Application Programming by M. Tim Jones, I have been reading to refresh myself on Linux programming, specifically in the C language, I have been trying to explore using the Eclipse CDT IDE.

I have managed to get projects set up in Eclipse for a simple application that prints numbers to a file. For the sake of practice, I have split the code into 1) a static library, libexp, based on the random number API library example from Chapter 7 2) a static library, libtherm, that wraps the random function with a function that returns the "temperature" 3) a simple executable that calls the temperature library function multiple times and prints the results.

Eclipse CDT
I downloaded and installed the Eclipse CDT Helios version for Linux (x86_64)
This requires a Java Runtime be installed on the machine. I had to install OpenJDK (1.6.0_18, 64-bit)

Project Structure

I started from an existing project I had created using the Automake/Autoconfig to set up a build environment. In this set up, I there was a single "project" directory with an app and lib subfolders containing respective source and build files.

As far as I can tell, the Eclipse CDT approach is that there is a single build target per Project. Perhaps if you develop the Makefile rather than have Eclipse create one you could do a different set up. Going with a completely Eclipse controlled build process I created separate projects for each static library and the executable file. All the source files went directly into each project directory under the workspace.


Build Artifacts

See Right-click Project > Properties > C/C++ Build > Settings > Build Artifact
For each of my projects libexp and libtherm, I set the Build Artifact properties as Artifact Type: Static Library, Artifact Name: ${ProjName}, Artifact Extension: a.

This results when you compile in Eclipse building and archiving the object files into libexp.a and

For temp-app the difference was the Build Artifact was set to Type Executable and there was no extension.

Referencing Libraries

In my case, the libtherm library references libexp library. The temp-app needed to reference both libtherm and libexp.
For libtherm Properties > C/C++ General > Paths and Symbols > References. I checked off libexp / Active.

This adds under the Includes > GNU C tab the Include directory /libexp.

I also updated the Properties > Project References to check off libexp project.

These steps also add GCC Compiler flags. Under Properties > C/C++ Build > Settings > GCC C Compiler > Includes it adds under -l included paths: "${workspace_loc:/libexp}"

If you click on the main GCC C Compiler heading All the options are listed:
-I"/home/me/workspace/libexp" -O0 -g3 -pedantic -Wall -c -fmessage-length=0


For the temp-app the procedure was more or less the same. Under the Project References, Path and Symbol References I added the two library projects libexp, libtherm.

Difference seems to be in the Executable type Project, the C/C++ Build > Settings has new options for GCC C Linker. Under Libraries -l I added "therm" and "exp" (GCC C Linker will prepend "lib" and append ".a"). Under the Library Search Path (-L) I added paths to the Debug directories in my other projects where the library artifacts were being built. For GCC C Linker All Options this results in:
-static -L"/home/me/workspace/libtherm/Debug" -L"/home/me/workspace/libexp/Debug" -o"appexp" ./test.o -ltherm -lexp

(note: one crucial step when linking libraries that may refer to each other: you must order them in a top down way. i.e. the libraries that have their own references to lower level libraries should be ordered first, so in my case it was -ltherm then -lexp. See this discussion on StackOverflow for more details: GCC C++ Linker errors: Undefined reference to ...')

Running the Project

Once the projects have been set up and you have a working build. You can try to run it.

See Run > Run Configurations
Add a new C/C++ Application to run e.g. "AppExp". Clicking run will execute the program with output going to your Eclipse Console panel

2 comments:

  1. Note made some edits that help to explain some aspects of the linking of multiple libraries. Included a useful link to a Stackoverflow thread on that topic.

    http://stackoverflow.com/questions/1095298/gcc-c-linker-errors-undefined-reference-to-vtable-for-xxx-undefined-referen/1095321#1095321

    ReplyDelete
  2. Thanks for this post, Eclipse CDT is at times pretty obscure when it comes to configuring a project.

    I'm not finding 'GCC C Linker All Options' in my project's settings...

    ReplyDelete