我有一个简单的普通lisp服务器程序,它使用osicat库与posix文件系统进行接口。我需要这样做,因为系统会创建指向文件的符号链接,并且使用POSIX stat元数据,而这两件事都不是用可移植的lisp直接完成的。
我正在使用quicklisp管理依赖项,并且将所有这些都固定在一个工作的发行版上。这个应用程序在CCL和SBCL之间是可移植的,我倾向于在第一个阶段构建它并使用后者来部署它。我用asdf defsystem声明应用程序的依赖项,我可以使用quicklisp加载它,以便于从本地项目进行开发。
对于部署,我只是使用了一些在远程(.e )上复制开发人员环境的ansible剧本。设置quicklisp,将代码推入本地项目,运行出用户主目录),这是很麻烦的,但大多数情况下都可以。最近,随着它变得越来越稳定,我一直使用sb-ext:save-lisp-and-die编译它,使用一个简单的编译脚本。这意味着我可以获得一个可执行文件,它可以更像服务器一样运行,使用服务管理脚本和匿名用户帐户。
它一直运行得很好,所以我最近将这个步骤移到了下一个级别,我正在用编译脚本构建.deb包,这样我就可以将所有的东西捆绑到一个可重定位的二进制文件中。这也是一种工作,但是生成的二进制文件不能从原始构建主机中重新定位。他们拒绝启动,而且他们似乎试图动态地加载一个共享库以供osicat使用。
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
Mar 15 12:47:14 annie [479]: {10005C05B3}>:
Mar 15 12:47:14 annie [479]: Error opening shared object "libosicat.so":
Mar 15 12:47:14 annie [479]: libosicat.so: cannot open shared object file: No such file or directory.它看起来像是图像希望在原始构建树的quicklisp档案中找到这个
(ERROR "Error opening ~:[runtime~;shared object ~:*~S~]:~% ~A." "/home/builder/buil...quicklisp/dists/quicklisp/software/osicat-20180228-git/posix/libosicat.so
(SB-SYS:DLOPEN-OR-LOSE #S(SB-ALIEN::SHARED-OBJECT :PATHNAME #P"因此,在查看源代码时,我意识到当quicklisp获取osicat并执行它的构建操作时,它会编译这个DLL来包装它与系统libaries的接口,而不是直接与它们联系--可能是因为它使用的是cffi groveller,所以我对cffi还不太了解(目前为止)。这很好,但它不是使用系统链接器链接到.so,而是尝试从固定路径(不是很可移植的路径)将其链接到dlopen,这破坏了save-image的有用性。
我在这一点上有点困惑,但在深入研究QL和cffi构建之前,我想知道是否有一些构建或编译配置会使它以更“静态”的方式引导,或者影响包装库的生产。理想情况下,我只想要一个blob,我可以把它包装在一个安装程序中,并将它与系统库连接起来,但是如果我必须部署一些额外的人工工具,这可能是可以的。我不知道如何使自动生成的共享对象发生在更受控的路径上。
不过,在这一点上,我也可以为我的posix调用编写一个.so,并将其与应用程序一起分发,并向其更直接地尝试和FFI。这会有点痛苦,所以我不想这么做。
发布于 2019-03-15 14:18:47
也许您可以在SBCL上使用sb-posix:symlink和sb-posix:fstat,通过功能切换消除osicat依赖。
https://stackoverflow.com/questions/55183247
复制相似问题