The comment by sds at Saving CLOS objects provides a reference to a Common Lisp Open Code Collection (CLOCC) file (closio.lisp) for printably reading & writing CLOS objects. Instructions for installing the software are at Installation of CLOCC. However, not having previously used CLOCC, I would like some additional guidance in setting things up for reading/writing CLOS objects. Here are the additions to my init file (.clinit) so far:
(in-package :cl-user)
(setq *clocc-root* "D:\\clocc\\")
(load "D:\\clocc.fasl")
(load
(compile-file ;warns about |make|::COMPILED-FILE-P being undefined
(translate-logical-pathname
"clocc:src;defsystem;defsystem")))
(dolist (s '("clocc:src;cllib;base" "clocc:src;port;sys"))
(mk:add-registry-location (translate-logical-pathname s)))
Instructions for what to add next appreciated.
The instructions were obsolete. Sorry.
The installation instructions now say (I removed the systems you don't need):
(compile-file "c:/gnu/clocc/clocc") ; or whatever ...
(load *)
;; * load the defsystem facility
;; most lisps come with "asdf"; if this fails, get it yourself from
;; https://common-lisp.net/project/asdf/
(require "asdf")
;; * compile some systems
(asdf:compile-system "port")
(asdf:compile-system "cllib")
...
You will need to follow the asdf instructions:
$ mkdir -p ~/.config/common-lisp/source-registry.conf.d/
$ echo '(:tree "c:/gnu/clocc/")' > asdf.conf
Related
While using SBCL normally I want to try CCL for some testing and installed it via homebrew on my computer. That worked fine but I fail to use quicklisp with CCL. If I try to load quicklisp's setup.lisp I get the following error message:
➜ ~ ccl64
Clozure Common Lisp Version 1.11.6 DarwinX8664
For more information about CCL, please see http://ccl.clozure.com.
CCL is free software. It is distributed under the terms of the Apache
Licence, Version 2.0.
? (require 'asdf)
ASDF
("uiop" "UIOP" "asdf" "ASDF")
? (load "~/quicklisp/setup.lisp")
> Error: There is no package named "ASDF/SYSTEM-REGISTRY" .
> While executing: CCL::%FASL-NVPACKAGE, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Retry finding package with name "ASDF/SYSTEM-REGISTRY".
> Type :? for other options.
1 > :POP
I couldn't find a simple solution searching the web. CCL comes with ASDF as (require 'ASDF) is working. In quicklisp's documentation I couldn't find anything about extra efforts to use it with two lisp implementations in parallel.
If I check ASDF's version as suggested here I get "3.1.5" as installed version, which should be quite recent.
Is there anything obvious I am missing?
I think I found it: I had some old data in my ~/.cache directory from another attempt to install ccl. After deleting it, I can load quicklisp's setup.lisp without any error.
Please advice If I should delete my question or leave it here to prevent others from repeating my errors.
Please note that various Lisps have some startup files. Some of them are by default:
SBCL: ~/.sbclrc
CLISP: ~/.clisprc.lisp
Clozure: ~/.ccl-init.lisp
From the documentation of CCL:
By default, Clozure CL will look for a file named ccl-init.lisp in your home directory, and load it upon startup. On Unix systems, it will also look for .ccl-init.lisp.
CCL uses an ordinary lisp file called ccl-init.lisp which on unix systems is usually put on your home path. So you can add the following lines in that file (on my Ubuntu machine it's path is /home/me/.ccl-init.lisp) which instructs CCL to load quicklisp upon startup:
#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
(user-homedir-pathname))))
(when (probe-file quicklisp-init)
(load quicklisp-init)))
This is enough for enabling your CCL to communicate with quicklisp.
I'm trying to run an executable with an Hunchentoot server and I'm getting (after an unusual high CPU usage):
<INFO> [17:55:14] weblocks/server server.lisp (start) -
Starting weblocks WEBLOCKS/SERVER::PORT: 40001
WEBLOCKS/SERVER::SERVER-TYPE: :HUNCHENTOOT DEBUG: T
debugger invoked on a SB-INT:EXTENSION-FAILURE in thread
#<THREAD "main thread" RUNNING {1008C1EA13}>:
Don't know how to REQUIRE sb-cltl2.
Do you have any idea what's going on ? It works correctly on Slime where I use the start function.
(sbcl manual: http://www.sbcl.org/manual/#Customization-Hooks-for-Users)
In the main entry point, I try to capture the running thread so that I keep the server running on the foreground (my notes). This pattern worked with another clack-based web framework.
(defun start ()
(weblocks/debug:on)
(weblocks/server:start :port *port*))
(defun main ()
(defvar *port* (find-port:find-port))
(start)
(handler-case (bt:join-thread (find-if (lambda (th)
(search "hunchentoot" (bt:thread-name th)))
(bt:all-threads)))
(#+sbcl sb-sys:interactive-interrupt
#+ccl ccl:interrupt-signal-condition
#+clisp system::simple-interrupt-condition
#+ecl ext:interactive-interrupt
#+allegro excl:interrupt-signal
() (progn
(format *error-output* "Aborting.~&")
(uiop:quit 1))
;; for others, unhandled errors (we might want to do the same).
(error (c) (format t "Woops, an unknown error occured:~&~a~&" c)))))
Or any indication of what could be the cause ?
Thanks again.
(I'm using 40ants' weblocks:reblocks branch)
SBCL Debian 1.2.4
edit I tried
export SBCL_HOME=/usr/local/lib/sbcl/
I build with
build:
$(LISP) --quit \
--eval '(ql:quickload "foo")' \
--eval '(require :sb-cltl2)' \
--eval '(asdf:make :foo)'
=>
fatal error encountered in SBCL pid 25248(tid 140737353910016):
can't load .core for different runtime, sorry
Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb>
The following environment failed:
export SBCL_HOME=/usr/local/lib/sbcl/
The error message tells us the following:
can't load .core for different runtime, sorry
Apparently the SBCL you ran used the given SBCL_HOME to find its core file, but failed due to the core being generated by different version SBCL.
A quick look at SBCL's source (starting from require) shows that the underlying function #'SB-INT:SBCL-HOMEDIR-PATHNAME is called to determine the installation path.
It looks like the one installed from the Debian package was installed in /usr/lib/sbcl/. The core file was easily found when starting Slime. You also had another version of SBCL in ~/.roswell/, but I guess you also ran ros install which installed it under /usr/local/lib/sbcl (/usr/local/ is for software that is not managed by the system).
Starting the roswell one when setting SBCL_HOME to the directory of the Debian one provoked the error about the incompatible core file (I guess).
What remains suprising is that (SB-INT:SBCL-HOMEDIR-PATHNAME) returns nil when starting your main function.
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
It seems a problem with comtibility with ASDF and ECL this is solved in last commit take a look here,
Add back make-build on ECL
This provides for backward compatibility with ECL, whose current
maintainer Daniel K. has decided to keep supporting the make-build
interface and has forked ASDF for that.
you can install/use the last ASDF from this repo
You may use either bundled ASDF (which is a frozen 3.1.7 version with some fixes backported) – then you load ASDF with (require asdf), or you may use upstream 3.3 version.
If you are interested in using upstream ASDF, download asdf.lisp file and call:
(load (compile-file "/path/to/asdf.lisp")) instead of (require 'asdf).
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.
I am working some lisp code on sbcl in order to run function in mode daemon.
The problem is when I use the function sb-thred:make-thread, for instance as follow:
(sb-thread:make-thread (lambda () (progn (sleep 1) (when t (print "background action")))))
I get the following error message:
Not supported in unithread builds. [Condition of type SIMPLE-ERROR]
What is wrong ? ... thanks for help.
SBCL has threads disabled by default on Mac OS X. To check if SBCL is build with threads run in the repl
(member :sb-thread *features*)
If not, compile it from source (using your current SBCL). From the INSTALL
sh make.sh --with-sb-thread
Suppose I have a directory A, and subdirectory B. I cd into A and launch lisp. In that lisp process, I would like to launch a Python subprocess where Python sees B as its current working directory. The lisp process needs to have cwd in A, and the python process should have cwd in B. How do I do this in a cross-platform, simple way?
I'm looking for a solution that works with CCL and SBCL (probably using 'run-program function), and works for Windows, Linux, and OS X.
I looked at the CCL run-program documentation, and I didn't see a way to change the cwd of the launched process.
I looked at Python command-line arguments, and I didn't see one that would change the cwd of the python process.
I thought about a run-program call for 'cd B; python ...', but I'm not sure how that would work, since it's really running two programs; cd, and then python.
The Python code is being provided as input (as a file), so I cannot change any of that code (by adding an os.chdir() call or similar).
A python wrapper file that launches the python input file as a subprocess isn't ideal, because I'm sending stdin and listening to stdout of the python process launched by lisp. Adding another subprocess in between lisp and the python process that evals the input file means I'd need to do a lot of stout/stdin relaying, and I have a feeling that this would be brittle.
krzysz00's approach worked very well. Since the directory change is handled in lisp, before the python process is launched, this approach will work for launching other processes in different subdirectories (not just python).
For documentation, here's my code using krzsz00's approach that worked for SBCL & CCL. Note that it uses Hoyte's defmacro! macro, from Let Over Lambda, to easily avoid unwanted variable capture:
#+:SBCL
(defun cwd (dir)
(sb-posix:chdir dir))
(defun getcwd ()
#+SBCL (sb-unix:posix-getcwd)
#+CCL (current-directory))
(defmacro! with-cwd (dir &body body)
`(let ((,g!cwd (getcwd)))
(unwind-protect (progn
(cwd ,dir)
,#body)
(cwd ,g!cwd))))
Usage:
(with-cwd "./B"
(run-program ...))
To run external programs (like your python process portably) see external-program. To change the current working directory, use this slightly modified (public domain) function cwd from the file http://files.b9.com/lboot/utils.lisp, which is reproduced below.
(defun cwd (&optional dir)
"Change directory and set default pathname"
(cond
((not (null dir))
(when (and (typep dir 'logical-pathname)
(translate-logical-pathname dir))
(setq dir (translate-logical-pathname dir)))
(when (stringp dir)
(setq dir (parse-namestring dir)))
#+allegro (excl:chdir dir)
#+clisp (#+lisp=cl ext:cd #-lisp=cl lisp:cd dir)
#+(or cmu scl) (setf (ext:default-directory) dir)
#+cormanlisp (ccl:set-current-directory dir)
#+(and mcl (not openmcl)) (ccl:set-mac-default-directory dir)
#+openmcl (ccl:cwd dir)
#+gcl (si:chdir dir)
#+lispworks (hcl:change-directory dir)
#+sbcl (sb-posix:chdir dir)
(setq cl:*default-pathname-defaults* dir))
(t
(let ((dir
#+allegro (excl:current-directory)
#+clisp (#+lisp=cl ext:default-directory #-lisp=cl lisp:default-directory)
#+(or cmu scl) (ext:default-directory)
#+sbcl (sb-unix:posix-getcwd/)
#+cormanlisp (ccl:get-current-directory)
#+lispworks (hcl:get-working-directory)
#+mcl (ccl:mac-default-directory)
#-(or allegro clisp cmu scl cormanlisp mcl sbcl lispworks) (truename ".")))
(when (stringp dir)
(setq dir (parse-namestring dir)))
dir))))
Combining these two functions, the code you want is:
(cwd #p"../b/")
(external-program:start "python" '("file.py") :output *pythins-stdout-stream* :input *pythons-stdin-stream*)
(cwd #p"../a/")
This will cd to B, run the python process as if by python file.py &, send the python process's stdin/stdout to the specified streams (look at the external-program documentation for more details), and finally execute another cwd that returns the lisp process to A. If the lisp process should wait until the python process is finished, use external-program:run instead of external-program:start.
I ended up writing krzysz00's suggestion up into a package that can be found here.
Then someone pointed out that UIOP comes with getcwd and chdir. If you have a fairly recent lisp, UIOP should come included with your edition of asdf.
I dont know what lisp is but could this work?
import subprocess
subprocess.Popen('python myscript.py', cwd='B')
http://docs.python.org/library/subprocess.html