Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Mac OS X, Problems passing COMMON with a shared library.

Michael_B_10
Beginner
740 Views

I have the program:

PROGRAM main
  USE GLOBAL
  IMPLICIT NONE
  CALL open_f()
  print*,'In test',flags(1), ACC_TRUNC_F
END

and I create a shared library that contains the GLOBAL module:

MODULE GLOBAL

  IMPLICIT NONE

  INTEGER :: flags(1)
!DEC$ATTRIBUTES DLLEXPORT :: /FLAGSN/
  COMMON /FLAGSN/ flags
  INTEGER :: ACC_TRUNC_F
  EQUIVALENCE(flags(1), ACC_TRUNC_F)
CONTAINS
  SUBROUTINE open_f()
    IMPLICIT NONE
    flags(1) = 99
    print*,'In F',flags(1), ACC_TRUNC_F
  END SUBROUTINE open_f

END MODULE GLOBAL

And when I run the program the values print correctly in the subroutine, but when I print it in the main program the values are zero:

 In F          99          99
 In test           0           0

I'm using intel 15 on Mac OS X 10.9. It works if I build a static library and it works building shared on Windows.

What I'm I missing?

Misc. information:

To compile the module

libtool: compile:  ifort -g -check all -I../../src -I../../fortran/src -c H5fortran_types.f90 -o H5fortran_types.o >/dev/null 2>&1
/bin/sh ../../libtool  --tag=FC   --mode=compile ifort -g -check all -I../../src -I../../fortran/src  -c -o H5f90global.lo  H5f90global.f90
libtool: compile:  ifort -g -check all -I../../src -I../../fortran/src -c H5f90global.f90  -o .libs/H5f90global.o
libtool: compile:  ifort -g -check all -I../../src -I../../fortran/src -c H5f90global.f90 -o H5f90global.o >/dev/null 2>&1

To make the library (ignore all the other files in the library (They were empty for the testing, it's part of a bigger program),

/bin/sh ../../libtool  --tag=FC   --mode=link ifort -g -check all -I../../src -I../../fortran/src  -version-info 6:205:0   -o libhdf5_fortran.la -rpath /Users/brtnfld/hdf5/trunk.min/hdf5/lib H5f90global.lo H5fortran_types.lo H5_ff_F90.lo H5_ff.lo H5Aff.lo H5Dff.lo H5Eff.lo H5Fff.lo H5Gff.lo H5Iff.lo H5Lff.lo H5Off.lo H5Pff.lo H5Rff.lo H5Sff.lo H5Tff.lo H5Zff.lo H5_DBLE_InterfaceInclude.lo H5f90kit.lo H5_f.lo H5Af.lo H5Df.lo H5Ef.lo H5Ff.lo H5Gf.lo H5If.lo H5Lf.lo H5Of.lo H5Pf.lo H5Rf.lo H5Sf.lo H5Tf.lo H5Zf.lo H5Aff_F90.lo H5Dff_F90.lo H5Eff_F90.lo H5Fff_F90.lo H5Lff_F90.lo H5Off_F90.lo H5Pff_F90.lo H5Rff_F90.lo H5Tff_F90.lo HDF5.lo ../../src/libhdf5.la -lz -ldl -lm
libtool: link: ifort -dynamiclib -undefined dynamic_lookup -o .libs/libhdf5_fortran.6.dylib  .libs/H5f90global.o .libs/H5fortran_types.o .libs/H5_ff_F90.o .libs/H5_ff.o .libs/H5Aff.o .libs/H5Dff.o .libs/H5Eff.o .libs/H5Fff.o .libs/H5Gff.o .libs/H5Iff.o .libs/H5Lff.o .libs/H5Off.o .libs/H5Pff.o .libs/H5Rff.o .libs/H5Sff.o .libs/H5Tff.o .libs/H5Zff.o .libs/H5_DBLE_InterfaceInclude.o .libs/H5f90kit.o .libs/H5_f.o .libs/H5Af.o .libs/H5Df.o .libs/H5Ef.o .libs/H5Ff.o .libs/H5Gf.o .libs/H5If.o .libs/H5Lf.o .libs/H5Of.o .libs/H5Pf.o .libs/H5Rf.o .libs/H5Sf.o .libs/H5Tf.o .libs/H5Zf.o .libs/H5Aff_F90.o .libs/H5Dff_F90.o .libs/H5Eff_F90.o .libs/H5Fff_F90.o .libs/H5Lff_F90.o .libs/H5Off_F90.o .libs/H5Pff_F90.o .libs/H5Rff_F90.o .libs/H5Tff_F90.o .libs/HDF5.o    ../../src/.libs/libhdf5.dylib -lz -ldl -lm    -install_name  /Users/brtnfld/hdf5/trunk.min/hdf5/lib/libhdf5_fortran.6.dylib -compatibility_version 7 -current_version 7.205 -single_module
libtool: link: (cd ".libs" && rm -f "libhdf5_fortran.dylib" && ln -s "libhdf5_fortran.6.dylib" "libhdf5_fortran.dylib")
libtool: link: ar cru .libs/libhdf5_fortran.a  H5f90global.o H5fortran_types.o H5_ff_F90.o H5_ff.o H5Aff.o H5Dff.o H5Eff.o H5Fff.o H5Gff.o H5Iff.o H5Lff.o H5Off.o H5Pff.o H5Rff.o H5Sff.o H5Tff.o H5Zff.o H5_DBLE_InterfaceInclude.o H5f90kit.o H5_f.o H5Af.o H5Df.o H5Ef.o H5Ff.o H5Gf.o H5If.o H5Lf.o H5Of.o H5Pf.o H5Rf.o H5Sf.o H5Tf.o H5Zf.o H5Aff_F90.o H5Dff_F90.o H5Eff_F90.o H5Fff_F90.o H5Lff_F90.o H5Off_F90.o H5Pff_F90.o H5Rff_F90.o H5Tff_F90.o HDF5.o
libtool: link: ranlib .libs/libhdf5_fortran.a
libtool: link: ( cd ".libs" && rm -f "libhdf5_fortran.la" && ln -s "../libhdf5_fortran.la" "libhdf5_fortran.la" )

And to make the program:

/bin/sh ../../libtool  --tag=FC   --mode=link ifort -g -check all -I../../fortran/src -I../../fortran/src    -o libh5test_fortran.la  tf_F08.lo tf.lo t.lo  -lz -ldl -lm
libtool: link: ar cru .libs/libh5test_fortran.a .libs/tf_F08.o .libs/tf.o .libs/t.o
libtool: link: ranlib .libs/libh5test_fortran.a
libtool: link: ( cd ".libs" && rm -f "libh5test_fortran.la" && ln -s "../libh5test_fortran.la" "libh5test_fortran.la" )
/bin/sh ../../libtool  --tag=FC   --mode=link ifort -g -check all -I../../fortran/src -I../../fortran/src    -o fortranlib_test fortranlib_test-tH5F.o fortranlib_test-tH5D.o fortranlib_test-tH5R.o fortranlib_test-tH5S.o fortranlib_test-tH5T.o fortranlib_test-tH5VL.o fortranlib_test-tH5Z.o fortranlib_test-tH5Sselect.o fortranlib_test-tH5P.o fortranlib_test-tH5A.o fortranlib_test-tH5I.o fortranlib_test-tH5G.o fortranlib_test-tH5E.o fortranlib_test-tHDF5.o fortranlib_test-fortranlib_test.o libh5test_fortran.la ../../test/libh5test.la ../../fortran/src/libhdf5_fortran.la ../../src/libhdf5.la -lz -ldl -lm
libtool: link: ifort -g -check all -I../../fortran/src -I../../fortran/src -o .libs/fortranlib_test fortranlib_test-tH5F.o fortranlib_test-tH5D.o fortranlib_test-tH5R.o fortranlib_test-tH5S.o fortranlib_test-tH5T.o fortranlib_test-tH5VL.o fortranlib_test-tH5Z.o fortranlib_test-tH5Sselect.o fortranlib_test-tH5P.o fortranlib_test-tH5A.o fortranlib_test-tH5I.o fortranlib_test-tH5G.o fortranlib_test-tH5E.o fortranlib_test-tHDF5.o fortranlib_test-fortranlib_test.o  ./.libs/libh5test_fortran.a ../../test/.libs/libh5test.a ../../fortran/src/.libs/libhdf5_fortran.dylib /Users/brtnfld/hdf5/trunk.min/src/.libs/libhdf5.dylib ../../src/.libs/libhdf5.dylib -lz -ldl -lm

 

 

 

 

 

 

 

 

 

 

0 Kudos
15 Replies
Steven_L_Intel1
Employee
740 Views

I'm having trouble working through all the extraneous build stuff. Please show the build commands for just the sources you showed here. 

0 Kudos
Michael_B_10
Beginner
740 Views

Sorry, here are the commands that I can do manually (basically what make is doing) to create the library and executable.

In the src directory:

/bin/sh ../../libtool --tag=FC --mode=compile ifort -g -check all -I../../src -I../../fortran/src -c -o H5f90global.lo H5f90global.f90

ifort -g -check all -I../../src -I../../fortran/src -c H5f90global.f90 -o .libs/H5f90global.o

/bin/sh ../../libtool --tag=FC --mode=link ifort -g -check all -I../../src -I../../fortran/src -version-info 6:205:0 -o libhdf5_fortran.la -rpath /Users/brtnfld/hdf5/trunk.min/hdf5/lib H5f90global.lo ../../src/libhdf5.la -lz -ldl -lm

ranlib .libs/libhdf5_fortran.a

In the test directory, which contains the main program (fortranlib_test.f90):

ifort -g -check all -I../../fortran/src -I../../fortran/src -c -o fortranlib_test-fortranlib_test.o `test -f 'fortranlib_test.f90' || echo './'`fortranlib_test.f90

/bin/sh ../../libtool --tag=FC --mode=link ifort -g -check all -I../../fortran/src -I../../fortran/src -o fortranlib_test fortranlib_test-fortranlib_test.o ../../fortran/src/libhdf5_fortran.la -lz -ldl -lm

Here is the output from each command:

% /bin/sh ../../libtool --tag=FC --mode=compile ifort -g -check all -I../../src -I../../fortran/src -c -o H5f90global.lo H5f90global.f90
libtool: compile:  ifort -g -check all -I../../src -I../../fortran/src -c H5f90global.f90  -o .libs/H5f90global.o
libtool: compile:  ifort -g -check all -I../../src -I../../fortran/src -c H5f90global.f90 -o H5f90global.o >/dev/null 2>&1
% ifort -g -check all -I../../src -I../../fortran/src -c H5f90global.f90 -o .libs/H5f90global.o
% /bin/sh ../../libtool --tag=FC --mode=link ifort -g -check all -I../../src -I../../fortran/src -version-info 6:205:0 -o libhdf5_fortran.la -rpath /Users/brtnfld/hdf5/trunk.min/hdf5/lib H5f90global.lo ../../src/libhdf5.la -lz -ldl -lm
libtool: link: ifort -dynamiclib -undefined dynamic_lookup -o .libs/libhdf5_fortran.6.dylib  .libs/H5f90global.o    ../../src/.libs/libhdf5.dylib -lz -ldl -lm    -install_name  /Users/brtnfld/hdf5/trunk.min/hdf5/lib/libhdf5_fortran.6.dylib -compatibility_version 7 -current_version 7.205 -single_module
libtool: link: (cd ".libs" && rm -f "libhdf5_fortran.dylib" && ln -s "libhdf5_fortran.6.dylib" "libhdf5_fortran.dylib")
libtool: link: ar cru .libs/libhdf5_fortran.a  H5f90global.o
libtool: link: ranlib .libs/libhdf5_fortran.a
libtool: link: ( cd ".libs" && rm -f "libhdf5_fortran.la" && ln -s "../libhdf5_fortran.la" "libhdf5_fortran.la" )
% ranlib .libs/libhdf5_fortran.a

%/bin/sh ../../libtool --tag=FC --mode=link ifort -g -check all -I../../fortran/src -I../../fortran/src -o fortranlib_test fortranlib_test-fortranlib_test.o ../../fortran/src/libhdf5_fortran.la -lz -ldl -lm
libtool: link: ifort -g -check all -I../../fortran/src -I../../fortran/src -o .libs/fortranlib_test fortranlib_test-fortranlib_test.o  ../../fortran/src/.libs/libhdf5_fortran.dylib /Users/brtnfld/hdf5/trunk.min/src/.libs/libhdf5.dylib -lz -ldl -lm

 

 

 

 

0 Kudos
Steven_L_Intel1
Employee
740 Views

I don't have a Mac readily available to me - what happens if you aren't using EQUIVALENCE and assign to ACC_TRUNK_F directly? I am just trying to narrow down the situation. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
740 Views

You might need to use

DLLEXPORT when you build the shared library

and

DLLIMPORT when you build the application using the shared library

Jim Dempsey

0 Kudos
Michael_B_10
Beginner
740 Views

If I change it to:

MODULE GLOBAL

  IMPLICIT NONE

  INTEGER :: flags(1)
!DEC$ATTRIBUTES DLLEXPORT :: /FLAGSN/
  COMMON /FLAGSN/ flags
  INTEGER :: ACC_TRUNC_F
!  EQUIVALENCE(flags(1), ACC_TRUNC_F)
CONTAINS
  SUBROUTINE open_f()
    IMPLICIT NONE
    flags(1) = 99
    ACC_TRUNC_F = flags(1)
    print*,'In F',flags(1), ACC_TRUNC_F
  END SUBROUTINE open_f

END MODULE GLOBAL

Then flags(1) is still 0 but ACC_TRUNK_F is correct,

In F          99          99
 In test           0          99

0 Kudos
Michael_B_10
Beginner
740 Views

jimdempseyatthecove wrote:

You might need to use

DLLEXPORT when you build the shared library

and

DLLIMPORT when you build the application using the shared library

Jim Dempsey

I thought that was the point of using a module, from https://software.intel.com/en-us/node/535307:

"When a module is used in other program units, through the USE statement, any objects in the module with the DLLEXPORT property are treated in the program using the module as if they were declared with the DLLIMPORT property. So, a main program that uses a module contained in a DLL has the correct import attributes for all objects exported from the DLL."

 

0 Kudos
Steven_L_Intel1
Employee
740 Views

Michael is correct - the DLLEXPORT in the module turns into a DLLIMPORT on USE. I am not sure if you even need this on OS X - I thought it was a Windows thing only, but I could be wrong. I do note that you didn't DLLEXPORT open_f - this would be required on Windows but apparently not on OS X.

Thanks for doing the experiment. I now have enough to send on to the developers. Issue ID is DPD200368212.

0 Kudos
jimdempseyatthecove
Honored Contributor III
740 Views

The behavior of the program is as if there were two ACC_TRUNC_F's. One declared and used in the scope of the PROGRAM, and the other declared and used in the scope of the DLL. In order for this to happen, you must be linking in a .o file that contains the ACC_TRUNC_F (either directly or indirectly via a static library). *** Note, this variable may be coming in unintentionally by way of linking in one of your older static libraries that happen to contain this variable.

Edit: Try changing the name to something you know has never been used before. How about:

ACC_TRUNC_F_BUG_CHECK

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
740 Views

It's simply a compiler bug on OS X only. It works fine on Windows and Linux. The EQUIVALENCE is messing up the variable import.

0 Kudos
Michael_B_10
Beginner
740 Views

Thanks Steve,

I thought maybe libtool and/or ranlib was doing something to the library, but I also see the problem using CMake. I look forward to having a fix as we've had this problem for sometime now.

 

0 Kudos
Michael_B_10
Beginner
740 Views

Has there been an update for  Issue ID  DPD200368212 ?

Thanks.

0 Kudos
Kevin_D_Intel
Employee
740 Views

Sorry, nothing as of yet.

0 Kudos
Michael_B_10
Beginner
740 Views

I see that this has been fixed in intel 17, but can you tell me the original Intel version that this was fixed in?

Thanks for fixing this. 

0 Kudos
Kevin_D_Intel
Employee
740 Views

The internal tracking issue is not yet closed nor does it indicate anything has been fixed/changed; however, there are some recent notes suggesting this is reproducible without EQUIVALENCE and that it may relate to the default linker behavior. Comments suggest using the linker option "-commons use_dylibs" yields the expected results. I expect your macOS and Xcode are updated now vs. versions used back when this was first reported so it could be an underlying change in a newer linker that's at play. I'll inquire w/Development about the internal tracking record.

0 Kudos
Michael_B_10
Beginner
740 Views

Thank you very much for pointing out  -Wl,-commons,use_dylibs

That indeed fixed the issue for both gnu and Intel compilers, and for all versions of OSX that I test on (10.9,10.10,10.11).

0 Kudos
Reply