我是Yesod的新手,无法静态构建Yesod,因此可以部署到Heroku。
我已更改默认的.cabal文件以反映静态编译
if flag(production) cpp-options: -DPRODUCTION ghc-options: -Wall -threaded -O2 -static -optl-static else ghc-options: -Wall -threaded -O0
而且它不再构建。我收到一堆警告,然后是许多未定义的引用,如下所示:
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 ...)
如果我仅使用just进行编译,-static而没有进行-optl-static 任何编译,则一切正常,但是当尝试在Heroku上启动时,应用程序崩溃。
-static
-optl-static
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版本不同。我也尝试像对libgmp一样将libc添加到库批次中,但是当应用程序在Heroku端启动时,这会导致分段错误。
在我的PC上一切正常。我正在使用ghc 7.0.3运行64位archlinux。 Yesod官方博客上的博客文章看起来很简单,但是我对此感到困惑。谁有想法?如果有一种方法可以在 不进行 静态构建的情况下使它正常工作,那么我也对此持开放态度。
编辑
每个Employed Russians答案我做了以下修复。
Employed Russians
首先在lib项目目录下创建一个新目录,然后将缺少的共享库复制到其中。您可以通过运行获取此信息ldd path/to/executable,并heroku run ldd path/to/executable和比较输出。
lib
ldd path/to/executable
heroku run ldd path/to/executable
然后我这样做了heroku config:add LD_LIBRARY_PATH=./lib,当启动应用程序时,动态链接器将在新的lib目录中查找库。
heroku config:add LD_LIBRARY_PATH=./lib
最后,我创建了一个ubuntu 11.10虚拟机,并从那里构建并部署到Heroku,它具有足够老的glibc,可以在Heroku主机上运行。
编辑:从那以后我就在Yesod Wiki上写了一个教程
我不知道Yesod是什么,但我 确切 知道您其他每个错误的含义。
首先,你应该 不 尝试静态链接。您得到的警告是完全正确的: 如果 您静态链接并使用要获得警告的例程之一,则必须安排在与libc.so.6版本 完全相同 的系统上运行您在构建时使用过。
与普遍的看法相反,静态链接在Linux上生成的是 更少 但不是更多的可移植可执行文件。
您的其他(静态)链接错误是由于libopenssl.a链接时丢失而引起的。
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。
/lib/ld- linux.so
/lib/libc.so.6
libpthread.so.0
libnsl.so.1
libc.so.6
LD_LIBRARY_PATH
/lib/ld-linux
那么有什么解决方案呢?有几种可能性(难度越来越大):
ld-2.14.so
/path/to/ld-2.14.so --library-path <whatever> /path/to/your/executable
这通常可以正常工作,但会混淆看着的应用程序argv[0],并中断那些自己重新执行的应用程序。
argv[0]
您可以在较旧的系统上构建。
你可以使用appgcc(这个选项已经消失了,看到这为它曾经被描述)。
appgcc
您可以设置与目标系统匹配的chroot环境,并在该chroot中进行构建。
您可以构建自己的Linux到旧版Linux交叉编译器