Как скомпилировать файл jocaml с помощью ocamlbuild и включить пакет?
Как я могу скомпилировать исходный файл jocaml, для которого нужен пакет cryptokit (успешно скомпилированный с сопутствующим ocaml) с помощью инструмента ocamlbuild?
Когда я выполню команду ocamlbuild -pkg cryptokit -use-jocaml a.native
Я получаю эту ошибку:
Warning: tag "package" does not expect a parameter, but is used with parameter "cryptokit"¬
+ jocamlopt -I /prefix/lib/ocaml -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/unix.cmxa /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native¬
File "_none_", line 1:¬
Error: Files /prefix/lib/ocaml/unix.cmxa¬
and /prefix/lib/ocaml/unix.cmxa¬
both define a module named Unix¬
Command exited with code 2.¬
Compilation unsuccessful after building 4 targets (3 cached) in 00:00:00.
По сути, модуль ocaml Unix конфликтует с самим собой. Эта ошибка появляется только при включении Cryptokit (с -pkg cryptokit
) наверное потому что Cryptokit требует Unix. a.ml
может фактически быть пустым и все еще воспроизвести ошибку.
Я пытался добавить -use-ocamlfind
флаг, но поскольку он также использует ocamlfind для получения компилятора, он выбирает компилятор ocaml вместо jocaml.
Выполняя последовательно те же команды, что и ocamlbuild (отображается -verbose 1
), Я получил это, когда я выполняю последний без /.../unix.cmxa
тогда больше нет столкновения, но загружен неправильный модуль Unix: это из ocaml, а не из jocaml, поэтому он полностью вылетает, когда я использую любую функцию jocaml в a.ml
:
jocamlopt -I /prefix/lib/ocaml -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native
Тем не менее, когда я также удаляю -I /prefix/lib/ocaml
часть, то она успешно компилируется:
jocamlopt -I /prefix/lib/ocaml/site-lib/cryptokit -I /prefix/lib/ocaml/site-lib/num /prefix/lib/ocaml/nums.cmxa /prefix/lib/ocaml/site-lib/cryptokit/cryptokit.cmxa a.cmx -o a.native
Подводя итог, я заставил его работать, выполнив вручную модификацию последней команды, но я бы хотел, чтобы ocamlbuild работал.
Я думаю, что эта ошибка связана с тем, что для Cryptokit требуется модуль Unix: так как я скомпилировал его с ocaml, а не с jocaml, на этапе компоновки он пытается связать его с ocaml stdlib (который необходимо включить), а не с jocaml stdlib one (который неявно включен как часть stdlib).
2 ответа
Я понятия не имел, что есть активные пользователи комбинации ocamlbuild+JOcaml! Из любопытства, не могли бы вы рассказать немного больше о том, для чего вы используете JOCaml+cryptokit?
Я не знаю много о Cryptokit или JOCaml, но похоже, что ваша основная проблема не связана с ocamlbuild. Если я правильно понимаю, (1) для Cryptokit требуется Unix и (2) JOCaml должен использовать свой собственный вариант Unix. Если это правильно, компиляция Cryptokit для Unix от ocaml и ожидание того, что он будет работать, когда он связан с программой JOCaml, которая сама требует Unix от JOCaml, неизбежно создаст много проблем. Если это работает в вашем случае, это должно быть потому, что либо используемая вами часть Cryptokit на самом деле не требует Unix, либо программа JOCaml, с которой вы тестируете, на самом деле не требует Unix JOCaml. В долгосрочной перспективе, вероятно, было бы лучше скомпилировать Cryptokit непосредственно с JOCaml (я не знаю, насколько вам комфортно с экосистемой OCaml в целом, но я бы лично попытался создать коммутатор OPAM, где ocaml{c,opt}
псевдонимы для jocaml{c,opt}
и строить программы из этого).
Что касается конкретной детали ocamlbuild, трудно дать какой-либо точный совет без tarball, чтобы иметь возможность воспроизвести вашу установку и поэкспериментировать с ней. Но я бы попробовал один из двух следующих вариантов:
- Ты можешь использовать
-use-ocamlfind
и учитьocamlfind
использоватьjocaml
вместоocaml
используяOCAMLFIND_COMMANDS
переменная окружения (см.man ocamlfind
) - Вы можете избежать
-use-ocamlfind
целиком и вместо того, чтобы позвонитьocamlfind
в качестве инструмента командной строки для определения местоположения библиотеки криптокитов (ocamlfind query cryptokit
). Вы бы тогда не использовали-pkg cryptokit
но пройти путь самостоятельно (с-lflags
а также-cflags
или изменив вашmyocamlbuild.ml
конфигурационный файл).
Разработка на -use-ocamlfind
вариант, предложенный гашем, заставил его работать с добавлением небольшого неприятного хака: удаление "unix"
от requires
поле META
файл из cryptokit
пакет. Это работает, потому что jocaml связывает все с threads
а также unix
по умолчанию (реальным решением было бы отключить это поведение, но это кажется намного сложнее). Итак, рабочая команда компиляции:
ocamlbuild -use-ocamlfind -use-jocaml -pkg cryptokit a.ml
Я думаю, что это можно обобщить на любой пакет, который использует либо unix
или же threads
при компиляции с jocaml. Дополнительный вопрос заключается в том, возможно ли сделать это динамически с _tags
или же myocamlbuild.ml
файл (примечание: комментарий, если это примечание необходимо переместить).