asdf:load-system after closing emacs? - common-lisp

When I create a new project with quickprojects, and then load it with asdf:load-system, everything works fine.
But when I come back to emacs after it has been closed and a run (asdf:load-system "system-name"), I get an error:
Component "next" not found
[Condition of type ASDF/FIND-COMPONENT:MISSING-COMPONENT]
I understood the package system to be like a project management system where I can load a package from the repl when I choose.
Which mistake am I making?

In quickproject.lisp, there is the following line:
(pushnew *default-pathname-defaults* asdf:*central-registry*
:test 'equal)
Which is the reason why the system can be loaded: the path to your new project is pushed into ASDF's *central-registry*, which acts like the PATH environment variable in POSIX to indicate where to look for systems.
This change is not persisted and the next time you start Lisp, the variable is set to its default value and the path is not set. I think Quickproject should at least warn that this is happening because it is not very intuitive1
Usually you should add your projects in a path that is visible by ASDF, as explained in 4.1 Configuring ASDF to find your systems. Pushing to *central-registry* works but is old style: 4.2 Configuring ASDF to find your systems — old style.
When using Quicklisp you can also define your projects in ~/quicklisp/local-projects/ (either directly or by using symlinks), which is a place that Quicklisp makes also visible by ASDF.
You can temporarily bind *default-pathname-defaults* to one of these known locations when creating your projects, so that it can be found again when restarting your environment:
(let ((*default-pathname-defaults*
(merge-pathnames "quicklisp/local-projects/"
(user-homedir-pathname)))
(quickproject:make-project "test-project"))
1. To Quickproject's defense, this is explained in the second sentence of the documentation:
Quickproject provides a quick way to make a Common Lisp project. After creating a project, it extends the ASDF registry so the project may be immediately loaded.

Related

When I reset Slime, recompile and reinstall packages - why?

I have a SBCL package called frosty.
I am using SLIME with emacs. When I close emacs for the day, and then open it the next day, it's as if I am "starting again".
All my quicklisp packages need to be reloaded. And my frosty package needs to be compiled manually.
Is there a way to have the REPL automatically understand the packages/QL packages from the start?
Thanks
You can define a system to group your files as a unit that can be compiled as a whole, and once it is compiled once, the resulting object files are stored in cache and loaded faster the next time (without compilation).
defsystem
At the root of your frosty directory, you can add an ASDF system definition. It contains the following at minimum:
(defsystem "frosty"
;; system dependencies:
;; those are system names, not package names; they often are
;; identical but in general a system can define zero, one or
;; more packages
:depends-on ("alexandria"
"cl-ppcre"
;; etc.
)
;; this declares a list of component, here there is a single entry,
;; namely (:file "frosty") which represents a Lisp source file.
;; If you organized your files differently, e.g. under a src/ directory,
;; you need to add a :pathname option.
;; See https://asdf.common-lisp.dev/asdf.html#The-defsystem-grammar
:components ((:file "frosty"))
)
What we want to do is be able to call:
(ql:quickload "frosty")
And have Quicklisp install all the dependencies and your own system.
In order for quicklisp to know about your .asd file, your project needs to be visible in the quicklisp/local-projects directory. Alternatively, you can choose to link your project under ~/common-lisp/ directory, or any other directory searched by the ASDF central registry (see documentation).
.sbclrc
In your ~/.sbclrc init file, you can add expressions to be evaluated, and in particular you can write (ql:quickload "frosty") here so that it is executed each time SBCL is started.
One of the following will work.
Don't quit the running lisp / emacs. Only an option if you're able to leave processes running overnight on the machine you're using, but that usually is the case now.
Save a core image and restart that: See here and the --core option.
Write a little Lisp source file which just reloads everything, perhaps by using a system definition.
The first two are superficially attractive but have the consequence that, over time, you end up running in a world which you only may be able to recreate and which gradually becomes infested by elves (anyone who has used d machines seriously will remember this problem). The last option means you know how to recreate the state of the world, but you have to pay the cost of doing so.
Once upon a time when computers were slower most people did one of the first two. Now they're quick the last seems preferable in many cases.

Adding a directory globally to cffi:*foreign-library-directories*

I am using the Nix package manager under macOS to install much of my software, including dynamic libraries. And I would like to make them accessible to CFFI. That means adding a path to cffi:*foreign-library-directories*. Fine, but how can I do this
globally for my system (should work for packages loaded via Quicklisp, for example)
without loading CFFI every time I start sbcl?
Ignoring the second criterion, I can just add a few lines to ~/.sbclrc:
(ql:quickload "CFFI")
(pushnew (merge-pathnames ".nix-profile/lib/" (user-homedir-pathname))
cffi:*foreign-library-directories*
:test #'equal)
What I am looking for is a way to add the path after CFFI is loaded. A bit like eval-after-load in Emacs Lisp. Is that possible?
I think that you should try to use the mechanisms of the underlying system instead, i. e. on Linux ldconfig (resp. ld.so.conf), on MacOS DYLD_LIBRARY_PATH. The CFFI manual says that the *foreign-library-directories* are only used as a fallback if the system mechanism fails.

Having to Re-install Quicklisp Packages on Each Restart

I am writing a (SBCL) Common Lisp program that has the following line at the top of the file:
(defpackage :my-package
(:use :cl :cl-who :hunchentoot :parenscript))
I am running Emacs 25, SBCL and SLIME on MacOS.
Whenever I evaluate the line above, I always get this error at first:
The name "CL-WHO" does not designate any package.
[Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]
Then, I run (ql:quickload "cl-who") and watch the CL-WHO package install. I repeat for the other two packages. Once I have done that, the form can be evaluated successfully.
The problem is that I need to do this each time I restart the Emacs (or Lisp process, which I assume is roughly equivalent in this case). Why is it that when I install something with Quicklisp it is not "remembered" for the next session? Am I doing something wrong?
Is this a problem with configurations or a general misunderstanding of how it is supposed to work?
Then, I run (ql:quickload "cl-who") and watch the CL-WHO package install. I repeat for the other two packages. Once I have done that, the form can be evaluated successfully.
You can quickload more than one system at once:
(ql:quickload '(:cl-who :hunchentoot :parenscript))
[...] each time I restart the Emacs (or Lisp process, which I assume is roughly equivalent in this case).
That's the case here, but notice that you can start a Lisp process from the shell and connect to it from Emacs. In that case, you could exit and restart Emacs without killing the Lisp process.
Start a new REPL from the shell and create a server:
(ql:quickload :swank)
(swank:create-server :port 5000)
And then, call slime-connect from Emacs (with localhost and 5000 for the host and port parameters). That can be used also to monitor a running application.
Why is it that when I install something with Quicklisp it is not "remembered" for the next session?
The system is fetched, compiled and installed on your machine, which explains why the second time you quickload a project, it is faster. But a system is only loaded in your environment when you request it, either with Quicklisp or ASDF.
Define a system
See §6. Defining systems with defsystem for an introduction on how to define a system. Suppose you name your system stackoverflow. The simplest way to get started is to create the following file:
~/quicklisp/local-projects/stackoverflow/stackoverflow.asd
which contains:
(defsystem "stackoverflow"
:depends-on ("cl-who" "hunchentoot" "parenscript"))
When you execute (ql:quickload "stackoverflow"), Quicklisp will load all its dependencies.
Instead of loading all the required systems, you only need to load a single one.
Either automatically load this system...
Lisp implementations can execute code at startup. One possible way for this is to execute the code from a configuration file: [.]ccl-init.lisp, .eclrc, .lispworks, .sbclrc (your case), etc. Execute quickload only if Quicklisp itself is available:
#+quicklisp
(ql:quickload "stackoverflow")
... or dump an image with all systems preloaded
You can also load all the required systems, and dump an executable image.
Start a fresh SBCL from a terminal (not from Slime), call (ql:quickload "stackoverflow"), and then:
(sb-ext:save-lisp-and-die "my-env"
:executable t
:compression 9)
(compression is optional)
Then, an executable file named "my-env" should be created in the same directory. Each time you start it, you have a fresh Lisp environment containing the systems you loaded before saving the image.

Mixing Qt and boost causes compilation error with "check" keyword

I am using Qt in a project and am now trying to include another project that uses boost.
I have added no_keywords to my config in the qt project file to avoid collision between the signal and slots functionality that is present in boost and Qt. But now I get a compilation error which seems to stem from double definition of a function called "check". Is there some way to avoid this?
An example is has_postfix_operator.hpp (line 141):
static ::boost::type_traits::yes_type check(has_operator); // this version is preferred when operator exists
Apparently there is a "check" defined in Qt.
I'm using Qt4.7 and boost 1.48. Running MacOSX 10.6.8
You should also look at /usr/include/AssertMacros.h, which defines a macro named "check" - that could be the cause of your problem.
To check this, add -d __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 to your compiler flags.
If that works, that was your problem.
Here's a comment from that file:
Prior to Mac OS X 10.6 the macro names used in this file conflicted
with some user code, including libraries in boost and the proposed C++
standards efforts, and there was no way for a client of this header to
resolve this conflict. Because of this, most of the macros have been
changed so that they are prefixed with
__ and contain at least one capital letter, which should alleviate the current and future conflicts. However, to allow current sources to
continue to compile, compatibility macros are defined at the end with
the old names. A tops script at the end of this file will convert
all of the old macro names used in a directory to the new names.
Clients are recommended to migrate over to these new macros as they
update their sources because a future release of Mac OS X will remove
the old macro definitions ( without the double-underscore prefix ).
Clients who want to compile without the old macro definitions can
define the macro
__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES to 0 before this file is included.

Isabelle HOL on Windows 10

I installed Windows 10 (64bit). Since then, Isabelle HOL is no longer starting, even after a re-installation (which ran through smoothly). The error message is the following: "Startup Error: Error starting Java VM". This happens with the two versions I tested (2013-2 and 2015).
The jvm.dll which is specified in the configuration file, exists in the right folder. Additionally, I have installed Java SDK in newest version (8.51) in both, 32bit and 64bit.
Is there a known compatibility problem with Windows 10? Isabelle used to work with Windows 7 and 8.
Thank you for you help.
Update (150822)
From the developer's mailing list, there's a link to a test release:
NEWS: updated to jdk-8u60, with support for x86_64-windows
www4.in.tum.de/~wenzelm/test/Isabelle_21-Aug-2015
That's working different from Isabelle2015, in how it does some things with paths, so it might find the things it needs for Windows 10, or it may not. However, even if it works, there may be some incompatibilities with Isabelle2015 (in theorem proving).
Regardless, Isabelle only gets released 1 to 2 times a year, and I wouldn't expect anything special to be released for Windows 10 within 4 to 6 months. The links above, though, show that M.Wenzel can package together a test release, but he mainly operates on the user's mailing list.
In my batch file below, I set HOMEDRIVE and HOMEPATH, which you don't need if you want .isabelle to be in C:\user.
In this test release, those settings don't affect my home path. It also appears that USER_HOME is used, though my setting of USER_HOME doesn't make my batch file work for this test release.
Anyway, this test release has changed the way it works to discover things, and accomodates Windows even more, as shown by the new behaviour of the function File.platform_path.
It's working different enough, and requires enough changes, that I should stay with Isabelle2015, or I'll be out of sync with the official release.)
Original
(Zeroeth: Problems like this generally get hashed out on the mailing list, but I go ahead show you how I start Isabelle using a batch file, which I started doing before I had to start doing it.)
First, the Java that Isabelle uses is in this folder:
Isabelle2015\contrib\jdk\x86-cygwin\jre
Doing a normal Java install for Windows is not going to change which Java that Isabelle uses.
Below, I give you a batch file and bash file to start Isabelle/jEdit, which is an alternative to using Isabelle2015\Isabelle2015.exe.
For myself, what I've done is manually replace the 32-bit jre folder shown above with the jre in jre-8u45-windows-x64.tar.gz. (I renamed the old 32-bit folder. The most recent Java tar files can be found at the download page.)
Consequently, if I try to start up Isabelle with Isabelle2015.exe, I also get a popup that says, "Startup Error, Error starting Java VM", but starting Isabelle with the batch/bash combination works for me on Windows 8.1.
What I show you below may not fix your problem, but I guess Isabelle2015.exe has to get some info from the OS to work right, and maybe that's changed with Windows 10:
https://lists.cam.ac.uk/mailman/htdig/cl-isabelle-users/2014-December/msg00033.html
You put the batch and bash file below in the folder that you have or want your .isabelle folder. Change ISAHOME below to where your Isabelle distribution is. PATH needs the Cygwin bin in the path, and the path for isabelle, which I set in the batch file.
FILE: start-isabelle.bat
:: Isabelle2015.exe uses these directly. Setting HOME or USER_HOME doesn't work
set HOMEDRIVE=%~d0
set HOMEPATH=%~p0
:: Cygwin uses HOME, and this is how HOME is set in Cygwin-Terminal.bat
set HOME=%HOMEDRIVE%%HOMEPATH%
:: ADD PATHS: 'cygwin/bin' to start terminal, 'Isabelle2015/bin' for 'isabelle'
set ISAHOME=E:\E_2\d ev\Isabelle2015
set PATH=%PATH%;%ISAHOME%/contrib/cygwin/bin;%ISAHOME%/bin;
set CHERE_INVOKING=true
::MINTTY CONSOLE
start /MIN mintty.exe -i /Cygwin-Terminal.ico "%~dp0start-isabelle.bash"
:: REGULAR WINDOWS CONSOLE
::bash --login -i "%~dp0start-isabelle.bash"
FILE: start-isabelle.bash
#!/usr/bin/env bash
#
isabelle jedit -l HOL
With 64-bit Java, I can increase the size of the memory that Isabelle uses, by making this change in .isabelle\Isabelle2015\etc\settings:
JEDIT_JAVA_OPTIONS="-Xms1g -Xmx4g -Xss4m"
or
JEDIT_JAVA_OPTIONS="-Xms1024m -Xmx4096m -Xss4m"
With 32-bit Java, when I do that, Isabelle will start but then terminate.

Resources