I am trying to write a wrapper code for a simple "Hello World" program on Fortran, but I keep getting linking conflicts whenever I call a subroutine from another file.
These are the codes I used:
file name: helloworld.f90
module hellomod
public
contains
subroutine printing
print *, 'Hello World!'
return
end subroutine
end module hellomod
program main
use hellomod, only: printing
call printing
end program main
file name: hellowrap.f90
subroutine wrapping
use hellomod, only: printing
call printing
end subroutine wrapping
program hellowrap
implicit none
call wrapping
end program hellowrap
The error I got:
/usr/bin/ld: /tmp/cc5p8TIE.o: in function `wrapping_':
hellowrap.f90:(.text+0x5): undefined reference to `__hellomod_MOD_printing'
collect2: error: ld returned 1 exit status
I am a newbie in Fortran programming, so it would be great if I could know what exactly I might be doing wrong.
P.S: I did go through the other questions which were similar to mine. I tried those fixes, but they simply didn't work. One of the questions I explored was about linking a module, but when I tried to compile them together, I got an error as there are essentially two 'main' functions.
I want to compile these files separately, so this does not work. I do not exactly know if this is exclusively a linking issue.
Compiled languages generate executables in two steps, 1.Compilation and 2.linking
Compilation step just compiles each block of the program to object files as long as they are syntactically correct. The final executable has to be linked to libraries like standard and external libraries, In this step, the program is put together as a whole. When you directly compile a program, both steps are done one after the other.
What you are getting is a linker error. The linker is not able to find the object file (compiled machine code but not linked) containing the function wrapping
. (Some fortran compilers add an underscore in the binary name for historical reasons to hint it is a fortran function. This can be ignored if you stay within fortran)
You can approach this in two ways. You can compile both .f90 files separately and then link the resulting binaries or compile them in a single step so both steps are handled as once. The second way is just doing gfortran helloworld.f90 hellowrap.f90 -o programname
Now the regarding the problem of two main functions, all programs should have an "entrypoint" which is the start of execution. This is the function automatically called on start of a program. There can only be one of this. For binaries on linux this is _start
but usually compilers implement a wrapper function like main
in C/C++ and the program
in fortran. The program can have only one entry point. In terms of binary, the program block is just another function like main and it should be unique.
TLDR: You can include all the files in the gfortran command but you can have only one program block in all the files you provide. You should remove program wrapping
or program main
as there can be only one entrypoint for the program.