ocamlc (на самом деле ocamlc.opt) не в состоянии скомпилировать в байт-код программу, использующую threads.cma. Простейший пример: ===== begin thrtest.ml ===== let _ = Thread.join (Thread.create (fun () -> print_string \"Hello\\n\") ()) ===== end thrtest.ml ===== $ rpm -q ocaml ocaml-3.04+7-alt1 $ ocamlopt -thread -o thrtest unix.cmxa threads.cmxa thrtest.ml $ ./thrtest Hello (так все работает) $ ocamlc -thread -o thrtest unix.cma threads.cma thrtest.ml Error on dynamically loaded library: /usr/lib/ocaml/dllthreads.so: undefined symbol: external_raise Причина подобной ситуации в том, что ocamlc при сборке байт-кода пытается подгрузить через dlopen() все указанные в *.cma-файлах динамические библиотеки (dll*.so), чтобы проверить наличие там нужных примитивов. Однако библиотека dllthreads.so ссылается на переменную external_raise, которая определена только в libcamlrun.a (и, соответственно, в /usr/bin/ocamlrun), но не в libasmrun.a. Поэтому dllthreads.so может быть загружена только программой, скомпилированной в байт-код. Видимые мной способы решения проблемы: 1. Проигнорировать и при необходимости собирать подобные программы с -custom - так собирается, но это некрасиво. 2. Вернуть на место байт-кодовый ocamlc (не заменять его полностью на ocamlc.opt). Для ocamlopt такой проблемы нет, поэтому его можно оставить полностью в native. 3. Всадить в otherlibs/systhreads/posix.c директиву: #ifndef NATIVE_CODE asm(\".weak external_raise\") #endif В результате dllthreads.so можно будет загрузить и из native-программы; работать она, естественно, не будет (при первой же попытке обращения к этой переменной получим SIGSEGV), но от нее это и не требуется - нужно лишь успешное выполнение dlopen() и dlsym(). (Попробовал собрать так - работает, lablgtktop_t собирается и по крайней мере выполняет свои же примеры (там потоки в явном виде не применяются - только свой при инициализации lablgtktop_t). Что будем делать? --- ---
0000844-ocaml-3.04+7-threadhack.patch - тот самый хакерский вариант с .weak
Лучше всего выбрать оба варианта - и не убивать байткодовые версии, и хакнуть posix.c Сейчас всё пересобираю (с CVS-ным 3.04+9)...
давно исправлено...