Intel Fortran with Visual Studio integration makes it easy to create and consume static libraries. Static libraries are shared components that compile to LIB files which in turn link into DLLs and EXEs.
Static libraries have several benefits:
- Unit Testing Static libraries enable unit testing. The static library makes it easy to create a unit test project that tests the static library in isolation. The unit test project is typically a console application. This pattern is also common in C++.
- Internal Code Reuse Code that is shared among multiple DLLs within a solution can be collocated in a static library.
- External Code Reuse Static libraries can also be used to publish code for use by 3rd parties. This use case is more complicated since certain compiler options can cause binary incompatibilities such as the choice run-time library. This use case is not covered in this post.
- Organization Splitting up a large project into several static libraries makes the application easier to understand and maintain.
The the example below shows how to compile a static libraries into a Fortran console application.
The solution has two projects: the “Calculator” static library and the main console application that calls the Calculator.
The static library has a single module with some advanced numerical computation routines. The
Subtract subroutine has the
bind(c) attribute. This will affect how the compiler exports the name of the function in the LIB.
module Calculator implicit none contains function Add(x, y) result(z) real(8) :: z real(8), intent(in) :: x, y z = x + y end function function Subtract(x, y) result(z) bind(c) real(8) :: z real(8), intent(in) :: x, y z = x - y end function end module
After you compile the LIB file, you can use DUMPBIN to inspect how the functions are being exposed. This is important when using LIB files from 3rd parties. DUMPBIN is a command line utility for inspecting binaries. The easiest way to run DUMPBIN is to open the Visual Studio command prompt from the Start Menu (or a shortcut) and
cd to the target directory.
(If the project does not compile a LIB file, try putting a module-less subroutine that calls a library routine. I’ve occasionally seen this behavior when starting a new project. Once the LIB compiles, you can get rid of the dummy subroutine.)
For this application use
dumpbin /symbols to show the exported symbols. The
Subtract symbols are highlighted in the figure below. The
Add method is exported as
_CALCULATOR_mp_ADD where mp = ‘module procedure’. This is the typical Fortran name mangling convention. The
Subtract method is exported using the C convention,
bind(c) was used. This means that the
Subtract method can be linked into a C or C++ application.
Link the Static Library
Linking the static library to the calling application is very easy using the Visual Studio integration.
First, add the calling application project. In this sample we use a console application shown below. The
Main subroutine references the Calculator module from the static library.
program Main use Calculator implicit none real(8) :: x, y x = 1.0 y = 2.0 print *, 'Add', Add(x, y) print *, 'Sub', Subtract(x, y) end program
To link the static library, right-click on the calling project and select Project Dependencies. Select “Calculator” as a dependency of the “Program” application and click OK. Build the solution, and your are done.
When interfacing with 3rd party LIB files (w/out source code), you will need to point the compiler to the path of the LIB files using the following linker options. If the static library uses modules, you will also need to point the compiler to the module (*.mod) binaries. Things get more complicated when dealing with Debug and Release modes and 32- and 64-bit configurations.
- Fortran | General | Additional Include Directories (for modules)
- Linker | General | Additional Library Directories
- Linker | Input | Additional Dependencies
But if you have access to the source code to compile the LIB internally, the Visual Studio integration takes care of all this.
The link below contains sample code using Visual Studio 2010 and Intel Fortran.