Search code examples
common-lispasdfecl

Building an executable with ECL: missing dependency or can not find make-build in asdf/interface


I'm trying to build an executable with ECL. I looked at the doc and this other SO question, where we learn that with ECL v <= 16.1.3 we must add a

(require 'adsf)

Then I push my project to the asdf registry:

(pushnew "~/projects/my-project/" asdf:*central-registry* :test #'equal)

I load it:

(load "my-project.asd")

My program obviously has Quicklisp dependencies.

I copied the initialization of Quicklisp from my .sbclrc to ~/.eclrc:

#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                       (user-homedir-pathname))))
  (when (probe-file quicklisp-init)
    (load quicklisp-init)))

So than I can Quickload my project: (this step does not appear in the doc but this allows to find the project dependencies)

(ql:quickload "my-project")

I also

(use-package :my-project)

but now, as I want to build the executable with

(asdf:make-build :my-project
                 :type :program
                 :move-here #P"./"
                 :epilogue-code '(progn (my-project:main)
                                        (si:exit)))

I get the error

Cannot find the external symbol MAKE-BUILD in #<"ASDF/INTERFACE" package>.

Can someone help ? Thanks !

ECL 16.1.3

ps: and it seems that, in the REPL, to enter a restart nb has no effect.


My makefile:

ecl-build:
    ~/.roswell/impls/x86-64/linux/ecl/16.1.3/bin/ecl \
        --eval "(require 'asdf)" \
        --eval '(format t "--- ASDF version: ~a~&" (asdf:asdf-version))' \

        --eval "(pushnew \"~/projets/cl-torrents/\" asdf:*central-registry* :test 'equal)" \
        --eval '(load "cl-torrents.asd")' \
        --eval '(asdf:make-build :cl-torrents :type :program :move-here #P"./" :epilogue-code "(progn (torrents "matrix") (si:exit))")'

Result:

;;; Loading "/home/vince/quicklisp/setup.lisp"
;;; Loading #P"/home/vince/.roswell/impls/x86-64/linux/ecl/16.1.3/lib/ecl-16.1.3/asdf.fas"
--- ASDF version: 3.2.1
An error occurred during initialization:
Cannot find the external symbol MAKE-BUILD in #<"ASDF/INTERFACE" package>..
Makefile:22: recipe for target 'ecl-build' failed
make: *** [ecl-build] Error 1

edit 27, oct - progress

The simplest path now seems to unsure to use ASDF bundled into ECL, which will have the make-build command.

I had a newer ASDF version because of my Quicklisp's initialization code into ~/.eclrc. I removed it and now I have ASDF v3.1.8.2, which is ok. But now, ECL doesn't know any dependencies:

Component :DEXADOR not found, required by #.

Indeed, because there is no Quicklisp any more.

ECL doc says to include all libraries path into asdf:*central-registry*. By chance, Quicklisp installed all libraries into ~/quicklisp/dists/quicklisp/software/.

First, I wonder how this will work in a CI pipeline where Quicklisp has not run before…

Then I see that adding only this directory is not enough, Dexador's dependencies will in turn not be found, I had to add dexador's directory precisely:

    --eval "(pushnew \"~/quicklisp/dists/quicklisp/software/dexador-20170830-git/\" asdf:*central-registry* :test 'equal)" \

So do I really have to write code to include every directory here ?

How to make this work when Quicklisp has not run once before ?

update: With Ecl installed with Roswell: requireing asdf before everything in my .eclrc gives the version 3.1.8.2, after Quicklisp initialization 3.2.1 and make-build symbol unknown.

With Debian's Ecl: first v2.33.10 and then v3.2.1 likewise.

Looks like a dead end.

update november: I waited for the release of ASDF 3.3.0 to manually update. It was buggy. Message on the mailing list: waiting for 3.3.1: buggy again.

Went with the lisp-devel Docker image, shipping ECL 16.1.3. (I don't want to compile ECL myself on each and every VPS). I could build an executable (52Mo in weight), but got a runtime error:

Condition of type: SIMPLE-ERROR Package ((UIOP/STREAM . #)) referenced in > compiled file NIL but has not been created


Solution

  • I Went with the lisp-devel Docker image, shipping ECL 16.1.3. (I don't want to compile ECL myself on each and every VPS). I could build an executable (52Mo in weight VS 78Mo with SBCL), so I was able to deliver it with Gitlab CI.

    For reference, to launch Docker and mount your sources:

    service docker start
    docker run --rm -it -v /home/you/projets/project:/usr/local/share/common-lisp/source  daewok/lisp-devel:latest bash
    

    Unfortunately I got a runtime error:

    Condition of type: SIMPLE-ERROR Package ((UIOP/STREAM . #)) referenced in > compiled file NIL but has not been created

    It also seems I had to ql:quickload :closer-mop manually before loading my app.

    I won't investigate this.