How to load a module inside an OCaml file? - functional-programming

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.

Related

Disable parallel execution in make

I have a building process that creates a header file. In the second stage, several source files are generated from that header file. Then these source files are built into a binary. If anyone is interested these sources are generated with gSOAP utilities (wsdl2h, soapcpp2).
I have made Makefile.am, etc to build these sources, but there are problems when I want to use parallel execution.
Makefile.am would look something like this in a very simplified form
## generate header file
service.h : service.wsdl
wsdl2h -o $# service.wsdl
## list of generated source files
generated_files = source1.cpp source2.cpp source3.cpp
## generate source files
$(generated_files) : service.h
soapcpp2 $^
## build binary
binary: $(generated_files)
gcc -o $# $^
The rules say that service.h will be generated if service.wsdl changes. If service.h changes, soapcpp2 will generate source?.cpp files with one command execution.
Everything works fine until I try to build in parallel (for instance make -j4). The problematic line is the last one which generates many soruce files. If running in parrallel all these files are generated many times, while other make processes already try to compile them.
I followed instructions to disable parallel https://www.gnu.org/software/make/manual/html_node/Parallel-Disable.html, but with no success. If I try
.NOTPARALLEL: $(generated_files)
or
.NOTPARALLEL: service.h
The parallel execution just does not work any more. I also tried with .WAIT, and got no rule to make target .WAIT.
First, the .WAIT special target was introduced in GNU make 4.4. Since you are getting a no rule to make target error for it, it's clear you're using an older version which doesn't support it. It's usually a good idea to include the version of whatever tool you're using when asking for help.
The best thing to do is not disable parallelism but instead tell make that a single invocation of the recipe will generate all the files. If you have GNU make 4.3, then you can use a "grouped target" rule, like this:
## generate source files
$(generated_files) &: service.h
soapcpp2 $^
the &: here tells make that instead of building each target with a different invocation of the recipe, which is the default, a single invocation of the recipe builds all the targets.
If you don't have GNU make 4.3 then you'll need to play a trick to get the same behavior, something like this:
## generate source files
.sentinel : service.h
soapcpp2 $^
#touch $#
$(generated_files) : .sentinel ;
## build binary
binary: $(generated_files)
gcc -o $# $^
This has all the generated files depend on a single file .sentinel (you can name it whatever you want), which is the one make knows is generated by the recipe that also creates all the other source files. This isn't perfect but it will work for simple situations.

How can be C files linked when using E-ACSL plugin?

I am trying to generate an annotated file with Frama-C E-ACSL plugin. I created the following files:
Insert.c: contains all the structures to create a linked list.
AxiomTest.c: includes the main function where the asserts it must fulfil are indicated. All functions and structures are determined in terms of Insert.c file
When compiling/instrumenting a program the manual specifies the following terminal command:
$ e-acsl-gcc.sh -c <files> -O <output>
For a successful compilation Insert.c and AxiomTest.c must be linked but I cannot find any flag for that.
Any help? Or is there any other way to do it right?
e-acsl-gcc.sh does compile and link files with option -c, despite looking like it only compiles (the -c here is unrelated to GCC's -c option, which does only compilation, without linking).
If you want to give extra flags to the linker, man e-acsl-gcc.sh (or e-acsl-gcc.sh -h) will indicate option -l:
-l pass additional options to the linker

Makefile run an action before everything

For building my target I have a list of prerequisites contained in a file list.txt and a script for generating this file generate-list.sh.
I need the script to be executed as first thing every time I invoke the make in order to have the list.txt updated and to give ti make the right list of prerequisites.
prebuild:
touch list.txt
.SECONDEXPANSION:
exe: prebuild $$(shell cat list.txt)
touch exe
<files in list.txt>:
<rules for generating these files>
In this way when I run make I first get an error from cat saying that list.txt does not exist, then list.txt is generated but since the cat failed the prerequisites contained in list.txt are not generated.
One method you could use, given that generate_list.sh must be executed at the very start every time, would be to explicitly execute it using the shell function. This would mean altering your makefile to something like
$(shell ./generate_list.sh > /dev/null)
.SECONDEXPANSION:
exe: $(shell cat list.txt)
touch exe
#echo $?
<files in list.txt>:
<rules for generating these files>
Executing this makefile produces
$ make
touch exe
deps.c test.c
where my generate_list.sh file contains
#!/bin/bash
touch test.c deps.c
echo deps.c test.c > list.txt
echo 'Created prerequisites list.'
Notes
/dev/null is included in $(shell ./generate_list.sh > /dev/null) incase your generate_list.sh produces an output as this would cause an error in make of
$ make
GNUmakefile:1: *** missing separator. Stop.
otherwise.
#echo $? shows that all of the prerequisites in list.txt are now included as prerequisites of exe.
Alternate Method Based on Auto Dependency Generation
What you are attempting to do is very similar to automatic dependency generation which can be accomplished using the -include directive in make. For future usage you may want to consider going down this route and altering your generate_list.sh script to create a makefile that can be included in your main makefile.

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) Can I determine the version of the c99 compiler on my machine?

Is there a command line flag, or something similar, that I can use to get c99 to print it's version?
I'm looking for output similar to gcc's -v flag, which gives me:
Using built-in specs.
Target: i686-apple-darwin11
Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.11~28/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~28/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
I really only care about the Target: line and the last line.
c99 --version
~$c99 --version
gcc (Debian 4.4.5-8) 4.4.5
also try c99 --help
~$ c99 --help
Usage: gcc [options] file...
Options:
-pass-exit-codes Exit with highest error code from a phase
--help Display this information
--target-help Display target specific command line options
--help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]
Display specific types of command line options
(Use '-v --help' to display command line options of sub-processes)
--version Display compiler version information
-dumpspecs Display all of the built in spec strings
-dumpversion Display the version of the compiler
-dumpmachine Display the compiler's target processor
-print-search-dirs Display the directories in the compiler's search path
-print-libgcc-file-name Display the name of the compiler's companion library
-print-file-name=<lib> Display the full path to library <lib>
-print-prog-name=<prog> Display the full path to compiler component <prog>
-print-multi-directory Display the root directory for versions of libgcc
-print-multi-lib Display the mapping between command line options and
multiple library search directories
-print-multi-os-directory Display the relative path to OS libraries
-print-sysroot Display the target libraries directory
-print-sysroot-headers-suffix Display the sysroot suffix used to find headers
-Wa,<options> Pass comma-separated <options> on to the assembler
-Wp,<options> Pass comma-separated <options> on to the preprocessor
-Wl,<options> Pass comma-separated <options> on to the linker
-Xassembler <arg> Pass <arg> on to the assembler
-Xpreprocessor <arg> Pass <arg> on to the preprocessor
-Xlinker <arg> Pass <arg> on to the linker
-combine Pass multiple source files to compiler at once
-save-temps Do not delete intermediate files
-pipe Use pipes rather than intermediate files
-time Time the execution of each subprocess
-specs=<file> Override built-in specs with the contents of <file>
-std=<standard> Assume that the input sources are for <standard>
--sysroot=<directory> Use <directory> as the root directory for headers
and libraries
-B <directory> Add <directory> to the compiler's search paths
-b <machine> Run gcc for target <machine>, if installed
-V <version> Run gcc version number <version>, if installed
-v Display the programs invoked by the compiler
-### Like -v but options quoted and commands not executed
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o <file> Place the output into <file>
-x <language> Specify the language of the following input files
Permissible languages include: c c++ assembler none
'none' means revert to the default behavior of
guessing the language based on the file's extension
Options starting with -g, -f, -m, -O, -W, or --param are automatically
passed on to the various sub-processes invoked by gcc. In order to pass
other options on to these processes the -W<letter> options must be used.

Resources