Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29280 Discussions

Duplicate symbol error with IFX compilation

Balakrishna_Narra
3,009 Views

Hi all,

I am working in legacy application which is distributed into multiple DLL, and originally built in 32 bit of Intel Classic compiler IFORT,  (due to confidentiality I may not be able to share the code), but I can explain the different scenarios I worked on , and if you can help me how to address the issue it would be great help

Scenarios1 : 32 bit IFORT (works perfect)

1. Source code compiles without any error

2. linker is able to link all dependency dll's without any error

 

Scenario 2: 64 bit IFORT (works perfect)

1. Source code compiles without any error

2. linker is able to link all dependency dll's without any error

(Now that IFORT is deprecated we have to migrate to IFX)

 

Scenario 3: 64 bit IFX

1. Source code compiles without any error

2. linker is not able to link all dependency dll's. it throws an "error: duplicate symbol: abcde"

 

In one of threads (https://community.intel.com/t5/Intel-Fortran-Compiler/Has-anyone-else-had-a-duplicate-symbol-link-error-using-IFX-and/td-p/1351163) i see @Lorri_M_Intel  suggesting to compile the files separately by IFORT and then link

I am able to isolate the problem to two files and If I compile these two files in IFORT (64 bit) and then link the project file I am able to build it successfully. Can you please help me to address this issue.

I am working on Visual studio environment, please let me know if you need any additional details 

 

0 Kudos
19 Replies
JohnNichols
Valued Contributor III
2,991 Views

You need to be a bit more specific, but with legacy code you can get caught out with changes in DLL contents between versions.

Be more specific

0 Kudos
Balakrishna_Narra
2,969 Views

Hello JohnNichols , thank you for the reply, Can you please help me with the details I can add, to be more specific.

0 Kudos
andrew_4619
Honored Contributor III
2,987 Views

Your link does not work but it is this topic https://community.intel.com/t5/Intel-Fortran-Compiler/Has-anyone-else-had-a-duplicate-symbol-link-error-using-IFX-and/m-p/1351163

 

That thread is 2 years old, what version of IFX are you using? If it is not the latest then I would try first because there have been huge numbers of fixes in IFX since 2022.

 

 

 

0 Kudos
Balakrishna_Narra
2,967 Views

Hello andrew, thank you for the reply, the link you have posted is the right one, yes the post is old but similar to what I am facing, I am using the latest 2024.1.0 version, please let me know if I have add any specific information. Thank you 

0 Kudos
andrew_4619
Honored Contributor III
2,956 Views

You could run dumpbin on those two object files to see if the duplicate symbol can be seen in both. If it can then copy the files and start to delete things until you have a minimalist pair of files that still shows duplicate symbols.  In doing so you will understand more about the cause and then may be able to post a reproducer or indeed 'fix' the code. Things only tend to get fixed if there is a reproducer,

0 Kudos
Balakrishna_Narra
2,955 Views

Thank you Andrew, I will try this and keep you posted on my findings,

0 Kudos
Balakrishna_Narra
2,857 Views

Hello Andrew,

Below is the minimalization I could do and I am able to still reproduce the issue, Can you please suggest

 

I have created a new library project in Visual studio

!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: DuplicateSymbolTestDll1
!DEC$ ENDIF
subroutine DuplicateSymbolTestDll1

PARAMETER ( MAX = 35 )
CHARACTER NAME*48

!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: TISDB1
!DEC$ ENDIF
COMMON / TISDB1 / NCM,LENG,GE(70*MAX)
!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: TISDB2
!DEC$ ENDIF
COMMON / TISDB2 / NAME(MAX)
!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: TISDB3
!DEC$ ENDIF
COMMON / TISDB3 / NCX,IST(70),NDATA,NCODE,NMAX,KINIT,OMR(70)
!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: TISDB4
!DEC$ ENDIF
COMMON / TISDB4 / IG(10*MAX)

end subroutine DuplicateSymbolTestDll1

 

and I added another file for the same project like

 

!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: sub2
!DEC$ ENDIF
SUBROUTINE sub2 (NC,ISTOF)


      EXTERNAL BDDB1
     PARAMETER ( MAX = 5 )
     PARAMETER (NDA=7, NCO=10, LENP=5, NMAP=609)

     COMMON / TISDB1 / NCM,LENG,GE(70*MAX)
     COMMON / TISDB2 / NAME(MAX)
     COMMON / TISDB3 / NCX,IST(LENP),NDATA,NCODE,NMAX,KINIT,OMR(LENP)
     COMMON / TISDB4 / IG(10*MAX)


END SUBROUTINE

BLOCK DATA BDDB1
        DOUBLE PRECISION EXPMIN,EXPMAX,DXPMIN,DXPMAX
        PARAMETER ( MAX = 5 )
        PARAMETER ( MAXTD2 = 9 )
        PARAMETER ( NDA=7, LENP=5)
        CHARACTER NAME*48

COMMON / TIDEFV / EXPMIN,EXPMAX,DXPMIN,DXPMAX
COMMON / TISDB1 / NCM,LENG,GE(70*MAX)
COMMON / TISDB2 / NAME(MAX)
COMMON / TISDB3 / NCX,IST(LENP),NDATA,NCODE,NMAX,KINIT,OMR(LENP)

!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: /TISUNI/
!DEC$ ENDIF
COMMON / TISUNI / IS
COMMON / TISERC / KTEL,KPRIN,KSTATE
DATA IS / 0 /
DATA KTEL,KPRIN,KSTATE / 3 * 0 /

DATA EXPMIN,EXPMAX,DXPMIN,DXPMAX /-8.D0 ,8.D0 ,-8.D0 ,9.D0/
DATA NCM, LENG / MAX , LENP /
DATA NAME / MAX * ' ' /
DATA NCX, NDATA, NCODE, NMAX, KINIT / 0, NDA, 10, MAXTD2, 0 /
DATA OMR / 1.E0, 1.01, 1.6, 1.0, 45.65/

END BLOCK DATA

with these two files if I try to build, Compilation works fine but the linking fails and throws the below error

Balakrishna_Narra_0-1718887025604.png

 

Can you please suggest, what is causing this error and how to address such issues

 

Thank you 

 

(also complete solution is packaged and attached for reference)

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,847 Views

You have more than one problem. In the 1st file you have MAX=35, in the 2nd file you have MAX=5.

 

While the MAX parameter defines the array size for only the last entry in a named common (ok for mismatch in this case)

MAX is also used as an initialization value for other variables (e.g. NCM). This may cause execution errors.

 

As to the linker name conflict, I cannot say.

 

Jim Dempsey

0 Kudos
Balakrishna_Narra
2,845 Views

Hello Jim Dempsey,

Thank you for pointing the value mismatch for Max variable, This is a dummy project I created to reduce the problem to small and easy to understand.

I have changed the max parameter and I am still getting the same error, I am not sure if this is something to do with common block within the block data, if I comment that common blocks inside Block data the project is able to build without errors

 

Thank you

0 Kudos
andrew_4619
Honored Contributor III
2,836 Views

 

 

Compiling with Intel® Fortran Compiler 2024.1.0 [Intel(R) 64]...
Source1.f90
DuplicateSymbolTestDll1.f90
Linking...
lld-link: error: duplicate symbol: TISDB1
>>> defined at x64\Debug\Source1.obj
>>> defined at x64\Debug\DuplicateSymbolTestDll1.obj
lld-link: error: duplicate symbol: TISDB2
>>> defined at x64\Debug\Source1.obj
>>> defined at x64\Debug\DuplicateSymbolTestDll1.obj
lld-link: error: duplicate symbol: TISDB3
>>> defined at x64\Debug\Source1.obj
>>> defined at x64\Debug\DuplicateSymbolTestDll1.obj

 

 

Well firstly I get the same result! I added !DIR$ DEFINE _DLL=1 in the top of the sources to remove the _DLL variable undefined  but that just removes the warnings.

 

Note TISDB4 is not duplicate. If you remove !DEC$ ATTRIBUTES DLLEXPORT :: TISDB1 that that is no longer duplicate. It looks to  me that the commons are being exported automatically and the explicit export is doing it as well.  I don't do much dll work and I stopped using common blocks about 20 years ago so I am not sure of the correct behaviour in dll's.  Now there is some concrete source code I would hope we can get a better response from the forum at large.

 

Addition if I comment out TISBD1,2 and 3 exports that give errors then dumpbin on the dll gives:

 

 Section contains the following exports for DuplicateSymbolTestDll1.dll
    00000000 characteristics
           0 time date stamp
        0.00 version
           1 ordinal base
           4 number of functions
           4 number of names
    ordinal hint RVA      name
          1    0 00001030 DUPLICATESYMBOLTESTDLL1 = DUPLICATESYMBOLTESTDLL1
          2    1 00001000 SUB2 = SUB2
          3    2 00005840 TISDB4 = TISDB4
          4    3 00005720 TISUNI = TISUNI

 

So it clearly works for the other commons but why the difference????????? I think BLOCKDATA might be the trigger for an IFX bug with DLL export?

 

0 Kudos
Balakrishna_Narra
2,835 Views

Thank you Andrew for your kind response, I am not sure why "DLLEXPORT:TISDB1" is explicitly used and the person who wrote this program is now retired, hoping to get better understanding of this issue and learn from forum (fingers crossed)

 

0 Kudos
JohnNichols
Valued Contributor III
2,815 Views

you could view this as a Monte Carlo type problem. 

1. Create the soln with the two files and the absolute minimum code to make them work. 

2. Adding one line a time in some logical fashion look for the offending code, like MC looks at one point and then another.  It is a cut and paste exercise, once you have a single point of error, upload the solution files here as an attachment so people can play with it at the smallest size, and learn to use the insert code function on the  tool bar, it is the ... and look for the </>, then people can read it. 

3.  This is the only way to build LISP code, it works. 

 

0 Kudos
Balakrishna_Narra
2,812 Views

Thank you JohnNichols for explaining how things work here, your suggestions are noted and will try to improve my postings in future

0 Kudos
andrew_4619
Honored Contributor III
2,794 Views

Does you application use a lot of blockdata or is the one shown the only one? If you replace that with an initialisation routine that you call at the start up of the dll.  Blockdata is an ancient think that you should aim to beg rid off IMO.  The edits to source1.f90 make it work....

 

 

!DIR$ DEFINE _DLL=1

!!DEC$ IF (_DLL==1)
!!DEC$ ATTRIBUTES DLLEXPORT :: sub2
!!DEC$ ENDIF
!SUBROUTINE sub2 (NC,ISTOF)
!      
!      
!      EXTERNAL BDDB1
!      PARAMETER ( MAX = 5 )
!      PARAMETER (NDA=7, NCO=10, LENP=5, NMAP=609)
!      
!      COMMON / TISDB1 / NCM,LENG,GE(70*MAX)
!      COMMON / TISDB2 / NAME(MAX)
!      COMMON / TISDB3 / NCX,IST(LENP),NDATA,NCODE,NMAX,KINIT,OMR(LENP)
!      
!      COMMON / TISDB4 / IG(10*MAX)
!      
!      
!END SUBROUTINE

!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT :: BDDB1_INIT
!DEC$ ENDIF
subroutine BDDB1_INIT()
      DOUBLE PRECISION EXPMIN,EXPMAX,DXPMIN,DXPMAX
      PARAMETER ( MAX = 5 )
      PARAMETER ( MAXTD2 = 9 )
      PARAMETER ( NDA=7, LENP=5)
      CHARACTER NAME*48

      COMMON / TIDEFV / EXPMIN,EXPMAX,DXPMIN,DXPMAX
      COMMON / TISDB1 / NCM,LENG,GE(70*MAX)
      COMMON / TISDB2 / NAME(MAX)
      COMMON / TISDB3 / NCX,IST(LENP),NDATA,NCODE,NMAX,KINIT,OMR(LENP)
!DEC$ IF (_DLL==1)
!DEC$ ATTRIBUTES DLLEXPORT ::  /TISUNI/
!DEC$ ENDIF
      COMMON / TISUNI / IS
      COMMON / TISERC / KTEL,KPRIN,KSTATE
      IS=0
      KTEL=0; KPRIN=0; KSTATE = 0
      EXPMIN =-8.D0; EXPMAX=8.D0; DXPMIN=-8.D0; DXPMAX=9.D0
      NCM=MAX; LENG = LENP
      NAME = ' '
      NCX=0; NDATA=NDA; NCODE=10; NMAX=MAXTD2; KINIT=0
      OMR=[1.E0, 1.01, 1.6, 1.0, 45.65]
end subroutine BDDB1_INIT
!BLOCK DATA BDDB1
!      DOUBLE PRECISION EXPMIN,EXPMAX,DXPMIN,DXPMAX
!      PARAMETER ( MAX = 5 )
!      PARAMETER ( MAXTD2 = 9 )
!      PARAMETER ( NDA=7, LENP=5)
!      CHARACTER NAME*48
!
!      COMMON / TIDEFV / EXPMIN,EXPMAX,DXPMIN,DXPMAX
!      COMMON / TISDB1 / NCM,LENG,GE(70*MAX)
!      COMMON / TISDB2 / NAME(MAX)
!      COMMON / TISDB3 / NCX,IST(LENP),NDATA,NCODE,NMAX,KINIT,OMR(LENP)
!
!!DEC$ IF (_DLL==1)
!!DEC$ ATTRIBUTES DLLEXPORT ::  /TISUNI/
!!DEC$ ENDIF
!      COMMON / TISUNI / IS
!      COMMON / TISERC / KTEL,KPRIN,KSTATE
!      DATA IS / 0 /
!      DATA KTEL,KPRIN,KSTATE / 3 * 0 /
!
!      DATA EXPMIN,EXPMAX,DXPMIN,DXPMAX /-8.D0 ,8.D0 ,-8.D0 ,9.D0/
!      DATA NCM, LENG / MAX , LENP /
!      DATA NAME / MAX * ' ' /
!      DATA NCX, NDATA, NCODE, NMAX, KINIT / 0, NDA, 10, MAXTD2, 0 /
!      DATA OMR / 1.E0, 1.01, 1.6, 1.0, 45.65/
!      
!END BLOCK DATA

 

0 Kudos
Balakrishna_Narra
2,666 Views

Thank you Andrew, I will check on this and keep you posted, and Yes we have lot of Block data in the complete program, need to see how to overcome this issue

But still I was wondering if it is a IFX bug (because this works fine with IFORT)?? how can we check with Intel people to know if its a bug or an functionality change?

 

Thank you and really appreciate it Andrew

 

0 Kudos
andrew_4619
Honored Contributor III
2,635 Views

Well I have have no idea on the correct usage of BLOCKDATA within a DLL it is an IMO and obsolete legacy hangover. I think given IFORT works this does look like a bug in IFX we would need one of the Intel Moderators  to look at the reproducer @Ron_Green  @Devorah_H_Intel upthread.  

0 Kudos
Balakrishna_Narra
2,453 Views

Hi @Ron_Green , @Devorah_H_Intel , @TobiasK 

Can you please suggest how to address this issue

 

Thank you

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,719 Views

This may be motivation to "bite the bullet" and convert these COMMON/BlockData into module.

 

You will need to be careful if the code references a COMMON block name with different variable names.

This can be corrected with the rename-list feature.

 

Jim Dempsey

0 Kudos
Balakrishna_Narra
2,666 Views

This would be the last thing we want to do (as it needs lot of effort and time), Jim Dempsey. But yes I agree with your suggestion to get rid of old ways of working. we will have this on our list.

 

Thank you , really appreciate it!!! 

0 Kudos
Reply