Связывание библиотеки через ocamlbuild/ocamlfind
У меня есть локально закрепленный проект OPAM под названием ojasmine, который я хочу скомпилировать как библиотеку для использования другим проектом под названием test_tournabox (в конечном итоге компилируется в javascript). Тем не менее, компиляция test_tournabox не удается с ошибкой ссылки.
Я компилирую ojasmine следующим образом, получая целевой файл 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.
Затем я устанавливаю это так:
ocamlfind install ojasmine META _build/ojasmine.cma
Мне показалось странным, что ojasmine.cma не было в моем каталоге проектов, а вместо этого находится в каталоге _build.
Выход:
Installed /home/laheadle/.opam/4.02.0/lib/ojasmine/ojasmine.cma
Installed /home/laheadle/.opam/4.02.0/lib/ojasmine/META
Далее я cd
в мой проект Tournabox и попробуйте создать тестовый набор:
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
Это терпит неудачу с ошибкой:
Error: Error while linking test_tournabox.cmo:
Reference to undefined global `Ojasmine'
Кажется, что ojasmine.cma не связан с исполняемым файлом test_tournabox.byte. Но я бы ожидал, что аргумент -linkpkg в ocamlfind это устроит. Что мне не хватает?
Редактировать: вот файл META:
description = "Unit Tests for javascript"
requires = "js_of_ocaml,js_of_ocaml.syntax"
version = "0.1"
Вот 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 видит это:
(trusty)laheadle@localhost:~/ocaml/ojasmine$ ocamlfind query ojasmine
/home/laheadle/.opam/4.02.0/lib/ojasmine
вот:
(trusty)laheadle@localhost:~/ocaml/ojasmine$ ls `ocamlfind query ojasmine`
META ojasmine.cma
Вот 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; |]
И 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
1 ответ
Ваш META
файл должен содержать archive
переменная, так что ocamlfind
может правильно связать вашу программу с архивом, а не с объектными файлами. Также вам нужно установить свой cmi
файлы. (И, хотя это не нужно для компиляции, но это хороший способ установки mli
файлы). Итак, добавьте следующее к вашему META
archive(byte) = "ojasmine.cma"
И не забудьте установить cmi
,