I am trying to build a simple program using Yojson: the main.ml file is just
let () = exit 1;
and an mod.ml file contains
open Yojson
open Yojson.Basic.Util
let rec json_to_tree json =
let _ = json |> member "key" in
()
I have a Makefile which first compiles .ml files, then links. For simplicity, let assume we run the three following commands:
ocamlfind ocamlc -package yojson -g -c mod.ml
ocamlfind ocamlc -package yojson -g -c main.ml
ocamlfind ocamlc -package yojson -g -o inter mod.cmo main.cmo
The problem is that the linking part produces the following error:
File "_none_", line 1:
Error: Required module `Yojson' is unavailable
which I have no idea to solve. Using the Unix module can lead to similar error which are resolved adding unix.cma when linking, but this doesn't help for Yojson.
For the sake of completeness, I installed yojson via opam, and ocamlfind list | grep yojson returns
yojson (version: 1.3.3)
yojson.biniou (version: 1.3.3)
This works.
ocamlfind ocamlc -package yojson -linkpkg -g -o inter mod.cmo main.cmo
While this works, https://github.com/ocaml/dune is the better option to building ocaml code.
Related
I am trying to transform the Yojson with the source code download online into a byte file using js_of_ocaml.
I try the following commands:
%: ocamlfind ocamlc -package yojson -linkpkg -g -o yojson.cmo
%: ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-ppx -linkpkg -g -o -package yojson yojson.byte
I am trying to compile into bytecode an OCaml file but it give the following error:
%: ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-ppx -linkpkg -o preprocessing.byte preprocessing.ml
File "preprocessing.ml", line 4, characters 5-22:
4 | open Yojson.Basic.Util
^^^^^^^^^^^^^^^^^
Error: Unbound module Yojson
The OCaml compiler will not use any compilation units that are not specified on the command line. In addition, you have to specify them in a correct order, so that a user of a unit will come after that unit, e.g.,
ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-ppx -linkpkg -o preprocessing.byte yojson.cmo preprocessing.ml
Also, your invocation,
ocamlfind ocamlc -package yojson -linkpkg -g -o yojson.cmo
is incorrect and should issue an error. You need to specify the -c option to generate the object file.
With that said, you don't need to do what you're doing at all, like building yojson manually (you could install from opam). In fact, it is much better to use a high-level tool, like dune to build your js_of_ocaml programs. The dune documentation provides detailed instructions on how to do this
I have this OCaml program
open Core.Std;;
open Printf;;
let all l = List.fold ~f:(&&) ~init:true l;;
let any l = List.fold ~f:(||) ~init:false l;;
let main () = let bools = [true; false; true; true; false; true] in
printf "%b %b\n" (all bools) (any bools);;
main();;
And then two make files, the first is
all: a.out
#true
a.out: fold.cmx
ocamlfind ocamlopt -g -linkpkg -package core -package core_kernel -thread -w -10 fold.cmx
fold.cmx: fold.ml fold.cmi
ocamlfind ocamlopt -g -c fold.cmx -package core -package core_kernel -thread -w -10 fold.ml
fold.cmi: fold.mli
ocamlfind ocamlopt -g -c -package core -package core_kernel -thread -w -10 fold.mli
fold.mli: fold.ml
ocamlfind ocamlc -i -package core -package core_kernel -thread -w -10 fold.ml > fold.mli
clean:
#rm *.cmx *.cmi *.o tests 2>/dev/null || true
Which produces an a.out that gives the expected output of false true.
The second is
all: fold
#true
fold: fold.cmx
ocamlfind ocamlopt -g -o fold -linkpkg -package core -package core_kernel -thread -w -10 fold.cmx
fold.cmx: fold.ml fold.cmi
ocamlfind ocamlopt -g -c fold.cmx -package core -package core_kernel -thread -w -10 fold.ml
fold.cmi: fold.mli
ocamlfind ocamlopt -g -c -package core -package core_kernel -thread -w -10 fold.mli
fold.mli: fold.ml
ocamlfind ocamlc -i -package core -package core_kernel -thread -w -10 fold.ml > fold.mli
clean:
#rm *.cmx *.cmi *.o tests 2>/dev/null || true
which produces a fold that on my machine, hangs without output. The only difference between the two is that one of them puts its output in fold and the other puts it in a.out. The version numbers for my ocaml, ocamlc, ocamlopt, and ocamlfind are all 4.02.1 and opam show core says it's version 112.06.01. Any of you guys know what's causing the difference?
You are running the standard fold program. Try ./fold.
I'm trying to use the OcamlGraph library and it's not clear to me how to add it to my project. It was suggested to me that I just compile the source of the library along with the source of my project, but there has to be some way of linking the binary of a precompiled library without using OPAM. Can this be done, and if so, how?
Thanks.
compiling:
ocamlc -I /path/to/ocamlgraph -c mysource.ml
(as suggested by ocamlfind ocamlc -package ocamlgraph -c -only-show, if ocamlfind and ocamlgraph are installed)
linking:
ocamlc -I /path/to/ocamlgraph /path/to/ocamlgraph/graph.cma mysource.cmo -o test.byte
(as suggested by ocamlfind ocamlc -linkpkg -package ocamlgraph -only-show )
But normally, you should use ocamlfind and the ocamlgraph package of opam or your distribution.
Using ocaml 4.01.0 and core 111.17.00 as installed by opam.
I have two, probably related, problems that I've boiled down to the following simplified modules.
I have an outer module (Zee here) that contains an inner module (Foo). My main program is in xx.ml.
The first problem is that when I build using corebuild xx.byte, I get the error message:
File "zee.ml", line 1:
Error: The implementation zee.ml does not match the interface zee.cmi:
The field `Foo' is required but not provided
The second problem, which may stem from whatever I'm doing wrong to cause that error, is that if I uncomment the commented-out code in xx.ml below, I get:
File "xx.ml", line 3, characters 23-32:
Error: Unbound module Zee.Foo
I'm new to ocaml, but I have other code with nested modules that seems to be working. I haven't been able to figure out what is different about this situation that causes these errors. Is there something about declaring module signatures inside of other modules that I'm missing?
Here is the code (separate files as indicated by headers):
(**** zee.mli ****)
module type Foo = sig
val x : int
end
val bar : int
(**** zee.ml ****)
module Foo = struct
let x = 10
end
let bar = 20
(**** xx.ml ****)
open Core.Std
(*
let () = printf "%d\n" Zee.Foo.x
*)
let () =
printf "%d\n" Zee.bar
The full output from corebuild with the code exactly as above:
bash# rm -rf _build && corebuild xx.byte
ocamlfind ocamldep -syntax camlp4o -package bin_prot.syntax -package sexplib.syntax,comparelib.syntax,fieldslib.syntax,variantslib.syntax -package core -modules xx.ml > xx.ml.depends
ocamlfind ocamldep -syntax camlp4o -package bin_prot.syntax -package sexplib.syntax,comparelib.syntax,fieldslib.syntax,variantslib.syntax -package core -modules zee.mli > zee.mli.depends
ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g -annot -bin-annot -short-paths -thread -syntax camlp4o -package bin_prot.syntax -package sexplib.syntax,comparelib.syntax,fieldslib.syntax,variantslib.syntax -package core -o zee.cmi zee.mli
ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g -annot -bin-annot -short-paths -thread -syntax camlp4o -package bin_prot.syntax -package sexplib.syntax,comparelib.syntax,fieldslib.syntax,variantslib.syntax -package core -o xx.cmo xx.ml
ocamlfind ocamldep -syntax camlp4o -package bin_prot.syntax -package sexplib.syntax,comparelib.syntax,fieldslib.syntax,variantslib.syntax -package core -modules zee.ml > zee.ml.depends
ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g -annot -bin-annot -short-paths -thread -syntax camlp4o -package bin_prot.syntax -package sexplib.syntax,comparelib.syntax,fieldslib.syntax,variantslib.syntax -package core -o zee.cmo zee.ml
+ ocamlfind ocamlc -c -w A-4-33-40-41-42-43-34-44 -strict-sequence -g -annot -bin-annot -short-paths -thread -syntax camlp4o -package bin_prot.syntax -package sexplib.syntax,comparelib.syntax,fieldslib.syntax,variantslib.syntax -package core -o zee.cmo zee.ml
File "zee.ml", line 1:
Error: The implementation zee.ml does not match the interface zee.cmi:
The field `Foo' is required but not provided
Command exited with code 2.
This is because you said
module type Foo =
sig
val x : int
end
while you meant
module Foo :
sig
val x : int
end
The first statement declares a module type Foo and specifies (note the use of the = sign reminiscent of a binding) the signature for this module type. The module type can then be used to specify the expected signature of arguments to a functor or to filter the signature of a module implementing a superset of Foo.
The second statement declares a module Foo and specify (note the use of the : character reminiscent of a type constraint) the signature of this module.
File "zee.ml", line 1:
Error: The implementation zee.ml does not match the interface zee.cmi:
The field `Foo' is required but not provided
This is because you promised a module type Foo in the interface file which you did not implement in the implementation file — instead you implemented a module with this interface.
File "xx.ml", line 3, characters 23-32:
Error: Unbound module Zee.Foo
This is because the module definition is hidden by your interface file.
How to build with enabled profile information using Ocamlbuild? It seems -p doesn't work there.
Now, I use ocamlopt for this. For example,
$ ocamlfind ocamlopt -c -p -thread -package core test.ml
$ ocamlfind ocamlopt -p -o test -thread -package core -linkpkg test.cmx
How to do the same with
ocamlbuild -user-ocamlfind test.native
You can pass the argument explicitly,
ocamlbuild -cflags -p
or in your _tags file,
true : profile
There is also a rule for the file-name,
ocamlbuild test.p.native