Deploying Yesod to Heroku, can't build statically

后端 未结 3 1460
旧巷少年郎
旧巷少年郎 2020-11-22 15:51

I\'m very new to Yesod and I\'m having trouble building Yesod statically so I can deploy to Heroku.

I have changed the default .cabal file to reflect static compilat

相关标签:
3条回答
  • 2020-11-22 15:58

    I have no idea what Yesod is, but I know exactly what each of your other errors means.

    First, you should not try to link statically. The warning you get is exactly right: if you link statically, and use one of the routines for which you are getting the warning, then you must arrange to run on a system with exactly the same version of libc.so.6 as the one you used at build time.

    Contrary to popular belief, static linking produces less, not more, portable executables on Linux.

    Your other (static) link errors are caused by missing libopenssl.a at link time.

    But let's assume that you are going to go the "sane" route, and use dynamic linking.

    For dynamic linking, Linux (and most other UNIXes) support backward compatibility: an old binary continues to work on newer systems. But they don't support forward compatibility (a binary built on a newer system will generally not run on an older one).

    But that's what you are trying to do: you built on a system with glibc-2.14 (or newer), and you are running on a system with glibc-2.13 (or older).

    The other thing you need to know is that glibc is composed of some 200+ binaries that must all match exactly. Two key binaries are /lib/ld-linux.so and /lib/libc.so.6 (but there are many more: libpthread.so.0, libnsl.so.1, etc. etc). If some of these binaries came from different versions of glibc, you usually get a crash. And that is exactly what you got, when you tried to place your glibc-2.14 libc.so.6 on the LD_LIBRARY_PATH -- it no longer matches the system /lib/ld-linux.

    So what are the solutions? There are several possibilities (in increasing difficulty):

    1. You could copy ld-2.14.so (the target of /lib/ld-linux symlink) to the target system, and invoke it explicitly:

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

      This generally works, but can confuse an application that looks at argv[0], and breaks for applications that re-exec themselves.

    2. You could build on an older system.

    3. You could use appgcc (this option has disappeared, see this for description of what it used to be).

    4. You could set up a chroot environment matching the target system, and build inside that chroot.

    5. You could build yourself a Linux-to-olderLinux crosscompiler

    0 讨论(0)
  • 2020-11-22 16:03

    You have several issues.

    You should not build production binaries on bleeding edge distributions. The libraries on the production system will not be forward compatible.

    You should not link glibc statically - it will always at runtime try to load additional libraries. For example cpu-based assembly. That is what your first warnings are about.

    The last linker errors look like they are related to a missing openssl library on the command line.

    But all in all - downgrade your distribution.

    0 讨论(0)
  • 2020-11-22 16:08

    I had similar problems launching to Heroku (which uses glibc-2.11) where I had an application that required glibc-2.14, but I did not have access to the source and could not re-build it. I tried many things and nothing worked.

    My workaround was to launch the service on Amazon Elastic Beanstalk and just provide an API interface.

    0 讨论(0)
提交回复
热议问题