使用 asdf 我可以加载仅提供先前制作的 FASL 的系统
我有一台相同的开发机器和生产机器(虚拟机映像的副本)。 我想将应用程序与 asd 文件一起交付到生产计算机,但我不想交付源代码。我想到了两种方法:
1.通过在生产机器中仅提供 FASL 文件来让 asdf 加载系统
优点:当我需要更改某些内容时,我只需在开发机器中编译文件并替换生产机器中的 fasl。
缺点:我不知道是否可以以及如何做到。
2.使用 save-lisp-and-die,或者最好Zachary Beane 的 builapp 工具(我是使用 SBCL)来自动化该过程。
优点:更容易自动化,更简洁,并且只需一个(虽然很大)文件传输。
缺点:先前解决方案的优点。
我知道我提到的这些缺点和优点彼此相比并不那么重要,但我想知道我没有看到的任何优点或缺点可能会改变我的选择,或者我没有想到的任何其他解决方案。另外,无论我选择什么,我都想知道解决方案 1 是否可行以及如何可行。
I have a development machine and a production machine which are identical (Copy of a vm image).
I want to deliver the application to the production machine along with the asd file but I don't want to deliver source code. I have thought of 2 ways:
1.Having asdf load a system by providing only the FASL files in the production machine
Pros: When I need to change something I will just compile the file in devel machine and replace the fasl in the production machine.
Cons: I dont know if and how it can be done.
2.Using save-lisp-and-die, or preferebly Zachary Beane's builapp tool (I am using SBCL) to automate the process.
Pros: More easily automated, more concise, and just one (although big) file delivery.
Cons: The pros of the previous solution.
I know that those cons and pros I mention arent so important compared to each other, but I would like to know any pros or cons that I don't see that may change my options, or any other solution that I havent though of. Also no matter what I choose I would like to know if solution 1 is possible and how.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我目前负责维护 ASDF。我不知道 ASDF 允许这样做。我不是为此而设计的。也就是说,我从未尝试过,也不能发誓它不会,或者一个简单的黑客不会让你做到这一点。我欢迎对 ASDF 和/或扩展进行这样的攻击。
最坏的情况是,如果 ASDF 不允许您这样做,“简单”的 hack 就是创建包含 (eval-when (:compile-toplevel :load-toplevel :execute) 的文件(错误“这不是真正的源” file")) 并给他们一个时间戳 1970-01-01 来代替你的源文件。脚本可以为您做到这一点,并且巧妙地破解您的源注册表可以让您在真实源代码和虚假源代码之间切换。
祝你好运。
I currently maintain ASDF. I don't know that ASDF allows that. I wasn't designed for it. That said, I have never tried and can't swear that it won't, or that a simple hack won't let you do it. I'll welcome such a hack into ASDF and/or an extension.
At worst, if ASDF won't otherwise let you do it, a "simple" hack would be to create files containing (eval-when (:compile-toplevel :load-toplevel :execute) (error "This is not the real source file")) and give them a timestamp of 1970-01-01 in lieu of your source files. A script could do that for you, and clever hacking of your source-registry could allow you to switch between real source code and fake source code.
Good luck.
一般来说,这些系统工具应该允许这样做。您所需要的只是系统描述和 FASL 文件。然后系统工具应该使用 FASL 文件进行加载。只需要确保它对某些源文件没有硬依赖即可。
这种方式软件在 Lisp 世界中已经交付了数十年(超过 30 年)。这种做法并没有什么问题。如果某个特定工具(这里是 ASDF,但还有其他工具)有问题,应该向作者投诉。
如果您遇到实际问题,您应该在 ASDF 邮件列表上讨论或在此处发布问题。您有实际问题吗?
这不会直接帮助您,但它可能会给您一些系统工具通常如何工作的提示。
LispWorks 6 及其自己的 DEFSYSTEM 示例
我们在 FOO 目录中有三个文件:
system.lisp 包含以下系统描述:
上面设置了基于路径名的
*foo-directory*
在加载文件的路径名上。因此我们可以设置一个真正的绝对路径名,但不必手动指定它。
或者,我们可以使用相对路径名 - 这取决于人们想要使用什么。
我选择这个是为了展示如何自动设置绝对路径名。
现在我将此文件加载到 LispWorks 中,然后编译系统:
我们创建了两个 fasl 文件。
现在,我将 system.lisp 文件和 fasl 文件复制到新目录中:
现在,我将在
b
目录中启动一个新的 LispWorks,加载 system.lisp 文件,然后加载系统:完成并有效。
此外,这可以通过相对目录或所谓的逻辑路径名来完成。逻辑路径名具有从某个路径名到物理路径名的映射,因此能够使用与系统无关的路径名 - 独立于体系结构、操作系统和目录结构。这提供了与特定部署场景的额外独立性。
Generally these system tools should allow that. All you need is the system description and the FASL files. The system tool should then use the FASL files for loading. One only needs to make sure that it does not have a hard dependence on some source file.
This way software has delivered in the Lisp world for decades (> 30 years). There is nothing wrong with that approach. If a particular tool (here ASDF, but there are others) has a problem with that, one should complain to the authors.
If you have a practical problem with it, you should discuss it on the ASDF mailing list or post a question here. Do you have a practical problem with it?
This will not help you directly, but it may give you some hints how a system tool usually works|ed.
Example with LispWorks 6 and its own DEFSYSTEM
We have three files in a directory FOO:
system.lisp contains the following system description:
Above sets the
*foo-directory*
pathname based on the pathname of the loaded file.Thus we can set a real absolute pathname, but don't have to manually specify it.
Alternatively we could use relative pathnames - this depends on what one wants to use.
I chose this to show how to set up an absolute pathname automagically.
Now I load this file into LispWorks then compile the system:
We have created two fasl files.
Now I copy the system.lisp file and the fasl files into a new directory:
Now I'll start a fresh LispWorks in the
b
directory, load the system.lisp file and then load the system:Done and works.
Additionally this can be done with relative directories or so-called logical pathnames. Logical pathnames have a mapping from some pathname to a physical pathname, thus enable to use system-independent pathnames - independent from architecture, OS and directory structures. This gives an additional level of independence from the specific deployment scenario.
截至 2013 年 2 月,ASDF 3 现在提供了一种使用 FASL-OP 和 PRECOMPILED-SYSTEM 完全满足您需求的方法。
As of February 2013, ASDF 3 now offers a way to do exactly what you want, using FASL-OP and PRECOMPILED-SYSTEM.
Faré 是对的 -- ASDF 中的逻辑使
load-op
依赖于compile-op
,并且它将检查compile-op 是否尝试将 fasl 上的文件写入日期与 .lisp 文件上的文件写入日期进行比较时,
是必需的。我相信您应该能够通过定义 cl-source-file 的子类(例如
fasl-only
)来完成这项工作,然后覆盖操作
方法,以便它始终返回fasl-only
和compile-op
上的 -done-pt
。设置您的 defsystem 以便
:default-component-class
是仅 fasl
可能是最方便的,然后您的 defsystem 可以只列出:文件
组件。谨慎的做法是重写compile-op 和fasl-only 上的input-files 方法以返回
nil
,但我不确定这是必要的。Faré is right --- the logic in ASDF makes a
load-op
depend on acompile-op
, and it will check to see if thecompile-op
is necessary by trying to compare the file-write-date on the fasl with the file-write-date on the .lisp file.I believe you should be able to make this work by defining a sub-class of cl-source-file, say
fasl-only
, and then override theoperation-done-p
method onfasl-only
andcompile-op
so that it always returnst
.It will probably be most convenient to set up your defsystem so that the
:default-component-class
isfasl-only
, and then your defsystem can just list:file
components.It might be prudent also to override the
input-files
method oncompile-op
andfasl-only
to returnnil
, but I'm not sure that's necessary.