【问题标题】:(ASDF 3) How do you flag a file|component as "dirty" or in need of rebuilding?(ASDF 3) 如何将文件|组件标记为“脏”或需要重建?
【发布时间】:2021-07-23 09:05:44
【问题描述】:

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

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

【问题讨论】:

    标签: common-lisp asdf


    【解决方案1】:

    我首先添加了一个依赖于环境变量当前值的新组件类型来测试以下内容。包和定义如下,基于手册的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) ())
    

    为了测试这一点,我在quicklisp/local-projects 中创建了test-asdf,并带有以下test-asdf.asd 文件:

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

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

    (defpackage :test-asdf (:use :cl))
    (in-package :test-asdf)
    
    (print "loaded")
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-09
      • 2010-10-09
      • 1970-01-01
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      相关资源
      最近更新 更多