3

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

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

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

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

编辑:

拉马伦:

我去看看泥球。谢谢你。

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

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

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

路易斯:

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

编辑2:

面包车:

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

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

Java 具有类加载器隔离,这就是它解决版本依赖问题的方式。然后是如何将所需的库放入项目中的单独问题(a la Maven)。前者是核心语言问题;后者与工具有关。我将编写一个 SLIME 扩展,它执行 ASDF-INSTALL 对项目包含目录(a la Maven)所做的工作,并修改 lib 源代码以拦截 defpackage 调用,以某种方式预先添加一个 gensym 字符串以强制隔离。我知道,这种方法有很多漏洞,而且我对封装规范的了解还不够,不知道我能把它埋到多深。

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

4

5 回答 5

1

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

我在这个模型中看到的一个可能的问题是,如果你突然发现你的支持库的一部分依赖于库 BLAHONGA,在 2008 年 12 月 1 日之前签出 CVS,而你的支持库的其他部分也依赖于 BLAHONGA,但需要从 2008 年 12 月 29 日起,该功能仅在 CVS 中可用。我猜版本依赖也可能是一种可能性。

于 2009-01-06T12:52:58.040 回答
1

你想要CCL:SAVE-APPLICATION

于 2009-01-05T17:31:49.053 回答
1

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

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

于 2009-01-09T04:18:47.593 回答
1

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

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

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

编辑:

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

于 2009-01-05T14:04:09.347 回答
0

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

  1. 将整个系统的结构,包括所需的库,放入一个修订控制系统。(像 svn externals 和 git 等价的技术可以帮助解决这个问题)
  2. 在您的 cl 初始化文件中进行适当配置asdf:*central-registry*,以指向工作副本中包含.asd文件的目录。

实际上,因为我同时处理多个项目,所以我通常使用上述多个配置填充我的 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*

于 2011-09-07T18:59:53.677 回答