OCaml - Compiling multiple files into one executable - compilation

I've wrote a sudoku solver in OCaml and I want to create a single executable for it.
I've got 3 files: board.ml, solver.ml and main.ml
board.ml contains the type of the board, functions to read from files, check validity, ...
solver.ml contains the functions to solve a given sudoku. solver.ml uses functions from board.ml
main.ml is a program which uses functions from both board.ml and solver.ml to solve a sudoku provided by command line arguments.
I don't use .mli files because the signatures are defined in the .ml files like:
module Board :
sig
(* signature *)
end
=
struct
(* implementations *)
end
I've already been able to do this with all the code in board.ml like:
ocamlc board.mli board.ml main.ml -o sudoku_solver
The end result should be one executable called "sudoku_solver" so I can do:
./sudoku_solver "sudoku.txt"

just use:
ocamlbuild main.native
and run it with
./main.native "sudoku.txt"

Related

"Can't open module file 'types.mod'" when compiling a main.f90 program

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

Compile Module and Main Program In the Same File Using GFortran?

I am new to fortran and I have this fortran90 program I am trying to run where the module and the main are in the same file called main.f90:
module real_precision
implicit none
integer, parameter :: sp = selected_real_kind(1)
integer, parameter :: dp = selected_real_kind(15)
end module real_precision
program main_program
use real_precision
implicit none
real(sp) :: a = 1.0_sp
real(dp) :: b = 1.0_dp
print *, a
print *, b
end program main_program
And I compiled it once doing:
gfortran main.f90 -o main.x
Then run it:
./main.x
However I made a change to the module and saved it but compiling and running it this same way provides the same output which leads me to think that the module needs to be compiled? How do I compile both where they're in the same file? I could make the module a separate file but I'd like to know how to do it this way!
selected_real_kind(p) returns the kind parameter of a real with precision at least p digits (if one exists). It does not give a kind parameter for a real with exactly that precision.
If your compiler has does not have a real with precision less than q then selected _real_kind(q) and selected_real_kind(q-1) will not return different kind parameters.

Compiling multiple Ocaml files

I am new to Ocaml and trying to write some small example application. I am using ocamlc version 3.11.2 under Linux Ubuntu 10.04. I want to compile two files:
a.ml
b.ml
File b.ml uses definitions from a.ml. As far as I understand, I can use ocamlc -c to perform compilation only. I can call ocamlc one final time when I have all the .cmo files to link them to an executable. Also, when compiling a file that uses definitions from another file, I have to tell the compiler in which .cmi file to find the external definitions.
So my idea was to use:
ocamlc -i -c a.ml > a.mli
ocamlc -c a.mli b.ml
ocamlc -o b a.cmo b.cmo
The first step works and produces files a.mli and a.cmo, but when running the second step I get
File "b.ml", line 1, characters 28-31:
Error: Unbound value foo
where foo is a function that is defined in a.ml and called in b.ml.
So my question is: how can I compile each source file separately and specify the interfaces to be imported on the command line? I have been looking in the documentation and as far as I can understand I have to specify the .mli files to be included, but I do not know how.
EDIT
Here some more details. File a.ml contains the definition
let foo = 5;;
File b.ml contains the expression
print_string (string_of_int foo) ^ "\n";;
The real example is bigger but with these files I already have the error I reported above.
EDIT 2
I have edited file b.ml and replaced foo with A.foo and this works (foo is visible in b.ml even though I have another compilation error which is not important for this question). I guess it is cleaner to write my own .mli files explicitly, as suggested by
It would be clearer if you showed the code that's not working. As Kristopher points out, though, the most likely problem is that you're not specifyig which module foo is in. You can specify the module explicitly, as A.foo. Or you can open A and just use the name foo.
For a small example it doesn't matter, but for a big project you should be careful not to use open too freely. You want the freedom to use good names in your modules, and if you open too many of them, the good names can conflict with each other.
First fix the unbound value issue, as explained by Jeffrey's answer.
This is a comment about the commands you're using.
Decomposing compilation in several steps is a good way to understand what's going on.
If you want to write your own a.mli, most likely to hide some values of the module A, then your command ocaml -i -c a.ml > a.mli is a good way to get a first version of the this file and then edit it. But if you're not touching a.mli, then you don't need to generate it: you can also directly enter
ocamlc -o foo a.ml b.ml
which will produce a.cmo, b.cmo and the exectuable foo.
(It will also generate a.cmi, which is the compiled version of a.mli, that you get by issuing ocamlc -c a.mli. Likewise it will also generate b.cmi).
Note that order matters: you need to provide a.ml before b.ml on the command line. This way, when compiling b.ml, the compiler has already seen a.ml and knows where to find the module A.
Some more comments:
You're right in your "As far as I understand" paragraph.
you don't really include a separate file, it's more like import in Python: the values of module A are available, but under the name A.foo. The contents of a.ml has not been copy-pasted into b.ml, rather, values of the module A, defined in a.ml and it's compiled version a.cmo have been accessed.
if you're using this module A in b.ml, you can pass any of the following on the command line before b.ml:
a.mli, which will get compiled into a.cmi
a.cmi if you've already compiled a.mli into a.cmi
a.ml or its compiled version a.cmo if you don't need to write your own a.mli, i.e. if the default interface of module A suits you. (This interface is simply every value of a.ml).

Generating list of generated sources (a la foreach) in automake

I am currently working on a project using templates quite extensively, and running into memory constraints during instantiation. I have split up the instantiation into a number of very simple files, which are all three-liners consisting of includes only.
I let these be generated by a rule in Makefile.am. Now I have a quite long list of files that should be generated in my Makefile, and would like to refactor this list with a foreach-like expression. In more specific terms: I have a line like
libfoo_la_SOURCES = a_0.cpp a_1.cpp ... b_0.cpp b_1.cpp ... c_0.cpp c_1.cpp ...
which could be more concisely expressed as
libfoo_la_SOURCES = $(foreach i,a b ...,$(foreach j,0 1 ...,$i_$j.cpp))
However, the second construct is not only warned against by automake, but also does not work: The files given in this manner are neither compiled nor cleaned.
My current workaround is generating this file list by a shell script.
Any ideas how to implement this iteration?
I would forget about making loops: the GNU extension is not standard, and not understood by Automake. One standard (and portable) make construction you can use here is the macro expansion with substitution: $(var:subst1=subst2) will expand to the value of $(var) after replacing any suffix subst1 of a word by subst2. Automake understands this.
If subst1 is empty, as in $(var:=subst2), you are appending subst2 to all files in $(var). You can use this to construct your list of files as follows:
f = a b c d e f
g = $(f:=_0) $(f:=_1) $(f:=_2) $(f:=_3)
all_files = $(g:=.cpp)
echo:
#echo $(all_files)
Running make echo with the above Makefile will display all files from a_0.cpp to f_3.cpp.
Like you, I discovered that the GNU make foreach function will not work like this because
the sources need to be there at the time the Makefile is generated. So, I use GNU Autogen (also here) to generate a makefile fragment which is subsequently included in Makefile.am. So it's probably not that different than your shell script approach.

Fortran query and print out function or subroutine name

Is it possible in Fortran to query the name of the function or subroutine that I am in? I.e., what do I put in place of '???' to get it to print 'my_subroutine' on the screen?
subroutine my_subroutine()
write(*,*) ???
end subroutine my_subroutine
I am trying to find a way to implement a custom debugger/profiler using nothing but a text editor's search and replace mechanism. Programmatically querying my position in the code would be helpful.
No, you can't. What you want to achieve is called reflection and it is not available in Fortran (nor in C or C++ for what matters).
You can use the preprocessor to print out the file name and line number. You might want take advantage of the predefined preprocessor symbols __LINE__ and __FILE__. Here's an example:
A preprocessor macro is defined in header file (so that it can be used in multiple locations), call it errormsg.h:
#define ERRORMSG(msg) write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,msg
Then you can include this header file in your program, library or module files, for example:
#include "errormsg.h"
program main
ERRORMSG("not really an error...")
call foo()
end program
subroutine foo()
ERRORMSG("not an error too!")
end subroutine
The ERRORMSG("not really an error...") seems like weird syntax for fortran code, but it get's replaced by the c-preprocessor using the macro definition. So when this is compiled, it looks like:
write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,"not really an error"
For my ERRORMSG macro, I chose to use the 0 file unit to print to stderr. You obviously have the freedom to write the message how ever you like, as long as it results in syntactical correct FORTRAN code.
Getting this to compile requires you to pass flags to the compiler, and they differ slightly from compiler to compiler. This worked for me, for example:
gfortran -cpp -o errorTest errorTest.f90
That is, for gfortran, -cpp invokes the c-preprocessor before compiling. The output from the above program looks like this:
There was an error at 5 in file
errorTest.f90
Error message: not really an error...
There was an error at 13 in file
errorTest.f90
Error message: not an error too!
This might have the effect you are looking for, especially if you write only one subroutine per file.
I found an easy semi-automated way out of this situation: use regex to add a hardcoded definition of __FUNCTION__ right after the SUBROUTINE declaration. Done from within the makefile will take care that every compilation refreshes the __FUNCTION__ macro.
Suppose we have a F77 listing that looks like this
file 'my-file.F'
SUBROUTINE my_sub(var1, var2, var3)
INCLUDE 'some-include.PRM'
INTEGER var1
INTEGER var2
! the rest of my code here
WRITE(*,*)__FUNCTION__
END SUBROUTINE
I want to convert it to
file 'my_file.F.F'
SUBROUTINE my_sub(var1, var2, var3)
#undef __FUNCTION__
#define __FUNCTION__ "my_sub"
INCLUDE 'some-include.PRM'
INTEGER var1
INTEGER var2
! the rest of my code here
WRITE(*,*)__FUNCTION__
END SUBROUTINE
Note the amended code is now located in another source file: my-file.F.F
To do this I added the following lines to 'Makefile'
my-file.o: my-file.F
perl -pne 's/^(\s+SUBROUTINE\s*)([^(]+)(\(.*\))/$$1$$2$$3\n#undef __FUNCTION__\n#define __FUNCTION__ _S($$2)/ixms' $< > $<.F; \
$(FC) $(CPPFLAGS) $(FCFLAGS) -c $<.F -o $#
Assuming FC is defined as the fortran compiler executable, this should perform the following procedure on all the subroutines in the file:
undefine a __FUNCTION__ macro that was possibly defined earlier.
Add a __FUNCTION__ directive two lines below the SUBROUTINE definition, containing the subroutine's name.
save the file under another name.
compile the new source into the required object file.
The result should be my-file.o in this case.
You may have noticed that I'm using the macro _S() as well. This is a 'stringify' macro. You just need to add it to the top of your fortran file (I place it inside a config.h that I include everywhere)
There is a different implementation for GNU and intel:
#ifdef __INTEL_COMPILER
#define _S(x) #x
#else
#define _S(x) "x"
#endif
There are sometimes non-standard features in compilers to help you to print where you currently are. These are highly compiler specific and should be used only for debugging.
In gfortran you can use subroutine BACKTRACE. From the manual:
BACKTRACE shows a backtrace at an arbitrary place in user code.
Program execution continues normally afterwards.
The output will look like an error message, but it may be helpful.
Why don't you just hard write the name of the subroutine you're in, in the WRITE statement?
You cannot programmatically (dynamically) give or change the name of the subroutine, therefore I see no reason to try to access it either that way (about that: while I'm not sure that it is impossible to access it somehow, I'm quite sure that it is the wrong way to go ... you will cause yourself more trouble going that way, than just hard coding it).
Btw, why are you trying to print it out anyway? Wouldn't a well phrased diagnostic message be more informative?

Resources