Обходной путь для ошибки "Шаблон Haskell + C"?

У меня есть следующая ситуация:

Ошибка GHС# 9010 делает невозможным установку библиотеки B с использованием GHC 7.6. Когда TH обрабатывается, GHCi запускается и пытается загрузить библиотеку X, которая выходит из строя с сообщением типа

Loading package charsetdetect-ae-1.0 ... linking ... ghc:
~/.cabal/lib/x86_64-linux-ghc-7.6.3/charsetdetect-ae-1.0/
libHScharsetdetect-ae-1.0.a: unknown symbol `_ZTV15nsCharSetProber'

(фактическое имя "неизвестного символа" отличается от машины к машине).

Есть ли какие-либо обходные пути для этой проблемы (кроме, конечно, не использовать Template Haskell)? Может быть, библиотека X должна быть скомпилирована по-другому или есть способ остановить ее от загрузки (так как она не должна вызываться во время генерации кода)?

Ответ 1

Это действительно одна из основных причин, по которой 7.8 переключился на динамический GHCi по умолчанию. Вместо того, чтобы пытаться поддерживать каждую функцию каждого формата объектного файла, он создает динамические библиотеки и позволяет обрабатывать динамический загрузчик системы.

Попробуйте построить с опцией g++ -fno-weak. На странице руководства g++:

-fno-слабая

Не используйте слабую поддержку символов, даже если она предоставляется компоновщиком. По умолчанию g++ будет использовать слабые символы, если они доступны. Этот параметр существует только для тестирования и не должен использоваться конечными пользователями; это приведет к утере кода и не принесет никаких преимуществ. Эта опция может быть удалена в будущей версии g++.

Еще одна проблема с __dso_handle. Я обнаружил, что вы можете, по крайней мере, загрузить библиотеку и, по-видимому, работать, связав файл, который определяет этот символ. Я не знаю, приведет ли этот хак к чему-то другому.

Итак, в X.cabal добавьте

if impl(ghc < 7.8)
    cc-option: -fno-weak
    c-sources: cbits/dso_handle.c

где cbits/dso_handle.c содержит

void *__dso_handle;