Use of FTL in Code::Blocks

The Fortran Template Library (FTL) is a general purpose library that implements generic containers, easy string manipulation and more. It heavily relies on the C Pre-Processor (PP) directives (#include "Afile", #define B etc.). The use of the PP makes it difficult for the Code::Blocks to parse the library code. Only in CBFortran v1.8, the PP parsing was considerably improved, which enabled to have the code-completion for the FTL.

While this short tutorial is about the use of FTL, it may be useful for other users who work with code containing PP directives too.

Installation of the FTL on Linux

Download the FTL from github.com/SCM-NV/ftl.

Open terminal and cd to FTL code directory ("ftl-master" in my case). Compile the FTL with:

make install BUILD=release PREFIX=your_ftl_install_dir USE_PCRE=false

Here I used "USE_PCRE=false" because I have had a problem with "USE_PCRE=true" which is the default option. "PREFIX=your_ftl_install_dir" defines a directory where compiled files will be copied.

Installation of the FTL on Windows

Download the FTL from github.com/SCM-NV/ftl.

I had some problems to compile FTL on Windows. It seems, developers do not test FTL on this platform. However, after minor changes in the text file "makefile" in "ftl-master" directory, FTL can be compiled. Required changes in the "makefile":

  • Rename "libftl.so" to "libftl.dll" (use a replace function in your editor).

  • Add linker flag: "LDFLAGS = -lregex". It seems, that the "regex" library is by default added by GFortran on Linux, but it is not the case with MinGW.

/images/ftl_edit_makefile_win.png

I used MSYS2 for the compilation. After installation of MSYS2, as described on www.msys2.org, I started "MSYS2 MinGW 64-bit" from the Start menu. I navigated to the "ftl-master" directory (Note: for navigation to a different directory in "MSYS2 MinGW 64-bit" you need to use forward-slash "/" instead of a backslash "\" as accustomed on Windows), and then typed in:

make install BUILD=release PREFIX=your_ftl_install_dir USE_PCRE=false

Note that "make.exe" which comes with MSYS2 is not the same as "mingw32-make.exe". If you try to use "mingw32-make.exe", more changes in the makefile may be required.

Setup and compilation of the C::B project with FTL

Open the Code::Blocks IDE and create a new project.

Add a new file to the project and call it e.g. "stringIntegerMap.F90". Here the file extension "F90" is used because GFortran pre-process Fortran files with such extension. You can add "-cpp" compiler option to have the same effect.

Copy this code to the created file:

! Defines string-integer map: ftlHashMapStringInt
#define FTL_TEMPLATE_KEYTYPE_IS_FTLSTRING
#define FTL_TEMPLATE_KEYTYPE_NAME String
#define FTL_TEMPLATE_TYPE integer
#define FTL_TEMPLATE_TYPE_NAME Int
#define FTL_INSTANTIATE_TEMPLATE
#include <ftlHashMap.F90_template>

Copy code to the main.f90:

program hello
    use ftlStringModule
    use ftlHashMapStringIntModule
    implicit none

    type(ftlHashMapStringInt) :: dist
    integer :: d1
    type(ftlString) :: city, dstr

    ! Create map.
    call dist%New(10)
    ! Add some values to the map.
    call dist%Set('London', 1020)
    call dist%Set('New York', 6380)
    call dist%Set('Paris', 850)
    call dist%Set('Tokyo', 8900)

    ! Find some values in the map.
    d1 = dist%Get('Paris')
    call  dstr%New(d1)
    print *, 'Paris is ', dstr, 'km away.'

    city = 'Beijing'
    if (.not. dist%Has(city)) then
        print *, "I don't know distance to Beijing."
    else
        print *, 'How can that be?'
    end if
end program

If you will try to compile the project, you will get one or more error. We need to define in the C::B where the FTL can be found.

In the project build options dialog (Menu->Project->Build options…) add:

  • a search directory for the compiler ("your_ftl_install_dir"/include/ftl);

  • a search directory for the linker ("your_ftl_install_dir"/lib);

  • a link library "ftl" (actual file is "libftl.so").

/images/ftl_build_options_compiler_search_dir.png /images/ftl_build_options_linker_search_dir.png /images/ftl_build_options_link_lib.png

Try to compile the project. Depending on the moon phase, you may succeed. I am joking of course. The problem is that "main.f90" depends on "stringIntegerMap.F90" but the C::B doesn't know it. Yet.

Setup of Code::Blocks parser for FTL

If you try to edit the code "main.f90", you will not get the code-completion list for the FTL entities. It is the same problem as with the project compilation: C::B doesn't know where to find "ftlHashMap.F90_template" and "ftlString.F90" files.

To solve it, open the "Project/targets options" dialog (Menu->Project->Properties), "Fortran" tab. Add a file "'ftl-master'/src/ftlString.F90" to the list of additional files to be parsed. We need this because we use "ftlString" in the code above. Add "'ftl-install-dir'/include/ftl" to the list of additional directories to be searched for include files during the parsing. This directory contains "ftlHashMap.F90_template" and other template files.

/images/ftl_project_fortran_options.png

After closing the dialog, the project is reparsed and you can compile the project and get a code-completion list when you edit your code.

/images/ftl_codecompletion.png

When you start your compiled program from the inside of C::B, you should see an expected output. However, when you try to start your program outside of C::B, you will get an error message complaining that "libftl.so" ("libftl.dll" on Windows) is not found. It is because your OS does not know where to find "libftl.so". The problem can be solved by setting the LD_LIBRARY_PATH environment variable on Linux or the PATH environment variable on Windows to point to "your_ftl_install_dir/lib".