Подтвердить что ты не робот

Развертывание Yesod для Heroku, не может статически

Я очень новичок в Yesod, и мне не удается создать Yesod статически поэтому я могу разворачиваться в Героку.

Я изменил файл .cabal по умолчанию, чтобы отразить статическую компиляцию

if flag(production)
   cpp-options:   -DPRODUCTION
   ghc-options:   -Wall -threaded -O2 -static -optl-static
else
   ghc-options:   -Wall -threaded -O0

И он больше не строит. Я получаю целую кучу предупреждений, а затем Количество ссылок undefined:

Linking dist/build/personal-website/personal-website ...
/usr/lib/ghc-7.0.3/libHSrts_thr.a(Linker.thr_o): In function
`internal_dlopen':
Linker.c:(.text+0x407): warning: Using 'dlopen' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In
function `__hsunix_getpwent':
HsUnix.c:(.text+0xa1): warning: Using 'getpwent' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In
function `__hsunix_getpwnam_r':
HsUnix.c:(.text+0xb1): warning: Using 'getpwnam_r' in statically
linked applications requires at runtime the shared libraries from the
glibc version used for linking
/usr/lib/libpq.a(thread.o): In function `pqGetpwuid':
(.text+0x15): warning: Using 'getpwuid_r' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/libpq.a(ip.o): In function `pg_getaddrinfo_all':
(.text+0x31): warning: Using 'getaddrinfo' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__63.o): In function `sD3z_info':
(.text+0xe4): warning: Using 'gethostbyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__164.o): In function `sFKc_info':
(.text+0x12d): warning: Using 'getprotobyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__155.o): In function `sFDs_info':
(.text+0x4c): warning: Using 'getservbyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/libpq.a(fe-misc.o): In function `pqSocketCheck':
(.text+0xa2d): undefined reference to `SSL_pending'
/usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage':
(.text+0x31): undefined reference to `ERR_get_error'
/usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage':
(.text+0x41): undefined reference to `ERR_reason_error_string'
/usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL':
(.text+0x2f8): undefined reference to `SSL_check_private_key'
/usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL':
(.text+0x3c0): undefined reference to `SSL_CTX_load_verify_locations'
(... snip ...)

Если я просто скомпилирую только -static и без -optl-static все строит отлично, но приложение падает, когда оно пытается начните с Heroku.

2011-12-28T01:20:51+00:00 heroku[web.1]: Starting process with command
`./dist/build/personal-website/personal-website -p 41083`
2011-12-28T01:20:51+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: error while loading shared libraries: libgmp.so.10:
cannot open shared object file: No such file or directory
2011-12-28T01:20:52+00:00 heroku[web.1]: State changed from starting
to crashed

Я попробовал добавить libgmp.so.10 в LD_LIBRARY_PATH, как это предложено в здесь и затем получил следующую ошибку:

2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: /lib/libc.so.6: version `GLIBC_2.14' not found
(required by ./dist/build/personal-website/personal-website)
2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: /lib/libc.so.6: version `GLIBC_2.14' not found
(required by /app/dist/build/personal-website/libgmp.so.10)
2011-12-28T01:31:25+00:00 heroku[web.1]: State changed from starting
to crashed
2011-12-28T01:31:25+00:00 heroku[web.1]: Process exited

Кажется, что версия libc, с которой я компилируюсь, другой. Я также попробовал добавить libc в пакет библиотек так же, как и для libgmp, но это приводит к ошибке сегментации когда приложение начинается с стороны Heroku.

Все работает отлично на моем ПК. Я запускаю 64-битный archlinux с ghc 7.0.3. Сообщение блога на официальном блоге Yesod выглядело довольно легко но я в тупике. У кого-нибудь есть идеи? Если есть способ заставить эту работу работать без статического старта, я тоже открыт для этого.

ИЗМЕНИТЬ

Per Employed Russians answer Я сделал следующее, чтобы исправить это.

Сначала создался новый каталог lib в каталоге проекта и копировал в него отсутствующие разделяемые библиотеки. Вы можете получить эту информацию, запустив ldd path/to/executable и heroku run ldd path/to/executable и сравнив вывод.

Затем я сделал heroku config:add LD_LIBRARY_PATH=./lib, поэтому при запуске приложения динамический компоновщик будет искать библиотеки в новом каталоге lib.

Наконец, я создал виртуальную машину ubuntu 11.10 и построил и развернул ее в Heroku, у этого есть достаточно старый glibc, который работает на хосте Heroku.

Изменить: С тех пор я написал учебник по Yesod wiki

4b9b3361

Ответ 1

Я не знаю, что такое Yesod, но я точно знаю, что означает каждая из ваших других ошибок.

Во-первых, вы не должны пытаться связывать статически. Предупреждение, которое вы получаете, совершенно правильно: , если вы ставите статическую ссылку, и используйте одну из подпрограмм, для которой вы получаете предупреждение, тогда вы должны организовать запуск в системе с точно такой же версией libc.so.6 как тот, который вы использовали во время сборки.

Вопреки распространенному мнению, статическая привязка создает меньше, не более, переносимых исполняемых файлов в Linux.

Другие (статические) ошибки ссылок вызваны отсутствием libopenssl.a во время соединения.

Но предположим, что вы собираетесь пойти "разумным" маршрутом и использовать динамическое связывание.

Для динамической компоновки Linux (и большинство других UNIX) поддерживает обратную совместимость: старый двоичный файл продолжает работать на более новых системах. Но они не поддерживают форвардную совместимость (двоичный файл, построенный на более новой системе, обычно не работает на более старой версии).

Но это то, что вы пытаетесь сделать: вы создали систему с glibc-2.14 (или новее), и вы работаете в системе с glibc-2.13 (или старше).

Другая вещь, которую вам нужно знать, - это то, что glibc состоит из 200+ двоичных файлов, которые должны точно соответствовать. Два ключевых бинарных файла: /lib/ld-linux.so и /lib/libc.so.6 (но есть еще много: libpthread.so.0, libnsl.so.1 и т.д. И т.д.). Если некоторые из этих двоичных файлов поступают из разных версий glibc, вы обычно получаете сбой. И это именно то, что вы получили, когда вы пытались разместить glibc-2.14 libc.so.6 на LD_LIBRARY_PATH - он больше не соответствует системе /lib/ld-linux.

Итак, каковы решения? Существует несколько возможностей (с большим трудом):

  • Вы можете скопировать ld-2.14.so (цель символической ссылки /lib/ld-linux) в целевую систему и явно вызвать его:

    /path/to/ld-2.14.so --library-path <whatever> /path/to/your/executable
    

    Это обычно работает, но может запутать приложение, которое смотрит на argv[0], и разбивается на приложения, которые повторно выполняются сами.

  • Вы можете использовать более старую систему.

  • Вы можете использовать appgcc (этот параметр исчез, см. this для описания того, чем он был раньше).

  • Вы можете настроить среду chroot, соответствующую целевой системе, и построить внутри этого chroot.

  • Вы можете создать себе кросс-компилятор Linux-to-oldLinux

Ответ 2

У вас есть несколько проблем.

Вы не должны создавать производственные двоичные файлы на граничных распределениях кровотечений. Библиотеки производственной системы не будут совместимы с переходом.

Нельзя связывать glibc статически - он всегда во время выполнения пытается загрузить дополнительные библиотеки. Например, сборка на основе процессора. Вот о чем ваши первые предупреждения.

Последние ошибки компоновщика выглядят так, как будто они связаны с отсутствующей библиотекой openssl в командной строке.

Но в целом - понизите распределение.

Ответ 3

У меня были аналогичные проблемы с запуском Heroku (который использует glibc-2.11), где у меня было приложение, которое требовало glibc-2.14, но у меня не было доступа к исходному коду и он не мог его перестроить. Я пробовал много вещей и ничего не работал.

Мое обходное решение состояло в том, чтобы запустить службу на Amazon Elastic Beanstalk и просто предоставить интерфейс API.