ASDF或其他模块系统独立于家庭和站点配置

时间:2009-01-05 05:01:25

标签: deployment lisp asdf

我正在尝试找出实际应用程序开发的最佳实践。我无法理解如何正确配置第三方库以作为独立程序包进行部署。似乎ASDF-INSTALL和ASDF旨在将库安装到家庭或站点,从而改变开发平台的状态。如果我正在开发服务器端应用程序并且我想在盒子上管理整个CL安装的这些依赖项,那就没问题。

但是,如果我想创建一个独立的应用程序,通过安装脚本部署,并在自己的CL实例中单独运行,该怎么办?我想避免为任何其他应用程序更改CL实例或目标系统配置(即覆盖其他应用程序所依赖的库的其他副本)。在Java中,我所要做的就是创建一个包含这些库的include目录并设置我的CLASSPATH。我如何在CL中获得相同级别的隔离,假设我没有安装自己的CL运行时,而是使用系统上的内容?

我发现这是所有动态编译/解释语言的常见问题,因为运行时的生命周期比运行时运行的任何特定应用程序(即Ruby或Python)长,并且应用程序将共享相同的库加载状态。我对这些语言没有任何经验,所以最好的做法可能就是盯着我看。

IDK,如果这是特定于实现的,但我正在运行Clozure CL。

编辑:

Ramarren:

我会看看Mudballs。谢谢。

安装库与我想要的相反,因为安装意味着修改主机系统状态。我认为关键必须在你的最后一段。如何创建启动脚本以将 central-registry 设置为隔离目录?是否可以使用ASDF-INSTALL将内容提取到所述目录中?如果你的CL实现的基本图像不包括ASDF,你如何引导整个事情(Clozure默认有ASDF,但CLISP会怎么做)?

我也在想开发团队。在我创建一个新的CL项目存根并对CVS或SVN进行初始提交之后,其他开发人员如何将其检查到本地环境并使用它?即使假设每个人的个人资料/网站启动中都有ASDF,其他开发人员的 central-registry 中也可能有一组不同的库。我们不应该仅仅同步一起完成项目。必须有一种干净的方法从Emacs / SLIME启动CL运行时的项目特定实例,并加载项目中指定的内容,不多也不少。

如果有任何最佳实践资源在线,使用CL或任何其他语言,我将很乐意推出自己的解决方案并开源。

路易斯:

SAVE-APPLICATION适用于部署,但不适用于我概述的多开发项目存根。

编辑2:

vatine:

版本依赖性正是这个问题的原因。如果我正在开发Perl或Ruby Web应用程序,那么我可以依赖webadmin的存在来管理这些依赖项。为零售或中小型企业开发应用程序,其中Lisp是外星技术(我无法说服他们“熟练”他们的IT组织管理它),这种方法是不可接受的。

我昨晚能够通过创建项目级.lisp文件来获得我想要的东西,该文件加载自己的项目特定的ASDF实例,设置项目本地的中央注册表,并手动下载依赖库(没有ASDF-INSTALL,这对于CLSQL和Weblocks来说是一个痛苦的依赖级联)。从开发工具的角度来看,它仍然不是理想的,因为我必须从我的家和网站上删除SLIME和Clozure本身的所有自定义。此外,共享依赖项也未解析(CLSQL和Weblock都使用MD5)。

Java具有类加载器隔离,它解决了版本依赖问题。然后就是如何将你想要的libs放到项目中的另一个问题(la Maven)。前者是核心语言问题;后者与工具有关。我将破解一个SLIME扩展,它执行ASDF-INSTALL对项目包含目录(la Maven)所做的操作,并修改lib源代码以拦截defpackage调用以某种方式预先添加gensym字符串以强制隔离。我知道,这种方法有很多漏洞,而且我对包装规格知之甚少,不知道我可以埋葬它的深度。

我对Python一无所知,但我确实知道存在零售级别的应用程序;我一直都在使用MusicBrainz Picard。我将研究Python是如何做到的。

5 个答案:

答案 0 :(得分:1)

首先,ASDF与安装库无关。它只是一个按照它们之间的依赖关系定义的顺序编译和加载一组文件的工具。 ASDF-INSTALL安装东西,它使用ASDF来确定依赖关系(我认为),但还有其他安装机制,如clbuild,手工提取和符号化,或最近的开发Mudballs,它取代了ASDF也是如此。

特殊变量asdf:*central-registry*包含搜索asdf系统的目录列表。它通常包含一个带有符号链接到实际系统定义文件的目录的补丁,但这不是必需的,因为它只包含带有系统定义文件的每个目录。

此变量将大部分时间由具有系统/站点库注册表的启动脚本填充,但您可以将其更改为您喜欢的任何内容,包括隔离的本地目录。关于前一段之前的那一段,请注意在同一CL运行时上运行许多应用程序并不常见。通常会启动一些默认的裸核,然后加载并运行库和应用程序,然后在它完成时关闭。

编辑:

ASDF只是一个库,其变量与任何其他lisp变量一样。在您描述的情况下,您可能希望抑制系统/用户启动脚本(这是特定于实现的(在CCL中,它显然是-n或--no-init命令行参数),然后手动加载asdf.lisp,{{ 1}}。或者可能创建一个递归扫描项目目录的函数,并在那里用.asd文件推送所有子目录。

答案 1 :(得分:1)

你想要CCL:SAVE-APPLICATION

答案 2 :(得分:1)

一般来说,我会说作为第三方库安装的任何东西都应该修改主机系统状态(实际上)。本地开发的东西可以通过几种方法处理,我使用的是自己的符号链接场(在需要时使用随附的shellcript来重建场)。 Lisp项目被签出到他们自己的目录中。相互依赖的项目同样以这种方式检查,在ASDF系统定义中相互引用,并通过符号链接场获取。

我看到这个模型的一个可能性问题是,如果你突然发现支持库的一部分依赖于BLAHONGA库,在2008-12-01之前从CVS中检出,支持库的其他部分也依赖于BLAHONGA,但需要一个仅在2008-12-29的CVS中提供的功能。我想版本依赖也是可能的。

答案 3 :(得分:0)

对于您的开发环境,您始终可以在某处检入外部库,并让每个开发人员将其检入asdf:*central-registry*

另一种选择是拥有一个开发盒,让每个开发人员在那里运行一个Lisp + Swank。

答案 4 :(得分:0)

之前我遇到过这样的问题。我通常解决它的方式如下:

  1. 整个系统的结构(包括所需的库)添加到修订控制系统中。 (像svn externals和git等效的技术可以帮助解决这个问题)
  2. 在cl init文件中正确配置asdf:*central-registry*,以指向工作副本中包含.asd个文件的目录。
  3. 实际上,因为我同时处理多个项目,所以我通常使用多个配置填充我的cl init文件,如上所述。如,

    (defun project1 ()
      (push "/home/rpg/project1/src/" asdf:*central-registry*)
      (push "/home/rpg/project1/extlib/" asdf:*central-registry*))
    

    然后,当我启动开发环境时,我只需键入(project1),就可以为ASDF配置为在项目1上下文中工作。

    一种变体是为每个项目创建一个加载文件,并将其检入源库的根目录。此加载文件将配置ASDF的中央注册表并加载系统。通过使用*load-truename*,中央注册表的配置可以独立于工作副本的位置。

    另一种变体是自动搜索工作目录树以查找包含.asd个文件的所有目录,并相应地填充asdf:*central-registry*