ocamlfind, where to find/how to build? - ocaml

I know next to nothing about ocaml, but I want to install Coccinelle (on cygwin), which has a dependency to the binary ocamlfind.
However, installing either ocaml-3.11.0-win-mgw.exe or ocaml-3.11.0-win-msvc.exe
from http://caml.inria.fr/download.en.html, there are no such binary. In fact not a single file in the installed directory contains any reference to the string "ocamlfind".
And downloading the source code (ocaml-3.12.1), grep only finds the following references:
./Changes:- PR#5165: ocamlbuild does not pass '-thread' option to ocamlfind
./Changes:- PR#5217: ocamlfind plugin should add '-linkpkg' for toplevel
./ocamlbuild/command.ml: else None (* Sh"ocamlfind ocamlc" for example will not be digested. *)
./ocamlbuild/findlib.ml: | Cannot_run_ocamlfind
./ocamlbuild/findlib.ml: | Cannot_run_ocamlfind ->
./ocamlbuild/findlib.ml:let ocamlfind = "ocamlfind"
./ocamlbuild/findlib.ml: run_and_parse Lexers.ocamlfind_query
./ocamlbuild/findlib.ml: "%s query -l -predicates byte %s" ocamlfind name
./ocamlbuild/findlib.ml: "%s query -a-format -predicates native %s" ocamlfind name
./ocamlbuild/findlib.ml: run_and_parse Lexers.blank_sep_strings "%s query -r -p-format %s" ocamlfind name
./ocamlbuild/findlib.ml: (* TODO: Improve to differenciate whether ocamlfind cannot be
./ocamlbuild/findlib.ml: error Cannot_run_ocamlfind
./ocamlbuild/findlib.ml: run_and_parse Lexers.blank_sep_strings "%s list | cut -d' ' -f1" ocamlfind
./ocamlbuild/findlib.ml:make another ocamlfind query such as:
./ocamlbuild/findlib.ml: ocamlfind query -p-format -r package1 package2 ... *)
./ocamlbuild/lexers.mli:val ocamlfind_query : Lexing.lexbuf ->
./ocamlbuild/lexers.mll:and ocamlfind_query = parse
./ocamlbuild/lexers.mll: | _ { raise (Error "Bad ocamlfind query") }
./ocamlbuild/manual/manual.tex:\texttt{ocamlfind}). Here is the list of relevant options:
./ocamlbuild/ocaml_specific.ml: if !Options.use_ocamlfind then begin
./ocamlbuild/ocaml_specific.ml: (* Note: if there is no -pkg option, ocamlfind won't be called *)
./ocamlbuild/ocaml_specific.ml:if not !Options.use_ocamlfind then begin
./ocamlbuild/options.ml:let use_ocamlfind = ref false
./ocamlbuild/options.ml: "ocamlyacc"; "menhir"; "ocamllex"; "ocamlmklib"; "ocamlmktop"; "ocamlfind"]
./ocamlbuild/options.ml:let ocamlfind x = S[V"OCAMLFIND"; x]
./ocamlbuild/options.ml: "-use-ocamlfind", Set use_ocamlfind, " Use ocamlfind to call ocaml compilers";
./ocamlbuild/options.ml: if !use_ocamlfind then begin
./ocamlbuild/options.ml: ocamlc := ocamlfind & A"ocamlc";
./ocamlbuild/options.ml: ocamlopt := ocamlfind & A"ocamlopt";
./ocamlbuild/options.ml: ocamldep := ocamlfind & A"ocamldep";
./ocamlbuild/options.ml: ocamldoc := ocamlfind & A"ocamldoc";
./ocamlbuild/options.ml: ocamlmktop := ocamlfind & A"ocamlmktop";
./ocamlbuild/signatures.mli: val use_ocamlfind : bool ref
./ocamlbuild/signatures.mli: | Cannot_run_ocamlfind
./ocamlbuild/signatures.mli: (** Transitive closure, as returned by [ocamlfind query -r]. *)
and none of this is any references to install of such a binary. So I am sort of lost on how to proceed. Go back to older releases of ocaml?
BTW, the native ocaml cygwin packages did also not contain any ocamlfind binary.

Is google down today? http://projects.camlcity.org/projects/findlib.html
There is no precompiled binary, but on cygwin it compiles fine out of the box.

Related

Unbound value "string_of_sexp"

It works quite well in utop with #require "ppx_jane" but
I added (preprocess (pps ppx_jane)) in my dune file which looks like this:
(library
(preprocess (pps ppx_jane))
(name raftml)
(modules raft rpc types)
(libraries
core
core_unix
proto
grpc
grpc-lwt
ocaml-protoc
lwt
lwt.unix
h2
h2-lwt-unix
domainslib
yojson
ppx_jane
ppx_sexp_conv
ppx_deriving_yojson
ppx_deriving
ppx_deriving_yojson.runtime))
And my types are like this:
type log = {
mutable command: string;
mutable term: int32;
mutable index: int32
} [##deriving sexp]
I call sexp_of_log in my code like this:
let persist () = Out_channel.write_all "file_name" ~data:(Sexp.to_string (sexp_of_log { command = "hello"; term = (10l); index = (24l); }))
And there's an error when I run dune build: Unbound value "string_of_sexp"
I solved this by adding:
open Sexplib.Std
At the top of the file that has the record types deriving sexp.

How to use jbuild and ppx_driver with ppx_deriving

I am trying to use jbuilder together with ppx_deriving (ppx_deriving_yojson specifically) but got stuck for well over an hour now. My current approach is a jbuild file, containing the following:
(jbuild_version 1)
(executables
((names (my-binary))
(libraries
(ppx_deriving
ppx_deriving_yojson
cohttp
yojson))
(preprocess (pps (ppx_deriving_yojson ppx_driver.runner)))))
But that results in
Command [5] exited with code 1:
$ (cd _build/default && ../.ppx/default/ppx_deriving_yojson+ppx_driver.runner/ppx.exe --dump-ast -o src/my_file.pp.ml --impl src/my_file.ml)
File "src/my_file.ml", line 16, characters 5-13:
Error: Attribute `deriving' was not used
Running the generated ppx_driver in _build/.ppx/default/ppx_deriving_yojson+ppx_driver.runner/ppx.exe manually with -print-transformations gives empty output, so I am obviously missing something.
The code builds fine with topkg by just including ppx_deriving and ppx_deriving_yojson as dependencies.
As of more recent versions of ppx_deriving_yojson this should be possible.
Code:
type t = {x: int; y: int} [##deriving to_yojson]
let () = print_endline (Yojson.Safe.to_string (to_yojson {x= 1; y= 2}))
And a sample jbuild file:
(jbuild_version 1)
(executables
((names (main))
(preprocess (pps (ppx_deriving_yojson)))
(libraries (ppx_deriving_yojson.runtime))))
(install
((section bin)
(files ((main.exe as main)))))

ocamlbuild include extra packages

I am working through the LLVM ocaml tutorial, and using the following command line to compile:
ocamlbuild -cflags -g,-I,+llvm-3.4 -lflags -I,+llvm-3.4 toy.byte
Is there any way to move those extra cflags and lflags into the _tags or myocamlbuild.ml files so that I don't need to type them/can store them in source control/make reproducible builds?
Here is the _tags file:
<{lexer,parser}.ml>: use_camlp4, pp(camlp4of)
<*.{byte,native}>: g++, use_llvm, use_llvm_analysis
<*.{byte,native}>: use_llvm_executionengine, use_llvm_target
<*.{byte,native}>: use_llvm_scalar_opts, use_bindings
And here is the myocamlbuild.ml file:
open Ocamlbuild_plugin;;
ocaml_lib ~extern:true "llvm";;
ocaml_lib ~extern:true "llvm_analysis";;
ocaml_lib ~extern:true "llvm_executionengine";;
ocaml_lib ~extern:true "llvm_target";;
ocaml_lib ~extern:true "llvm_scalar_opts";;
flag ["link"; "ocaml"; "g++"] (S[A"-cc"; A"g++ -rdynamic"]);;
dep ["link"; "ocaml"; "use_bindings"] ["bindings.o"];;
I do something like...
let mlflags = []
and cflags = []
and clibs = []
let rec arg_weave p = function
| x::xs -> (A p) :: (A x) :: arg_weave p xs
| [] -> []
and arg x = A x
...
let () = dispatch begin function
| After_rules ->
flag ["ocaml"; "compile"] (S (List.map arg mlflags));
flag ["c"; "compile"] (S (arg_weave "-ccopt" cflags));
flag ["c"; "link"] (S (arg_weave "-cclib" clibs));
...
end
The other option is to tag additional options. For example, in the ocaml_specific.ml file they have one set-up for debug and all the combinations of flag options for where the option is relevant.
flag ["ocaml"; "debug"; "compile"; "byte"] (A "-g");;
flag ["ocaml"; "debug"; "link"; "byte"; "program"] (A "-g");;
flag ["ocaml"; "debug"; "pack"; "byte"] (A "-g");;
flag ["ocaml"; "debug"; "compile"; "native"] (A "-g");;
flag ["ocaml"; "debug"; "link"; "native"; "program"] (A "-g");;
flag ["ocaml"; "debug"; "pack"; "native"] (A "-g");;
then, in the _tags file, you can have true : debug to turn it on for all files, or true can be replaced by a pattern for limiting the option. So if an option doesn't exist already, you can create your own and you'll see that it's similar to the fully myocamlbuild.ml solution, but additional flags for each tag instead of including them all at once.
-g is replaced by true: debug in _tags.
-I options ideally should be replaced by the corresponding ocamlfind package, e.g. calling ocamlbuild -use-ocamlfind and specifying true: package(llvm,llvm_analysis) in _tags and/or whatever other packages are called (and remove ocaml_lib calls in myocamlbuild.ml).
On the side note, just create a Makefile with whatever ocamlbuild invocation is needed and run make to build.

Module case name confusion

I made the mistake of updating software and now I can't run any OUnit tests.
I think I've managed to boil the problem down to a simple REPL session.
$ ocaml -I /opt/local/lib/ocaml/site-lib/oUnit
OCaml version 4.01.0
# Ounit.assert_equal;;
Error: Wrong file naming: /opt/local/lib/ocaml/site-lib/oUnit/ounit.cmi
contains the compiled interface for
Ounit when OUnit was expected
# OUnit.assert_equal;;
Error: Reference to undefined global `OUnit'
Any ideas what I'm doing wrong?
I'm running this on a Mac laptop which has the default case-insensitive/case-preserving file-system, but dinking with the case of the include path doesn't help.
My larger problem manifests thus:
ocamlbuild \
-libs \
nums,str,unix,oUnit,graph \
-cflags \
-g,-w,+a-4,-warn-error,+a-4,-I,/opt/local/lib/ocaml/site-lib/oUnit,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
-lflags \
-g,-I,/opt/local/lib/ocaml/site-lib/oUnit,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
./AllTests.native
Error: No implementations provided for the following modules:
OUnitCore referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
/opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitLoggerStd referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitUtils referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
/opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitConf referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
/opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitAssert referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
/opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitBracket referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
/opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitTest referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
/opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitRunner referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitChooser referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitLogger referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
/opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
OUnitTestData referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2)
Command exited with code 2.
Compilation unsuccessful after building 646 targets (645 cached) in 00:00:02.
Your first error is probably because your OS does not distinguish cases in filenames but OCaml does:
$ ocamlobjinfo `ocamlfind query oUnit`/oUnit.cmi
File /mnt/home/jun/.opam/system/lib/oUnit/oUnit.cmi
Unit name: OUnit
Interfaces imported:
cb146e345f0b34fc8ad4b5afe69d1f20 OUnit
...
You can see that the module is called "OUnit" not "Ounit".
The second error is clearly because the library is not loaded into the REPL yet. The REPL's knows the existence of the function, but has no code loaded. It is accessible if you load the library and those on which it depends:
ocaml -I `ocamlfind query oUnit` unix.cma oUnitAdvanced.cma oUnit.cma
OCaml version 4.01.0
# OUnit.assert_equal;;
- : ?cmp:('a -> 'a -> bool) ->
?printer:('a -> string) ->
?pp_diff:(Format.formatter -> 'a * 'a -> unit) ->
?msg:string -> 'a -> 'a -> unit
= <fun>
I solved the problem by changing my ocamlbuild invocation to use -use-ocamlfind which seems to work around all the path confusion.
I also uninstalled all OCaml modules and instead installed OPAM and then installed OUnit and others via OPAM, and re-logged in so that my environment is pristine.
The build command that works for me now is
ocamlbuild \
-use-ocamlfind \
-libs graph \
-pkgs str,unix,ounit \
-cflags -g,-w,+a-4,-warn-error,+a-4,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
-lflags -g,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
./AllTests.native
which is generated by my updated build script
(* Usage: ocaml make.ml [<ModuleToBuild>.{byte,native}] *)
#load "unix.cma";;
let args = match Array.to_list Sys.argv with
| [] -> failwith "no program on argv"
| _::[] -> ["AllTests.byte"]
| _::argv -> argv
let library_paths = [
(* TODO: Figure out why `opam install ocamlgraph` fails *)
"-I"; "/opt/local/lib/ocaml/site-lib/ocamlgraph";
]
(* If the -p flag is first in the argument list, then replace it
with a host of flags that enable profiling via ocamlprof. *)
let args, c_opt_flags, l_opt_flags =
match args with
| "-p"::rest ->
(* Treat the targets as debug and profile targets. *)
"-tags"::"debug,profile"
(* Use profiling versions of the compilers which instrument
various flow control constructs with entry counters. *)
::"-ocamlc"::"ocamlcp"
::"-ocamlopt"::"ocamloptp"
::rest,
(* Instrument all available points. *)
["-P"; "a"],
(* Link with a wrapper that dumps profiling data if program
exits noramlly. *)
["-p"]
| _ -> args, [], []
let standard_flags = [
"-use-ocamlfind";
(* TODO: Figure out why `opam install ocamlgraph` fails *)
"-libs"; "graph";
"-pkgs"; "str,unix,ounit"; (* TODO: graph *)
"-cflags"; (String.concat "," (
[
"-g";
"-w"; "+a-4";
"-warn-error"; "+a-4";
]
# c_opt_flags
# library_paths));
"-lflags"; (String.concat "," (
[
"-g";
]
# l_opt_flags
# library_paths));
]
let build_command = "ocamlbuild"
let argv = build_command::(standard_flags # args)
let _ = begin
Printf.printf "%s\n" (String.concat " \\\n\t" argv);
flush stdout;
Unix.execvp build_command (Array.of_list argv);
end;;

How do i compile something with Pgocaml

I'm trying to use Pgocaml for database interactions within my application.
This is the file I'm trying to compile:
let () =
let dbh = PGOCaml.connect () in
let insert name salary email =
PGSQL(dbh) "insert into employees (name, salary, email) values ($name, $salary, $?email)"
in
insert "Ann" 10_000_l None;
insert "Bob" 45_000_l None;
insert "Jim" 20_000_l None;
insert "Mary" 30_000_l (Some "mary#example.com");
let print_row (id, name, salary, email) =
let email = match email with Some email -> email | None -> " -"
in Printf.printf "%ld %S %ld %S\n" id name salary email in
let rows =
PGSQL(dbh) "select id, name, salary, email from employees"
in List.iter print_row rows;
PGOCaml.close dbh
This is how I am trying to compile it:
ocamlbuild -use-ocamlfind -pkg pgocaml pgex.native
and this is the error I am getting:
+ ocamlfind ocamldep -package pgocaml -modules pgex.ml > pgex.ml.depends
File "pgex.ml", line 4, characters 19-97:
Error: Syntax error
Command exited with code 2.
Why am I getting this error?
Thanks in advance!
PG'OCaml is a syntax extension, it is not a regular ocaml code, so you need to take extra steps to let it perform its magic. First, read the tutorial which also explains how to compile projects with pgocaml. Second, tell the build system that pgex.ml should be preprocessed with camlp4 - i.e. create _tags file with the contents <pgex.ml>: syntax(camlp4o).