r6.0.0:Building Guide

From liblfds.org
Jump to navigation Jump to search

Directory Layout

The source archive contains the following directory tree;

/liblfds600/bin/                    - the library binary (static or dynamic) ends up in here
/liblfds600/inc/                    - public header files
/liblfds600/obj/                    - directory for object files for liblfds
/liblfds600/src/lfds600_abstraction/  - abstraction layer sources
/liblfds600/src/lfds600_freelist/     - freelist sources
/liblfds600/src/lfds600_queue/        - queue sources
/liblfds600/src/lfds600_ringbuffer/   - ringbuffer sources
/liblfds600/src/lfds600_slist/        - singly linked list sources
/liblfds600/src/lfds600_stack/        - stack sources
/test/bin/                        - the test and benchmark program binary ends up in here
/test/obj/                        - directory for object files for the test and benchmark program
/test/src/                        - test and benchmark program sources

Library

In short; /liblfds600/bin contains the library binary, /liblfds600/inc contains the public header files, /liblfds600/obj is the temporary directory for object files and /liblfds600/src contains one directory per data structure, where each such directory contains the multiple C files for that data structure.

The root contains a considerable number of files required for building on various platforms.

Each data structure directory contains one header file, which is private to that data structure and which is the only include made by the C files in that data structure. That header file then in turn includes a library-wide private header file, which in turn includes the public header files.

So when the compiler comes to build a C source file, it sees headers in the following order;

  1. public header
  2. library wide internal header
  3. data structure internal header
  4. the actual C code

The root directory also contains the various files involved in building; makefiles, library definition files, Visual Studio 2008 project files, etc.

Test and Benchmark Program

The test and benchmark program follows the same pattern, although of course there is no public header file directory. So we find /test/bin contains the binary, /test/obj is the temporary directory for object files and /test/src contains the C and H files.

The /test directory also contains the makefiles and the Visual Studio 2008 project files.

Building

Toolchains

Linux

Under Linux, liblfds and the test and benchmark program are built using gcc version 4.1.0 or later and GNUmake 3.8.1 or later.

Windows User-Mode

On Windows, for liblfds and the test and benchmark program, depending on your target platform, one of the following toolchains is required;

Microsoft Visual Studio 2008 is Microsoft's commerical, fully fledged development GUI. It is expensive and supports all Windows platforms - which is to say, 32 and 64 bit Windows as well as the three possible CPU types (IA64, x64 and x86).

Visual C++ 2008 Express Edition is Microsoft's free development GUI. It only supports 32-bit Windows on x86. (You can run it on any Windows platform, but it does not ship with 64 bit compilers).

Microsoft Windows SDK is Microsoft's free command line based development environment. It has no GUI, but supports all Windows platforms - which is to say, 32 and 64 bit Windows as well as the three possible CPU types (IA64, x64 and x86).

Windows Kernel-Mode

On Windows, for liblfds and the test and benchmark program, the following toolchain is required;

The Windows Drivers Kit is Microsoft's kernel development environment. It is command line based and supports all Windows platforms (including ARM based platforms which are not yet supported by liblfds).

Library

The library builds as a static or dynamic library, with release or debug builds. The toolchain in use varies by platform.

Linux

GCC

There is a GNUmake makefile, /makefile.linux, which has the following targets;

  • arrel (release static)
  • ardbg (debug static)
  • sorel (release shared object)
  • sodbg (debug shared object)

The Linux makefile detects your CPU type by calling uname -m and so automatically produces the correct build for your CPU type. With 32-bit Linux on a 64-bit CPU, uname appears to lie about the CPU type, making it appears as a 32-bit CPU, which causes the makefile to behave properly.

The default build is debug static.

The resulting object files are placed directly in /liblfds600/obj and the resulting binaries are placed directly in /liblfds600/bin. If you wish to change build type, you need to make clean first.

Windows User-Mode

Microsoft Visual Studio 2008 / Visual C++ 2008 Express Edition

There is a Visual Studio 2008 project file, /liblfds600/liblfds.sln, which has the following platforms;

  • Win32 (for 32 bit CPUs)
  • x64 (for 64 bit CPUs)

and the following configurations;

  • Debug DLL
  • Debug Lib
  • Release DLL
  • Release Lib

The default build is x64 debug lib. The DLL builds both link to the DLL version of the MS run-time libraries. The static builds link to the static versions of the MS run-time libraries.

With Visual C++ 2008 Express Edition, the x64 platform will not be available.

As is customary with Visual Studio, each build has it's own object file and output binary directory (/liblfds600/obj/$(Platform)/$(Configuration) and /liblfds600/bin/$(Platform)/$(Configuration), respectively), so it is not necessary to clean between switching configuration or platform types.

Microsoft Windows SDK

There is a GNUmake makefile, /makefile.windows, which has the following targets;

  • librel (release static)
  • libdbg (debug static)
  • dllrel (release DLL)
  • dlldbg (debug DLL)

To use this makefile, open a command shell and run vcvars*.bat as appropriate for your target platform. The particular vcvars batch file you run will select the target platform and the SDK ships with cross compilers, so it is possible on all platforms to build for all platforms.

As with the Linux makefile, the makefile places its output directly in /liblfds600/bin and /liblfds600/obj. A make clean is required when switching between build types.

Windows Kernel-Mode

Windows Driver Kit

The Windows kernel build environment is primitive and has a number of severe limitations; in particular, all source files must be in one directory and it is not possible to choose the output binary type (static or dynamic library) from the build command line; rather, a string has to be modified in a text file used by the build (!)

To deal with these limitations, it is necessary for a Windows kernel build to run a batch file prior to building. There are two batch files, one for static library builds and the other for dynamic library builds. They are idempotent; you can run them as often as you like and switch between them as often as you want. It's all fine.

Both batch files copy all the sources file into a single directory, /liblfds600/src/single_dir_for_windows_kernel/.

The static library batch file will then copy /liblfds600/sources.static into /liblfds600/src/single_dir_for_windows_kernel/, which will cause a static library to be built.

The dynamic library batch file will then copy /liblfds600/sources.dynamic into /liblfds600/src/single_dir_for_windows_kernel/, which will cause a dynamic library to be built. It will also copy src/driver_entry.c into /liblfds600/src/single_dir_for_windows_kernel/, since the linker requires the DriverEntry function to exist, even though it's not used.

To build, start a build command line as usual, indicating through the command line you select whether you are making a debug or release build. Then run the appropriate liblfds batch file to select a static or dynamic library. Then, finally, run build.exe in the root directory, with whatever arguments you prefer.

Note that due to limitations in the build environment, object files appear in a subdirectory in /liblfds600/src/single_dir_for_windows_kernel/, rather than in the usual /liblfds600/obj/. The final binary output however still appears as usual in /liblfds600/bin/.

Note that the sources file used to compile the library asserts the define WIN_KERNEL_BUILD. This appears to be necessary, due to the lack of a compiler-provided method to differentiate in the code between a user-mode or kernel-mode build.

Test and Benchmark Program

The test and benchmark program is a command line application with release or debug builds.

Linux

GCC

There is a GNUmake makefile, /test/makefile.linux, which has the following targets;

  • rel (release build)
  • dbg (debug build)

The makefile detects your CPU type by calling uname -m and so correctly produces 32 or 64 bit builds. On 32 bit Linux on 64 bit CPUs, what seems to happen is the OS lies about the CPU type and so fools the makefile into thinking it really is on a 32 bit platform.

The default build is debug.

The makefile does not build liblfds. The library must be build manually beforehand. The library can be built as a static library or shared object; the test and benchmark program will compile properly in both cases.

The test and benchmark makefile knows where it is in the liblfds directory structure and directly reads the /bin and /inc directories and as such the test and benchmark program will compile properly against both the static and shared object builds of liblfds.

The static build will then be runnable. The dynamic build will not, since the operating system will not be able to find the liblfds shared object. To resolve this issue, the shared object either must be installed on your system (e.g. copied into one of the usual shared object directories such as /usr/local/lib/ or /usr/lib/) or the environment variable LD_LIBRARY_PATH must have been set to include a path to the shared object.

Windows User-Mode

Microsoft Visual Studio 2008 / Visual C++ 2008 Express Edition

There is a Visual Studio 2008 project file, /test/test.sln, which has the following platforms;

  • Win32 (for 32 bit CPUs)
  • x64 (for 64 bit CPUs)

and the following configurations;

  • Debug
  • Release

The default build is x64 debug.

With Visual C++ 2008 Express Edition, the x64 platform will not be available.

As is customary with Visual Studio, each build has it's own object file and output binary directory (/test/obj/$(Platform)/$(Configuration) and /test/bin/$(Platform)/$(Configuration), respectively), so it is not necessary to clean between switching configuration or platform types.

This project file will (unlike the makefiles) automatically build the liblfds library and builds it as a static library, automatically correctly selecting debug or release. The project file does not detect the platform and so the x86 or x64 build type must be selected.

Microsoft Windows SDK

There is a GNUmake makefile, /test/makefile.windows, which has the following targets;

  • rel (release build)
  • dbg (debug build)

The default build is debug.

To use this makefile, open a command shell and run vcvars*.bat as appropriate for your target platform. The particular vcvars batch file you run will select the target platform and the SDK ships with cross compilers, so it is possible on all platforms to build for all platforms.

The makefile does not build liblfds. The library must be build manually, as a static library, beforehand. The test and benchmark makefile knows where it is in the directory structure and directly reads the /liblfds600/bin and /liblfds600/inc directories, so it is not necessary to install liblfds on your system to build and run the test and benchmark program.

Windows Kernel-Mode

Windows Driver Kit

The test and benchmark program is a command line program. As such, it is not currently supported for the Windows kernel platform. In fact, the abstraction layer has been ported, but this doesn't make anything work, since it's a command line program with a main(). I'm currently considering what direction to take with this, since I want an out-of-box test and benchmark to be available, which would mean an installable driver with some means of getting output.

Note that the abstraction layer is almost ported. The necessary abstraction functions have been implemented, but the thread function prototype in the Windows kernel returns void, unlike the thread function prototypes for Windows and Linux user-mode. This means that the thread functions cannot currently compile, since they return a value (which is cast to the correct type for the platform). Under Windows Kernel, they cannot return a value at all.

Usage

Library

There is a single public header file, /liblfds600/inc/liblfds600.h. This contains the APIs for all of the data structures. You need to include this header file in your source code. The library binary, on all platforms and for all build variants, ends up in /bin/liblfds600.*, where the suffix varies by platform and build variant (static or dynamic library). For static builds, you need to link directly to the binary. For dynamic builds, you need to arrange your system such that the loader at run-time can locate the library.

Test and Benchmark Program

The test and benchmark program is run from the command line.

For usage documentation, see the testing and benchmarking guide.