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

How do I resolve name conflict among libraries when linking object codes?

stevenchan
Beginner
1,544 Views
Hi:
I have two compiled libraries. Library A carries a function called 'geterror', and Library B happens to carry a different function of the same name.
I only need one 'geterror', how do I instruct the Fortran compiler to ignore the other 'geterror' when linking object codes?
Steven
0 Kudos
5 Replies
Kevin_D_Intel
Employee
1,544 Views
This is a function of the linker (ld) and not the compiler and you can pass the necessary linker option via the compiler using the compiler option: -Wl,-zmuldefs

The first instance seen of the duplicate named symbol will be used during the link.

The example below links using object files and static archives that contain a duplicate symbol "sub". In the example below, case 1 shows the error you might be hitting; case 2 executes the "subA" instance since subA.o appears ahead of subB.o; case 3 executes the "subB" instance since the static archive libsubB.a appears before libsubA.a.

[bash]subA.f90
=======
subroutine sub
print *,"SubA"
end

sub.f90
subroutine sub
print *,"SubB"
end

test.f90
======
program test
call sub
end

$  ifort -c subA.f90
$  ifort -c subB.f90
$  ifort -c test.f90

$  ar crv libsubA.a subA.o
r - subA.o
$  ar crv libsubB.a subB.o
r - subB.o

$  ifort test.o subA.o subB.o
subB.o: In function `sub_':
subB.f90:(.text+0x0): multiple definition of `sub_'
subA.o:subA.f90:(.text+0x0): first defined here

$ ifort -Wl,-zmuldefs test.o subA.o subB.o
$ ./a.out
 SubA

$ ifort -Wl,-zmuldefs test.o -L. -lsubB -lsubA
$ ./a.out
 SubB
[/bash]
0 Kudos
stevenchan
Beginner
1,544 Views
Kevin:
Thank you very much for taking time to help me.
Here's another more tricky situation -- instead of ignoring the other 'geterror', I want to use it later in the same program. Using your example, it is like:
  1. test.f90
  2. ======
  3. programtest
  4. callsub ! Invoke 'sub' in SubA.f90
  5. call sub ! Invoke 'sub' in SubB.f90
  6. end
Is there a way to do this?
Steven
0 Kudos
Kevin_D_Intel
Employee
1,544 Views
I'm not aware of a way to accomplish that. If each geterror could have a unique name and the arguments to each differed, then you could define a generic interface for these two and call them using the same name, geterror. The interface determines which actual one is called based on matching the argument types. I'm not sure if that meets with your needs/interests.

In the earlier example, give each subroutine a unique name, subA and subB, with a unique argument. Create a generic interface for the name "sub" and then call subA and subBusing the name "sub". This case no longer requires the linker option because the subroutines have unique names.

[bash]subA.f90
=======
subroutine subA(A)
integer, intent(in)  :: A
write(*,*)"SubA, A=",A
end

subB.f90
=======
subroutine subB(B)
real, intent(in)   :: B
write(*,*)"SubB, B=",B
end

test.f90
=======
program test

   interface sub
      subroutine subA(A)
      integer,intent(in) :: A
      end subroutine subA

      subroutine subB(B)
      real,intent(in) :: B
      end subroutine subB
   end interface

integer ::   tA
real    ::   tB

tA=1
tB=2.0

call sub(tA)
call sub(tB)

end

$ ifort -c subA.f90
$ ifort -c subB.f90
$ ifort -c test.f90

$ ar crv libsubA.a subA.o
a - subA.o
$ ar crv libsubB.a subB.o
a - subB.o

$ ifort test.o -L. -lsubB -lsubA
$ ./a.out
 SubA, A=           1
 SubB, B=   2.000000
[/bash]
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,544 Views

program test
use libA, subA => sub
use libB, subB => sub
call subA! Invoke 'sub' in SubA.f90
call subB ! Invoke 'sub' in SubB.f90
call foo
call fooBar
end

subroutine foo
use libA
call sub ! Invoke 'sub' in SubA.f90
end subroutine foo

subroutine fooBar
use libB
call sub ! Invoke 'sub' in SubB.f90
end subroutine fooBar

Jim Dempsey
0 Kudos
stevenchan
Beginner
1,544 Views
Jim:
This is a great workaround. Thank you very much!
Steven
0 Kudos
Reply