Search code examples
fortrangfortrannumericnumerical-recipes

Fortran undefined reference to _[subroutine name]


I'm testing out Numerical Recipies in Fortran 90 vol2 helloBessel as written in the book.

program helloBessel
use nrtype
use nr, ONLY: flmoon, bessj0
implicit none

integer(I4B) :: n = 200, nph = 2, jd
real(SP) :: x, frac, ans

call flmoon(n, nph, jd, frac)
write (*,*) jd
x = jd**0.25_sp
ans = bessj0(x)
write (*,*) "Hello, Bessel: ", ans
end program helloBessel

It gives this error:

gfortran -o bessel nr.o nrtype.o helloBessel.f90 
/tmp/cchJfVZl.o: In function `MAIN__':
helloBessel.f90:(.text+0x28): undefined reference to `flmoon_'
helloBessel.f90:(.text+0xb4): undefined reference to `bessj0_s_'
collect2: error: ld returned 1 exit status

I tried making smaller example just in case:

program helloTest
use nrtype
use nr, ONLY: test
implicit none

real(SP) :: z, t
call test(z, t)
write (*,*) t

end program helloTest

I compile it that way:

gfortran -c nr.f90
gfortran -c nrtype.f90
gfortran -o test nr.o nrtype.o helloTest.f90

It still gives out this error:

/tmp/cc76cg5g.o: In function `MAIN__':
helloTest.f90:(.text+0x1a): undefined reference to `test_'
collect2: error: ld returned 1 exit status

Is it a problem in code or compilation procedure? What am I doing wrong? My question is different than others, as my version is high enough not to cause problems and I already tell compiler about all file, which doesnt solve the problem.

Relevant code from modules

MODULE nrtype
    INTEGER, PARAMETER :: I4B = SELECTED_INT_KIND(9)
    INTEGER, PARAMETER :: SP = KIND(1.0)
END MODULE nrtype
MODULE nr
INTERFACE
    SUBROUTINE test(x,y)
        USE nrtype
        REAL(SP), INTENT(IN) :: x
        REAL(SP), INTENT(OUT) :: y
    END SUBROUTINE test
END INTERFACE

INTERFACE
    SUBROUTINE flmoon(n,nph,jd,frac)
        USE nrtype
        INTEGER(I4B), INTENT(IN) :: n,nph
        INTEGER(I4B), INTENT(OUT) :: jd
        REAL(SP), INTENT(OUT) :: frac
    END SUBROUTINE flmoon
END INTERFACE

INTERFACE bessj
    FUNCTION bessj_s(n,x)
        USE nrtype
        INTEGER(I4B), INTENT(IN) :: n
        REAL(SP), INTENT(IN) :: x
        REAL(SP) :: bessj_s
    END FUNCTION bessj_s
    FUNCTION bessj_v(n,x)
        USE nrtype
        INTEGER(I4B), INTENT(IN) :: n
        REAL(SP), DIMENSION(:), INTENT(IN) :: x
        REAL(SP), DIMENSION(size(x)) :: bessj_v
    END FUNCTION bessj_v
END INTERFACE
END MODULE nr

Update: as per Vladimir F answer, I created test.f90,

function test(x, y)
real, intent(in) :: x
real, intent(out) :: y

y = x + 2
return
end function test

updated real(SP) :: z = 1, t in helloTest, compiled with

gfortran -o test test.f90 nr.o nrtype.o helloTest.f90

and got my 3.0000 in result. Thank you!


Solution

  • There is no subroutine test in the code you are showing. The interface only promises one, but you have to actually supply it.

    Similarly for the first error, you have to actually add code that has the implementations of flmoon, bessj0. A Google search shows it should be in bessj0.f90 but I can't test it myself.