Deployment 使用asdf,我可以加载一个仅提供以前制作的FASL的系统

Deployment 使用asdf,我可以加载一个仅提供以前制作的FASL的系统,deployment,lisp,compilation,common-lisp,asdf,Deployment,Lisp,Compilation,Common Lisp,Asdf,我有一台相同的开发机器和一台生产机器(vm映像的副本)。 我希望将应用程序与asd文件一起交付到生产机器,但不希望交付源代码。我想到了两种方法: 1.让asdf通过在生产机器中仅提供FASL文件来加载系统 优点:当我需要更改某些内容时,我只需在devel机器中编译文件,并在生产机器中替换fasl 缺点:我不知道这是否能做到,如何做到 2.使用save lisp和die,或者更倾向于(我使用SBCL)自动化流程 优点:更容易自动化,更简洁,而且只需一次(尽管很大)文件传递 缺点:前面解决方案的优点

我有一台相同的开发机器和一台生产机器(vm映像的副本)。 我希望将应用程序与asd文件一起交付到生产机器,但不希望交付源代码。我想到了两种方法:

1.让asdf通过在生产机器中仅提供FASL文件来加载系统

优点:当我需要更改某些内容时,我只需在devel机器中编译文件,并在生产机器中替换fasl

缺点:我不知道这是否能做到,如何做到

2.使用save lisp和die,或者更倾向于(我使用SBCL)自动化流程

优点:更容易自动化,更简洁,而且只需一次(尽管很大)文件传递

缺点:前面解决方案的优点


我知道我提到的这些优点和缺点彼此相比并不重要,但我想知道我不认为会改变我的选择的任何优点或缺点,或者我没有想到的任何其他解决方案。另外,无论我选择什么,我都想知道解决方案1是否可行以及如何实现。

通常,这些系统工具应该允许这样做。您只需要系统描述和FASL文件。然后,系统工具应使用FASL文件进行加载。您只需要确保它不会对某个源文件产生硬依赖

通过这种方式,软件在Lisp世界中已经交付了几十年(>30年)。这种做法没有错。如果某个特定的工具(这里是ASDF,但还有其他工具)对此有问题,应该向作者投诉

如果你对它有实际问题,你应该在ASDF邮件列表上讨论,或者在这里发布一个问题。你对此有实际问题吗

这不会直接帮助您,但它可能会为您提供一些系统工具通常如何工作的提示

LispWorks 6及其自己的DEFSYSTEM示例

目录FOO中有三个文件:

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包含以下系统说明:

(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"))
上面根据加载文件的路径名设置
*foo目录*
路径名。 因此,我们可以设置真正的绝对路径名,但不必手动指定它。 或者,我们可以使用相对路径名——这取决于您想使用什么。 我选择这个来演示如何自动设置绝对路径名

现在我将此文件加载到LispWorks中,然后编译系统:

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)
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)
我们已经创建了两个fasl文件

现在,我将system.lisp文件和fasl文件复制到一个新目录中:

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
现在,我将在
b
目录中启动一个新的LispWorks,加载system.lisp文件,然后加载系统:

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)
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)
完成并工作


此外,这可以通过相对目录或所谓的逻辑路径名来完成。逻辑路径名具有从某个路径名到物理路径名的映射,因此能够使用独立于系统的路径名—独立于体系结构、操作系统和目录结构。这为特定部署场景提供了额外的独立性。

我目前维护ASDF。我不知道ASDF允许这样做。我不是为它而设计的。也就是说,我从未尝试过,也不能发誓它不会,或者一个简单的黑客不会让你这么做。我欢迎对ASDF和/或扩展进行这样的黑客攻击

在最坏的情况下,如果ASDF不允许您这样做,一个“简单”的黑客将创建包含以下内容的文件(eval when(:compile toplevel:load toplevel:execute)(错误“这不是真正的源文件”)),并给它们一个1970-01-01的时间戳来代替源文件。一个脚本可以帮你做到这一点,而对源代码注册表的巧妙破解可以让你在真实源代码和虚假源代码之间切换

祝你好运。

Faré是对的---ASDF中的逻辑使
加载操作取决于
编译操作
,它将通过尝试比较fasl上的文件写入日期和.lisp文件上的文件写入日期来检查
编译操作
是否必要

我相信您应该能够通过定义cl源文件的子类来实现这一点,比如说
fasl only
,然后覆盖
fasl only
compile op
上的
operation-done-p
方法,以便它总是返回
t

可能最方便的方法是设置您的defsystem,使
:default component class
仅为
fasl
,然后您的defsystem可以只列出
:file
组件


compile op
fasl only
上重写
input files
方法以返回
nil
可能也是明智的做法,但我不确定这是否有必要。

从2013年2月起,ASDF 3现在提供了一种方法来精确地执行您想要的操作,使用FASL-OP和预编译系统。

只是加载任务没有加载它找到的内容???如果没有源代码,它应该只加载FASL…我从头开始加载我的项目,这意味着它编译了源代码并生成了FASL,然后将它们放在.cache dir中。然后我删除了.lisp文件并尝试再次加载项目(为了以防万一,我还在lisp文件上复制了fasls)。它不起作用。它要求lisp文件。不,它将始终要求lisp文件,因为它通过比较lisp和fasl文件上的写入日期来确定需要编译的内容。请参阅我上面的解释(以及ASDF手册),了解如何修改此行为。是的,我发布了它:我想知道ASDF是否应该只能加载FASL。据我所知,这个问题并不经常出现,这让我有点惊讶。Fare说还没有想到这一点,所以我想我必须尝试一个扩展,或者像他提议的那样进行黑客攻击。所以要回答你的问题,我是否对ASDF有实际问题,取决于我所要求的ASDF的功能是否应该