Compilation error with sexplib - ocaml

I need to use Sexplib in my program. I tried
ocamlc sexplib.cma prog.ml
Error: Unbound module Sexplib
and I got the error. But I can use Sexplib in top level if I load ppx_sexp_conv package first:
#require "ppx_sexp_conv";;
open Sexplib;;
So I also tried this:
ocamlfind ocamlc -package ppx_sexp_conv sexplib.cma prog.ml
Error: Error while linking /Users/neko/.opam/system/lib/sexplib/sexplib.cma(Sexplib):
The external function `caml_ba_get_1' is not available
I have no idea what this means and what I need to do now... Can anyone help?

caml_ba_get_1 is a function of the Bigarray module. You might try linking in the bigarray package (or bigarray.cma). On my system the function is defined in libbigarray.a.

The linker is missing C externals used by your package. You should be able to fix this by passing -linkpkg to ocamlfind so that it passes the relevant arguments to the linker:
ocamlc -package ppx_sexp_conv -linkpkg prog.ml

Related

How to compile a file that uses the JsooTop module?

I have this in a file named main.ml:
let () = JsooTop.initialize ()
I tried compiling the file using:
ocamlfind ocamlc -package js_of_ocaml -linkpkg -o main.byte main.ml
But this error appears:
File "main.ml", line 1, characters 9-27:
Error: Unbound module JsooTop
It appears that JsooTop is not present on my machine, so I ran opam install js_of_ocaml-toplevel, and tried compiling the file again using:
ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-toplevel -linkpkg -o main.byte main.ml
js_of_ocaml main.byte
But I get warnings:
Warnings from ocamlfind:
findlib: [WARNING] Interface topdirs.cmi occurs in several directories: /usr/lib/ocaml, /usr/lib/ocaml/compiler-libs
Warnings from the js_of_ocaml executable:
There are some missing primitives
Dummy implementations (raising 'Failure' exception) will be used if they are not available at runtime.
You can prevent the generation of dummy implementations with the commandline option '--disable genprim'
Missing primitives provided by +dynlink.js:
caml_add_debug_info
caml_dynlink_add_primitive
caml_dynlink_get_current_libs
caml_dynlink_lookup_symbol
caml_dynlink_open_lib
caml_remove_debug_info
Missing primitives provided by +toplevel.js:
caml_get_current_environment
caml_get_section_table
caml_invoke_traced_function
caml_realloc_global
caml_reify_bytecode
caml_static_alloc
caml_static_free
caml_static_release_bytecode
caml_terminfo_setup
My question is: what is the proper way to compile a file that uses the JsooTop module?
First, make sure that the required OPAM packages are present:
opam install js_of_ocaml js_of_ocaml-toplevel
To build a program that uses the JsooTop module, compile the file in this way:
ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-toplevel -linkpkg -o main.byte main.ml
js_of_ocaml --toplevel --dynlink +dynlink.js +toplevel.js main.byte
Note the inclusion of --toplevel, --dynlink, +dynlink.js, and +toplevel.js. The commands above will produce a JavaScript file named main.js.

How to link OCaml object file with Core module?

I have simple program, which uses function from Core.Std module, e.g.:
open Core.Std
let _ = List.last [1;2;3]
I can compile and link it by ocamlfind or ocamlbuild:
ocamlfind ocamlc -package core -linkpkg -thread app.ml
ocamlbuild -use-ocamlfind -pkgs core -tag thread app.native
But I don't know how to compile and link such file using "normal" OCaml compiler:
ocamlc -c -I ~/.opam/system/lib/core_kernel/ -I ~/.opam/system/lib/core/ app.ml
ocamlc ~/.opam/system/lib/core_kernel/core_kernel.cma ~/.opam/system/lib/core/core.cma app.cmo
Last of above commands gives the following error:
File "_none_", line 1:
Error: Error on dynamically loaded library: /home/maciej/.opam/system/lib/stublibs/dllcore_kernel_stubs.so: /home/maciej/.opam/system/lib/stublibs/dllcore_kernel_stubs.so: undefined symbol: caml_ba_alloc
What am I doing wrong?
You can use ocamlfind ocamlc -only-show … to see the full command constructed by ocamlfind . Your error points towards some missing transitive dependencies of Core and an old version of OCaml and Core.

OCaml: how to solve findlib warnings of multiple `cmi`s

Now I try to write a compiler using ocamlfind and some packages, especially ppx_sexp_conv with opam.
Somehow dependencies of ppx_sexp_conv require compiler-libs so the compilation option -I ~/.opam/VERSION/lib/compiler-libs is added when compiling files by ocamlfind ocamlc -package ppx_sexp_conv.
The problem is, compiler-libs includes very common name files like parsing.cmi, main.cmi, lexing.cmi.
This make conflicts of .cmi files and make many noisy warnings as follows:
$ ocamlfind ocamlc -package ppx_sexp_conv -c parser.mli
findlib: [WARNING] Interface main.cmi occurs in several directories: ., /home/nomaddo/.opam/4.02.3/lib/ocaml/compiler-libs
findlib: [WARNING] Interface lexer.cmi occurs in several directories: ., /home/nomaddo/.opam/4.02.3/lib/ocaml/compiler-libs
findlib: [WARNING] Interface topdirs.cmi occurs in several directories: /home/nomaddo/.opam/4.02.3/lib/ocaml/compiler-libs, /home/nomaddo/.opam/4.02.3/lib/ocaml
findlib: [WARNING] Interface parser.cmi occurs in several directories: ., /home/nomaddo/.opam/4.02.3/lib/ocaml/compiler-libs
```
Note that main.cmi, parsing.cmi, lexing.cmi and main.cmi exist in the same directory.
I believe that such file names are common and everybody want to use.
My question is, how to quiet such noisy warnings.
Thanks to them, it is hard to find more important warnings and errors immediately...
My environment: ocaml 4.02.3 with opam 1.2.2.
One way to suppress those warnings is to set findlib environment variable OCAMLFIND_IGNORE_DUPS_IN to /home/nomaddo/.opam/4.03.0/lib/ocaml/compiler-libs.
Here is an example with OCaml 4.03.0 and ppx_sexp_conv version 113.33.01+4.03.
parser.mli:
type t = int [##deriving sexp]
In shell, do the following
export OCAMLFIND_IGNORE_DUPS_IN=/home/nomaddo/.opam/4.03.0/lib/ocaml/compiler-libs
ocamlfind ocamlc -package ppx_sexp_conv -dsource -c parser.mli
You can see the .mli is preprocessed and no extra warning is emitted.
Reference:
findlib man page
Mantis 6754

MirageOS - Unable to build unikernel for XEN

I've written a simple MirageOS-based Unikernel to execute a basic HTTP GET call. While it is working without any problems when I run it as a Unix binary, the moment I configure it for XEN (mirage configure --xen) and launch the make command, I get the following error:
ocamlbuild -use-ocamlfind -pkgs lwt.syntax,cohttp.lwt,cohttp.lwt-core,mirage-console.xen,mirage-http,mirage-types.lwt -tags "syntax(camlp4o),annot,bin_annot,strict_sequence,principal" -tag-line "<static*.*>: -syntax(camlp4o)" -cflag -g -lflags -g,-linkpkg,-dontlink,unix main.native.o
+ ocamlfind ocamlopt -g -linkpkg -dontlink unix -output-obj -package mirage-types.lwt -package mirage-http -package mirage-console.xen -package cohttp.lwt-core -package cohttp.lwt -package lwt.syntax -syntax camlp4o unikernel.cmx main.cmx -o main.native.o
File "_none_", line 1:
Error: No implementations provided for the following modules:
Unix referenced from /home/mirage/.opam/system/lib/lwt/lwt-unix.cmxa(Lwt_engine),
/home/mirage/.opam/system/lib/lwt/lwt-unix.cmxa(Lwt_unix),
/home/mirage/.opam/system/lib/lwt/lwt-unix.cmxa(Lwt_io),
/home/mirage/.opam/system/lib/lwt/lwt-unix.cmxa(Lwt_log),
/home/mirage/.opam/system/lib/ipaddr/ipaddr_unix.cmxa(Ipaddr_unix),
/home/mirage/.opam/system/lib/xenstore_transport/xenstore_transport_lwt_unix.cmxa(Xs_transport_lwt_unix_client),
/home/mirage/.opam/system/lib/conduit/conduit-lwt-unix.cmxa(Conduit_lwt_unix),
/home/mirage/.opam/system/lib/cohttp/cohttp_lwt_unix.cmxa(Cohttp_lwt_unix_debug),
/home/mirage/.opam/system/lib/cohttp/cohttp_lwt_unix.cmxa(Cohttp_lwt_unix)
Command exited with code 2.
Compilation unsuccessful after building 7 targets (0 cached) in 00:00:03.
make: *** [main.native.o] Error 10
I just started working with MirageOS and OCaml so it might be a stupid question but right now I really don't know what to do.
You should not use Cohttp_lwt_unix. As the name suggests, it runs on unix, not on xen. If you want an example of a webserver that is xen-proof, you can look at this skeleton or at the code used by mirage-seal.
As #Drup says, you need to avoid any "unix" packages if you want to be portable. Instead, use a Mirage adaptor for cohttp. This one should work:
https://github.com/mirage/mirage-http

OCaml: Reference to undefined global `A`

I have a three signatures A.mli,B.mli,and C.mli. Within them I have submodules Aa, Bb, and Cc respectively and also a signature for the implementations Ai, Bi, and Ci.
I have implemented them in a file called D.ml which looks like this
open A
open B
open C
module Ai : Aa = struct ... end
module Bi : Bb = struct ... end
module Ci : Cc = struct ... end
I compile them each in turn with the following commands:
ocamlfind ocamlc -linkpkg -thread -package core A.mli
ocamlfind ocamlc -linkpkg -thread -package core B.mli
ocamlfind ocamlc -linkpkg -thread -package core C.mli
ocamlfind ocamlc -linkpkg -thread -package core D.ml
which all succeed.
I then have a file E.ml where I try to use the modules Ai, Bi, Ci.
open A
open B
open C
module M = Ai(Ci)
(* do something else *)
However when I try to compile E.ml I get the
Error: Error while linking E.cmo:
Reference to undefined global `A`
I think I have to somehow include D.ml in the compilation step but I'm unsure how to.
Using ocamlc or ocamlopt compiler directly (even with the help of ocamlfind) is not an easy task, and should be left only for those, who write OCaml tools and very sure in what they're doing. So, in short, just use ocamlbuild, that is the default way of compiling things in OCaml world. Since, you're using Core library it would be also a good idea to use corebuild instead of ocamlbuild. corebuild is shipped with core, and is actually a small wrapper around ocamlbuild, that adds core dependencies, as well as some handy flags. So, with corebuild you can compile just with:
corebuild E.native
Without corebuild, you can compile with
ocamlbuild -pkg core E.native
ocamlbuild will do all the work for you, i.e., find all dependencies, sort them in correct order, invoke proper tools, etc... You just need this one, command.
If you're still interested in how to compile your example project properly, then you can ask ocamlbuild about this. Use -classic-display option, that will show you all intermediate commands,
ocamlbuild -use-ocamlfind -classic-display -pkg core E.byte
Will show you all steps. (You may need to ocamlbuild -clean, so that you can see all the steps from the start).