Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linking Error : Calling external function throws undefined refernce error #4008

Open
assem2002 opened this issue May 16, 2024 · 8 comments
Open
Labels

Comments

@assem2002
Copy link
Contributor

Calling a function or subroutine from another file throws error.

func.f90

function f() result(d) 
    implicit none 
    integer :: d 
    d = 9
end function f

prog.f90

program a
    implicit none
    integer :: c
    integer  :: f 
    external :: f
    c = f()
    print *, c
end program a
assem@assem-PC:~/Desktop/fortran/test_05$ ../../../lfortran/src/bin/lfortran --implicit-interface  -c func.f90 
assem@assem-PC:~/Desktop/fortran/test_05$ ../../../lfortran/src/bin/lfortran --implicit-interface  -c prog.f90 
assem@assem-PC:~/Desktop/fortran/test_05$ ../../../lfortran/src/bin/lfortran --implicit-interface  -o mmm func.o prog.o 
/usr/bin/ld: prog.o: in function `main':
LFortran:(.text+0x7): undefined reference to `f'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The command 'clang -o mmm func.o prog.o  -L"/home/assem/lfortran/src/bin/../runtime" -Wl,-rpath,"/home/assem/lfortran/src/bin/../runtime" -llfortran_runtime -lm' failed.
assem@assem-PC:~/Desktop/fortran/test_05$ 
@assem2002
Copy link
Contributor Author

same as in #4009

@kmr-srbh
Copy link
Contributor

@assem2002 the above error occurs because there is no function f() defined inside prog.f90. I think this might be the correct way to do what you wished to achieve.

prog.f90

program a
   implicit none
   integer :: c
   interface f1
      integer function f() result(d)
      end function
   end interface f1
   c = f()
   print *, c
end program a

function f() result(d)
   integer :: d
   d = 9
end function f

This gives the required output

(base) saurabh-kumar@Awadh:~/Projects/System/lfortran$ lfortran ./examples/example.f90
9

@kmr-srbh
Copy link
Contributor

For loading the function from an external module, we can do

func.f90

module func
   implicit none
contains
   function f() result(d)
      integer :: d
      d = 9
   end function f
end module func

prog.f90

program a
   use func
   implicit none
   integer :: c
   c = f()
   print *, c
end program a

Which gives the output

(base) saurabh-kumar@Awadh:~/Projects/System/lfortran$ lfortran ./examples/example.f90
9

@assem2002
Copy link
Contributor Author

assem2002 commented May 16, 2024

@kmr-srbh. Yeah you're right about your suggested code.but we should be able to call an external function that's defined in another file using external keyword.
gfortran compiles these files and the example files mentioned above normally with no issue.
We have to support such a thing because lapack uses this way to build its own library . (Note that lapack uses Fortran 77 style which doesn't support module)

@kmr-srbh
Copy link
Contributor

kmr-srbh commented May 16, 2024

@assem2002 could you please share the steps you followed to compile this using GFortran? How does the compiler know where f is present?

@assem2002
Copy link
Contributor Author

@kmr-srbh

assem@assem-PC:~/Desktop/fortran/test_05$ gfortran -c func.f90 
assem@assem-PC:~/Desktop/fortran/test_05$ gfortran -c prog.f90 
assem@assem-PC:~/Desktop/fortran/test_05$ gfortran -o mmm func.o prog.o 
assem@assem-PC:~/Desktop/fortran/test_05$ ./mmm 
           9

I think it just compiles prog.f90 and the object file waits for the undefined variables to be found in linking phase. for sure it doesn't have the advantages that mod file offers so that is why LFortran requires --implicit-interface flag to be used if we call an external function in our code.

@kmr-srbh
Copy link
Contributor

Looks like we are dealing with legacy code here.

@assem2002
Copy link
Contributor Author

as @Pranavchiku mentioned it would compile normally with --generate-object-code flag.
-c flag in gfortran handles this issue with no problem. should we do the same in LFortran? If not just let's close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants