[[PageOutline]] = FORTRAN applications = == F2X == One option is to use f2c to convert your FORTRAN program to C. M.F. Somers has created a [http://boinc.gorlaeus.net/F2c.php BOINC-enabled f2c library] that simplifies this process. == Windows: cygwin == Include the file 'boinc_api_fortran.C' in the api/Makefile.am, but comment out the 'zip' calls, to avoid the linking with 'libboinc_zip.a' To link it is necessary to include the 'winmm.dll' library (-lwinmm). == Windows: Visual Studio == === Wrapping FORTRAN in C++ main program === One approach is to have a C++ main program do all the interaction with BOINC, and call FORTRAN functions to do the work. An example of this from Paul Calvert is [http://boinc.berkeley.edu/for_win_build.zip here] and [http://boinc.berkeley.edu/fortran_app.zip here]. === Calling BOINC API from FORTRAN === Note: there is [/TestLibs.zip a working example] similar to the following (based on outdated BOINC code); see also its [/taufer.txt README]. Start by creating a new FORTRAN project. Add all the FORTRAN specific files, then add all the files needed for the BOINC library (e.g. `boinc_api.C`). Make sure that BOINC and the FORTRAN files are compiled using the same type of standard libraries. i.e. if the BOINC is compiled with the debug multithreaded DLL libraries, make sure the FORTRAN files are compiled with the DLL setting. For every BOINC function you want to call from Fortran you must add an interface and subroutine: {{{ INTERFACE SUBROUTINE boinc_finish(status) END SUBROUTINE boinc_finish END INTERFACE }}} Remember to declare the type of arguments. INTEGER status You must then tell the compiler that the function you are interfacing is a C routine. You do this by adding the statement: {{{ !DEC$ ATTRIBUTES C :: boinc_finish }}} The interface will end up looking like this: {{{ INTERFACE SUBROUTINE boinc_finish(status) !DEC$ ATTRIBUTES C :: boinc_finish INTEGER status END SUBROUTINE boinc_finish END INTERFACE }}} You can now call the BOINC function in FORTRAN. {{{ call boinc_finish(0) }}} == Intel FORTRAN compiler == `-ax` generate codes specialized for processors specified by `` while also generating generic IA-32 code. `` includes one or more of the following characters: K:: Intel Pentium III and compatible Intel processors W:: Intel Pentium 4 and compatible Intel processors N:: Intel Pentium 4 and compatible Intel processors. Enables new optimizations in addition to Intel processor-specific optimizations P:: Intel Core(TM) Duo processors, Intel Core(TM) Solo processors, Intel Pentium 4 and compatible Intel processors with Streaming SIMD Extensions 3 (SSE3) instruction support B:: Intel Pentium M and compatible Intel processors You should not use the `-x` options! == Instructions from Martin Korth == ''(can someone please integrate these with the above?)'' Under Linux: 1. Compile BOINC libs the standard way (you need `boinc.a`, `boinc_api.a`, and for graphics also `boinc_graphics_lib.a`). 2. Compile `boinc_api_fortran.o`. 3. Compile own graphics lib if needed. 4. Compile app files (for us: `ifort -O2 ...' and 'icc -O2 ...`). 5. Link application (for us: `ifort -static-libcxa ...`). Link with: `boinc_api_fortran.o`, `boinc.a`, `boinc_api.a`, `boinc_graphics_lib.a`, `C-(runtime)-libs` (`dl`, `nsl`, `gcc_s`, `stdc++`, `pthread`, `m`, `c`, ... - as they are not default for the Fortran compiler), and own graphics lib. Under Windows: 1. Compile BOINC libs the standard way (you need `libboinc.lib`, `libboincapi.lib`). 2. Compile `boinc_api_fortran.o` (at the moment I still use my old solution with an interface for every Fortran function). 3. Compile own graphics lib if needed. 4. Compile app files (for us: `ifort /nologo /MT /O2 ...` and `cl /nologo /MT /O2 ...`) - 'nmake' makes life easier ... 5. Link application (for us `ifort /nologo /MT ...`). Link with: `libboinc.lib`, `libboincapi.lib`, own graphics lib, `gdi32.lib` `user32.lib` `opengl32.lib` `glu32.lib` `advapi32.lib` `delayimp.lib` `freetype.lib` `glut32.lib` (you may need `/link /nodefaultlib:libc.lib`). == Instructions from Scott Kruger == Under Linux with ifort: boinc_api_fortran.C seems work just fine, except that a few modifications were needed to make it work for us. 1. Need to include "str_util.h" 2. Comment out '#include "boinc_zip.h"' 3. Comment out these functions: boinc_write_init_data_file, boinc_zip 4. Change the function boincrf_ to the following: {{{ void boincrf_(const char* s, char* t, int * s_len, int * t_len) { STRING_FROM_FORTRAN sff(s, *s_len); sff.strip_whitespace(); boinc_resolve_filename(sff.c_str(), t, *t_len); string_to_fortran(t, *t_len); } }}} Compile and include boinc_api_fortran.o when you link everything together. Under Windows with ifort: We were unable to get the either the INTERFACE or boinc_api_fortran.C approaches to work properly, so we settled on a combination of the two. boincrf_ is still useful because you are working with Fortran strings, so you'll still want to use boinc_api_fortran.C (we compiled it with libboincapi.lib). You will still need to change a few things around: 1. Visual Studio 2005 didn't like strlcpy somewhere in the BOINC API, so that had to be changed to strncpy (you might not have to do this if strlcpy works for you). 2. Make all the aforementioned changes to boinc_api_fortran.C except step 4 Also, you'll want to explicitly include Fortran INTERFACEs to your code. boincrf_ is especially tricky: {{{ INTERFACE SUBROUTINE boincrf_(s, t, s_len, t_len) !DEC$ ATTRIBUTES C :: boincrf_ CHARACTER* (*) s !DEC$ ATTRIBUTES REFERENCE :: s CHARACTER* (*) t !DEC$ ATTRIBUTES REFERENCE :: t INTEGER s_len INTEGER t_len END SUBROUTINE boincrf_ END INTERFACE }}} You'll have to include an interface for every BOINC function you want to call, but it isn't all that difficult for the others. == Example from David Braun == [attachment:fortran.tar.gz Example FORTRAN application]. Instructions: {{{ ../fortran/configure '--with-boinc=/usr/people/dbraun/src/boinc/build-5.9.3' \ '--with-boinc_src=/usr/people/dbraun/src/bo