Hi,
I think I found a bug when porting my Windows .dll project to Linux .so. I was working on a dll project (in Visual Studio), and the time came to compile this project on Linux. The project consists of module procedures encapsulated in separate submodules. I found the following issue when compiling this project:
In my VS project, for each module procedure I use !DEC$ ATTRIBUTES DLLEXPORT to make them available outside the world. According to Steve (https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux...) ifort under Linux should ignore DLLEXPORT. But.. It does not. Here is the example (module + module procedure in a submodule) of what happens:
MODULE MOD1 IMPLICIT NONE INTERFACE MODULE SUBROUTINE PR_MOD1(SOME_INT) IMPLICIT NONE !DEC$ ATTRIBUTES DLLEXPORT :: PR_MOD1 INTEGER, INTENT(IN) :: SOME_INT ! ... END SUBROUTINE PR_MOD1 END INTERFACE END MODULE MOD1
SUBMODULE (MOD1) MOD1_PR_MOD1 IMPLICIT NONE CONTAINS MODULE SUBROUTINE PR_MOD1(SOME_INT) !DEC$ ATTRIBUTES DLLEXPORT, ALIAS:"PR_MOD1" :: PR_MOD1 IMPLICIT NONE INTEGER, INTENT(IN) :: SOME_INT PRINT*, 'PR_MOD1 subroutine issued with an argument: ', SOME_INT END SUBROUTINE PR_MOD1 END SUBMODULE MOD1_PR_MOD1
Compiling above module + submodule into libtest.so library and reviewing it through nm I received:
$ nm -D libtest.so 0000000000000710 T PR_MOD1 w _Jv_RegisterClasses 0000000000200b40 A __bss_start w __cxa_finalize w __gmon_start__ 0000000000200b40 A _edata 0000000000200b50 A _end 00000000000007b8 T _fini 00000000000005c8 T _init U for_write_seq_lis U for_write_seq_lis_xmit 00000000000006f0 T mod1._ 0000000000000700 T mod1.mod1_pr_mod1._
Which means I do not have an access to module subroutine: PR_MOD2. I found that when I modify my DLLEXPORT statement to be handled by the preprocessor, I can avoid this. In this case I will have in module MOD1 (instead of !DEC$ ATTRIBUTES DLLEXPORT :: PR_MOD1):
!DEC$ IF DEFINED(__linux) !DEC$ ELSE !DEC$ ATTRIBUTES DLLEXPORT :: PR_MOD1 !DEC$ ENDIF
and in submodule (instead of !DEC$ ATTRIBUTES DLLEXPORT, ALIAS:"PR_MOD1" :: PR_MOD1):
!DEC$ IF DEFINED(__linux) !DEC$ ELSE !DEC$ ATTRIBUTES DLLEXPORT, ALIAS:"PR_MOD1" :: PR_MOD1 !DEC$ ENDIF
Reviewing libtest.so through nm I received:
w _Jv_RegisterClasses 0000000000200b50 A __bss_start w __cxa_finalize w __gmon_start__ 0000000000200b50 A _edata 0000000000200b60 A _end 00000000000007c8 T _fini 00000000000005d0 T _init U for_write_seq_lis U for_write_seq_lis_xmit 0000000000000700 T mod1._ 0000000000000710 T mod1.mod1_pr_mod1._ 0000000000000720 T mod1_mp_pr_mod1_
Which is different than what it was before. Now, I have module procedure mod1_mp_pr_mod1_ available to use. Please tell me if this is a bug or I am doing sth wrong with placing DLLEXPORT statements in my code.
Regards,
Piotr
P.S. I am using Intel Fortran Compiler 17 Update 1