I have a locally pinned OPAM project called ojasmine which I want to compile as a library to be used by another project called test_tournabox (ultimately compiling to javascript). However, the compilation of test_tournabox is failing with a link error.
I compile ojasmine as follows, giving the target ojasmine.cma:
ocamlbuild -cflag -annot -use-ocamlfind -pkgs js_of_ocaml.log,js_of_ocaml,js_of_ocaml.syntax -syntax camlp4o ojasmine.cma
Finished, 5 targets (5 cached) in 00:00:00.
Then I install it like so:
ocamlfind install ojasmine META _build/ojasmine.cma
I found it strange that ojasmine.cma was not in my project directory, but instead is in the _build directory.
The output is:
Installed /home/laheadle/.opam/4.02.0/lib/ojasmine/ojasmine.cma
Installed /home/laheadle/.opam/4.02.0/lib/ojasmine/META
Next, I cd
to my tournabox project and try to build the test suite:
ocamlbuild -cflag -annot -use-ocamlfind -pkgs js_of_ocaml.log,js_of_ocaml,js_of_ocaml.syntax,ojasmine -syntax camlp4o test_tournabox.byte
+ ocamlfind ocamlc -linkpkg -syntax camlp4o -package ojasmine -package js_of_ocaml.syntax -package js_of_ocaml -package js_of_ocaml.log choice.cmo util.cmo entry.cmo ttypes.cmo columns.cmo countries.cmo country_group.cmo jsutil.cmo performance_group.cmo round_group.cmo seed_group.cmo tlog.cmo tourney.cmo tournabox_lib.cmo test_tournabox.cmo -o test_tournabox.byte
This fails with the error:
Error: Error while linking test_tournabox.cmo:
Reference to undefined global `Ojasmine'
It seems that ojasmine.cma is not linked into the executable test_tournabox.byte. But I would expect the -linkpkg argument to ocamlfind to arrange for this. What am I missing?
Edit: Here is the META File:
description = "Unit Tests for javascript"
requires = "js_of_ocaml,js_of_ocaml.syntax"
version = "0.1"
Here is ocamlobjinfo:
trusty)laheadle@localhost:~/ocaml/ojasmine$ ocamlobjinfo _build/ojasmine.cma
File _build/ojasmine.cma
Force custom: no
Extra C object files:
Extra C options:
Extra dynamically-loaded libraries:
Unit name: Ojasmine
Interfaces imported:
ef5bf1a1d49ad28ddd8176a4f17055e1 Ojasmine
c1a8a443b33589e4865a918c21fbbeb4 Js
5de66fdff01f2735974be770893841e1 Pervasives
a88f91d0f04fd66bc0bbaaf347081e95 CamlinternalFormatBasics
Uses unsafe features: no
Force link: no
ocamlfind sees it:
(trusty)laheadle@localhost:~/ocaml/ojasmine$ ocamlfind query ojasmine
/home/laheadle/.opam/4.02.0/lib/ojasmine
here it is:
(trusty)laheadle@localhost:~/ocaml/ojasmine$ ls `ocamlfind query ojasmine`
META ojasmine.cma
Here is ojasmine.ml:
open Js
let describe (s : js_string t) (f: unit -> unit) : unit =
Js.Unsafe.fun_call (Js.Unsafe.variable "describe")
[| Js.Unsafe.inject s;
Js.Unsafe.inject (Js.wrap_callback f) |]
let it (s : js_string t) (f: unit -> unit) : unit =
Js.Unsafe.fun_call (Js.Unsafe.variable "it")
[| Js.Unsafe.inject s;
Js.Unsafe.inject (Js.wrap_callback f) |]
class type matcher = object
method toBe: bool t -> unit meth
method _not: matcher t readonly_prop
end
let expect_bool (b: bool t) : matcher t =
Js.Unsafe.fun_call (Js.Unsafe.variable "expect") [|Js.Unsafe.inject b; |]
And ojasmine.mli:
open Js
val describe: js_string t -> (unit -> unit) -> unit
val it: js_string t -> (unit -> unit) -> unit
class type matcher = object
method toBe: bool t -> unit meth
method _not: matcher t readonly_prop
end
val expect_bool: bool t -> matcher t
Your META
file should contain an archive
variable, so that ocamlfind
can properly link your program with the archive, not object files. Also you need to install your cmi
files. (And, although it is not needed for compilation, but it is a good manner to install mli
files). So, add the following to your META
archive(byte) = "ojasmine.cma"
And do not forget to install cmi
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With