How to install new packages for common lisp without asdf-install - common-lisp

I am new to cl, and I just learned to install packages using asdf-install, but I don't know how it works, I wonder how the package can be installed manully, then I could understand the use of the files in the root directory of the source code, thanks.

Short answer: Just use quicklisp.
Long answer: if you want to understand, how the package, or - more precisely - ASDF system, is laid out, that's a good idea. Actually, there's nothing hard about that.
Every ASDF system should have a system definition file with .asd extension. This file names other file of the system with their paths relative to the .asd file, their types (by default: lisp source code) and dependencies. Your Lisp should know where to find the system definition file. In ASDF there are 2 ways to inform Lisp about it: adding the directory, in which you store the file or symlink to it, to asdf:*central-registry* list or setting up special configuration files (called source-registry - more on that in ASDF manual).
Now if you want to install the system by hand, just download its sources, extract them into some directory (like in /home/user/lib/lisp/ - you may get /home/user/lib/lisp/cl-ppcre-2.3.1/, inside which there's cl-ppcre.asd). To let your Lisp find out about it just (push "/home/user/lib/lisp/cl-ppcre-2.3.1/" asdf:*central-registry*) (and don't forget the trailing slash - it's required), and then you can load the system with (asdf:oos 'asdf:load-op :cl-ppcre).
You might also setup a special dir, where you'll symlink your existing systems, like /home/user/.lisp/ and add it to *central-registry* at Lisp startup type (e.g. in .sbclrc). Now if you want to temporarily override some of the system linked in this dir, say, with a newer version, you don't need to unlink anything - just push the path to alternative system to *central-registry*.
Quicklisp does all that for you and more...

Related

Why do I need to evaluate defpackage for a new REPL?

I use ADSF to organise my projects.
(asdf:defsystem :sender
:version "0.1.4"
:serial t
:depends-on (:cl-json :dexador :clsql :clsql-sqlite3)
:components ((:file "packages")
(:file "validation")
(:file "sender")))
But when I open a new repl (slime, emacs), I have to go to the packages.lisp file and evaluate the form before I can change the repl to that package with (in-package :sender).
Is there a way to make the slime repl remember my packages?
My current thinking is that I need to "run" adsf to load all my files. If so, how?
UPDATE:
Actually, I need to compile all the files manually before I can actively use them in the repl. I believe I am using asdf incorrectly.
From a .asd system definition, the steps would be:
compile the .asd file, so that you Lisp image knows about the system
C-c C-k or programmatically: (asdf:load-asd "system").
LOAD it somehow: (ql:quickload "system") to install dependencies
or (asdf:load-system "system"), but it will fail if your project has unknown dependencies, Quicklisp would download them.
avoid using cl:load for asdf systems, load-asd / load-system will do more complex stuff.
use it on the REPL. The package that was defined in a packages.lisp file should be available, because this file was declared in the .asd.
You can add stuff to your ~/.sbclrc (or similar for other implementations). Here I tell ASDF where a project lives, so I can quickload it without manually compiling the .asd before:
(pushnew "/home/vince/projets/ciel/" asdf:*central-registry* :test #'equal)
This is an "old" style not encouraged anymore by the ASDF documentation.
Or simply create a symlink for your project to ~/quicklisp/local-projects/ or ~/common-lisp/.
I wouldn't "load-system" my project in the init file, because that's a side effect that would show sometimes when I don't want it (like building an image: if that involves reading my init file, I'd have an unwanted system in it).
Saving a core image with a ton of dependencies is cool. Use it with sbcl --core …. The advantage is that it starts up instantly in the REPL, when loading all projects and dependencies would take a few seconds.
Pointers
ASDF
ASDF cookbook
ASDF manual
ASDF best practices
ASDF Build System explained
Overview
A system is an object which describes a library (or an application) which consists of: a name, a version, a list of files and subsystems, and a list of other systems it depends on. There is more.
If you want to have Lisp know a certain system, then we need to execute its defsystem form either manually or find it automatically. That ONLY makes the system definition known.
If you want to load the system's files, then you need to LOAD the SYSTEM. If you want to compile the system's files files, the you need to COMPILE the system.
So, if you want to use a package (which is a namespace), then you need to run the DEFPACKAGE form. If that form is describe in a file which is component of a system, then you need to load that system.
ASDF : a popular build system for Common Lisp
system -> library, application. It is a bunch of files and dependencies.
system definition -> not the system itself, but a description of it. Use DEFSYSTEM to describe a system
system operations -> like load-system, compile-system and others.
system registry -> Typically we want ASDF to find the systems by name. See the manual or a tutorial for ASDF.
lisp file -> some file we can compile or load
fasl file -> some compiled file we can load
package -> a namespace for symbols, that's actually a built-in feature for Common Lisp
Quicklisp -> a library manager with a selection of curated Common Lisp libraries/applications. The libraries can be loaded over the Internet. Be aware that there is little to no security when loading foreign code from the Internet.
Use a system, its components and dependencies
If you want to use a system you need to load it first. Manually or automatically.
That loading can be done automatically:
For example in an init-file for your Lisp you can load all systems you want/need. Alternative write a function which loads all systems you want.
saving an image. Some Lisps support saving an image. Thus one can load all interesting systems and then save an image. If one starts that image later, all those systems are already in memory. (side problem: getting newer versions loaded)

How to determine file type in Lisp

Is there anything like file in shell for lisp to determine file type? If not, how do you determine file tpye?
In most case pathname-type is good enough, but sometimes you may run into some files doesn't have been correct named.
The functionality of file is available in libmagic:
As of version 4.00 of the Ian Darwin/Christos Zoulas version of file, the functionality of file is incorporated into a libmagic library that is accessible via C (and C-compatible) linking;[7][8] file is implemented using that library.
Wikipedia
And there is a binding for Common Lisp.
I had to install libmagic-dev on my system, and then:
CL-USER> (ql:quickload :magicffi)
...
(:MAGICFFI)
CL-USER> (magicffi:pathname-mime #P"/bin/ls")
"application/x-sharedlib; charset=binary"
See MAGICFFI.

OCaml: How can I get the path to the *current module* / my project's directory?

I'm new to OCaml, but I'm trying to figure out the equivalent of __filename, __dirname from Node. That is, I need to build a path relative to the file containing the code in question.
For reference, I'm working through Ghuloum's IACC: http://ell.io/tt$ocameel
I'm building my first compiler, and I have an utterly-simplistic ‘runtime’ file (in C — temporarily) adjacent to the compiler's source-code. I need to be able to pass the path to this file, as an argument (or a pre-compiled version, I suppose) to gcc or my linker, to have it linked against my compiler's output when I invoke the linker/assembler tooling.
(This may be a stupid question — I'm at a bit of an unknown-unknown here, “how does a compiler get the runtime to the linker”, or something like that. Any commentary about idiomatic solutions to this is welcome, even if it's not a direct answer to the above question!)
If you're running the source file directly via ocaml myfile.ml, Sys.argv.(0) will give you the path to the source file and you can use Filename.dirname to get the directory from that.
If you first compile the source file into an executable and then run the executable, Sys.argv.(0) will give you the name of the executable. In that scenario it's impossible to get the location of the source code (especially if you consider that the person running the executable might not even have the source code on their system).
If you set up your project structure, so that your sources live in src/, your compiled binary in bin/ and the compiled stdlib in lib/, you could just use Filename.dirname Sys.argv.(0) ^ "../lib" as the library path for gcc. This will work whether you run ocaml src/mycompiler.ml, bin/mycompiler or just mycompiler after installing everything to /usr/ or /usr/local/.

Compile only some C files in src folder

Is there a way to compile only some *.c (or *.cpp) files in src folder and not all of them? Perhaps it may be possible by modifying Makevars somehow?
A bit of background: I made a mistake of committing some files to the git master branch and would be easier for me to avoid their compilation rather than renaming them all or removing the branch.
That really is a Makefile (language) question that you can address via a Makevars file with proper settings.
But beware:
R really prefers the default settings and its implicit Makefile. You can get by with Makevars for settings things like compiler / linker options, doing dependencies among files right is much harder. Very few packages do it right. You are more likely to break dual-architecture builds on, eg, OS X and (via Makevars.win) on Windows.
There is no reason to leave the repo in a sad state. Just clean up your git repo, and the world will be a better place too.

How to tell asdf to use the directory of the .asd file as root directory of project

I am trying to load my project using a self-made .asd file, but somehow asdf does not recognize that the .asd file should also be the root-directory of the project and therefore resuling in an error like failed to find the TRUENAME of /home/$USER/rel-path-to-file where rel-path-to-file is the path to the corresponding file, relative to the loaded .asd file.
This is what I did:
(push "path-to-project-directory-of-asd-file" asdf:*central-registry*)
then
(asdf:load-system 'project-name)
It DOES find my .asd file but somehow not the .lisp files it shall load.
The asdf has been configured and installed by quicklisp. Therefore I also "installed" the project into quicklisp using a symlink, this worked as well. It DOES find the .asd file using ql:quickload :name but still doesn't use the directory containing the .asd file as the project-root.
How can I fix this?
Lisp pathnames are historically such that they require you to add a slash after directory name (I was told this is so due to the operating systems which were created before I was even born), so in order to tell Lisp that you target a directory you must end the name with the slash.
See asdf:system-relative-pathname.

Resources