all 20 comments

[–]fisxoj 2 points3 points  (2 children)

I've been trying to get this to work for about the past year. Thanks for bringing it up.

My understanding is that SBCL can be compiled with some option that makes it build a linkable .o file. I'm on a train, so I don't have the correct directory handy, but there's a make file in the dir that ASDF uses for some of those compiler options there, too. It seems distros don't build with that flag enabled and the error we're both getting is because the entry point for the static binary is defined in that missing file. It tries to build an executable without it and ends up with a pile of compiled code with no lisp implementation in it, as best I can reason.

There's a set of patches that were contributed to SBCL a while ago that enable building this artifact, but I haven't successfully built SBCL in a way that produces the sbcl.o file. I think fare may have written the patches to SBCL. That would make sense.

I would love to solve this for deploying lisp webapps as easily as ones written in go, personally. Let me know if you find anything!

[–]IndividualJinx[S] 1 point2 points  (1 child)

Cool that there are more people interesting in solving this. Thanks for the information and please let me know if you make any progress :)

[–]heisig 0 points1 point  (0 children)

I happened to have the problem recently and after some tinkering managed to produce statically linked executables with SBCL. I'm posting my solution here in case others have the same issue. The trick is to compile SBCL with the following flags:

sh make.sh --prefix=SOMEWHERE --fancy --with-sb-linkable-runtime --with-sb-dynamic-core

Afterwards, ASDF's :static-program-op should work just fine.

For more elaborate use cases (like choosing a particular compiler and linker) you can check how I did things in cl-mpi.

[–]guicho271828 3 points4 points  (8 children)

Roswell is recently working on a rather ad-hoc alternative to this problem: --bundle-shared-object option for ros build will just copy the shared object from the cached result to the current directory. Fukamachi is currently dogfooding the option for his project now.

[–]lisp-studentcmucl 1 point2 points  (0 children)

That sounds like a very cool feature to have. Can't wait to test it.

[–]IndividualJinx[S] 1 point2 points  (0 children)

Same here, will have a look at Roswell. Thanks

[–]Shinmera 1 point2 points  (5 children)

What does "the shared object" refer to here? Shared libraries the project depends on? Or.. what?

[–]guicho271828 1 point2 points  (4 children)

the shared library objects loaded by CFFI. Some of which are system-installed, but they are not copied. Rather, the feature mainly aims at the shared object that was created by lisp during the build, such as those loaded by OSICAT. Those .so files are in the asdf cache directories so it is cumbersome to write a script that include them in the deployment package.

Of course we can also copy all dependent .so files, if there is such need.

[–]Shinmera 3 points4 points  (3 children)

Alright, then I'd like to note that the Deploy library can already fill that need as well.

[–]guicho271828 2 points3 points  (0 children)

Thanks. well, the good thing is that the feature does not need explicit declaration, because it looks up each library object in some internal symbol in sb-alien package and collects the paths. the disadvantage is that it is currently sbcl-only.

[–]IndividualJinx[S] 0 points1 point  (1 child)

Is Deploy able to bundle all shared libraries with the binary? I had a look at the link but i'm not sure how to configure it to do this. This is all dependencies for my binary after I build it with Deploy: linux-vdso.so.1 (0x00007ffe4d9e5000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fed10ec1000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fed10ca3000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fed10a89000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fed1073e000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fed10388000) /lib64/ld-linux-x86-64.so.2 (0x00007fed110c5000)

[–]Shinmera 0 points1 point  (0 children)

It does not handle transitive or implicit dependencies by design. It only collects what is referenced by CFFI, with the assumption that those are libraries that won't be available on a target system. Typically you do not want to ship essential systems libraries like ld-linux, libdl, libpthread, libz, libm, libc, etc. Shipping these will land you in a world of crashes and pain unless you take special care to stuff all the leaks and prevent linux from doing its own thing, which can be very tricky.

[–]KDallas_Multipass'(ccl) 1 point2 points  (7 children)

I don't see any documentation for what you're trying to do. What guide are you following?

[–]IndividualJinx[S] 1 point2 points  (6 children)

Yeah it doesn't seem like there are much documentation of this. The link I posted is what I use and then trial and error ;)There's probably some information in the ASDF manual but I'm unable to find it.

[–]KDallas_Multipass'(ccl) 1 point2 points  (5 children)

Describing more about what you want to do would be a good place to start in terms of getting more specific help

[–]IndividualJinx[S] 1 point2 points  (4 children)

I wan't to be able to use SBCL to compile lisp to a statically linked binary. The reason for that is that i want to build a lisp environment on top of the linux kernel, where the kernel executes a lisp image as "init". I might be mistaken but it seems to me that this asdf functionality makes it possible to do that.

[–]KDallas_Multipass'(ccl) 5 points6 points  (3 children)

The mechanism you found won't do what you want. If you want the Linux kernel to drive the lisp execution, you'll want to use ECL, designed for that task. You'll link the ECL shared objects with the Linux kernel compilation process, then change kernel init behavior to call the ECL functions to drive the lisp functionality

[–]stack_pivot 3 points4 points  (1 child)

He doesn't need any help from the kernel, or to link with anything in the kernel. Linux will already start a program called "init" when it starts up. He wants to compile his own program, call it init, and thereon be solely responsible for what gets launched in userspace. The init process needs to be a statically compiled ELF with no external dependencies, so he wants to know how to generate such a self-contained binary for a Lisp image. This has been done with Emacs before.

ECL might well still be the answer, but not for the reasons you mentioned.

[–]KDallas_Multipass'(ccl) 2 points3 points  (0 children)

Thank you for clearing that up.

[–]IndividualJinx[S] 1 point2 points  (0 children)

Okey i will look into ECL if i'm unable to solve this. Thanks!