1.14. Creating a Static Library Project in a Workbench-Defined Project on Wind River Workbench 3.x

In this tutorial we will create and build a static library project for the Wind River General Purpose Platform (GPP) for VxWorks.

There are two general approaches to building static libraries with GNATbench. The difference is whether the project type is defined by Wind River Workbench or by the user.

The first approach uses a Workbench-defined type of project, for example a DKM project. As such it uses the Workbench builder, and all the facilities provided by the type of project are available. The second approach does not use a Workbench-defined project type. Instead, it uses a “User-Defined” project type. Building and cleaning are still supported for user-defined projects, among other capabilities, but the specific facilities provided by Workbench-defined (e.g. DKM) projects are not available. The first approach is somewhat simpler to use. We will examine the first approach in this tutorial.

1.14.1. Workspace Configuration

These initial settings must be done for each new workspace used. You will only have to do this once per workspace unless the preferences are somehow reverted.

Start Workbench.

1.14.1.1. Perspective Selection

Use the Window menu entry and select “Open Perspective”, then select “Advanced Device Development”. Of course you may skip that step if you are already using that perspective.

1.14.1.2. Disabling “Standard” Managed Builds

As of Wind River Workbench 3.0, “Flexible” managed builds are used by default and “Standard” managed builds are deprecated. New GNATbench projects must employ Flexible managed builds.

Therefore, set the options on the Wind River “Build” preference page as shown below to disable Standard managed builds. You must also ensure the option to “Create default build targets for new projects using flexible managed build” remains enabled.

enabling standard build pref page

1.14.2. Creating and Configuring the Project

The first step is to invoke the wizard. In the Application Development perspective, use the menu bar and select “File”, then “New”, and then the list of project types will be displayed in the menu, as shown in the following figure:

new project menu

In this tutorial we are making a library compatible with a DKM project so we want the DKM project creation wizard. Click on the wizard named “VxWorks Downloadable Kernel Module Project” to select it.

The Workbench wizard will open so that you can configure the new project (see figure below).

tutorial\_lib\_dkm\_wizard\_projname

Enter the name of the new project (we used “staticDKMlib”, arbitrarily) and choose to have the new project files reside in the default workspace location. Press Next.

If a Project Structure Wizard page is displayed, ignore it and press Next.

Another wizard page will appear, allowing you to select the build type. Take the defaults and press Next.

new DKM project wizard build setup

The next page (below) allows you to configure the build command and how the result is processed. Take all the defaults and press Next.

new DKM project wizard build support

The next page (below) allows you to configure the build spec(s) for the project. We first press “Deselect All” because we only want one build spec for this tutorial (because we will use the simulator). Then we selected “SIMNTgnu”. *Be sure to select the GNU version of any given build spec.*

tutorial\_lib\_dkm\_wizard\_build\_specs

The next page (below) allows you to configure a build target name and build tool for the project. In this case we change the default tool (“Linker”) to “Librarian” by selecting it from the pull-down list. Then press Next.

tutorial\_lib\_dkm\_wizard\_build\_target

The next page (below) allows you to configure the source code indexer for the project. This is a C++ tool so it is not pertinent to GNATbench projects. You can either take all the defaults and press Next, or disable the indexer altogether. It will not cause difficulties later if you choose to take the defaults. In the figure below we show how to disable the indexer.

new DKM project wizard indexer

You can now press Finish. The new project will be created and you will see it in the Project Explorer, like so:

tutorial\_lib\_init\_created\_project

Next we convert the new project to support Ada via GNATbench. To do this, we invoke the contextual menu on the new project node and select “New”, then “Other”, as shown below:

tutorial\_lib\_file\_new\_other

We then select “Convert to an Ada Project” in the resulting dialog and press OK.

conversion wizard for extending project

The first page of the conversion wizard will appear (shown in the next figure). We enter the name of the project to be converted and select the option to create a new GNAT project file.

tutorial\_sharelib\_conversion\_wizard\_page1.png

Press Finish. A new wizard will activate to allow you to make the GNAT project file content choices.

The first page asks for the GNAT project unit name. This is not the gpr file name. Rather, it is the name of the unit (the project) within the gpr file.

Unlike the Eclipse project name, the GNAT project unit name must be a legal Ada identifier. The wizard will try to make a legal Ada name from the Eclipse project name, for example, by substituting underscores for dashes. If the Eclipse project name is already a legal Ada identifier that name is used unchanged, as in this case:

project conversion project unit name page

Press Next. The next page allows you to configure the ada library settings

tutorial\_lib\_ada\_library\_settings\_dialog

Click Next to take all the defaults. The next page allows you to configure the ada stand alone library settings

tutorial\_lib\_ada\_stand\_alone\_library\_settings\_dialog

Set interface to P and keep Generate the file(s) of the interface enabled to have a p.ads file automatically created. This code will be initially empty and we will edit it shortly.

Click Next.

The next page allows selection of the directories that will hold sources and intermediate products. We take all the defaults.

tutorial\_project\_dirs\_dialog.png

The final page allows selection of one or more toolchains to be available to the project. The appropriate toolchain for the project’s selected build spec will be enabled by default, but can be changed. Multiple toolchains can be convenient for a number of reasons. For example, a project baseline compiler version can be used to build the actual release but a newer version of the same toolchain can also be used for the sake of improved error analysis. This page also allows selection of a “production” and “debug” scenario, in which different switches are applied (e.g., debugging versus optimization) depending on the current development mode. Other build options are also available on the page. We take the defaults and simply press Finish.

tutorial\_lib\_project\_build\_settings\_dialog.png

After conversion, note the presence of the new gnat.makefile in the Project Explorer. This is a makefile fragment that will automatically invoke the Ada compiler and other builder tools when the Workbench project builder is invoked. It must not be deleted.

Also note the “src” folder containing the p.ads interface file.

Edit the p.ads file and add in it the procedure Q declaration.

package P is
   procedure Q;
end P;

Create the body of this package. Select p.ads file and then run Ada > Generate Body menu.

Modify p.adb content to get the following.

with GNAT.IO;
package body P is

  -------
   -- Q --
   -------

   procedure Q is
   begin
      GNAT.IO.Put_Line ("Hello from P.Q");
   end Q;

end P;

In a real application we would add a unit in Library_Interface declaration of GNAT project file “staticDKMlib.gpr” for each unit included in the library interface.

for Library_Interface use ("P", "Q", "R");

1.14.3. Building the Project

In the Project Explorer, right-click to bring up the contextual menu. Select “Build Project”.

A pop-up will appear the first time you build the project. Just press “Continue”.

The build will then proceed and you can watch it in the Build Console. A sample successful build will look like the following:

tutorial\_lib\_build\_console\_result

After the build complete the project will appear as shown below. Note the “lib” folder containing the new library file.

tutorial\_lib\_built\_library

1.14.4. Client Projects Using the Library

Now that the library project is ready we can create and build a client project that uses the library. Strictly speaking you can build the client project first, making the necessary modifications to it after you build the static library project.

The client project is created via the new-project wizard just like any other DKM project. The project is also extended for GNATbench in the same manner. These construction and extension steps are described in great detail in the Creating and Building a General Purpose Platform Project on Wind River Workbench 3.x tutorial. Other than building it, follow those steps exactly. In this tutorial we have named the new client project “clientDKM”. The new main program is named “client_main” and we asked the wizard to generate the file for us.

The resulting new project will appear as follows:

tutorial\_lib\_both\_projects

The last required step is to associate the two GNAT project files so that the client project can make use of the static library when building the client’s Ada code. As always, this association is accomplished by placing a “with-clause” on the client’s GNAT project file (the “gpr file”) that references the static library’s GNAT project file. The fact that the static library gpr file is in a separate Workbench project does not matter.

with "../staticDKMlib/staticdkmlib.gpr";

project Clientdkm is

   for Languages use ("Ada");
   for Main use ("client_main.adb");
   for Source_Dirs use ("src/**");
   for Object_Dir use "obj";

   package Compiler is
      for Default_Switches ("ada") use ("-g", "-gnato", "-gnatwa", "-gnatQ", "-gnat12");
   end Compiler;

   package Builder is
      for Default_Switches ("ada") use ("-g");
   end Builder;

   package Linker is
      for Default_Switches ("ada") use ();
   end Linker;

   package Ide is
      for Gnat use "i586-wrs-vxworks-gnat";
      for Gnatlist use "i586-wrs-vxworks-gnatls";
      for Debugger_Command use "i586-wrs-vxworks6-gdb";
   end Ide;

end Clientdkm;

The “with-clause” on line one makes all the sources of the referenced GNAT project available, automatically, to the GNAT project file containing the clause. The clause must provide the path to the gpr file, but note that both absolute and relative paths are allowed. (This use of cross-project references is available generally, i.e., it is not limited to static library projects.)

The client main program can then reference the Ada package “P” provided by the static library:

with P;
procedure client_main is
begin
   P.Q;
end client_main;

1.14.5. Building the Client Project

We can now build the full client project using the “Build Project” menu entry:

tutorial\_lib\_build\_client\_invocation

A pop-up will appear the first time you build the project. Just press “Continue”.

The resulting build appears in the Build Console:

tutorial\_lib\_client\_wb\_project\_built

1.14.6. Static Library As Subproject

As illustrated, this approach works, but there is a problem: the static library project must be built before building the client project. If the static library is not already built, the Ada compiler will simply compile the required source files from the static library project sources into the client project – the static library will not be built. This is because the Workbench builder for the static library project was never invoked.

You can address this problem by making the static library project a “sub-project” of the client project. Do this by right-clicking on the static library project and selecting “Project References”, then “Add as Project Reference...”:

tutorial\_lib\_invoke\_project\_reference

In the resulting dialog box, enable the client project:

tutorial\_lib\_add\_proj\_ref\_dialog

Press OK and the Project Explorer will adjust to show the static library as a subproject of the client project:

tutorial\_lib\_nested\_lib\_project

Now, invoking the Workbench builder on the enclosing (client) super-project will also build, as necessary, the sub-projects. The other “build” oriented operations, such as project cleaning, will also now apply to the static library sub-project.

Note that if there are multiple client sub-projects under an enclosing super-project, you may need to set the build order to ensure the static library is built first.

The image below shows a full build of both projects invoked on the client node:

tutorial\_lib\_nested\_project\_full\_build

1.14.7. Congratulations!

You created a static library in a Workbench-defined project and used it with a client project.