首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Yesod部署到Heroku,不能静态地构建

将Yesod部署到Heroku,不能静态地构建
EN

Stack Overflow用户
提问于 2011-12-28 15:40:56
回答 4查看 39.2K关注 0票数 31

我对Yesod非常陌生,我很难静态地构建Yesod,所以我可以部署到Heroku。

我已更改默认的.cabal文件以反映静态编译。

代码语言:javascript
复制
if flag(production)
   cpp-options:   -DPRODUCTION
   ghc-options:   -Wall -threaded -O2 -static -optl-static
else
   ghc-options:   -Wall -threaded -O0

它也不再建造了。我收到了一大堆警告,然后出现了大量未定义的引用,如下所示:

代码语言:javascript
复制
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上启动时会崩溃。

代码语言:javascript
复制
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

我尝试按照LD_LIBRARY_PATH中的建议将libgmp.so.10添加到这里中,然后得到以下错误:

代码语言:javascript
复制
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端启动时,这会导致分段错误。

在我的电脑上一切正常。我用ghc 7.0.3运行64位archlinux。官方Yesod博客上的博客看上去很容易,但在这一点上我很困惑。有人有什么想法吗?如果有办法让这个东西在没有静态建筑的情况下工作,我也对此持开放态度。

编辑

按照Employed Russians的回答,我做了以下工作来解决这个问题。

首先,在项目目录下创建一个新目录lib,并将丢失的共享库复制到其中。您可以通过运行ldd path/to/executableheroku run ldd path/to/executable并比较输出来获取这些信息。

然后我做了heroku config:add LD_LIBRARY_PATH=./lib,所以当应用程序启动时,动态链接器将在新的lib目录中查找库。

最后,我创建了一个ubuntu11.10虚拟机,并从那里构建并部署到Heroku,它有一个足够老的glibc,可以在Heroku主机上工作。

编辑:我已经写了一个关于叶苏德维基的教程

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-12-28 16:23:29

我不知道叶索德是什么,但我很清楚你的其他每一个错误意味着什么。

首先,您不应该尝试静态链接。您得到的警告是完全正确的:如果您静态链接,并使用您要获得警告的例程之一,那么您必须安排在一个与构建时使用的libc.so.6版本完全相同的系统上运行。

与流行的观点相反,静态链接在Linux上产生的可移植可执行文件更少,而不是更多。

您的其他(静态)链接错误是由链接时缺少libopenssl.a造成的。

但让我们假设您将走“理智”的路线,并使用动态链接。

对于动态链接,Linux (和大多数其他UNIXes)支持向后兼容性:旧二进制继续在较新的系统上工作。但它们不支持前向兼容性(建立在较新系统上的二进制文件通常不会在旧系统上运行)。

但这正是您所要做的:您构建在一个具有glibc-2.14 (或更新版本)的系统上,在一个具有glibc-2.13 (或更高版本)的系统上运行。

您需要知道的另一件事是,glibc是由一些必须完全匹配的200+二进制文件组成的。两个关键的二进制文件是/lib/ld-linux.so/lib/libc.so.6 (但是还有更多的二进制文件:libpthread.so.0libnsl.so.1等等)。如果其中一些二进制文件来自不同版本的glibc,则通常会发生崩溃。这正是你所得到的,当你试图把你的glibc-2.14 libc.so.6放在LD_LIBRARY_PATH上-它不再匹配系统/lib/ld-linux

那么解决方案是什么呢?有几种可能性(难度越来越大):

  1. 您可以将ld-2.14.so ( /lib/ld-linux符号链接的目标)复制到目标系统,并显式调用它: /path/to/ld-2.14.so -库-path/path/to/your/可执行文件 这通常是可行的,但可能会混淆查看argv[0]的应用程序,而会使重新执行的应用程序中断。
  2. 你可以建立在旧的系统上。
  3. 您可以使用appgcc (此选项已消失,请参阅以了解过去的情况)。
  4. 您可以设置一个与目标系统匹配的chroot环境,并在该chroot中进行构建。
  5. 您可以为自己建立一个Linux到olderLinux交叉编译器。
票数 63
EN

Stack Overflow用户

发布于 2011-12-28 16:29:38

你有几个问题。

您不应该在流血边缘发行版上构建生产二进制文件。生产系统上的库将不会向前兼容。

您不应该静态地链接glibc -它总是在运行时尝试加载其他库。例如,基于cpu的程序集。这就是你第一次警告的意义。

最后一个链接器错误看起来与命令行中缺少的openssl库有关。

但总的来说-降低了你的发行量。

票数 5
EN

Stack Overflow用户

发布于 2013-07-12 21:38:54

我在Heroku (它使用glibc-2.11)上也遇到了类似的问题,在那里我有一个需要glibc-2.14的应用程序,但是我无法访问源代码,也无法重新构建它。我尝试了很多事情但什么也没成功。

我的解决办法是在AmazonElasticBean秸秆上启动该服务,并提供一个API接口。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8657908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档