I'm having a hard time debugging a compilation error in gfortran. My compiler is:
gfortran -v
Thread model: posix
gcc version 4.9.2 (x86_64-posix-seh-rev4, Built by MinGW-W64 project)
I can't include the real problem because it's too big. Below I'll discuss a model problem of what's happening:
I have one big module, let's call it ops, that I'd like to break down into several modules (e.g. add, subtract, multiply, divide, etc). To do this, I "use" modules "add" and "subtract" in module "ops", make the routines from "add" and "subtract" public, and then call the routines in "add" and "subtract" from the main program, which only uses "ops".
In this simple example (illustrated below in a simple program), using both modules works fine, and there are no errors. But when I do this with my big program, I get an error when trying to use the "subtract" module (I've also included what I mean in the program comments).
Here's the sample of the scenario:
module add_mod
private
public :: add
interface add; module procedure add1; end interface
contains
subroutine add1(a,b,c)
integer,intent(inout) :: a
integer,intent(in) :: b,c
a = b + c
end subroutine
end module
module subtract_mod
private
public :: subtract
interface subtract; module procedure subtract1; end interface
contains
subroutine subtract1(a,b,c)
integer,intent(inout) :: a
integer,intent(in) :: b,c
a = b - c
end subroutine
end module
module ops
use add_mod
! use subtract_mod ! Removing comment causes error...
private
public :: init
public :: add
! public :: subtract ! Removing comment causes error...
contains
subroutine init(a,b,c)
implicit none
integer,intent(inout) :: a,b,c
a = 0; b = 0; c = 0
end subroutine
end module
program test
use ops
implicit none
integer :: a,b,c
b = 1; c = 1
call add(a,b,c)
write(*,*) 'a,b,c = ',a,b,c
! call subtract(a,b,c) ! want to call...
write(*,*) 'a,b,c = ',a,b,c
end program
The error that I'm getting (in terms of the simplified example) is:
\add.o
\subtract.o
\subs.o
\main.o
gfortran: error: main.o: No such file or directory
make: *** [main] Error 1
The error from my big example looks like
C:\\Users\\charl\\Documents\\obj\parametricStudy.o
gfortran: error: C:\\Users\\charl\\Documnts\\obj\parametricStudy.o: No such file or directory
make: *** [C:\\Users\\charl\\Documents\\MOONS] Error 1
Where "parametricStudy" is the main program and "MOONS" is the name of the target/executable.
This really does not look like an error in terms of finding the executable, it looks like the executable is not made because of some other issue, but I don't have enough information to find out why. I've tried including all of the debugging flags I can think of:
fimplicit-none -Wuninitialized -cpp -fopenmp -Wall -Wextra -fbacktrace -fcheck=all -O0 -Og
Sorry for the long introduction, but here's my question: How can I debug this? I'm sorry if this was a poorly conveyed question, but I can't re-produce this error in a simple case, so I'm not sure how else to pose the question. Any help on a solution, debugging advice or improving this question is greatly appreciated!
UPDATE:
After seeing the comment about the compilation error typo, I tried reversing the order of the used modules. That is, now I tried using "subtract" alone, which works fine, but then try using "add" (together) and I get the same error. I'm now beginning to think that this is a compiler bug or something.
UPDATE 2:
I uploaded the code to github. It can be downloaded at
https://github.com/charliekawczynski/MOONS
The makefile is in the directory
\MOONS\makefiles\MOONS
And the output should show up in out_dir. To compile this, the $TARGET_DIR$ and $SRC_DIR$ must be defined. Please note that right now it is defined with the variable $USER$.
After changing the directory, I see a different misspelling (which seems to change when I make small changes in the code, e.g. removing some warnings related to unused variables).
UPDATE 3:
I've been removing more warnings related to un-used routines and variables, and now I see that the error still exists, but (as far as I see) there is no typo. Here is the new output:
gfortran -o
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\MOONS -J"
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\mod" -fimplicit-none -Wuninitialized -cpp -D_DOUBLE_PRECISION_ -D_FFT_RADIX2_ -fopenmp -Wall -Wextra -fbacktrace -fcheck=all -O0 -Og -D_DEBUG_DEL_ -D_DEBUG_INTERP_ -D_DEBUG_APPLYBCS_
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\IO_tools.o
...
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\init_Ufield.o
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\init_Pfield.o
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\energySolver.o
...
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\MOONS.o
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\richardsonExtrapolation.o
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\convergenceRate.o
C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\parametricStudy.o
gfortran: error: C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\obj\init_Pfield.: No such file or directory
make: *** [C:\\Users\\charl\\Documents\\GitHub\\MOONS\\out_dir\\MOONS] Error 1
C:\Users\charl\Documents\GitHub\MOONS\makefiles\MOONS>
I'm going to try a newer compiler and see if this fixes the problem
Related
A quick run down:
I'm new to fortran
I'm on a windows machine
Using sublime to edit an assignment fortran code
The assignment includes a main.f90 file (see the below image of the code for that file)
This main.f90 code calls in 3 different modules: 'types' and 'analytic_functions', and
'euler_formulas'
The following error keeps appearing whenever I try to run the command gfortran main.f90 in my windows command prompt:
Fatal Error: Can't open module file 'types.mod' for reading at (1): No such file or directory compilation terminated.
How do I fix this issue? All help will be greatly appreciated.
Here's the main.f90 code:
module read_write
use types
use analytic_functions, only : second_derivative_f
use euler_formulas, only : euler_3points
implicit none
private
public read_input, write_derivatives
contains
I don't know if this would help but here's the 'types.f90' code:
module types
! The iso_fortran_env is an intrinsic module that should already be
! inside of your compiler
use iso_fortran_env
implicit none
integer, parameter :: sp = REAL32 !< single precision kind
integer, parameter :: dp = REAL64 !< double precision kind
integer, parameter :: qp = REAL128!< quadruple precision kind
real(dp), parameter :: pi=acos(-1.0_dp)!< π = 3.141592...
end module types
Note: these .mod files are more or less like C headers, they allow the compiler to check types at compile time, which was usually not possible in Fortran 77 when compiling from several source files. They are created when you compile the modules.
Hence, you have first to compile the modules. Note that to compile and link main.f90, you also have to pass the object files to gfortran, otherwise the linker won't be able to resolve references to functions from these modules.
gfortran -c types.f90
gfortran -c analytic_functions.f90
gfortran -c euler_formulas.f90
gfortran main.f90 types.obj analytic_functions.obj euler_formulas.obj
The gfortran compiler is also able to compile all files at once, but you must pass the files in a specific order: if program or module B uses module A, then B.f90 must be after A.f90 on the command line. This is necessary for the compiler to find the .mod files when they are used.
gfortran types.f90 analytic_functions.f90 euler_formulas.f90 main.f90
First of all, please read ---PS--- part. This problem is my misunderstanding.
I'm using ubuntu18.04 OS and intel fortran compiler of "parallel studio xe 2020 update 4" ifort.
I have tried to generate dependency among fortran source files using the ifort compiler with the -gen-dep option.
The following simple code was written for my test. The filename is "main.f90".
program main
use mod_a
implicit none
end program main
I executed following command to generate dependency of "main.f90".
ifort -gen-dep -syntax-only main.f90
As a result, I got following error message.
main.f90(2): エラー #7002: コンパイル済みモジュールファイルを開くときのエラーです。INCLUDE パスを確認してください。 [MOD_A]
use mod_a
--------^
The error message notifies that "mod_a.mod" file does not existed yet (while it is written in Japanese).
In the case the "mod_a.mod" has already been generated with compiling mod_a.f90, I got the following "true dependency" with executing above command.
main.o : \
main.f90 mod_a.mod
How can I generate dependency without generating mod_a.mod?
If it exist that the additional ifort options to achieve my goal, I want to know the options with priority.
Thank you for reading.
---PS---
I appologize to everyone who has read this post.
This problem is my misunderstanding.
I tried compiling my "main.f90" program again with ifort -gen-dep -syntax-only main.f90.
program main
use mod_a
implicit none
end program main
As a result, I got following error message and "true dependency".
main.f90(2): エラー #7002: コンパイル済みモジュールファイルを開くときのエラーです。INCLUDE パスを確認してください。 [MOD_A]
use mod_a
--------^
main.o : \
main.f90 mod_a.mod
I don't know why I didn't see this "true dependency", but my goal was already achieved.
However, additionally, I found a another probrem and solved it.
In the case that "main.f90" has huge code which use many subroutines, functions, variables, etc...
ifort -gen-dep -syntax-only main.f90 returned
fatal error: too many errors emitted, stopping now
and didn't return dependency.
To solve this problem, I added the -no-diag-error-limit to ifort command.
You need to supply information about mod_a.
Either compile it beforehand or supply it to the ifort -gen-dep command as such
$ ifort -gen-dep -syntax-only main.f90 mod_a.f90
main.o : \
main.f90 mod_a.mod
mod_a.mod : \
mod_a.f90
mod_a.o : \
mod_a.f90
I asked a question about some strange behavior from a Fortran compiler here:
gfortran compiler cannot find misspelled full directory
Basically, the compiler sporadically** complains that a file is missing, but the problem is that the printed name of the file (full path, actually) is misspelled, so no wonder it's "missing". I thought that I resolved the problem by using relative paths, but it turns out that the problem was just dormant. Here's an example of one such complaint:
C:\Users\charl\Documents\GitHub\MOONS>gfortran -fopenmp -g -fimplicit-none -cpp
C:/Users/charl/Documents/GitHub/MOONS/code/globals/current_precision.f90
...
C:/Users/charl/Documents/GitHub/MOONS/code/solvers/induction/init_Bfield.f90
C:/Users/charl/Documents/GitHub
gfortran: error:
C:/Users/charl/Documents/GitHubMOONS/code/solvers/induction/init_Sigma.f90: No such file or directory
Notice that the forward slash ('/') is missing between GitHub and MOONS, and instead reads "GitHubMOONS". This path was correctly written in the makefile.
** I say sporadically because changing lines in the code sometimes results in the error disappearing. Similarly, removing some unused modules (that compile just fine) from my compilation list results in the error disappearing.
The compiler I'm using is:
GNU Fortran (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 4.9.2 Copyright (C) 2014 Free Software Foundation, Inc.
But I've seen the same problem with more recent compilers, e.g.:
x86_64-7.1.0-release-posix-seh-rt_v5-rev2
I think I am seeing a trend with when this error occurs, and it seems to occur more frequently when modules pass on public interfaces to other modules.
Question
So, my question is, given the following two modules:
module add_int_mod
implicit none
private
public :: add
interface add; module procedure add_int; end interface
contains
subroutine add_int(a,b)
implicit none
integer,intent(inout) :: a
integer,intent(in) :: b
a = a + b
end subroutine
end module
module add_all_mod
use add_int_mod
implicit none
private
public :: add
end module
What is the difference between these two programs, if any?
Program 1
program main
use add_all_mod ! only difference
implicit none
integer :: a,b
a = 0
b = 1
call add(a,b)
write(*,*) 'a = ',a
write(*,*) 'b = ',b
end program
Program 2
program main
use add_int_mod ! only difference
implicit none
integer :: a,b
a = 0
b = 1
call add(a,b)
write(*,*) 'a = ',a
write(*,*) 'b = ',b
end program
I appreciate any help/suggestions.
What is the right flag or order of flags to disable treating particular warning as error in GCC? I want to do that for -Wimplicit-interface.
>cat test.f90
call s
end
> gfortran -c -Werror -Wimplicit-interface -Wno-error=implicit-interface test.f90 -o test.o
test.f90:1.7:
call s
1
Warning: Procedure 's' called with an implicit interface at (1)
>ls test*
test.f90
No test.o was generated.
Without -Werror it works
> gfortran -c -Wimplicit-interface -Wno-error=implicit-interface test.f90 -o test.o
test.f90:1.7:
call s
1
Warning: Procedure 's' called with an implicit interface at (1)
> ls test*
test.f90 test.o
GCC version is gcc version 4.9.2 20141030 (Cray Inc.) (GCC).
This is not an explicit answer to the question. I found it educative enough and too long to be put as comment.
As you just found, you might not be able to achieve what you want if you combine -Werror and -Wno-error=implicit-interface. Let me explain: as opposed to what we have in the doc, especially the following sentence,
The combined effect of positive and negative forms is that more specific options have priority over less specific ones, independently of their position in the command-line.
It seems that it is not the case in the actual implementation. I had a similar problem recently, and by googling, I found this which contains this sentence:
'-w' permanently sets all warnings off no matter what specific warning is set on
It actually suggests that by using some non specific options, the actual implementation does not allow you to change specific option included in the non specific one.
As #innoSPG points out, the actual behaviour does not conform to what is claimed in the manual.
The comment by #MarkGlisse revealed that this have changed with GCC 5. Therefore it was probably a bug.
The solution is therefore to use the recent version, or to not use one of the -Werror and -Wimplicit-interface.
Or to really provide explicit interfaces everywhere, but that can be problematic, as MPI libraries differ in the amount of explicit interfaces provided in the mpi modules.
I'm using gcc 4.3.4 and ld 2.20.51 in Cygwin under Windows 7. Here's a simplified version of my problem:
foo.o contains function foo_bar() which calls bar() in bar.o
bar.o contains function bar()
main.c calls functions in foo.o, but foo_bar() is not in the call chain
If I try to compile main.c and link it to foo.o, I get an undefined reference to _foo_bar error from ld. As you can see from my Makefile except below, I've tried using flags for putting each function in its own section and having the linker discard unused sections.
COMPILE_CYGWIN = gcc -iquote$(INCDIR)
COMPILE = $(COMPILE_CYGWIN) -g -MMD -MP -Wall -ffunction-sections -Wl,-gc-sections $(DEFINE)
main_OBJECTS = main.o foo.o
main.exe : $(main_OBJECTS)
$(COMPILE) -o main.exe $(main_OBJECTS)
The function foo_bar() is a short function that provides a connection between two networking layers in a protocol stack. Some programs don't need it, so they won't link in the other object files related to the upper layer of the stack. It's a small function, and seems inappropriate to put it into its own .o file.
I don't understand why ld throws the error -- nothing is calling foo_bar(), so there's no need to include bar() in the final executable. A coworker has just told me that ld is not a "smart linker", so maybe what I'm trying to do isn't possible?
Unless the linker is from Cyberdyne Systems it has no way to know exactly which functions will actually be called. It only knows which ones are referenced. Even Skynet's linker can't predict what run-time decisions will be made or what will happen if you load a module dynamically at run-time and it starts calling various global functions1.
So, if you link in module m and it references function f, you will need to link with whatever module has f.
1. This problem is related to the Halting Problem and has been proven undecidable.
I hit the similar issue and I find this page:
http://lists.gnu.org/archive/html/bug-gnu-utils/2004-09/msg00098.html
Highligt:
The GNU linker still works at .o file granularity.
Gcc pulls in foo.o and then find bar() was undefined.
You'd better put foo_bar() into another .o file.