4.3. Library examples

Two library examples are provided, with complete makefiles.

Simple C and assembly code library (example_library directory)

The first library example demonstrates the tool options required to build both static and dynamic libraries with RVCT. The makefile for this example contains six main targets:

libsorts_static.a

This is a static library containing the example code, created using armar. It may be possible to create libraries with GNU ar and ranlib, however there are some known implementation-defined differences between the library symbol tables generated by the GNU tools. Where possible, you should therefore use armar provided with RVCT.

libsorts_dynamic.so

This is a dynamic library containing the same code as the libsorts_static.a target.

In particular for a dynamic library, the ‑‑apcs /fpic switch is given to the compiler, and ‑‑fpic is given to the linker. This indicates that you wish to generate position-independent code that can be located at any arbitrary virtual address.

sorts_static_rvct.axf, sorts_dynamic_rvct.axf

These are the application executables, linked against the respective libraries using armlink.

sorts_static_gld.axf, sorts_dynamic_gld.axf

These are similar to the above targets, however they are linked with GNU ld.

C++ example library (cpp_library directory)

This shows a simple C++ example that demonstrates the use of C++ class member functions in a library, based on the standalone C++ example. The library also contains definitions of static objects whose constructors are called during application startup.

The main difference in the startup procedure relates to how constructors for static C++ objects are called. For Linux applications there are two mechanisms used.

Firstly, constructors listed in the dynamic segment of a library (dynamic shared object, or DSO) are called by the dynamic loader. The dynamic loader uses other information in the dynamic segment to determine the dependencies of each library or application and initialize those first. Once this is complete, control is transferred to the application's initialization code.

Secondly, further constructors that are local to the application may be called if necessary. In a bare-metal application built using the RVCT libraries, the __cpp_initialize__aeabi_() library function calls these constructors. In a Linux application, the RVCT linker will resolve the necessary references from the corresponding GNU initialization functions to allow this code to be used instead.

Notes on constructors for static C++ objects

When developing C++ applications, you should be careful not to rely on the order in which static objects' constructors are called. Note that the ARM linker will not guarantee the order in which they are called at runtime, as the C++ standard does not guarantee the order in which the constructors are called.

The main consequence of this will be that the same code in a static library or a dynamic library may have its constructors called in a different order. The cpp_library example demonstrates this. When statically linked as part of the application executable, the C++ objects constructed in the library will have a different number than when the library is dynamic.

This is only of importance when you must rely on the ordering of constructors, for example where there are interdependencies between the objects. You can use the following points as a guide:

  • All dynamic library objects will be initialized after their dependencies and before those from static libraries and your main application. However, objects within the same dynamic library cannot have the order of their constructors guaranteed

  • Libraries that are statically-linked into your application will have their constructors called with the application's constructors during the C library initialization

  • All statically-linked library and application constructors will be called together, and the order in which they are called cannot be guaranteed.

Copyright © 2005-2006. All rights reserved.DAI0150B
Non-Confidential