Флаг динамической компоновки OCaml и компиляции -nodynlink

#ocaml #dynamic-linking

#ocaml #динамическое связывание

Вопрос:

В соответствии с главой Руководства пользователя OCaml о ocamlopt :

-nodynlink Разрешить компилятору использовать некоторые оптимизации, которые действительны только для кода, который никогда не связан с dynlink.

-shared […] В некоторых системах (в настоящее время только Linux AMD 64) весь код OCaml, связанный в плагине, должен быть скомпилирован без -nodynlink флага. […]

Для меня это означает, что:

  • Ограничение «не использовать флаг -nodynlink компиляции» применяется только к плагину.
  • Части, не являющиеся плагинами (расширяемое приложение), могут быть скомпилированы с использованием -nodynlink .

Итак, мой актуальный вопрос двоякий:

  1. Верна ли моя приведенная выше интерпретация?
  2. Когда я специально нарушил вышеуказанные ограничения, компилятор / загрузчик / etc не выдал мне предупреждающее сообщение. Какие ошибки / плохое поведение я должен ожидать в результате моих проступков?

Заранее благодарю вас!

Ответ №1:

Первый пункт правильный. Однако многие современные операционные системы по умолчанию используют исполняемые файлы PIE, что несовместимо с -nodynlink опцией.

Что касается вашего второго пункта, указание -shared во второй позиции приведет к удалению -nodynlink флага, что может объяснить, почему вы не получили никакой ошибки. В противном случае для непустых плагинов компоновщик должен сгенерировать ошибку перемещения. Обычно пытаются скомпилировать

 let printer () = Format.printf "I am a plugin@."
let () = Lib.register := printer :: !Lib.register
 

с

 # ocamlopt -shared -nodynlink plugin.ml -o plugin.cmxs 
 

дает мне

 /usr/bin/ld: plugin.o: warning: relocation against `camlPlugin__Pfield_51' in >read-only section `.text'
/usr/bin/ld: plugin.o: relocation R_X86_64_PC32 against symbol >`camlPlugin__const_block_11' can not be used when making a shared object; >recompile with -fPIC
/usr/bin/ld: final link failed: bad value