I am trying to compile a very simple program with a Makefile.
The program main.f90 just uses a module cic.f90.
These are the files:
main.f90
program main
use cic, only: pi, area
implicit none
real(kind=8) :: a
! print parameter pi defined in module:
print *, 'pi = ', pi
! test the area function from module:
a = area(2.d0)
print *, 'area for a circle of radius 2: ', a
end program main
the module file: cic.f90
module cic
implicit none
real(kind=8), parameter :: pi = 3.141592653589793d0
contains
real(kind=8) function area(r)
real(kind=8), intent(in) :: r
area = pi * r**2
end function area
real(kind=8) function circumference(r)
real(kind=8), intent(in) :: r
circumference = 2.d0 * pi * r
end function circumference
end module cic
Heres the simple Makefile I created:
#Makefile
main.so: main.f90 cic.o
gfortran -o main.so main.f90 cic.o
cic.o: cic.f90
gfortran-c cic.f90
this creates a main.so file but when I try and run it gives the following error
Segmentation fault (core dumped)
I am using a virtual machine running Ubuntu.
Is it something to do with the targets or how I named the module file, should it be cic.mod instead of .f90 or should the target for the module be .mod instead of .o?
Additionally, when I compile using the terminal writing the following:
gfortran main.f90 cic.f90 -o main.so
everything works
#Makefile
main.exe: main.o cic.o
gfortran -o $# $^
%.o: %.f90
gfortran -c $<
$# is the target (here, main.exe of file.o), $^ is 'all prerequisites' (here, main.o and cic.o) and $< is 'the prerequisite' (here, either cic.f90 or main.f90). See https://www.gnu.org/software/make/manual/make.html
I second Vladimir F in not using .so as an extension for something else as a shared object.
If you keep having trouble with the code, show us the actual code, the actual makefile, etc.
EDIT: PS: if you copy paste the Makefile, make sure to replace the indentation with tabs.
Related
I want to create a Makefile which will build a program which when run's output will be used as a value for a variable in the same Makefile.
Consider the program:
print_name.c:
#include <stdio.h>
int main() {
printf("foo\n");
return 0;
}
I'd like to use the standard output of this program to then determine a directory name to be stored in a variable used in the makefile and used for other rules, so far I've tried:
all: $(MY_DIRECTORY_NAME)/my_program
print_name: print_name.c | print_name
gcc $^ -o $#
MY_DIRECTORY_NAME:=$(shell ./print_name)
$(MY_DIRECTORY_NAME)/my_program: my_program.c
mkdir -p $(MY_DIRECTORY_NAME)
gcc $^ -o $#
However when I run:
make all
I get:
make: *** No rule to make target '/my_program', needed by 'all'. Stop
Whereas I'd like:
mkdir -p foo
gcc my_program.c -o foo/my_program
So basically, I want to compile print_name before the assignment to MY_DIRECTORY_NAME, and then that variable in then used in the following rules. Is this possible, and if not are there any workarounds for this?
The basic problem is that you need to build (and run) print_name before you can parse the rules that use it -- but all rules are read and parsed before anything is built. So you need to run make twice -- first to build print_name and second to build everything that depends on it. Something like
all: print_name
$(MAKE) `./print_name`/my_program
should do the trick
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
I've got a C++ program with a Makefile, building (g++) and running on Windows cmd. Thing is, sometimes it takes a while to run and save the results, and I want to run it with different parameters at the same time so that I can do something else while I wait for the first instance to finish. It doesn't work though, because of the executable I guess:
>make
g++ -c -o main.o main.cpp
Assembler messages:
Fatal error: can't create main.o: Permission denied
make: *** [main.o] Error 1
You have two problems: The one you ask about, and the reason you ask this question in the first place.
Lets start with the problem you have...
Judging by the Makefile you show, you have it all wrong.
Rules are in the format
target: sources_the_target_depend_on
The target is usually a file that need to be created. For an object file that is the name of the actual object file itself. The source files that the object files then depend on should be on the right-hand side.
To take an example from you Makefile (before you edited it away):
graph2: graph2.o
g++ -g -c graph.cpp -o graph2.o
Here you tell make that the file graph2 depends on the file graph2.o, and then it creates the graph2.o file. That's wrong. The rule should be that the file graph2.o depends om the file graph.cpp and go on to generate the file graph2.o:
graph2.o: graph.cpp
g++ -g -c graph.cpp -o graph2.o
This indirectly leads to the problem you have, with this line (deduced from your error and the Makefile):
main: main.o utils.o graph.o heuristics.o
g++ -g main.cpp -o main.o utils.o graph.o heuristics.o
This contains the same error as discussed above: You say that the file main depends on main.o and then the rule create main.o. Your rule should be
main: main.cpp utils.o graph.o heuristics.o
g++ -g main.cpp -o main utils.o graph.o heuristics.o
Note also how I no longer name the executable file main.o, as that is supposed to be used for object files.
Now lets continue with the reason you have the problem in the first place: That you need to edit the code to change data or values.
This is a problem that you need to solve. One common way to solve it is through command line arguments. If your program parses the command line arguments passed to your program you can pass it the values that could change from run to run.
How to do this is whole chapter on its own, so I wont give you any more details. There are plenty of tutorials online.
Lastly, you can simplify your Makefile considerably, by using implicit rules and variables.
I would simply create the Makefile to look something like this
# The compiler to use
CXX = g++
# Flags to pass to the compiler (add warnings when building)
CXXFLAGS = -Wall
# The main executable file to generate
TARGET = main
# List the object files needed to generate the main executable file
OBJECTS = main.o utils.o graph.o heuristics.o
# The all target depends on your main executable file
# Also as the first target in the Makefile, if no specific target is specified
# this will be the one that is used (it's the "default" target for the Makefile)
all: $(TARGET)
# The main executable file depends on the object files
$(TARGET): $(OBJECTS)
This is really it. the object files will be built automatically from their respective source files, and then the executable program will be linked using the object files listed.
I am encountering a problem when I include a Fortran
subroutine in a shared library. This subroutine has a
named common block.
I have a Fortran main program that uses this common block
and links with the shared library.
The behavior is that variables in the common block set in
either the subroutine or main program are not shared between
the two.
I am using gfortran 4.9.3 under MinGW on windows. Here are the pieces of
my very simple example.
Main program:
program mainp
common/whgc/ivar
ivar = 23
call sharedf
end
Subroutine:
subroutine sharedf
common/whgc/ivar
print *, 'ivar=', ivar
end
Makefile:
FC = gfortran
FFLAGS=-g
all: shltest.dll mainp.exe
shltest.dll: sharedf.o
$(FC) -shared -o shltest.dll sharedf.o
mainp.exe: mainp.o shltest.dll
$(FC) -o mainp.exe mainp.o shltest.dll
clean:
rm *.o mainp.exe shltest.dll
When mainp.exe is run, it produces ivar = 0 instead of the correct ivar=23
Here are the results of some experimentation I did with nm.
nm -g mainp.o shows:
...
00000004 C _whgc_
nm on sharedf.o shows the same.
nm -g shltest.dll shows:
...
71446410 B _whgc_
nm -g mainp.exe shows:
...
00406430 B _whgc_
This is the only _whgc_ symbol in mainp.exe.
However, when I run mainp.exe in gdb and set break points in both
mainp and sharedf, I can print the address of ivar at each break point. The addresses
are not the same.
From the behavior it seems clear that GNU ld is not correctly
matching the _whgc_ symbols but I'm unclear about what options
to pass either in the shared library build or the final link to
make it do so?
(Please don't suggest alternatives to common blocks. In my real
application I am dealing with legacy code that uses common blocks.)
EDIT:
I tried my example on Linux/x86 and there the behavior is correct.
Of course on Linux the shared library and executable are ELF format
objects and on Windows/MinGW the format is PE/COFF.
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