Impossible to compile Fortran code with include statement - unix

I have a script "simul.f" that starts with a line
include 'support.f'
and I also have the "support.f" script. The line showed above is the only line that call the support.f, so I tried to compile both of them using:
gfortran -o executable support.f simul.f
and I get the following error:
/home/pmachado3/LarryProject Oficial/WI1_francisco/T2/WI4/FF04/04-1$ gfortran -o exec support.f simul.f
/tmp/ccOicDhk.o: In function support_':
simul.f:(.text+0x0): multiple definition ofsupport_'
/tmp/ccnkwMCD.o:support.f:(.text+0x0): first defined here
collect2: ld returned 1 exit status
I made a test and tried to remove the line include from simul.f and it compiled however did not generate my output file .txt that should generate
Is there any way to compile the code in Unix with the include line??
The code works fine on Windows and was written in Force 2.0

You just compile the file that contains the include statement
gfortran -o executable simul.f
and the include is performed by the compiler automatically.
If the included file is in some other directory path you must tell the compiler where that path is
gfortran -o executable simul.f -Ipath

Related

gcc Compling and linking object file and source file at the same time

In a nutshell , the issue is I have some object file (say a.o , b.o ) and some source file (f.c and g.c)
I have to compile and link in a single step.
This is what I am doing but I don't think this is the write way atleast I should give something like -l or -L for linking
gcc -Wall -O0 -ggdb -fPIC a.o b.o f.c g.c -o executable
This is the correct way, -l is used to link to a library (for example, the ptheads library needs -lpthread) and -L is used to add directories to the directories in which the linker looks for library files.
There is nothing wrong with compiling the software this way.
Most build systems build files one at a time in order to avoid having to rebuild the object file in case the source file was not modified and the object file still exists. If you are fine with rebuilding code, then your approach is perfectly valid.

Specifying Directories during Fortran Compilation

I am using GNU Fortran 95 on OpenSUSE Leap to compile my source code, and I am trying to figure out how to tell gfortran to change the default directory to search for my modules.
Let me explain my setup. I've written several module files that contain general subroutines I use. I've placed and compiled these files in a folder entitled ModuleRepo. My working scripts are placed in a separate folder. For example, I tried the following command:
gfortran -o script script.f95 -I/pathToFolder/ModuleRepo module1.o module2.o
However, this is not working. It is returning the following error:
gfortran: error: module1.o: No such file or directory.
The *.o files do exist in ModuleRepo, so I'm unsure what's going on. Everything works fine if I copy all my module files to the directory. But, I'd like a way to avoid copying the same files over and over.
gfortran -o script script.f95 -I/pathToFolder/ModuleRepo /pathToFolder/ModuleRepo/module1.o /pathToFolder/ModuleRepo/module2.o

How to install/locate R.h and Rmath.h header files?

I am trying to compile some C code (called rand_beta) in terminal which contains the lines to include R.h and Rmath.h header files using gcc -o rand_beta rand_beta.c so I can then call the code from within R.
However, I get the error messages:
rand_beta.c:1:15: error: R.h: No such file or directory
rand_beta.c:2:19: error: Rmath.h: No such file or directory
It seems that these header files which should come installed with R are not on my system.
Can someone guide me as to how I can get my computer to find the R header files? Do I need to download them from somewhere?
The other answers try to guess where your R installation directory is. But there is a more robust solution. Use the R.home command in R to find it wherever it is:
> R.home('include')
/usr/lib64/R/include
That is the folder containing R.h and Rmath.h on my system. Your folder may be in a different place.
You first need to locate those headers. In my system, they are located in /usr/lib64/R/include/R.h, part of the R-devel package I installed with yum.
Then use the -I option of gcc to tell gcc where to find them.
gcc -I/usr/lib64/R/include -o rand_beta rand_beta.c
Then, you will also most probably need to export LD_LIBRARY_PATH to run your compiled program:
LD_LIBRARY_PATH=/usr/lib64/R/lib ./rand_beta
Another way is to specify some environment variables to directly use the include path:
export CPATH=/usr/lib64/R/include/
export C_INCLUDE_PATH=/usr/lib64/R/include/
export CPLUS_INCLUDE_PATH=/usr/lib64/R/include/
export GCC_INCLUDE_DIR=/usr/lib64/R/include/
This should then run fine:
gcc -o rand_beta rand_beta.c

The logic of the ocaml compile process

I wrote a small project in OCaml.
I have two folders:
./myUnionFind. inside there is a file myUnionFind.ml.
./percolation. inside there are two files: myPercolation.ml and percolation_stats.ml.
myUnionFind.ml works as a module.
myPercolation.ml works as a module too, but it uses MyUnionFind module defined in myUnionFind.ml.
percolation_stats.ml uses myPercolation.ml.
together with above all, I also use Batteries.
I want to compile them all to work and get a executable file run.
But how?
I have tried the following:
inside folder ./percolation, I did ocamlfind ocamlc -package batteries -linkpkg ../myUnionFind/myUnionFind.ml myPercolation.ml percolation_stats.ml -o run
It failed, and said File "myPercolation.ml", line 1, characters 0-16:
Error: Unbound module MyUnionFind, but I did include that folder ../myUnionFind, right?
Also, if I just want to compile ./myUnionFind/myUnionFind.ml once, how can I do so that not every time, myUnionFind.ml gets compiled again and again?
Inside myUnionFind, you should compile myUnionfind.ml to a compiled unit:
cd myUnionFind
ocamlc -c myUnionFind.ml
This will generate myUnionFind.cmo, which stores the compiled implementation, and myUnionFind.cmi, which stores the compiled interface. Other modules using MyUnionFind will need to access the cmi at type-checking type.
Inside percolation, you can compile myPercolation.ml to a module by doing
cd percolation
ocamlc -I ../myUnionFind -c myPercolation.ml
Again, you get both a .cmo and a .cmi. Note that the compiler has looked up myUnionFind.cmi automatically in the search path, and found it because of the -I option.
You can then compile percolation_stats (relying on both previous compilation units)
ocamlc -I ../myUnionFind -c percolation_stats.ml
You finally link the three resulting .cmo together to build an executable:
ocamlc ../myUnionFind.cmo myPercolation.cmo percolation_stats.cmo -o run
(If you use batteries, wrap each command with ocamlfind ocamlc -package batteries, but only the linking command with linkpkg).
To make this process simpler:
ocamlbuild is good at finding and compiling all the files of your current project to produce an executable. In the percolation directory, ocamlbuild percolation_stats.byte can produce an executable with all the stuff present
but if you want to use myUnionFind as an external library, the best thing to do would be to install it with findlib, to make it easy to find and specify from percolation; for information on how to create a findlib package (it's very simple), please see this older answer
once myUnionFind is a findlib package, the single command ocamlbuild -use-ocamlfind -pkgs batteries,my-union-find percolation_stats.byte (or .native) should be enough to get an executable

How to load a module inside an OCaml file?

I wish to use module Std inside my OCaml .ml file.
I tried #load "Std", but the compiler complains.
How can I load a module inside OCaml?
You must compile the module you wish to include first, provide the location of the compiled files to compilation commands of modules depending on it, then provide it in the final compilation command line.
Let's consider for instance file foo/moduleA.ml:
let v = 1
and file bar/moduleB.ml:
open ModuleA
let w = v
The commands:
$ cd foo
$ ocamlc -c moduleA.ml
$ cd ..
will produce moduleA.cmo and moduleA.cmi. The former is the bytecode object of the module (like a .o file in for native object files, but containing bytecode data and text), the later is a bytecode compiled header, produced from an automatically generated .mli file. This bytecode header is necessary for the compiler to compile files which depend on ModuleA.
$ cd bar
$ ocamlc -I ../foo -c moduleB.ml
$ cd ..
will succeed in producing moduleB.cmo, which depends on ModuleA, because the previous command has been successful, and because we indicate the compiler where to look for dependancies with the -I command line parameter, followed by the path of the first module.
The last command below will produce a bytecode executable from both modules:
$ ocamlc -I foo -I bar moduleA.cmo moduleB.cmo -o prog.byte
The modules must be provided in that order, to let the compiler know the dependancies first. The -I parameters this time indicate where to find the .cmo files.
In your case, you must therefore use the -I <location of std.cmi> for the compilation proper phase, and -I <location of std.cmo> (or std.cma, if it is a library) for the second phase (the link phase). If you can combine both phases in one command (ie. ocamlc -I foo foo/moduleA.ml bar/moduleB.ml -o prog.byte), and if both cmo and cmi files are in the same directory, only one parameter will suffice.

Resources