微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

(ASDF 3) 如何将文件|组件标记为“脏”或需要重建?

如何解决(ASDF 3) 如何将文件|组件标记为“脏”或需要重建?

我想告诉 ASDF,特定组件的状态已更改,应该在下次加载封闭系统时重新编译。动机:我设想有配置变量在被修改时触发这个过程。

必要的工具似乎在 asdf/plan 包中,如果我不得不猜测的话。

解决方法

我首先添加一个依赖于环境变量当前值的新组件类型来测试以下内容。包和定义如下,基于手册的 Object Model of ASDF 部分(这取决于 osicat):

(defpackage env-var-asdf
  (:use :cl)
  (:export #:cl-source-file-env-var
           #:depends-on-env-var))

(in-package env-var-asdf)

;; mixin
;;
;; this component depends on a posix environment variable (`varname`) and
;; stores the last known value (`last-value`). AFAIK objects are rebuilt when the 
;; asd file is reloaded,so you can preserve some state in the components if
;; the system definition does not change.
;;
(defclass depends-on-env-var ()
  ((varname :initarg :varname :reader env-var-varname)
   (last-value :accessor env-var-last-value)))

;; this method defines if the operation is already done,we return NIL if
;; the file needs to be recompiled; here,if no last known value exist for the
;; environment variable,or if the current value differs from the last one.
;;
;; I made it an `:around` method but this might be wrong (it never 
;; calls the next method; the behavior depends only on the 
;; environment variable).
;;
(defmethod asdf:operation-done-p :around (operation (component depends-on-env-var))
  (let ((value (osicat-posix:getenv (env-var-varname component))))
    (prog1 (and (slot-boundp component 'last-value)
                (string= value (env-var-last-value component)))
      (setf (env-var-last-value component) value))))

;; a cl-source-file with that mixin being the first superclass,;; again to prioritize the modified behaviour.
(defclass cl-source-file-env-var (depends-on-env-var asdf:cl-source-file) ())

为了对此进行测试,我在 test-asdf 中创建了 quicklisp/local-projects,并使用以下 test-asdf.asd 文件:

(defsystem test-asdf
  :depends-on ()
  :components ((env-var-asdf:cl-source-file-env-var "a"
                :varname "LANG")))

这里,当 a 环境变量被修改时,组件 LANG 被重新编译/重新加载。这是a.lisp

(defpackage :test-asdf (:use :cl))
(in-package :test-asdf)

(print "loaded")

在 REPL 中,当我第一次快速加载系统时,"loaded" 被打印到标准输出。如果我触摸文件 a.lisp,它会重新加载,我想我不确定为什么(ASDF 很复杂),我的意思是组件的 input-files 较新,因此即使 operation-done-p 也可能会强制重新编译{1}} 返回 NIL。 最后,如果我不接触文件而是在进程内更改了 LANG 环境变量,则该文件将再次加载。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。