2017-12-19 42 views
2

スタンドアロンの実行可能ファイルをSBCLでビルドするにはどうすればよいですか?私は試しましたSBCL:スタンドアロンの実行可能ファイルの作成

; SLIME 2.20 
CL-USER> (defun hullo() 
        (format t "hullo")) 
HULLO 
CL-USER> (sb-ext:save-lisp-and-die "hullo" :toplevel #'hullo :executable t) 

しかし、それだけで次のエラーが発生します。

Cannot save core with multiple threads running. 

Interactive thread (of current session): 
    #<THREAD "main thread" RUNNING {10019563F3}> 

Other threads: 
    #<THREAD "Swank Sentinel" RUNNING {100329E073}>, 
    #<THREAD "control-thread" RUNNING {1003423A13}>, 
    #<THREAD "reader-thread" RUNNING {1003428043}>, 
    #<THREAD "swank-indentation-cache-thread" RUNNING 
    {1003428153}>, 
    #<THREAD "auto-flush-thread" RUNNING {1004047DA3}>, 
    #<THREAD "repl-thread" RUNNING {1004047FA3}> 
    [Condition of type SB-IMPL::SAVE-WITH-MULTIPLE-THREADS-ERROR] 

私は間違っていますか?

+0

エラーは、複数のスレッドを実行していると言います。したがって、複数のスレッドを実行することなく保存する必要があります。スライムではなくrepl(例えば、端末内)で同じものを直接試してみてください。 –

+0

@DanRobertson、それはうまく動作します。しかし、これは本当に実行可能ファイルをコンパイルする唯一の方法ですか?奇妙なことに思えます。 – Toothrot

+0

面倒です。それを少し簡単にするいくつかの方法があります。画像を保存することは難しい問題です。保存したい国はたくさんありますが、それについて何をすべきかは明白ではありません。ファイルを開くとどうなりますか?オープンソケット?あなたの現在の作業ディレクトリやコマンドラインの引数はどうなりますか?実行中の他のスレッドはどうすればよいですか?開いているファイルがあり、コアを保存してからファイルを移動すると、コアを復元するときにストリームの状態はどうなりますか?実行中のアプリケーションでは、ファイルのiノードが移動しないため、これは問題ではありません。リンク解除と同じです。 –

答えて

4

あなたが間違っていることは、複数のスレッドが実行されている間に画像を保存しようとしていることです。 Lispの多くのエラーとは異なり、エラーメッセージは問題の内容を正確に説明しています。

sbclマニュアルhereで関数を調べると、実際には複数のスレッドが実行されている画像を保存できないことがあります。余分な糸はスワンク(SLIMEのCL半分)から来ます。マニュアルでは、余分なスレッドを破棄して機能を追加して*save-hooks*に機能を追加して、スレッドを復元するために*init-hooks*に機能を追加することができます。

これは、スライムで実行しているときにイメージを保存しないで、ターミナルで直接sbclを開始する(注:readlineサポートなし)、プログラムを読み込んでそこから保存することです。

スライムを使った作業は異なります。理論的にはSWANK-BACKEND:SAVE-IMAGE機能がありますが、それが機能するかどうかはわかりません。また、イメージを保存するとプロセスが終了するので、Windowsを使用している場合を除き、最初にフォーク(SB-POSIX:FORK)することができます。しかし、フォークはよく指定されていないため、ファイル記述子に問題がある(つまり、fork->close swank connection->save and dieを試してみると、親プロセスの接続が閉じている(または悪くなっているように見えますが、 。そのようなことをオンラインで読むことができます。 sbclスレッドが実装される方法により、フォークするスレッドのみがクローンをフォークし、他のスレッドはクローンされないことに注意してください。したがって、フォークして保存する必要がありますが、部分スライム状態のため実行可能ファイルを実行するときに問題が発生する可能性があります。

buildappに興味があるかもしれません。

保存アプリケーションでスライムを使用できるようにするには、スワンクを読み込んでソケットやポートでリッスンして(おそらくコマンドライン引数で)Emacsでそのスワンクバックエンドにスライムで接続することができます。

+2

[sbcli](https://github.com/hellerve/sbcli)は、readlineサポートをreplに提供します([cl-readline](https ://github.com/mrkkrp/cl-readline))。必要なときに便利です。 – Ehvince

+0

@エフビンス私はそれを知らなかった。それは素晴らしいです –

1

Slimeからではなく、新しいsbclからsave-lisp-and-dieを実行する必要があります。 Dan Robertsonはもっと詳しく説明します。

最初は面倒ですが、Makefileに入れて再利用することができます。依存関係をロードすることを忘れないでください。

build: 
    sbcl --load cl-torrents.asd \ 
     --eval '(ql:quickload :torrents)' \ 
     --eval '(use-package :torrents)' \ # not mandatory 
     --eval "(sb-ext:save-lisp-and-die #p\"torrents\" :toplevel #'main :executable t)" 

quickloadはQuicklispがすでにマシンにQuicklispをインストールした場合、あなたの~/.sbclrがquicklispロード・スクリプト((load quicklisp-init))が含まれているため、ケースとすることができる、ロードされている意味しています。

あなたはSBCLとCCLのためにこれを行うにはまだ普及しているアプリであるbuildapp(上記)を見ることができます。 Debianにあります。 http://lisp-lang.org/wiki/article/buildapp使用例は

buildapp --output myapp \ 
     --asdf-path . \ 
     --asdf-tree ~/quicklisp/dists \ 
     --load-system my-app \ 
     --entry my-app:main 

のように見えるがロズウェル、より汎用的なツールは、また、実行可能ファイルを構築することになったが、それはあまり文書化されても参照してください。https://roswell.github.io/

CIシステム(Gitlab CIなど)で実行可能ファイルをビルドする場合は、既にSBCLを持つlisp Dockerイメージ、lispsおよびQuicklispがインストールされていることがわかります。コマンドライン引数を解析する場合は、 https://lispcookbook.github.io/cl-cookbook/testing.html#gitlab-ciと(私の)チュートリアルを参照してください:https://vindarel.github.io/cl-torrents/tutorial.html#org8567d07

関連する問題