Fortran .mod file doesn't update when compiling [duplicate] - module

I am working with GFortran and CodeBlocks but I'm having an issue about Modules and Multiple files.
i keep getting this error:
Fatal Error: Can't open module file 'mesh.mod' for reading at (1): No such file or directory
For some reason, GFortran is not building the 'mesh.mod' file.
This problem does not occur when I put all the code in a single .f90 file.
Bellow is an example of code that this error happens.
main.f90
MODULE MESH
IMPLICIT NONE
INTEGER :: IMAX,JMAX,NMAX
REAL(8), ALLOCATABLE :: XD(:),YD(:),FX(:,:),FY(:,:)
REAL(8) :: PI,E,DX,DY,H,L,RHO,MU
PARAMETER (PI = ACOS(-1.D0))
PARAMETER (E = 2.718)
END MODULE MESH
!**************************************************************
program Cavity
Use Mesh
implicit none
Real(8), Allocatable :: func(:)
Real(8) :: Der,DfDx
integer :: i
IMAX=10
DX=1./10
Allocate(xd(IMAX),func(IMAX))
Do i=1,IMAX
xd(i)=i*DX
End Do
Do i=1,IMAX
func(i) = xd(i)**2
End Do
Der=Dfdx(func,2)
Write(*,*) Der
End program Cavity
Derivatives.f90
Real(8) Function DfDx(f,i)
Use Mesh
implicit none
Real(8) :: f(1:Imax)
integer :: i
DfDx=(f(i+1)-f(i-1))/(2d0*dx)
return
end function DfDx
When I use console command line compilation instead of CodeBlocks interface I already solved this problem (Compiling Multiple Files with modules) but I'm still getting this problem with CodeBlocks.
Does anyone know how to solve this issue?

Assuming what you have written is how your code is, then it appears that the problem is that the module mesh is inside the main program and not a separate file. You should have three files: Mesh.f90, Derivatives.f90 and Main.f90.
Mesh.f90 is exactly as you have it,
module Mesh
implicit none
integer :: IMAX,JMAX,NMAX
real(8), allocatable :: XD(:),YD(:),FX(:,:),FY(:,:)
real(8) :: PI,E,DX,DY,H,L,RHO,MU
parameter (PI = ACOS(-1.D0))
parameter (E = 2.718)
end module Mesh
Derivatives.f90 should be written as another module, using contains:
module Derivatives
use mesh
contains
real(8) function dfdx(f,i)
real(8) :: f(i:imax)
integer :: i
DfDx=(f(i+1)-f(i-1))/(2d0*dx)
end function dfdx
end module Derivatives
and the Main.f90 will then use both modules. Note that I had to eliminate the variable DfDx; this is because it conflicts with the function DfDx in module Derivatives
program Cavity
Use Mesh
use Derivatives
implicit none
Real(8), Allocatable :: func(:)
Real(8) :: Der
integer :: i
IMAX=10
DX=1./10
Allocate(xd(IMAX),func(IMAX))
Do i=1,IMAX
xd(i)=i*DX
End Do
Do i=1,IMAX
func(i) = xd(i)**2
End Do
Der=Dfdx(func,2)
Write(*,*) Der
End program Cavity
I do not know how CodeBlocks works, but I would presume it lets you choose the compilation order. If that is the case, you should compile Mesh.f90 first, then Derivatives.f90, then compile Main.f90 before linking them to an executable.
When I compiled & linked them, I got an answer of 0.200000002980232; hopefully that links up to what you have as well.

On codeblock, you may go to Project properties > Build targets
Then select the file you want to build first (say mod.f90).
In the "Selected file properties" go to "Build"
Here,change the priority weight. Lower weight implies the file will be built first.

The problem is that in CodeBlocks "projects are built in the order of appearence, from top to bottom" (CodeBlocks Wiki), in other words, the files are compiled alphabetically.
Which means that in my case, Derivatives.f90 was being compiled before than Main.f90 causing the error.
A way to circumvent the problem is to set only the Main.f90 file as build target in CodeBlocks:
Menu Project/Properties...
In Build Target Files at the tab Build targets check only Main.f90
And use the command Include 'File_Name.f90' inside the Main.f90 code to include the other f90 files for compilation in the right order.

Related

I use Simply Fortran, but cannot include modules there [duplicate]

This question already has an answer here:
The mysterious nature of Fortran 90 modules
(1 answer)
Closed 2 years ago.
I have written the following Fortran Code in the System called "Simply Fortran":
program math2
use prec, only: print_kind_info
implicit none
call print_kind_info
end program math2
module prec
implicit none
integer, parameter :: dp = selected_real_kind(P=10,R=30)
integer, parameter :: sp = selected_real_kind(P=5,R=15)
integer, parameter :: dp_alt = kind(0.d0)
public :: dp, sp, print_kind_info
private
contains
! Subroutine comes here
subroutine print_kind_info()
real(sp) :: sing_prec
real(dp) :: double_prec
print*,'Single precision is kind ',sp
print*,'Double precision is kind ',dp
print*,'Kind of double precision number is ',dp_alt
end subroutine print_kind_info
end module prec
However, the module which I call 'prec' is not found. More precisely, the error message is the following:
use prec, only: print_kind_info
1
Fatal Error: Can't open module file 'prec.mod' for reading at (1): No such file or directory
compilation terminated.
Error(E42): Last command making (build\prec.o) returned a bad status
Error(E02): Make execution terminated
* Failed *
What I have to do that the module (see above code) is recognized properly? It is recognized in File Outline, but it is not inside the "module" folder. And I really don't have a plan here what to do. Moreover I have no experience with the Makefile environment (this BASHrc-like things I am not familar with).
Simply said: The problem is that the compiler doesn't know the module prec.mod at is defined after the main program but is used already in the main program.
So first define the module and after that the main program.
Better would be to place the module in a separate files and the main program in another file and compile these (in the right order) and link everything together.

how to call dll in fortran

I have one dll file which contains a function "ProcessWeather" and want to call this function in a fortran code, as shown below:
PROGRAM myprog
!DEC$ ATTRIBUTES DLLIMPORT :: EPLUSWTH
INTERFACE
SUBROUTINE ProcessWeather(InType,OutType,InFileName,OutFileName,ErrFlag)
CHARACTER(len=*), INTENT(IN) :: InType ! InputFile Type
CHARACTER(len=*), INTENT(IN) :: OutType ! OutputFile Type
CHARACTER(len=*), INTENT(IN) :: InFileName ! InputFile Name (Full path)
CHARACTER(len=*), INTENT(IN) :: OutFileName ! OutputFileName (Full path)
REAL(4), INTENT(OUT) :: ErrFlag ! If errors are found,
! set to true and put
! description put in file.
END SUBROUTINE
END INTERFACE
END PROGRAM
The dll file is put to the same place where I put the fortran file to.
When I compile the fortran code, I got the following error:
undefined reference to processweather_
Any suggestion will be highly appreciated.
If you are compiling with gfortran (as your comment seem to suggest) the !$DEC directives will be ignored. But you could use the GCC directives, namely the ATTRIBUTES directive and declare the attribute DLLIMPORT in it.
You could also just use the standard bind(C, name="the_name"). Also, as far as I remember, GCC did not require any attributes to make symbols externally visible when creating a DLL.

Case sensitiveness issue when calling an external DLL in Fortran and compiling with gfortran

I'm trying to call a DLL from a Fortran code compiled with gfortran. I'm importing DISCON_32.dll with:
!GCC$ ATTRIBUTES DLLIMPORT :: DISCON
and compiling with:
mingw32-gfortran "DISCON_32.dll" -cpp -ffree-line-length-none -fno-automatic -Wall -fdefault-real-8 -fno-underscoring -static BladedDLLInterface.o -o "my_program"
I get the error:
BladedDLLInterface.o:BladedDLLInterface.f90(.text+0x6cd): undefined reference to 'discon'
Note that entry point "discon" is here called as lowercase. When looking into the DLL with Dependency Walker, entry point is "DISCON" (uppercase).
I cannot change the case of the DLL. Is there a way to tell my Fortran code to look for "DISCON" entry point instead of "discon"?
(My extended googling of the question did not get me closer to a solution)
There are 3 ways to do this: let's make an example DLL and Fortran main to demonstrate the problem.
! dll1.f90
! gfortran dll1.f90 -shared -odll1.dll -Wl,--out-implib,libdll1.a
module not_used
use ISO_C_BINDING
implicit none
contains
function F(x) bind(C,name='F')
!GCC$ ATTRIBUTES DLLEXPORT :: F
real(C_DOUBLE) F
real(C_DOUBLE), intent(in) ::x
F = x**2
end function F
end module not_used
The command line use to build dll1.dll is shown in the comments.
Now we have a Fortran main:
! main1.f90
! fails:
! gfortran main1.f90 dll1.dll -omain1
! gfortran main1.f90 -L. -ldll1 -omain1
! works:
! gfortran main1.f90 dll1.dll -L. -ldll2 -omain1
! gfortran main1.f90 -L. -ldll1 -ldll2 -omain1
module mod1
implicit none
interface
function F(x)
import
implicit none
!GCC$ ATTRIBUTES DLLIMPORT :: F
double precision F
double precision, intent(in) :: x
end function F
end interface
end module mod1
program main1
use mod1
implicit none
double precision x, y
x = 13
y = f(x)
write(*,*) y
end program main1
The first two gfortran commands shown above fail to build main1.exe. The second two work, but we need a libdll2.a file, and we can create it with dlltool.exe. We start with dll2.def
; dlltool -z dll2.def --export-all-symbol dll1.dll
; dlltool -d dll2.def -l libdll2.a
LIBRARY dll1.dll
EXPORTS
f = F
The first comment line above shows how to dlltool.exe to create a starting point for dll2.def. The output is not very useful in our case, so mostly we used a text editor to modify the starting point. The dll2.def file will create a libdll2.a file that is usefule for linking with dll1.dll, thus the LIBRARY line above. The symbol that got exported was 'F', but gfortran is going to look for 'f', so we rename it in the exports section.
Then we use dlltool.exe to create libdll2.a via the second comment line above. Having a libdll2.a means we can compile main1.f90 according to the comments in lines 6 or 7.
The second method uses a binding name for the function. This requires the function to be interoperable, but if it isn't then you probably couldn't invoke it in any simple way given that it probably wasn't compiled by gfortran. Here we don't need an extra dll2.lib, just a different declaration of the function in main2.f90:
! main2.f90
! gfortran main2.f90 dll1.dll -omain2
! gfortran main2.f90 -L. -ldll1 -omain2
module mod2
use ISO_C_BINDING
implicit none
interface
function F(x) bind(C,name='F')
import
implicit none
!GCC$ ATTRIBUTES DLLIMPORT :: F
real(C_DOUBLE) F
real(C_DOUBLE), intent(in) :: x
end function F
end interface
end module mod2
program main2
use mod2
implicit none
double precision x, y
x = 13
y = f(x)
write(*,*) y
end program main2
This compiles with either of the gfortran commands given in the comments.
Finally you could use dynamic linking as in main3.f90:
! main3.f90
! gfortran main3.f90 dll1.dll -omain3
! gfortran main3.f90 -L. -ldll1 -omain3
module mod3
use ISO_C_BINDING
use ISO_C_BINDING, HANDLE => C_INTPTR_T
use ISO_C_BINDING, C_INTPTR_T => C_INTPTR_T
implicit none
abstract interface
function F(x) bind(C)
import
implicit none
real(C_DOUBLE) F
real(C_DOUBLE), intent(in) :: x
end function F
end interface
interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')
import
implicit none
!GCC$ ATTRIBUTES STDCALL :: LoadLibrary
integer(HANDLE) :: LoadLibrary
character(kind=C_CHAR) lpFIleName(*)
end function LoadLibrary
function GetProcAddress(hModule,lpProcName) bind(C,name='GetProcAddress')
import
implicit none
!GCC$ ATTRIBUTES STDCALL :: GetProcAddress
type(C_FUNPTR) GetProcAddress
integer(HANDLE), value :: hModule
character(kind=C_CHAR) lpProcName(*)
end function GetProcAddress
end interface
end module mod3
program main3
use mod3, F1 => F
implicit none
double precision x, y
type(C_FUNPTR) ptr
procedure(F1), pointer :: F
integer(HANDLE) hModule
hModule = LoadLibrary('dll1.dll'//C_NULL_CHAR)
ptr = GetProcAddress(hModule,'F'//C_NULL_CHAR)
call C_F_PROCPOINTER(ptr,F)
x = 13
y = f(x)
write(*,*) y
end program main3
Either of the gfortran commands in the comments successfully builds main3.exe.
Note: on retesting, the main2.f90 and main3.f90 methods worked, but for some reason the method with main1.f90 and dll2.def no longer works, failing at runtime because it's trying to find the symbol 'f' in main1.exe rather than dll1.dll. Can't figure out why at this point.
EDIT: Well, I found a way to make the first approach work with the dll1.dll created above and the main1.f90 as it is, but I don't really like it so I'll wait a few days to see if someone else comes up with a more palatable solution. If, after that time, this hasn't happened and someone is still interested, he should remind me and I may post what I came up with.

object oriented features with Solaris/Oracle Fortran compiler

I have been trying to compile an O-O fortran code with the fortran compiler of the Oracle Solaris Studio 12.4 suite (the latest as far as I know). But the compiler crashes. Here is a simplified version of my problem.
I define two simple types with one type-bound procedure each. One of the procedures has a variable of the other type as dummy argument:
MODULE MY_MODULE
type type0
real :: value = 0
contains
procedure :: print_value
end type type0
type type1
real :: value = 0
contains
procedure :: print_diff
end type type1
CONTAINS
subroutine print_value(self)
class(type0), intent(in) :: self
print*, self%value
end subroutine print_value
subroutine print_diff(self,var0)
class(type1), intent(in) :: self
type(type0), intent(in) :: var0
print*,self%value - var0%value
end subroutine print_diff
END MODULE MY_MODULE
PROGRAM MY_PROG
use my_module, only: type0,type1
type(type0) :: var0
type(type1) :: var1
var0%value = 3
var1%value = 10
call var1%print_diff(var0)
END PROGRAM MY_PROG
This program compiles and executes fine with gfortran:
[> gfortran myprog.f03 -o myprog.x
[> ./myprog.x
7.0
However, compilation with the Solaris f95 crashes:
[> f95 myprog.f03 -o myprog.x
f90: Internal Error, code=fw-interface-ctyp1-796, last src=myprog.f03:4
If I do any further simplification to the source code, then f95 compiles successfully. For instance, it works fine if:
type0 has no type-bound procedure
type1 has no type-bound procedure
procedure print_diff is replaced by a subroutine with no other argument than self
Is there anything I am doing wrong?
Is there an installation problem with my Solaris compiler? Is someone able to compile this code successfully with an other Solaris compiler?
Does someone know what the error code means (I haven't been able to find that out)?
After reporting my problem to Oracle, I just got their answer:
Thank you for reporting this and sorry for the problem. This is a known problem. It has already been fixed in our current development and ported to Studio 12.4. If you have a support contract, you can get the Studio 12.4 patch for it, otherwise the next release will contain the fix.

Preprocessors and use association

In summary, is it possible to access via use association a preprocessor directive defined in a Fortran module?
Context
I use preprocessor statements to define subroutines to print warning and error messages. For example, I use the following module/subroutine, in the file errors.f, to print warning messages
module errors
use, intrinsic :: iso_fortran_env, only : error_unit=>stderr
implicit none
contains
!> Print formatted warning message.
subroutine warn_print( file, line, mesg )
implicit none
character(len=*), intent(in) :: file
integer, intent(in) :: line
character(len=*), intent(in) :: mesg
write(stderr,'(a,a,a,i4,a,a)') "WARNING::", file, ":", line, ": ", mesg
end subroutine warn_print
end module errors
and, in a separate file errors.h, I use the above module and define a preprocessor macro
use errors
#define warn( text )warn_print(__FILE__,__LINE__,text)
I then #include the file errors.h in whichever file/module I wish to use the warning print routine which allows me to simply write
call warn("Some warning message")
and the compiler will automatically include the file and line number at which the warning message was called.
Question
The use of #include 'errors.h' is rather idiosyncratic in Fortran code and it hides the use of the errors module. Ideally I would prefer to define the above preprocessor in the errors module itself. However, then when using that module, this preprocessor directive is not available to the program/module which uses this module.
Is there a way to make a preprocessor directive accessible via use association?
The only other way I can think of doing it is to just have the errors module and define the preprocessor directive in my call to the compiler (using, for example, the -D flag with ifort). Any suggestions for any alternative way of achieving the above would be greatly appreciated.
No, it is simply not possible, since the preprocessing and the compilation stages are completely separate one from each other and the C preprocessor does not know anything about the Fortran USE statement.
I use to #include 'config.h' (from autoconf) in most of my .F90 sources, without problems.
This may not be what you are looking for, but if you are using ifort, you can use traceback functionality to achieve something similar (a bit more powerful, but also more ugly), e.g.
program tracetest
call sub(5)
write(*,*) '=== DONE ==='
end program tracetest
subroutine sub(n)
use ifcore
integer :: n
character(len=60) :: str
write(str,*) '=== TROUBLE DETECTED: n =',n ! code -1 means "do not abort"
call tracebackqq(str,-1)
end subroutine sub
Then, compile with -traceback to see the source file, line, and stack trace. The stack trace and line may be obscured because of inlining; to avoid that, you can specify -traceback -O0 to get smth like this:
=== TROUBLE DETECTED: n = 5
Image PC Routine Line Source
a.out 0000000000473D0D Unknown Unknown Unknown
a.out 0000000000472815 Unknown Unknown Unknown
a.out 0000000000423260 Unknown Unknown Unknown
a.out 0000000000404BD6 Unknown Unknown Unknown
a.out 0000000000402C14 sub_ 12 tracetest.f90
a.out 0000000000402B18 MAIN__ 2 tracetest.f90
a.out 0000000000402ADC Unknown Unknown Unknown
libc.so.6 000000323201EC5D Unknown Unknown Unknown
a.out 00000000004029D9 Unknown Unknown Unknown
=== DONE ===
Alternatively, if want to keep the optimizations, and also want to see the correct line (12), you can compile with (for example) -fast -traceback -debug all,inline_debug_info. Something similar may be available in other compilers, but I am not sure.