I am following this tutorial for OCaml when I try to write this program in a file and then compile and execute with dune.
open Base
open Stdio
let rec read_and_accumulate accum =
let line = In_channel.input_line In_channel.stdin in
match line with
| None -> accum
| Some x -> read_and_accumulate (accum +. Float.of_string x)
let () =
printf "Total: %F\n" (read_and_accumulate 0.)
However I get the error 'unbound module Base'. Looking online I found the solution of adding #require “base”;; to the .ocamlinit file and that allows me to use the module in utop but it still won't work with running a file using dune. How can I run this program from a file?
With the small amount of informations you're giving I can only guess that you didn't write a proper dune file. It should look like this::
(executable
(name read_and_acc)
(libraries base))
Related
I have the below OCaml file which compiles correctly without ppx and fails with this dune file
(library
(name so_proj)
(preprocess
(pps
ppx_inline_test
ppx_deriving.show
ppx_deriving.ord
ppx_deriving.map
ppx_deriving.eq
ppx_deriving.fold
ppx_deriving.iter)))
and works with
(library
(name so_proj))
the error being
File "SO_naming_existential.ml", line 23, characters 16-18:
23 | fun (Mod (type xr) (m : xr)) ->
^^
Error: migration error: existentials in pattern-matching is not supported before OCaml 4.13
here's the OCaml file in question which uses a new syntax (and provides an equivalent - I believe - version when it's not available)
type existentiel = Mod : 'x -> existentiel
module type existentiel_m = sig
type x
val value : x
end
let to_Module : existentiel -> (module existentiel_m) =
fun (Mod m) ->
let namedxr : type xr. xr -> (module existentiel_m) =
fun v ->
(module struct
type x = xr
let value = v
end)
in
namedxr m
(* Since 4.13 https://github.com/ocaml/ocaml/pull/9584 *)
let to_Module2 : existentiel -> (module existentiel_m) =
fun (Mod (type xr) (m : xr)) ->
(module struct
type x = xr
let value = m
end)
To confirm the origin of the error (and to run first for avoiding to waste time..) the command
dune build --verbose points indeed at an error happening in ppx
Running[2]: (cd _build/default && .ppx/0789030747a4993265eb655c993f5cab/ppx.exe --cookie 'inline_tests="enabled"' --cookie 'library-name="so_proj"' -o SO_naming_existential.pp.ml --impl SO_naming_existential.ml -corrected-suffix .ppx-corrected -diff-cmd - -dump-ast)
Command [2] exited with code 1:
$ (cd _build/default && .ppx/0789030747a4993265eb655c993f5cab/ppx.exe --cookie 'inline_tests="enabled"' --cookie 'library-name="so_proj"' -o SO_naming_existential.pp.ml --impl SO_naming_existential.ml -corrected-suffix .ppx-corrected -diff-cmd - -dump-ast)
File "SO_naming_existential.ml", line 23, characters 16-18:
23 | fun (Mod (type xr) (m : xr)) ->
^^
Error: migration error: existentials in pattern-matching is not supported before OCaml 4.13
Can one force ppx to use 4.13, or get a warning when a ppx is not compatible with a given version ? (or is it a bug ?)
An executable or a library could only be composed of compilation units that are compiled by the same compiler. In other words, you can't build some parts of your project with one compiler and the other parts with another.
When you compile an OCaml project using dune the compiler is searched in the in the directories specified in your PATH variable (in Linux). You can see which compiler is selected using the shell command which ocaml. And ocaml -version will tell you its version.
If you're using opam (most likely you are), then you can install the required version of the compiler using the following shell command,
opam switch create 4.13.1
once it is finished, activate the created switch with
eval $(opam env)
This will ensure that the newly installed version of OCaml is available in your path. Double-check that using which ocaml and ocaml -version.
Finally, install the dependencies required by your project with opam install and rebuild the project.
On Fedora 21, I compiled the Frama-C Aluminum distribution from source after installing all its prerequisites. My version of OCaml is 4.02.3. Frama-C and the Frama-C GUI work fine. I am trying to follow section 2.3, "The ViewCfg plug-in" of the Frama-C Plug-In Development Guide. However, in section 2.3.4, "Extending the Frama-C GUI", after I add the GUI extension code and run it using the "-load-script" option, I get the following message:
File "cfg_print.ml", line 87, characters 19-43:
Error: Unbound module GMenu
[kernel] user error: compilation of 'cfg_print.ml' failed
Lines 86-87 read:
let cfg_selector
(popup_factory:GMenu.menu GMenu.factory) main_ui ~button:_ localizable =
I googled "unbound module gmenu" but didn't find anything useful. I also never ran into this error while using the Neon and Sodium versions of Frama-C. Interestingly, if I skip that section and follow section 2.3.5, "Splitting files and writing a Makefile", I no longer get the "Unbound module GMenu" message, and the example works fine.
If I had to guess, when I use the "-load-script" option, Frama-C (or my version of OCaml, whatever the case may be) apparently cannot find the Gtk libraries for some reason. But if I use make, OCaml can find the Gtk libraries. Is there something possibly wrong with the way I installed Frama-C and/or the Gtk libraries? How can I check this, or more importantly, how can I fix this?
Your Frama-C installation is probably ok. What you observe is a bug that was introduced when we transitioned to OCamlfind. We will fix it for Frama-C Silicium.
In case you really want to use a script, here is the patch that you need to apply to the sources of Frama-C:
--- a/src/kernel_services/plugin_entry_points/dynamic.ml
+++ b/src/kernel_services/plugin_entry_points/dynamic.ml
## -236,7 +236,7 ## let load_script base =
else
Format.fprintf fmt "%s -c" Config.ocamlc ;
Format.fprintf fmt " -w Ly -warn-error A -I %s" Config.libdir ;
- if !Config.is_gui then Format.pp_print_string fmt " -I +lablgtk" ;
+ if !Config.is_gui then Format.pp_print_string fmt " -package lablgtk2" ;
List.iter (fun p -> Format.fprintf fmt " -I %s" p) !load_path ;
Format.fprintf fmt " %s.ml" base ;
Format.pp_print_flush fmt () ;
I have the following code in OCaml:
open Lwt
open Lwt_term
let () = Lwt_main.run (
lwt l = Lwt_read_line.read_line ~prompt:[text "foo> "] ())
when I try to compile using
ocamlfind ocamlc -package lwt cli.ml - o cli.byte
it I get the following error:
File "cli.ml", line 2, characters 0-13:
Error: Unbound module Lwt_term
I know it's unrelated to the problem above, but from utop I can open Lwt but I still can't open Lwt_term. What am I doing wrong?
Source file is located there so I bet that you need lwt.text package
Not really a real answer to the original question, but I have ended up using Core to accomplish it. The enlightenment came from finding the readline_test.ml file in a tests folder in the Core library (https://github.com/janestreet/core_extended/blob/master/lib_test/readline_test.ml).
Following that example it was really easy to implement readline-like functionality.
I find that when I run ocaml in terminal, ie, in interactive mode, it will load .ocamlinit. However, when I run ocaml test.ml, ie, in script mode, it doesn't load .ocamlinit file. This actually causes some trouble for me, since I have the following setup in my .ocamlinit:
let () =
try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
with Not_found -> ()
;;
#use "topfind";;
#thread;;
#camlp4o;;
#require "core.top";;
#require "core.syntax";;
So when I run in interactive mode, #use "topfind" will be executed and I can open other libraries in my code. But as .ocamlinit is not loaded in script mode, when I run ocaml test.ml in terminal, with test.ml like this:
open Core.Std;;
let () = print_endline "hello world"
It will fail with error: "Error: Unbound module Core".
My question is:
How to fix this so that when running ocaml in script mode, the .ocamlinit file will also be loaded?
Why the ocaml toplevel system doesn't load .ocamlinit file in script mode?
ps. The OCaml version is 4.01.0
I think that's a "bug" (or at least unexpected behaviour) in the toplevel. This could be fixed in future versions of OCaml. I don't have a satisfying workaround to propose, besides ocaml -noprompt < test.ml (which is not equivalent as you will get some noisy output from the toplevel instead of just your file executed), or of course compiling the program and running it (which may be as simple as ocamlbuild test.byte && ./test.byte).
I just installed a package called Ppl, here is the result of find -name "*ppl.*" under /usr/:
./lib/libppl.so.7.1.0
./lib/libppl.so.7
./lib/libcloog-ppl.so.0
./local/share/man/man3/libppl.3
./local/share/aclocal/ppl.m4
./local/include/ppl.hh
./local/lib/libppl.so
./local/lib/libppl.la
./local/lib/libppl.a
./local/lib/libppl.so.9
./local/lib/libppl.so.9.0.0
But when I run the following code by ocamlc -I /usr/local/lib/ocaml/3.11.2/apron -I /usr/local/lib/ocaml/3.11.2/gmp/ -I /usr/local/lib/ -c file.ml, I got an error Unbound value Ppl.manager_alloc_strict.
open Apron;;
open Mpqf;;
open Format;;
let print_array = Abstract0.print_array;;
let lincons1_array_print fmt x =
Lincons1.array_print fmt x
;;
let generator1_array_print fmt x =
Generator1.array_print fmt x
;;
let manpk = Polka.manager_alloc_strict();;
let manbox = Box.manager_alloc ();;
let manoct = Oct.manager_alloc ();;
let manppl = Ppl.manager_alloc_strict();;
...
Does anyone know what happened? Thank you very much!
You've showed us the library, but not anything regarding the OCaml interface to the library -- cmx or cmxa for native compilation. Just as the comment I left prior, do the same thing with where Ppl package for OCaml is. OCaml is not interfacing with the C library directly (.a, .so), but through a compiled interface (cmxa or cmi files).
You might also consider using the ocamlbuild system. You can tag modules with external dependencies, and have the build system find the package (via ocamlfind, or hard-coded).