Ocamlbuild doesn't take in account the included folders - ocaml

I am trying to use ocamlbuild to build my project. It needs to take into account an external library (also compiled with ocamlbuild) that contains in the folder myfolder/ the following files (myfolder is a symlink to the good library that I create in the file myocamlbuild.ml):
$ ls _build/myfolder/
PhTools.cmi PhTools.ml PhTools.mli
PhTools.cmo PhTools.ml.depends PhTools.mli.depends
To compile my library I run the following command:
ocamlbuild -use-ocamlfind -plugin-tags "package(eliom.ocamlbuild),package(containers),package(fileutils)" -Is "myfolder" -mods "myfolder/PhTools.cmo" _server/./TestHelloServices.cmo
When I run it I have the error:
[...]
ocamlfind ocamlc -I '' -I _server -I _type -i -thread -package eliom.server -package eliom.syntax.predef -package eliom.syntax.type -syntax camlp4o _type/TestHelloServices.ml > _type/TestHelloServices.inferred.mli
+ ocamlfind ocamlc -I '' -I _server -I _type -i -thread -package eliom.server -package eliom.syntax.predef -package eliom.syntax.type -syntax camlp4o _type/TestHelloServices.ml > _type/TestHelloServices.inferred.mli
File "TestHelloServices.eliom", line 6, characters 10-17:
Error: Unbound module PhTools
Command exited with code 2.
As you can see the option -I myproject hasn't been given to the command ocamlfind ocamlc -i .... You can note that if I add by hand ocamlfind ocamlc -i -I 'myproject' this step works. I tried lot's of differents things to solve my problem : using -cflags '-I,myproject' -lflags '-I,myproject', putting in _tags the line:
myproject: include
but I always have this error.
I don't know if it's a relevant information but I use a slightly modified version of the ocsigen myocamlbuild.ml file:
let client_dir = "_client"
let server_dir = "_server"
let type_dir = "_type"
module M = Ocamlbuild_eliom.Make(struct
let client_dir = client_dir
let server_dir = server_dir
let type_dir = type_dir
end)
open Ocamlbuild_plugin;;
let () =
dispatch begin function
| Before_options ->
M.dispatcher Before_options;
(* Link root project *)
(try
Unix.symlink "../../../../../myfolder/" "_build/myfolder"
with Unix.Unix_error (Unix.EEXIST, _, _)-> ());
| hook -> M.dispatcher hook
end;
Thank you in advance,
TobiasBora.

I guess ocamlbuild will not follow "external" (out of project tree) links.
Maybe hardlink will work, but better yet install the library as the normal ocamlfind package.

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.

Generate dump/explain files of Menhir when using ocamlbuild

I discovered that Menhir provides --dump and --explain options and it helps debugging a lot. But how can I enable these options under ocamlbuild so that Menhir always generates dump files at compile time?
I tried to write myocamlbuild file handling custom tag menhir_dump like the below:
... snip ...
(* OASIS_STOP *)
Ocamlbuild_plugin.dispatch (
MyOCamlbuildBase.dispatch_combine [
(function
| After_rules ->
flag ["menhir_dump"] (S [A "--dump"; A "--explain"])
| _ -> ()
);
dispatch_default
]
)
But when it compiles, the options are inserted into sub-command and the compilation fails during ocamlc stage.
menhir --dump --explain --raw-depend --ocamldep 'ocamlfind ocamldep -modules' src/parser.mly > src/parser.mly.depends
menhir --ocamlc 'ocamlfind ocamlc -g -annot -bin-annot --dump --explain -I src -package cmdliner -package menhirLib -I src' --dump --explain --infer src/parser.mly
+ menhir --ocamlc 'ocamlfind ocamlc -g -annot -bin-annot --dump --explain -I src -package cmdliner -package menhirLib -I src' --dump --explain --infer src/parser.mly
^^^^^^^^^^^^^^^^
ocamlc: unknown option '--dump'.
...snip...
Any suggestions?
I answer it myself.
There is, of course, a built-in ocamlbuild option for this. Just put explain in _tags like the below.
true: use_menhir, explain
You may lookup built-in options using ocamlbuild -documentation.

Basic Ocaml: How do I compile this?

Just beginning with ocaml and am struggling with the various compilers and tooling. E.g. ocamlopt, ocamlc, ocamlbuild, corebuild and so on. So, how do I compile the following?
open Core.Std
module Regex = Re2.Regex
let ls pattern =
let pat = Regex.create_exn pattern in
let matcher = Regex.matches pat in
Sys.ls_dir "."
|> List.filter ~f:matcher
|> List.iter ~f:(fun s -> print_string s; print_newline ())
let () =
match In_channel.input_line stdin with
| None -> print_string "No Input"
| Some pat -> ls pat
In utop I can just #require "re2" and go from there.
Without the inclusion of the regular expressions module I would just use corebuild ls.native, assuming that the above code is placed into ls.ml.
[edit]
Have so far tried
ocamlbuild -use-ocamlfind -package core -package re2
which spit out
ocamlfind ocamldep -package core -package re2 -modules ls.ml > ls.ml.depends
ocamlfind ocamlc -c -package core -package re2 -o ls.cmo ls.ml
+ ocamlfind ocamlc -c -package core -package re2 -o ls.cmo ls.ml
ocamlfind: Error from package `threads': Missing -thread or -vmthread switch
Command exited with code 2.
So after some googling I was led to this blog I tried
ocamlbuild -tag thread -use-ocamlfind -package core -package re2
which spits out over 6000 lines of what looks like make output before failing with:
collect2: error: ld returned 1 exit status
File "caml_startup", line 1:
Error: Error during linking
Command exited with code 2.
so I'm not sure what to try next.
I am using Ubuntu 14.04 on a 64bit machine. I ditched the apt-get versions of ocaml:
sudo apt-get remove --purge ocaml ocaml-base-nox ocaml-compiler-libs \
ocaml-interp ocaml-native-compilers \
ocaml-nox campl4 ocaml-base ocaml-docs opam
Then I installed opam from source according to the instructions here.
Next I installed core, utop, and re2 with opam install core utop re2
And finally I ran ocamlbuild -use-ocamlfind -package re2 -package core -tag thread ls.native
which built the desired executable.
I would suggest you to use oasis tool. It is not as hard, as one may think. But it removes all library burden from you.
Lets create a simple _oasis file for your project:
OASISFormat: 0.4
Name: ls
Version: 0.1
Synopsis: Testing oasis
Authors: Fizz_ed
License: MIT
Plugins: META (0.4), DevFiles (0.4)
BuildTools: ocamlbuild, camlp4o
BuildDepends: core, camlp4, threads,
sexplib.syntax,
bin_prot.syntax,
comparelib.syntax,
herelib,
herelib.syntax
Executable "ls"
Path: .
MainIs: ls.ml
CompiledObject: best
BuildDepends: re2
After you've created this file, run oasis setup command (if oasis is not installed, then install it using opam, or your package manager).
After that you will have a common configure script and makefiles. So all you need is to type
./configure
make
and your file will be compiled.
Or you can just use ocamlbuild directly, it will work too, since oasis created all the necessary files
ocamlbuild ls.native
A few explanations about the file. The preamle contains everything you need to build your core-style applications.
Executable section describes your executable file, and also adds a dependency to re2 library.
Update: fixed some issues.

ocaml batteries compiling : Unbound module Toploop

**Build mode: shared
ocamlbuild -no-links syntax.otarget byte.otarget src/batteries_help.cmo META shared.otarget
Finished, 0 targets (0 cached) in 00:00:00.
+ ocamlfind ocamlc -c -g -annot -warn-error A -package camomile,num,str -package camlp4.lib -pp camlp4of -pp camlp4of -I libs/estring -I benchsuite -I src -I testsuite -I build -I qtest -I libs -I src/syntax/pa_comprehension -I src/syntax/pa_strings -o libs/estring/pa_estring_top.cmo
libs/estring/pa_estring_top.ml
File "libs/estring/pa_estring_top.ml", line 18, characters 15-44:
Error: Unbound module Toploop
Command exited with code 2.**
Compilation unsuccessful after building 6 targets (5 cached) in 00:00:00.**
I have found toploop.cmi in path:
cd OCaml/lib/ocaml/compiler-libs/
ls topl*
toploop.cmi
and as you see,
export PATH=/home/xxx/OCaml/lib/ocaml/compiler-libs/:$PATH
I have made /home/xxx/... as my system path. But it still did not work. What I should do to include the module toploop?
You appear to be compiling Batteries (which version?) with OCaml 4.00, which introduced the new compiler-libs directory (but some distributions had one before so that may be off). toploop used to be at the root of the OCaml stdlib's directory, but you should now add a -I +compiler-libs option somewhere, or use the corresponding ocamlfind packaging (-package compiler-libs.toplevel).