#linux #haskell #libraries #static-linking #ld
#linux #haskell #библиотеки #статическое связывание #ld
Вопрос:
Не часто две вещи, которые я так сильно люблю, объединяются, чтобы вызывать у меня столько раздражения (помимо моих детей). Я написал программу на Haskell в процессе работы, которая использует такие библиотеки, как text, xml-enumerator, attoparsec-text и т.д. У меня он работает должным образом на моем рабочем компьютере с Windows, на моей виртуальной машине Ubuntu (32-разрядная версия), на моем рабочем столе Ubuntu (снова 32-разрядная версия) и на экземпляре EC2 под управлением Ubuntu (64-разрядная версия).
Наш клиент работает под управлением 64-разрядной версии CentOS 5.3. Я ни за что в жизни не смогу заставить этот исполняемый файл запускаться должным образом. Я попытался создать статический исполняемый файл с помощью:
ghc --make myprog.hs -optl-static -optl-pthread
Но когда я пытаюсь запустить этот исполняемый файл на сервере CentOS, я получаю сообщение об ошибке:
openFile: invalid argument (Invalid argument)
Я предполагаю, что это связано с ошибкой, описанной здесь . Я пробовал компилировать как из 32, так и из 64-разрядной Ubuntu, пробовал статические и общие сборки, ничего не работает (хотя я иногда получаю segfaults вместо приведенного выше сообщения об ошибке). Я могу попробовать загрузить CentOS 5.3 и создать для него виртуальную машину, но загрузка займет некоторое время, и я не уверен, какая версия GHC будет работать на нем (я попытался установить GHC 7 на их сервере, но столкнулся с проблемой libc).
На данный момент я предложил несколько возможных подходов, но я хотел бы избежать их, если это вообще возможно:
- Перепишите на другом языке (мысль о том, чтобы сделать это на Java, вызывает у меня тошноту, хотя было бы неплохо попробовать Cal / OpenQuark).
- Возможно, попробуйте альтернативный компилятор, такой как jhc. Но я не совсем уверен, как начать установку всех зависимостей для этой программы в jhc; если у людей есть опыт и они знают, что text / attoparsec / etc работают в jhc, я бы хотел это услышать.
- Лучший из всех взломов: создайте исполняемый файл Windows, установите wine на их сервер и запустите его таким образом.
В целом, это ситуации, в которых я действительно хотел бы, чтобы у нас был сервер JVM для GHC. Полагаю, я мог бы также попробовать LambdaVM. Но я хотел бы услышать совет сообщества о том, что здесь делать.
Комментарии:
1. Если вы собираетесь распространять его среди них в будущем, то создание виртуальной машины CentOS 5.3, безусловно, хорошая идея. И это может быть взломом из всех взломов, но если он работает под управлением wine, это может сэкономить вам много времени и душевных страданий.
Ответ №1:
Этот простой пример «работает для меня»:
$ cat A.hs
main = print "yes"
$ ghc -O2 --make -static -optc-static -optl-static A.hs -fvia-C -optl-pthread
$ ldd A
not a dynamic executable
$ ./A
"yes"
(и я использовал этот процесс, через .cabal, для отправки исполняемых файлов для клиентов в последние пару лет).
Я думаю, что лучше всего записать ошибки и заставить это работать. IHG также может профинансировать подобную работу, но я почти уверен, что команда GHC сочтет это первоочередной задачей, если вы пытаетесь поставлять продукты.
Комментарии:
1. Я попробую это завтра, я не подумал о параметрах -fvia-C или -optc-static. В общем, я бы отправил отчеты об ошибках для этого, но у меня невероятно ограниченный доступ к их серверу, поэтому я действительно могу предоставить полную информацию об отладке.
2. Поскольку у вас есть все необходимые статические библиотеки, это работает очень хорошо. (в моей системе мне действительно нужно было дополнительно скомпилировать libgmp и libffi)
Ответ №2:
Он связан со старой библиотекой glibc в CentOS. Вы должны скомпилировать с той же версией glibc, которая установлена на CentOS.
У меня была точно такая же проблема. Исполняемый файл Haskell, скомпилированный на arch (или Ubuntu), не будет запускаться на CentOS. В моем случае, однако, мне повезло, потому что наш администратор только что удалил CentOS и установил Arch для сервера приложений.
Ответ №3:
Я обнаружил проблему. Похоже, что ссылка на страницу Biohaskell верна: это проблема с загрузкой iconv. Это происходит при вызове openFile
, но не при вызове openBinaryFile
. Поскольку xml-enumerator
используется последний, он работал просто отлично. Переключение остальной части кода для использования openBinaryFile
вместо этого (через Data.Enumerator.Binary.enumFile
) заставило все работать.
Это хороший обходной путь для моего варианта использования, но ошибка все еще существует.