I am encountering a problem when I include a Fortran subroutine in a shared library. This subroutine has a named common block.
I have a Fortran main program that uses this common block and links with the shared library.
The behavior is that variables in the common block set in either the subroutine or main program are not shared between the two.
I am using gfortran 4.9.3 under MinGW on windows. Here are the pieces of my very simple example.
Main program:
program mainp
common/whgc/ivar
ivar = 23
call sharedf
end
Subroutine:
subroutine sharedf
common/whgc/ivar
print *, 'ivar=', ivar
end
Makefile:
FC = gfortran
FFLAGS=-g
all: shltest.dll mainp.exe
shltest.dll: sharedf.o
$(FC) -shared -o shltest.dll sharedf.o
mainp.exe: mainp.o shltest.dll
$(FC) -o mainp.exe mainp.o shltest.dll
clean:
rm *.o mainp.exe shltest.dll
When mainp.exe
is run, it produces ivar = 0
instead of the correct ivar=23
Here are the results of some experimentation I did with nm
.
nm -g mainp.o shows:
...
00000004 C _whgc_
nm on sharedf.o shows the same.
nm -g shltest.dll shows:
...
71446410 B _whgc_
nm -g mainp.exe shows:
...
00406430 B _whgc_
This is the only _whgc_
symbol in mainp.exe.
However, when I run mainp.exe
in gdb and set break points in both
mainp
and sharedf
, I can print the address of ivar
at each break point. The addresses
are not the same.
From the behavior it seems clear that GNU ld is not correctly
matching the _whgc_
symbols but I'm unclear about what options
to pass either in the shared library build or the final link to
make it do so?
(Please don't suggest alternatives to common blocks. In my real application I am dealing with legacy code that uses common blocks.)
EDIT:
I tried my example on Linux/x86 and there the behavior is correct. Of course on Linux the shared library and executable are ELF format objects and on Windows/MinGW the format is PE/COFF.