Useful Functions

Contents

Introduction
Operating Systems
Dependencies
Using the Library
Building and Installing
Versioning
Examples
CMakeLists.txt and Major files
CMake Comments
Adding new components to the library
Creating a new library

Introduction

This is a library of Useful Functions. If you have any questions please contact Andrew Maclean.

Library contents.

Subdirectories and their broad functional areas.

Subdirectory Functional Area.
Colour Contains a series of classes for manipulating RGB values.
Conversions Contains classes to effect conversions for output, translating between different formats, rotations and homogenous coordinates.
CSVParser A comma-separated value parser.
DateTime Date, system time and time conversion classes.
DTM Digital Terrain Modelling - routines for calculating volume.
FileUtilities File Utilities - routines for searching for a file and listing all files in directories. These will (optionally) recursively search subdirectories.
Examples Examples that illustrate the use of various components of the library. The directory structure reflects that of the library.
GeographicConversions Classes to convert to and from the various geographic coordinate systems in use.
GPSNavigation Classes that store and hold routes, points and tracks. Great circle navigation routines are also here.
GPSParser This is a library of parsers primarily for NMEA messages.
Logger Use this to log data to/from files.
Macros General macros that may be used by the library.
Statistics Some statistical routines.

All the library .h and .cpp files are prefixed with "uf". When the libraries are built, all the libraries have a prefix of "uf". Thus is it easy to identify the headers and libraries that belong to this collection of libraries.

Operating Systems

This library compiles as static and shared in Windows, Linux and QNX.

In Linux you have a further option regarding building shared libraries. This is called CMAKE_SKIP_RPATH.

If it is ON then runtime paths are not added when using shared libraries. This is useful when you are installing the library in a system directory like /usr/local.

If it is OFF then there is no need to do this as the paths to the library are build in to the code. However do not rename the library or change the path to the library because, if you do, your compiled code will not run.

Note that in QNX you must add -lm to the CMAKE_CXX_FLAGS when you run CMake.

Dependencies

Currently, the Boost libraries are needed for Homogenous Coordinate conversions (in /Conversions).

VTK will be needed for some parts of the library.

The library can be built without Boost or VTK if you set USE_BOOST and/or USE_VTK to OFF when using CMake to configure the library. The values of these settings will be propagated to any CMakeLists.txt files using the library as UF_USE_BOOST as UF_USE_VTK. Thus you can use these values to determine whether to find boost or find VTK in your own code. E.g. In your CMakeLists.txt file, do something like this:

# Now depending upon the variables set we determine whether additional
# libraries should be included,
# Boost
IF ( UF_USE_BOOST )
  # If FindBoost.cmake is in the modules directory of CMake then comment out the
  # following line. Otherwise set it to the path where BoostConfig.cmake is.
  SET ( Boost_DIR ${PROJECT_SOURCE_DIR} )
  FIND_PACKAGE(Boost REQUIRED)
ENDIF ( UF_USE_BOOST )

IF ( EXISTS ${Boost_INCLUDE_PATH} )
  INCLUDE_DIRECTORIES(${Boost_INCLUDE_PATH})
ENDIF ( EXISTS ${Boost_INCLUDE_PATH} )

IF ( EXISTS ${Boost_LIBRARY_PATH} )
  LINK_DIRECTORIES(${Boost_LIBRARY_PATH})
ENDIF ( EXISTS ${Boost_LIBRARY_PATH} )

# VTK
# FindVTK.cmake is in the modules directory of CMake.
#SET( VTK_DIR VTK_DIR-NOTFOUND )
IF ( UF_USE_VTK )
  FIND_PACKAGE(VTK REQUIRED)
ENDIF ( UF_USE_VTK )

Using the Library

You need to obtain the library from the repository.

Building and Installing

To use this library, firstly, download it from the repository into a directory called UF. Then create a build directory called UFBuild. You may also wish to create a build directory for the Examples called UFExamplesBuild. If you are thinking of installing the library then you can install it to a system-wide default library or to a directory you specify. So the directory structure looks something like this:

MyDevelopmentPath /UF
/UFBuild
/UFExamplesBuild

If in Linux, cd to UFBuild and type ccmake ../UF. If all goes well CMake will configure a build for you. If Boost or VTK are not on the system, set USE_BOOST and/or USE_VTK to OFF. Decide whether you want shared libraries or static libraries. If you are going to use shared libraries but are not installing the library then make sure CMAKE_SKIP_RPATH is OFF. If you are installing the libraries, then make sure CMAKE_SKIP_RPATH is ON and that the install path is correct. Check that the CMAKE_INSTALL_PREFIX is correct and press "c" and finally "g". Make sure you are in the directory and then type make and finally make install.

Linux commands
ccmake < path to library >
ccmake < path to library -GKDevelop3 > If you want to use KDevelop as the IDE.
If you install it, then the path structure will be something like this:
CMAKE_INSTALL_PREFIX /bin
/include/uf-x.y
/lib
/lib/uf-x.y

Where CMAKE_INSTALL_PREFIX is /usr/local in Linux or c:\Program Files\uf in Windows by default. In linux, if CMAKE_INSTALL_PREFIX is not the default path, you may need to add the directory CMAKE_INSTALL_PREFIX/lib to /etc/ld.so.conf and run ldconf. If CMAKE_SKIP_RPATH is OFF then no library files are installed but binaries and includes will be.

If you are in Windows, the procedure is similar to that in Linux except it is GUI based when using CMake and CMAKE_SKIP_RPATH is meaningless. IF you are using Visual Studio, then right-click on ALL_BUILD and select build. Finally right-click on INSTALL and select build. In Windows you can add the path to the dlls (CMAKE_INSTALL_PREFIX/bin) to the PATH environment variable.

For both Linux and Windows, you can also create an environment variable called UF_DIR. This should point to the directory containing UFConfig.cmake which is either the root of the build tree or the CMAKE_INSTALL_PREFIX/lib/uf<version> directory. Doing this will help FindUF.cmake find the library.

Versioning

The include files are in a directory called include/uf-x.y and in the lib directory there is a directory called uf-x.y containing the necessary CMake files to find and use the library.

It is proposed that release versions will have an even value for y.

Examples

Please note that the Examples directory is not part of the library build.

The CMakeLists.txt file in this directory will show you how to incorporate this library in your own code. This file requires FindUF.cmake to locate the UF library and to set the include and linker paths correctly. It also uses the values of UF_USE_BOOST and UF_USE_VTK to determine if Boost and VTK are needed.

If in Linux, cd to UFExamplesBuild and type ccmake ../UF/Examples. If UF is not found you will get a message to that effect. Then just set UF_DIR to MyDevelopmentPath/BuildUF or to CMAKE_INSTALL_PREFIX/lib/uf-x.y. Press "c" and finally "g". Make sure you are in the directory and then type make and finally make install.

If you are in Windows, the procedure is similar to that in Linux except it is GUI based when using CMake. IF you are using Visual Studio, then right-click on ALL_BUILD and select build. Finally right-click on INSTALL and select build.

CMakeLists.txt and Major files

CMake and the CMake include files needed to build the library:
CMakeLists.txt - the main CMakeLists.txt file that configures the build for the library.
CMakeOptions.cmake - options that the user can switch on or off.
DartConfig.cmake - Dart testing configuration file.
Examples/CMakeLists.txt - the main CMakeLists.txt file that configures the build for the examples.
Examples/FindUF.cmake - a script that finds the UF library.
GenerateUFConfig.cmake - generates the file UFConfig.cmake
LastConfigureStep/CMakeLists.txt - calls the final configuration file ufGenerateUFConfig.cmake
ufConfig.cmake.in - the UF configuration file for external projects. It is configured by UF and used by the UseUF.cmake module.
ufConfigure.h.in - the special system computed values are stored here and this file is used by UF to make ufConfigure.h.
ufCPack.cmake - sets up a package builder.
UF.bmp - The UF logo, used by the package builder.
ufGenerateUFConfig.cmake - configures UFConfig.cmake and writes it out for the build and install directories.
ufGenerateUFConfig.cmake - configures UFConfig.cmake and writes it out for the build and install directories.
ufIncludeDirectories.cmake - directories that must be included.
ufWin32Header.h - used to capture system differences between Windows and Unix operating systems. In particular we handle the Microsoft __declspec () for building DLLs here.
UseUF.cmake.in - used by UF to make UseUF.cmake.

CMakeLists.txt is the main file which sets up all that is needed for compiling, linking and installing the library. Here is a description of what this file does and the files that it needs.

CMakeLists.txt when used by CMake or ccmake does the following:

  1. Sets all the necessary variables.
  2. Includes CMakeOptions.cmake which contains any further compiler settings that are needed.
  3. Includes FindBoost.cmake which sets the include path for boost and the linker path (Win32 only) for Boost.
  4. Creates a file called ufBuildSettings.cmake containing the build configuration for CMake. This file is copied to the build directory and the <Install Directory>/lib/uf-<version> directory.
  5. Uses ufConfigure.h.in to create an include file ufConfigure.h. This file is copied to the build directory and the <Install Directory>/include/uf-<version> directory. System computed values are stored in this file.
  6. Uses UseUF.cmake.in to create a configuration file UseUF.cmake. This file is copied to the build directory and the <Install Directory>/lib/uf-<version> directory. System computed values are stored in this file. This file is included in a project using this library. It contains the necessary compiler and linker settings needed to use the library.
  7. Uses ufIncludeDirectories.cmake to find all the include directories. This file, UFIncludeDirectories.cmake, contains a list of all the include directories needed.
  8. It installs ufConfigure.h and ufWin32Header.h in the build directory and the <Install Directory>/include/uf-<version> directory.
  9. After all that it recurses into all the subdirectories and sets up the builds for the libraries and test programs.
  10. Then it sets up the configuration for cpack.
  11. Then it sets up the configuration for dart.
  12. Recurses into the directory called LastConfigureStep. Here the CMakeLists.txt file calls ufGenerateUFConfig.cmake which calls ufConfig.cmake.in to make ufConfig.cmake. This file is copied to the build directory and the <Install Directory>/lib/uf-<version> directory. ufConfig.cmake is the file loaded by external projects it calls UseUF.cmake and ufBuildSettings.cmake to set the paths and compiler/linker settings needed if you use the library.
  13. Finally Dart is included which reads DartConfig.cmake to set up the necessary structure for testing.

CMake Comments

In general the library will build without problems as a static or shared library under Unix. In Windows the libraries will build as static libraries with no problems. However because of the nature of dynamic link libraries (DLLs), some parts of the library will not build as a dll. So we need extra code in some of the the CMakeLists.txt files to address this problem.

Here are some more specific comments:

In /Colour the files will not build as a DLL in Windows. So we need to exclude ufColour.h and ufColour.cpp from building as a dll. This is done by the WRAP_EXCLUDE option in the CMakeLists.txt file in Colour. Note how we copy ufColour.cpp across when installing. This is done towards the end of the file. Of course then we have to include the .cpp file when building an application so in /Examples/Colour/CmakeLists.txt we find ufColour.cpp and add it to the build in this case.

In /Conversions if Boost is present we specifically include ufHomogenousCoordinateConversions.h. Additionally, this library will not build as a DLL, so we use the same technique as we used in Colour. Howerver there is a difference in that there are no source files, just header files. In this case, if we build as a static or shared library in Unix or static in Windows, we need to tell CMake to set the linker language correctly. This can be done by introducing a dummy file ufConversionsDummy.cpp which is is added to the source file list so that CMake can determine that it has to use C++ from the extension. However we can also set the linker language directly by issuing the command: SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES LINKER_LANGUAGE CXX), which has been done here. Note also that the CMakeLists.txt file in /Conversions and /Conversions/Test show a more fine-grained technique of excluding files from a build, in this case if UF_USE_BOOST is off, ufHomogenousCoordinateConversions.h and HomogenousCoordinates.cpp are excluded from the build.

DTM is dependent upon VTK so if VTK is not present then all of this library is excluded from the build.

In /Examples the various CMakeLists.txt files may also exclude/include examples based on the platform and what external libraries they need.

Adding new components to the library

  1. Create a new subdirectory (model it on an existing one).
  2. Edit ufWin32Header.h to put in the necessary symbols for building dlls.
  3. Edit ufGenerateUFConfig.cmake to add in the include directory path.
  4. Add in the subdirectory in CMakeLists.txt
  5. If building examples, create a new subdirectory (model it on an existing one). Also edit CMakeLists.txt in the /Examples directory to include the new subdirectory.

Creating a new library

You can use the structure of this library and the cmake files as a model for your library. The steps are as follows:

  1. Copy UF to a new directory and remove any .svn directories. This will prevent accidental overwriting of UF.
  2. Edit CMakeLists.txt and delete the directories listed in the SUBDIRS() macro. However do not delete SUBDIRS(LastConfigureStep). Also edit Examples/CMakeLists.txt removing any direcories listed in the SUBDIRS() macro. In both these cases, keep the SUBDIRS() statement. You will populate these with your own subdirectories.
  3. You may remove most of the UF directories if you want. However you must keep LastConfigureStep and Examples. Keep Examples/CMakeLists.txt, Examples/FindUF.cmake, Examples/UFExamples.html. You can delete the subdirectories in Examples because you will replace them with your own examples.
  4. Decide on a prefix for your library. Not "UF"!
  5. Edit the text in these files,replacing "uf" and "UF" keeping the case with your new prefix. It is important that you preserve the case in this step. E.g. If your new library is going to be called "FIIK" then replace "uf" with "fiik" and "UF with "FIIK".
    Files to edit:
    CMakeLists.txt
    CMakeOptions.cmake
    DartConfig.cmake
    Examples/CMakeLists.txt
    Examples/FindUF.cmake
    Examples/UFExamples.html (Edit this to reflect the contents of your examples directory.
    GenerateUFConfig.cmake
    LastConfigureStep/CMakeLists.txt
    ufConfig.cmake.in
    ufConfigure.h.in
    ufCPack.cmake
    ufGenerateUFConfig.cmake
    UF.html (Edit this to reflect the contents of your library.)
    ufIncludeDirectories.cmake
    ufWin32Header.h
    UseUF.cmake.in
  6. Rename the following files replacing "uf" and "UF" keeping the case with your new prefix. It is important that you preserve the case in this step. E.g. If your new library is going to be called "FIIK" then replace "uf" with "fiik" and "UF with "FIIK".
    Files to rename:
    Examples/FindUF.cmake
    Examples/UFExamples.html
    GenerateUFConfig.cmake
    ufConfig.cmake.in
    ufConfigure.h.in
    ufCPack.cmake
    ufGenerateUFConfig.cmake
    UF.html
    ufIncludeDirectories.cmake
    ufWin32Header.h
    UseUF.cmake.in
  7. Replace UF.bmp with a suitable logo for your library.
  8. At this point you should test and fix any errors.
  9. Begin adding in your library files using the CMakeLists.txt files in the subdirectories of UF as templates. It is strongly recommended that you prefix your header and source files in the library with your library prefix similar to the way it is done in UF. The reason for this is to prevent any conflicts over header inclusions. It also helps the user of the library in that they can clearly identify the library belonging to a particular file. Edit <your prefix>Win32Header.h to put in the necessary symbols for building dlls and <your prefix>Generate<your prefix>Config.cmake to add in the include directory path. Finally remember to add the subdirectories to your top-level CmakeLists.txt file and Examples/CMakeLists.txt file (if you are adding examples).