Как скомпилировать файл 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 файл (примечание: комментарий, если это примечание необходимо переместить).

Другие вопросы по тегам