Building a FORTRAN DLL - dll

I want to create a dll from following fortran77 code by using g77 compiler in Windows.
sample FORTRAN code
test.f
SUBROUTINE fsub (x)
INTEGER*4 x
x = x + 1
END
INTEGER*2 FUNCTION ffunc (y)
INTEGER*2 y
ffunc = y + 1
END
SUBROUTINE fstring (fstr)
CHARACTER*20 fstr
fstr = 'Jack Be Nimble'
END
I have used the following command
g77 -fno-f2c -shared -s -o test.dll test.f
but it gives an error saying
g77: unrecognized option `-shared'
..\lib\gcc-lib\i386-mingw32\2.95\..\..\..\libg2c.a(main.o)(.text+0x38): undefined
reference to 'MAIN__'
Alternatively I downloaded Mingw and tried to do the same using gfortran.exe
gfortran.exe -fno-f2c -shared -s -o test.dll test.f
Successfully created the test.dll.
My requirement is to create the dll using g77 but i am getting this "unrecognized option `-shared'"
Please help.

Related

error when calling subroutine from module in fortran [duplicate]

I am trying to compile some really old code (1986 and before). This code references an external function. Today's compilers ask for far more code to make this work. And I keep failing.
I now created a small hello world program, which demonstrates the problem.
hello.for
PROGRAM hello
USE func
PRINT *, "Hello World!"
PRINT *, f ()
END PROGRAM hello
func.for
MODULE func
PUBLIC f
CONTAINS
FUNCTION f ()
f='Hello Func'
END FUNCTION
END MODULE
This has not only one, but two problems:
How do I define the return type? Docs tell <type> FUNCTION <function> or FUNCTION <function> () <type>::<something> , but neither works.
How do I make the linker find the function?
gfortran -c func.for works (if I use the default return type real) and creates a mod file but linking does not work
$ gfortran hello.for
/tmp/ccHNzcXA.o: In function `MAIN__':
hello.for:(.text+0xa4): undefined reference to `__func_MOD_f'
collect2: error: ld returned 1 exit status
__func_MOD_f is not contained in the mod file, but in the o file there is func.for__func_MOD_f.
Any idea?
thanks
You have two issues, the delcaration of f and properly linking the module.
First, compiling the module yields the error:
% gfortran -c func.f
func.f:5:8:
f='Hello Func'
1
Error: Can't convert CHARACTER(1) to REAL(4) at (1)
This error is due to implicit typing of f and an incompatible assignment. Fixing this is simple, declare f explicitly as a character instead of an implicit type. Add:
character(len=30) :: f
to the function and now your module compiles. Here is the modified module:
MODULE func
PUBLIC f
CONTAINS
FUNCTION f ()
character(len=30) :: f
f='Hello Func'
END FUNCTION
END MODULE
Your second problem is linking. Your command:
gfortran hello.for
fails because you did not specify the module object. If you already compiled the module you would specify:
gfortran hello.for func.o
if you were compiling them both at the same time you would do:
gfortran -o hworld func.for hello.for
if you are compiling everything individually:
gfortran -c func.for
gfortran -c hello.for
gfortran -o hworld hello.o func.o
Any of these will compile and run:
% ./hworld
Hello World!
Hello Func
If you are modernizing your code, it would also be worth adding implicit none to avoid any implicit typing and declaring explicit variables for everything. e.g.:
module func
implicit none
contains
function f
implicit none
character(len=30) :: f
f='Hello Func'
end function f
end module func
and
program hello
use func
implicit none
print *, "Hello World!"
print *, f ()
end program hello

Postgresql 12 command line arguments initdb via Python 3 code, how to proceed?

Using Python 3.8.1 code, I unzipped the distribution of postgresql12 in a specific folder of root C, inside the code it creates two other folders, data and log. In the code I write the following line to set up a first database:
subP = subprocess.run([link_initdb, "-U NewDataBase", "-A AlphaBeta", "-E utf8", "-D C:\\Database\\pgsql\\data"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
But I get the following error message:
ubP.stderr: initdb: error: could not create directory " C:": Invalid argument
I don't know what I'm wrong!
For whatever reason there should be no space between -D and the filename.
To solve it you can use:
subP = subprocess.run([
link_initdb,
"-U postgres",
"-A password",
"-E utf8",
"--pgdata=C:\Database\pgsql\data",
],
shell=True,
)

gfortran, DLL and nothing making sense (or working) at all [duplicate]

This question already has answers here:
Fortran functions returning unexpected types and values
(3 answers)
Closed 2 years ago.
I have the following short piece of code in Fortran, which I named myDLL.f90:
Real(Kind=8) Function mySinCos(x,y)
Real(Kind=8), Intent(In) :: x, y
mySinCos = Sin(x)*Cos(y)
End Function mySinCos
Real(Kind=8) Function myPiSinCos(x,y)
Real(Kind=8), Intent(In) :: x, y
Real(Kind=8), Parameter :: Pi = 4.0d0*Datan(1.0d0)
myPiSinCos = Sin(Pi*x)*Cos(Pi*y)
End Function myPiSinCos
And the following main program TestDLL.f90:
Program TestDLL
Real(Kind=8) :: x, y
Real(Kind=8) :: a, b
x = 2.0d-01
y = 9.0d-01
a = mySinCos(x,y) !Should be 0.12349483641187213
b = myPiSinCos(x,y) !Should be -0.5590169943749475
Write(*,*) a
Write(*,*) b
End Program TestDLL
I compiled and linked the above sources with:
gfortran -shared -fPIC -o myDLL.dll myDLL.f90
gfortran -o a.exe TestDLL.f90 -L. myDLL.dll
No compilation/linkedition errors and a.exe runs without error messages. What it produces is:
6.0000000000000000
6.0000000000000000
Which obviously aren't the expected results as sin(...)*cos(...) must never be > 0.5 (or < -0.5), let alone 6.0000[...].
In a nutshell: compiled well, linked well, executed well and produced garbage.
Changing either x or y doesn't change the results. They're always 6.0000[...].
What went wrong? The example above doesn't differ a lot from other simple examples I've found in the internet.
I'm using GNU Fortran (MinGW.org GCC Build-20200227-1) 9.2.0, Windows 10 64-bit.
It works fine if I turn the two functions into a module:
Module myDLL
Implicit None
Contains
... The two original functions are inserted here ...
End Module myDLL
and import/use the module in the main program:
Program TestDLL
Use myDLL
Implicit None
... Other commands are inserted here ...
End Program TestDLL
Then, and only then, the correct results are spit.

Confusion with Fortran submodules and gcc compliation flag -Wuse-without-only

What is the remedy for this gcc Fortran compilation warning?
USE statement at (1) has no ONLY qualifier
The warning occurs when using submodules in gcc 6.0, 6.1, 6.2, and, 7.0.
The full compilation sequence and warning:
$ gfortran -c -Wuse-without-only -o mod_module.o mod_module.f08
$ gfortran -c -Wuse-without-only -o mod_module_sub.o mod_module_sub.f08
mod_module_sub.f08:1:19:
submodule ( mModule ) mSubModule
1
Warning: USE statement at (1) has no ONLY qualifier [-Wuse-without-only]
$ gfortran -c -Wuse-without-only -o demonstration.o demonstration.f08
$ gfortran -o demonstration demonstration.o mod_module.o mod_module_sub.o
$ ./demonstration
this + that = 3.00000000
expected value is 3
Main program (demonstration.f08):
program demonstration
use mModule, only : myType
implicit none
type ( myType ) :: example
example % this = 1.0
example % that = 2.0
call example % adder ( )
write ( *, * ) 'this + that = ', example % other
write ( *, * ) 'expected value is 3'
stop
end program demonstration
Module (mod_module.f08):
module mModule
implicit none
type :: myType
real :: this, that, other
contains
private
procedure, public :: adder => adder_sub
end type myType
private :: adder_sub
interface
module subroutine adder_sub ( me )
class ( myType ), target :: me
end subroutine adder_sub
end interface
end module mModule
Submodule (mod_module_sub.f08):
submodule ( mModule ) mSubModule ! <=== problematic statement
implicit none
contains
module subroutine adder_sub ( me )
class ( myType ), target :: me
me % other = me % this + me % that
end subroutine adder_sub
end submodule mSubModule
That is, what is the proper way to specify submodules? The flag -Wuse-without-only is essential in compilation of longer codes.
Depending on your perspective, it is just a compiler bug. File a bug report and wait for it to get fixed (or fix it yourself).
(An alternative perspective is that because that code gives submodules access to all the entities of their host, whether required or not, the warning is appropriate. But limiting host association requires F2015 support.)
-Wuse-without-only is just a warning to help enforce a particular programming style (one that I don't think is particularly useful). It cannot be "essential" to compile any code, short or long. If the warning bothers you in the meantime, remove that option.

ifort -coarray=shared produces incorrect exit status

If I compile and run
! main.f90
print*, 1/0
end program
with ifort then I get a division by zero error with an exit status of 2 (echo $?), as expected. However, If I compile using ifort -coarray=shared then I still get the error but now the exit status is 0. The problem is that CTest is unable to catch the error. This is my CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(testing Fortran)
enable_testing()
add_executable(main EXCLUDE_FROM_ALL main.f90)
add_test(main main)
add_custom_target(check COMMAND ctest DEPENDS main)
If I run make check then the output is
100% tests passed, 0 tests failed out of 1
even though the test actually failed. If I remove -coarray=shared or use gfortran then I get the correct output
0% tests passed, 1 tests failed out of 1
How can I make CTest report that the test failed? Am I doing something wrong or is this a compiler bug?
I'm testing with ifort 14.0.1 with the example code
program test
implicit none
print *, 1/0
end program
I can't quite replicate your initial return value of 3. In my testing the result of echo $? is 71, which correlates to the message thrown from the runtime error (note: gfortran won't even compile the example):
forrtl: severe (71): integer divide by zero
I am however replicating your return code of 0 from the coarray version. What is happening here is a bit more complicated, as ifort implements coarrays through MPI calls and for -coarray=shared basically wraps your program in a wrapper so you do not have to call mpirun, mpiexec or have to run intel's mpd to handle MPI communications. It is clear that the coarray images (MPI ranks) are all returning with error code 3:
application called MPI_Abort(comm=0x84000000, 3) - process 4
and
exit status of rank 1: return code 3
is emitted by each MPI rank, but the executable itself always returns with exit code 0. Whether this is the intended behavior or a bug is not clear to me, but it seems likely that the wrapper code to launch the MPI processes doesn't look at the MPI return codes from each rank. As pointed out in the comments, how would we expect different return values from different mpi ranks to be handled? It doesn't seem you are doing anything wrong.
Contrast this with a normal MPI example:
program mpitest
use mpi
implicit none
integer :: rank, msize, merror, mstatus(MPI_STATUS_SIZE)
call MPI_INIT(merror)
call MPI_COMM_SIZE(MPI_COMM_WORLD, msize, merror)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, merror)
print *, 1/0
call MPI_FINALIZE(merror)
end program
compiled with
mpiifort -o testmpi testmpi.f90
and run as (with mpd running):
mpirun -np 4 ./testmpi
This produced a severe runtime error 71 for integer divide by zero for each rank as before, but the error code is propagated back to the shell:
$ echo $?
71