2017-12-19 8 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

성가시다. 약간 더 쉽게 만들 수있는 몇 가지 방법이 있습니다. 이미지를 저장하는 것은 어려운 문제입니다. 하나는 저장하고 싶은 상태가 많이 있지만 그것에 대해해야할 일은 분명하지 않습니다. 파일을 열려면 어떻게됩니까? 열린 소켓? 현재 작업 디렉토리 또는 명령 행 인수는 어떻게됩니까? 다른 실행중인 스레드에는 어떤 일이 발생해야합니까? 열린 파일이 있고 코어를 저장 한 다음 파일을 이동하는 경우 코어를 복원 할 때 스트림의 상태는 무엇입니까? 파일의 inode가 이동하지 않기 때문에 실행중인 응용 프로그램에서는 문제가되지 않습니다. 연결 해제와 동일합니다. –

답변

4

잘못하고있는 것은 여러 스레드가 실행되는 동안 이미지를 저장하려고하는 것입니다. Lisp의 많은 오류와 달리 오류 메시지는 문제가 무엇인지 정확하게 설명합니다.

sbcl 설명서 here에서 함수를 살펴보면 실제로 여러 스레드가 실행중인 이미지를 저장할 수 없다는 것을 알 수 있습니다. 여분의 실은 swank (SLIME의 CL 절반)에서옵니다. 매뉴얼에 따르면 여분의 스레드를 파괴하는 *save-hooks*에 기능을 추가 할 수 있으며 스레드를 복원하기 위해 *init-hooks*에 기능을 추가 할 수 있습니다.

슬라임을 통해 실행될 때 이미지를 저장하지 않고 대신 터미널에서 직접 sbcl을 시작하는 것 (참고 : readline 지원 없음)은 프로그램을로드하고 거기에서 저장하십시오.

점액으로 작업하는 것은 다릅니다. 이론에서는 SWANK-BACKEND:SAVE-IMAGE 기능이 있지만 작동하는지 확실하지 않습니다. 또한 이미지를 저장하면 프로세스가 중단되므로 Windows를 사용하는 경우가 아니라면 먼저 포크 (SB-POSIX:FORK)를 표시 할 수 있습니다. 하지만 포킹은 잘 지정되지 않았고 파일 설명자 문제로 인해 문제가 발생합니다 (예 : fork->close swank connection->save and die을 시도한 경우 상위 프로세스의 연결이 닫히거나 열리는 것처럼 보이지만 더 낮은 수준에서 닫히는 경우 손상 될 수 있음) . 온라인에서 그런 것들을 읽을 수 있습니다. sbcl 쓰레드가 구현되는 방식 때문에, 포크 (fork)는 포크 (forks)와 다른 쓰레드 (thread)가 복제되지 않은 쓰레드 만 복제한다. 따라서 분기 및 저장은 작동해야하지만 부분 슬라임 상태로 인해 실행 파일을 실행할 때 문제가 발생할 수 있습니다.

buildapp에 관심이 있으실 것입니다.

저장 한 응용 프로그램에서 슬라임을 사용할 수있게하려면 swank를로드하고 소켓 또는 포트 (아마도 명령 줄 인수로)에서 수신을 시작한 다음 Emacs에서 슬레이크로 백팩에 연결할 수 있습니다 .

+2

[sbcli] (https://github.com/hellerve/sbcli)는 readline 지원을 repl에 제공합니다 ([cl-readline] (https : //github.com/mrkkrp/cl-readline)). 필요할 때 편리하게 사용할 수 있습니다. – Ehvince

+0

@Ehvince 나는 그것을 몰랐다. 환상적이다. –

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 (위에서 언급 한)를 살펴볼 수 있습니다. 데비안에 있습니다. 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, 다른 lisps 및 Quicklisp이 설치된 lisp Docker 이미지와 명령 줄 인수를 구문 분석하고 싶다면, https://lispcookbook.github.io/cl-cookbook/testing.html#gitlab-ci 및 (내) 자습서를 참조하십시오. https://vindarel.github.io/cl-torrents/tutorial.html#org8567d07

관련 문제