Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Common lisp 使用ASDF';s:针对单个文件进行编译_Common Lisp_Compiler Optimization_Asdf - Fatal编程技术网

Common lisp 使用ASDF';s:针对单个文件进行编译

Common lisp 使用ASDF';s:针对单个文件进行编译,common-lisp,compiler-optimization,asdf,Common Lisp,Compiler Optimization,Asdf,包含coredump响应的示例说明了如何将编译器策略应用于ASDF系统的组件文件: (defsystem simple-system :serial t :around-compile (lambda (next) (proclaim '(optimize (debug 3) (safety 3)

包含coredump响应的示例说明了如何将编译器策略应用于ASDF系统的组件文件:

(defsystem simple-system
  :serial t
  :around-compile (lambda (next)
                    (proclaim '(optimize (debug 3) 
                                         (safety 3)
                                         (debug 3)
                                         (speed 0)))
                    (funcall next))
  :components ((:module "src"
                        :components
                        (...))))

它还提到可以对单个文件进行“阴影处理”,但这是如何工作的。这让我很困惑,因为lambda表达式中的
next
绑定到一个闭包。由于我只需要将优化应用于几个组件文件,如何将这些文件名指定给
:around compile

您可以为系统、模块或文件添加
:around compile

更准确地说,如果您有这样一个
:file
组件:

(:file "a")
然后,您可以添加:

(:file "a" :around-compile ...)
如果您只想对给定的一组文件应用优化,请将它们分组到模块中。您甚至可以将模块的路径名设置为
,以使其文件位于同级组件所在的相同目录中:

(:module #:MY-OPTIMIZED-FILES
         :depends-on (...)
         ;; SAME DIRECTORY
         :pathname ""
         :serial t
         :around-compile "my-meta-lib:around-compile"
         :components ((:file "a")
                      (:file "b")
                      (:file "c")
                      (:file "d")))
如果未加载定义符号的系统,则不能引用符号,并且在ASDF系统的情况下,如果不先读取定义系统的表单,则不能声明依赖项。因此,您需要使用字符串来引用另一个包中的符号

处理系统时,字符串必须引用现有符号, 因此,您需要有一个不同的
.asd
文件,例如
simple system.meta.asd
,它定义了系统
“simple system.meta”
。使用
:defsystem dependens
添加依赖项,以确保在处理
简单系统之前加载元系统

例如,该系统可以是:

(defsystem simple-system.meta
  :depends-on ("trivial-cltl2")
  :components ((:file "meta")))
我之所以使用
trial-cltl2
,是为了能够在全球环境中反思宣言,并希望能够限制
宣告的影响

(defun my-meta-lib:around-compile (next)
  (let ((opt (trivial-cltl2:declaration-information 'optimize)))
    (proclaim '(optimize (debug 3) 
                         (safety 3)
                         (debug 3)
                         (speed 0)))
    (unwind-protect (funcall next)
      (proclaim (list* 'optimize opt)))))
据我所知,
宣告
修改全局环境,它可能会影响其他文件的编译,这就是为什么我更喜欢在编译完成后恢复环境

SBCL有一个实验性的
:policy
选项,用于
和编译单元
,该选项是为该用例设计的,策略在宏的动态范围内修改:

(flet ((debug () (assoc 'debug (sb-cltl2:declaration-information 'optimize))))
  (list (debug)
        (with-compilation-unit (:policy '(optimize (debug 3)))
          (debug))
        (debug)))

 ; => ((DEBUG 1) (DEBUG 3) (DEBUG 1))

我已经尝试过为一个中间组件文件添加
:围绕编译(lambda(next)(宣告(优化(调试3)))(funcall next))
,效果很好。但是在编译和加载整个系统之后,
(sbext:descripe compiler policy)
说debug仍然设置为3。以下组件文件是否也使用
(调试3)
编译?如果是这样的话,这不是我想要的。是的,因为我认为宣告设置了全局编译策略,一旦您设置了它,它就会一直被设置;这就是为什么我尝试用
我的meta-lib:around compile
实现一种更可组合的方法,它获取当前声明进行优化,调用declarate,然后在展开时恢复以前的声明。我今天做了一次编辑,修复了我最初遇到的符号与字符串的问题,这似乎是可行的,该策略仅适用于指定的文件。我还谈到了(本地(声明(优化…)(funcall next)),但hyperspec不清楚这是否应该在动态范围内工作,我将试图找到更多关于这个问题的信息SBCL中WITH-COMPUTING-UNIT的文档字符串说它有一个
:POLICY
选项。这是一个依赖于实现的选项,但这是处理SBCL的正确方法。请注意,所需的SBCL模块名称似乎是
sb-cltl2