Using asdf, I can download a system that provides only previously made FASL

I have a development machine and a production machine that are identical (copy of vm image). I want to deliver the application to the production machine along with the asd file, but I do not want to deliver the source code. I thought of two ways:

1. Saving asdf loads the system by providing only FASL files on the production machine

Pros: When I need to change something, I just compile the file in the devel machine and replace fasl on the production machine.

Cons: I do not know if and how to do this.

2. Using save-lisp-and-die, or preferably the Zachary Beane builapp tool (I use SBCL) to automate the process.

Pros: more easily automated, more compressed and only one (albeit a large) file.

Cons: the pros of the previous solution.

I know that these cons and professionals I mention arent so important compared to each other, but I would like to know any pros or cons that I do not see that can change my options or any other solution that I have, although of. Also, no matter what I choose, I would like to know if solution 1 is possible and how.

+4
source share
4 answers

As of February 2013, ASDF 3 now offers a way to do exactly what you want using FASL-OP and PRECOMPILED-SYSTEM.

+1
source

Typically, these system tools should allow this. All you need is a system description and FASL files. Then the system tool should use the FASL files to load. You just need to make sure that it does not have a hard dependency on some source file.

Thus, software has been supplied in the Lisp world for decades (> 30 years). There is nothing wrong with this approach. If a specific tool (here ASDF, but there are others) has a problem with this, the authors should complain.

If you have a practical problem with this, you should discuss it on the ASDF mailing list or ask a question here. Do you have a practical problem?

This will not help you directly, but may give you some advice on how a system tool usually works.

Example with LispWorks 6 and its own DEFSYSTEM

We have three files in the FOO directory:

RJMBA:foo joswig$ ls -l -rw-r--r-- 1 joswig admin 13 22 Jul 20:42 a.lisp -rw-r--r-- 1 joswig admin 14 22 Jul 20:42 b.lisp -rw-r--r-- 1 joswig admin 331 22 Jul 20:41 system.lisp 

system.lisp contains the following system description:

 (defvar *foo-directory* (make-pathname :name nil :type nil :directory (pathname-directory *load-pathname*) :defaults *load-pathname*)) (defsystem foo (:default-pathname *foo-directory*) :members ("a" "b")) 

The above is given the path *foo-directory* based on the path name for the downloaded file. Thus, we can establish the real absolute path, but it is not necessary to specify it manually. Alternatively, we could use relative paths - it depends on what you want to use. I chose this to show how to automatically create an absolute path.

Now I upload this file to LispWorks, then compile the system:

 CL-USER 12 > (compile-system 'foo) ;;; Compiling file /Lisp/foo/a.lisp ... ;;; Safety = 3, Speed = 1, Space = 1, Float = 1, Interruptible = 1 ;;; Compilation speed = 1, Debug = 2, Fixnum safety = 3 ;;; Source level debugging is on ;;; Source file recording is on ;;; Cross referencing is on ; (TOP-LEVEL-FORM 0) ; (TOP-LEVEL-FORM 1) ;; Processing Cross Reference Information ;;; Compiling file /Lisp/foo/b.lisp ... ;;; Safety = 3, Speed = 1, Space = 1, Float = 1, Interruptible = 1 ;;; Compilation speed = 1, Debug = 2, Fixnum safety = 3 ;;; Source level debugging is on ;;; Source file recording is on ;;; Cross referencing is on ; (TOP-LEVEL-FORM 0) ; (TOP-LEVEL-FORM 1) ;; Processing Cross Reference Information (FOO) 

We created two fasl files.

Now I copy the system.lisp file and the fasl files to the new directory:

 RJMBA:Lisp joswig$ mkdir bar RJMBA:Lisp joswig$ cp foo/system.lisp bar/system.lisp RJMBA:Lisp joswig$ cp foo/a.64xfasl bar/a.64xfasl RJMBA:Lisp joswig$ cp foo/b.64xfasl bar/b.64xfasl 

Now I launched the new LispWorks in the b directory, download the system.lisp file and boot the system:

 RJMBA:Lisp joswig$ cd bar RJMBA:bar joswig$ lispworks LispWorks(R): The Common Lisp Programming Environment Copyright (C) 1987-2009 LispWorks Ltd. All rights reserved. Version 6.0.0 User joswig on RJMBA.local ... CL-USER 1 > (load "system.lisp") ; Loading text file /Lisp/bar/system.lisp ;; Creating system "FOO" #P"/Lisp/bar/system.lisp" CL-USER 2 > (load-system 'foo) ; Loading fasl file /Lisp/bar/a.64xfasl "a" ; whatever the file does ; Loading fasl file /Lisp/bar/b.64xfasl "b" ; whatever the file does (FOO) 

Ready and working.

Additionally, this can be done using relative directories or the so-called logical paths. Logical paths are mapped from some path to the physical path, thus allowing the use of system-independent paths - regardless of architecture, OS, or directory structures. This provides an additional level of independence from a specific deployment scenario.

+4
source

I currently support ASDF. I do not know that ASDF allows this. I was not intended for this. However, I have never tried and cannot swear that this will not happen, or that a simple hack will not allow you to do this. I will welcome such a hack in the ASDF and / or extension.

In the worst case, if ASDF otherwise does not allow you to do this, a “simple” hack will be to create files containing (eval-when (: compile-toplevel: load-toplevel: execute) (error "This is not a real source file ")) and give them a 1970-01-01 timestamp instead of the source files. A script can do this for you, and cleverly hacking your source registry can allow you to switch between real source code and fake source code.

Good luck.

+4
source

Faré is right - the logic in ASDF makes load-op depend on compile-op , and it checks to see if compile-op needed, trying to compare the date the file was written to fasl with the date the file was written to the .lisp file.

I believe that you should do this work by subclassing the source file cluster, say fasl-only , and then redefine the operation-done-p method to fasl-only and compile-op so that it always returns t .

Most likely, it will be more convenient to configure your defsystem so that :default-component-class fasl-only , and then your defsystem could simply list the components :file .

You can also override the input-files method with compile-op and fasl-only to return nil , but I'm not sure if this is necessary.

+1
source