Where should a Quicklisp QUICKLOAD go in my source? Nowhere? - lisp

Let's say I build an application on top of net.aserve and bordeaux-threads. My package declaration might look like this:
(defpackage :my-package
(:use :cl :net.aserve :bordeaux-threads)
(:export …))
I use Quicklisp, so I run (ql:quickload "aserve") (ql:quickload "bordeaux-threads") in SLIME before compiling my package, and everything is fine.
Of course, tomorrow I start up SLIME again and I have to remember to issue the QUICKLOADs before I compile, otherwise I'm in for trouble.
I could put something like
(eval-when (:compile-toplevel)
(ql:quickload "aserve")
(ql:quickload "bordeaux-threads"))
at the top of my package—it's what I've done for development—but I have a feeling it's not a good idea to force a package manager on a user.
Is there a better alternative?

In your asd file, you should define the depends realtion as below:''
(asdf:defsystem #:aserve
:serial t
:depends-on (#:hunchentoot :hunchentoot-cgi
#::bordeaux-threads
#:parenscript)
...)
After then you just need to (ql:quickload :aserve) .

Use quickproject (accessible via (ql:quickload :quickproject)) to create a system for your application. As z_axis described, you can then fill the list of dependencies in the defsystem declaration (if you missed any when you called quickproject:make-project).
If you create your new project in the local-projects path of you Quicklisp installation, you can quickload your project too (even if it's not part of the Quicklisp distribution yet). Quickloading your project will of course download the dependencies (if they are part of the Quicklisp distribution), then load them.

If you don't want to include a quicklisp call in the deployed source code at all, separate the quickproject system definition file from the rest of the source.
At the top of the source, just before the defpackage call, add the necessary (require ...)'s for your package dependencies. This guarantees that those lisp packages are loaded (somehow) before proceeding, but does not specify 'how' those packages get loaded. They could be loaded by running the ql:quickload :my-package call (using quickproject), which would first load the dependencies, and then run through the require calls when loading the source. Or possibly a user could load the source directly (without calling ql:quickload), and the dependencies would be loaded during the require call, if those dependencies can be found on the *module-search-path*. This technique, as you said, would allow the end user to use whatever build tool he/she wants to load your source.
After experimenting with this for a few minutes, it seems that quicklisp latches into the require function call, so that if quicklisp is installed, and (require :bordeaux-threads) e.g., is called, lisp will use quicklisp to download and install that dependency. This is a very nice feature (IMO), because it allows the Common Lisp standard require function to act as the interface layer, and abstracts the specific build tool used to satisfy the dependency. Quicklisp can latch into the require, asdf latches into it (IIRC), etc.
So to answer your question, quicklisp calls should not go anywhere in the deployed source code, and requires should be used to ensure that dependencies are loaded before the package definition file is evaluated. If someone has quicklisp installed before loading the package definition file, those requires will be satisfied by using quicklisp to download and install the dependencies. If someone has asdf installed, those dependencies will be satisfied with that build tool. And if someone already has the dependencies installed (using some other technique), the requires will simply be passed over.

I had exactly the same question and I agree I should not force a package manager on a user. Before quicklisp's time I was using clbuild and it puts all .asd files into a systems/ directory. As long as the `systems/' directory is in asdf:central-registry, one can simply (require "a-package"), at least in SBCL and CCL, to load all relevant packages. The new clbuild2 retains this feature if you do install-from-upstream, and its integrated quicklisp does respect the separately installed-from-upstream packages, but quicklisp installed packages don't expose their .asd files anymore.
So my solution is to write a shell script that scans all quicklisp installed packages, usually under dists/quicklisp/software/, and link all .asd files there to a central place. In this way one doesn't need to load quicklisp into the cl image if one only wants to use quicklisp installed packages. I hope quicklisp could ship this feature by default.

Related

use-package does not download packages

I don't quite get the use-package package. I thought of it as a replacement of the older require statement in config files but on github it reads
This loads in the package XYZ, but only if XYZ is available on your system
So do I have to ensure that I have the package before?
Because sometimes it seems, all I need is the use-package statement for a fresh Emacs install to get the dependency.
Please clarify.
I think the point is to let you share your init.el across systems and simply have it ignore packages which are not available on any particular system.
It also appears to allow you to specify, but defer the evaluation of, your own customizations for any package you use until the package is actually loaded, so unlike require, it doesn't force you to load a package you are not going to use in this session.
There is a facility for requiring a package to be installed if it's not installed; look for the :ensure keyword and the use-package-always-ensure configuration variable in the documentation.

Emacs packages, installing globally versus locally with elpa

I run linux and use different user names to segment different activities.
Using elpa, there are some packages that I would like to install so that they get loaded no matter who the user, there are packages that I would like to be loaded for only one user.
Org-mode for example is something I would want to be loaded by every user.
C++ related packages I might want for user client1, but not ruby packages.
I might want ruby related packages for user client2, but not C++ packages.
There might be a new package for C++ programming that I do not want to include in serious work but want to play with using user experimental.
It used to be that global stuff you put in site lisp and local stuff you put someplace in ~, but that doesn't seem to work with elpa.
package.el looks for installed packages along the package-directory-list path (additionally to package-user-dir which is where packages get installed).
So I'd recommend you arrange to have a "global" user. And then change all other users to include
(require 'package)
(push "/home/globaluser/.emacs.d/elpa" package-directory-list)
in their ~/.emacs. This way, any package that you want to install for all users should be installed by globaluser.
BTW, another way to attack the vector is to distinguish "installed" and "enabled". I.e. always install your packages globally, and then have each user tweak its package-load-list in order to disable specific packages.
Finally any package whose mere installation&enabling (where "enabling" means to load the package's own -autoloads.el) ends up interfering with normal work is a bug (in my book), so yet another solution is to just install and enable all packages globally. And if the C++-using-user gets annoyed by some ruby-related packages, then file a bug report to the maintainer of the ruby-related package.

emacs el-get does not load packages

Using Emacs 24.3 on OS X, I have setup el-get as described. I am able to install, remove, and init packages using the el-get-* commands.
However, none of the packages ever actually load. The simple example I use is for the package 'ascii-table'. I do the following:
M-x el-get-install ascii-table
M-x el-get-init ascii-table
But when I do
M-x ascii-table
Emacs says it is not found. If I explicitly eval the ascii-table.el file that was downloaded by el-get, it works as expected.
Is there something I must do, after installing a package, to actually use the package? Or do I still need to put the necessary load-file or whatever in my init.el file to load the packages?
It sounds like, from the el-get documentation, that there was nothing else that needed to be done.
You can instruct el-get to require features from a package by adding the property features to the package's recipe file. From the documentation (do C-hvel-get-sourcesRET)
:features
List of features el-get will `require' for you.
For your particular case do M-xel-get-find-recipe-fileRETascii-tableRET, this open ascii-table's recipe file for you, then add the following to the recipe
:features (ascii-table)
The full recipe will be
(:name ascii-table
:auto-generated t
:type emacswiki
:description "simple ASCII table"
:website "https://raw.github.com/emacsmirror/emacswiki.org/master/ascii-table.el"
:features (ascii-table))
My advice would be not edit the original recipe but keep this in your personal recipes folder to avoid any conflicts when updating el-get.
That said you can always manually load a package, see #Drew's comment
Is el-get supposed to load libraries? I doubt it.
To load a library, put (require 'FEATURE-NAME) in your init file, where FEATURE is the feature provided by the library. If it does not provide any feature, then use the file name instead (between " chars).

How to install gtk-cffi in Windows?

gtk-cffi is a Lisp binding of GTK+3. I'm trying to install it on Windows.
At first I tried Quicklisp but it didn't have it (there is gtk-cffi-utils, but it didn't help at all). I want to install it from scratch but I don't know what to do...
Is there anybody who can give me some advice?
Looking at the page for gtk-cffi, I see that it depends on:
CFFI
Alexandria
Iterate
cl-cairo2
I believe these are all available through quicklisp, so I am going to assume that you can get all of them.
Looks like for gtk-cffi there are no official releases, and you have to pull it from CVS. So if you were to checkout the gtk-cffi repository to some directory, say "c:/gtk-cffi", it should be possible for you to start up lisp, make sure that ASDF can load quicklisp systems (including the above dependencies), do:
(push "c:/gtk-cffi/" asdf:*central-registry*) ;; change the pathname as needed, but be sure to end with "/"
(asdf:load-system "gtk-cffi")

How to use packages installed by quicklisp?

I've installed the CL-PNG package using quicklisp.
(ql:quicklisp 'png)
Now I want to define my own package which depends on the CL-PNG package. Like so:
(defpackage :FOO
(:use :CL :PNG)
(:export :BAR))
When compiling it I get this error:
The name "PNG" does not designate any package.
[Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]
It seems that I have to call (require :PNG) on the REPL before compiling my package.
What do I have to do to make the CL-PNG package available for the compiler without manually call require on the REPL?
UPDATE: I'm using SBCL.
You confuse two separate notions: a system and a package. A package is defined by Common Lisp standard and it's a collection of symbols, a way to control their visibility and usage. A system is not defined by the standard, it's a notion introduced by ASDF, which is a collection of metadata to manage files inter-dependencies in a single project in order to be able to properly compile and load it. Quicklisp is built on top of ASDF to provide a way to distribute projects, described in the form of ASDF systems.
So when you install (quickload) a system, called PNG, this doesn't mean, that this system has a package, called PNG. Does the system define any packages (usually it defines one, or even several of them) and how they are called is at the discretion of its author. Most of the projects will have package.lisp or packages.lisp files, where their packages are defined.
But in the case of CL-PNG system you're loading, it actually defines the package PNG, and it should be available in the running process after you quickload it. But you should somehow load it every time you start your Lisp system. ASDF provides a means to define a dependency on CL-PNG system, so that you can just load only your own system, and all of the systems it depends on will be loaded automatically, making available all packages you want to use.