Working with external Eiffel libraries

Organization of project source code on your local machine

First a note on setting up a local development environment on your work machine. It is a good idea to create a single dedicated directory for all your software projects in your home directory and name it 'proj', 'dev' or something similar. This directory will serve as the root directory for all projects you will work in.

Organization of Eiffel source code libraries: $ELIBS

When writing Eiffel systems you often use a number of third party, or rather external Eiffel source code libraries. By external we mean libraries developed and maintained outside of your current project and not included with EiffelStudio.

The solution presented here for organizing your external libraries is meant to:

  • Facilitate working with different versions of external libraries
  • Make it more explicit which version of an external library should be used when compiling a given system

Create a single dedicated directory in your proj directory called 'elibs' and define an environment variable $ELIBS that points to that directory. That directory is the root directory for all your external libraries. When compiling Eiffel systems you will need to list the external libraries you want to use in your Eiffel system in .ecf files. When you specifiy the paths to those libraries in the .ecf files you will only need to use the $ELIBS environment variable.

  1. Create a directory on your machine that will serve as the root directory for all locally installed but external Eiffel libraries. Eg:
  ~/proj/elibs
  1. Define an environment variable ELIBS an set the value of it to the path of the directory you just created.
  1. Below the ELIBS directory, create a "product" directory for each external Eiffel Library. Eg:
  $ELIBS/gobo
  $ELIBS/eposix
  $ELIBS/eldap
  1. Under each "product" directory create "product release" directories for each release of the given library product that you want installed. It's important that you follow the naming conventions for the releases of each library product since they will be explicitly used in the EiffelStudio .ecf files when refering to the libraries. Eg:
  $ELIBS/gobo/gobo33
  $ELIBS/gobo/gobo34
  $ELIBS/gobo/gobo38
  1. If you want to work against the bleeding edge repository version of a given library product, you should create a special directory for that purpuse. The directory name should be the product name followed by -dev. Eg:
  $ELIBS/gobo/gobo-dev

Note that you should make sure to checkout the repository code at the same directory level as the library product typically is released so that you easily can switch between a given version of a library and the bleeding edge repository for that library. For example that usuall means checking out the directories under "trunk" or "branches/specialhack" in a Subversion repository. Eg:

  $ELIBS/eldap/eldap-dev <-> http://eldap.seibostudios.se/svn/eldap/trunk      
  1. In your EiffelStudio .ecf files, make sure you use the $ELIBS environment variable in your cluster definitions together with the specific release you want to use. This is an .ecf example for including all the Gobo 3.8 libraries:
    <cluster name="elibs" location="$ELIBS\">
        <cluster name="gobo" location="$ELIBS\gobo\gobo38\library" recursive="true">
            <file_rule>
                <exclude>/se$</exclude>
                <exclude>/test$</exclude>
                <exclude>/EiffelBase$</exclude>
                <exclude>/EiffelTime$</exclude>
                <exclude>/no_expat$</exclude>
                <exclude>/example$</exclude>
                <exclude>/ge$</exclude>
                <exclude>/free_elks$</exclude>
            </file_rule>
        </cluster>
    </cluster>

This convention has the advantage of explicitly stating the version of the given library to use when compiling your Eiffel system: Do not use library specific environment variables like $GOBO in the EiffelStudio .ecf files, since it makes it unclear which version of Gobo you should use!

Handling Eiffel compiler dependencies: $ELIBS_COMPILER

Some Eiffel libraries may have alternative solutions dependending on the Eiffel compiler used. This is of course not desirable and hopefully this type of depedencies will eventually disappear for all ECMA compliant Eiffel compilers. In the case you need to refer to a specific Eiffel compiler in an .ecf file you are recommended to use the environment variable $ELIBS_COMPILER. Since we only intend to support ECMA compliant compilers, or those compilers that intend to be ECMA compliant the two possible values to use are:

$ELIBS_COMPILER value Meaning
es EiffelStudio compiler
gec Gobo Eiffel compiler

For example, a library may use a way of accessing external C features in a way that differs between the EiffelStudio and Gobo compilers. The files that access the external C features would then be in the following directory structure:

$ELIBS/foo/foo-dev/lib/spec/compiler/es
$ELIBS/foo/foo-dev/lib/spec/compiler/gec

In the .ecf files the relevant directory will be referred to by:

$(ELIBS)/foo/foo-dev/lib/spec/compiler/$(ELIBS_COMPILER)

Handling platform dependencies: $ELIBS_PLATFORM

Some Eiffel libraries may have alternative solutions dependending on the platform you are on. This is unavoidable due to platform differences. In the case you need to refer to a specific platform in an .ecf file you are recommended to use the environment variable $ELIBS_PLATFORM. Here are the possible values:

$ELIBS_PLATFORM value Meaning
linux32 Linux 32 bit
linux64 Linux 64 bit
win32 Windows 32 bit
sunos SunOS 32 bit

For example, a library may use a way of accessing external C features in a way that differs between platforms. The files that access the external C features would then be in the following directory structure:

$ELIBS/foo/foo-dev/lib/spec/compiler/es/linux32
$ELIBS/foo/foo-dev/lib/spec/compiler/es/linux64
$ELIBS/foo/foo-dev/lib/spec/compiler/es/win32

In the .ecf files the relevant directory will be referred to by:

$(ELIBS)/foo/foo-dev/lib/spec/compiler/$(ELIBS_COMPILER)/$(ELIBS_PLATFORM)

An example setup

Here is an example of how to set up the environment variables on 32-bit Linux. In my ~/.profile file I have:

export ELIBS=/home/paco/proj/elibs
export ELIBS_COMPILER=es
export ELIBS_PLATFORM=linux32