1
votes

The main program with too many subroutines and functions is existed. Some of the subroutines and functions also use subroutines, functions, and modules. I decided to write them in independent files due to clarity in the main program. Then I created an independent file as a module to collect them with the include command.

Now I have one main program and one independent file for the module. I compile the program but it shows an error. The error is about missing mentioned subroutine in the above independent file.

My question in general is: If you have a program with one main program and a number of sub-programs (subroutines, functions, and modules), which also they have sub-programs, what method do you use to assemble and run it?

I write my code in PLATO as a fortran95.

I will appreciate any comments that give me a little help and forgive me for writing shortcomings


What is the problem?

Consider the following structure. On the independent file as the main program:

MAIN PROGRAM

CALL A

CALL B

CALL C

END PROGRAM

On the independent file as the subroutine A:

SUBROUTINE A

...

END SUBROUTINE 

On the independent file as the subroutine B:

SUBROUTINE B
    
CALL B1

CALL B2
    
END SUBROUTINE 
---------------
SUBROUTINE B1
...
END SUBROUTINE
--------------
FUNCTION B2
...
END FUNCTION 

On the independent file as the subroutine C:

SUBROUTINE C
        
USE C1
    
CALL C2
        
END SUBROUTINE 
---------------
SUBROUTINE C1
...
END SUBROUTINE

On the independent file as the module C1:

MODULE C1

CONTAINS

SUBROUTINE C1-1
SUBROUTINE C1-2
SUBROUTINE C1-3
...
END MODULE

What I did:

I created an independent file as Module:

MODUL D

INCLUDE A.F95
INCLUDE B.F95
INCLUDE C.F95

END MODULE

Consequently, for the main program:

MAIN PROGRAM
    
USE D

CALL A
    
CALL B
    
CALL C
    
END PROGRAM

What is the Error:

Warning: Missing A (File address), Missing B (File address), Missing C (File address)

1
You really have to show us your code in the form of a small minimal reproducible example and the exact error message you have. Do not say "an error", copy and paste the exact error message. - Vladimir F
Take a look here: owsiak.org/fortran-and-gnu-make - this is a simple Fortran code where you have two modules, main file, and Makefile that builds everything. - Oo.oO
For the subprograms that you put into a separate file: are they are in one or more modules? Did you Fortran "use" those module(s) in the main program? Are you compiling the separate file first, so that when the main program is compiled, it can access the module information? - M. S. B.
@VladimirF I showed the structure symbolically. The whole of the code is about the above structure. - VOLCANIC_9
@M.S.B. I showed the structure and what I did, If more information is needed, please note me. Furthermore, I run the main program. - VOLCANIC_9

1 Answers

2
votes

The following makefile should work for your setup.

FC := gfortran

main: c1.o d.o main.o
    @$(FC) $^ -o main

main.o: main.f90 d.f90
    @$(FC) -c $<

d.o: d.f90 a.f90 b.f90 c.f90 c1.o
    @$(FC) -c $<

c1.o: c1.f90
    @$(FC) -c $<

clean:
    @rm -rf *.{o,mod} main

I used the following files (note the filenames and .f90 extensions)

! main.f90
program main
  use d

  print *, 'main'
  call a()
  call b()
  call c()
end program
! b.f90
subroutine b()
  logical :: tmp
  print *, 'b'
  call b1()
  tmp = b2()
end subroutine

subroutine b1()
  print *, 'b1'
end subroutine

logical function b2()   ! added: function needs return type.
  print *, 'b2'
  b2 = .true.
end function
! c.f90
subroutine c()
  use c1

  print *, 'c'
  call c1_1()       ! added this line. otherwise module c1 would not be used at all.
  call c2()
end subroutine

subroutine c2()
  print *, 'c2'
end subroutine
! c1.f90
module c1
contains

  subroutine c1_1()
    print *, 'c1_1'
  end subroutine
  subroutine c1_2()
    print *, 'c1_2'
  end subroutine
  subroutine c1_3()
    print *, 'c1_3'
  end subroutine

end module
! d.90
module d
contains    ! added: files a.f90,b.d90,c.f90 define procedures and must be included after `contains`.

  include 'a.f90'
  include 'b.f90'
  include 'c.f90'

end module