Common Lisp,asdf,测试,编译具有不同优化级别的系统

时间:2017-08-17 08:22:54

标签: optimization common-lisp asdf

我真正想要的是源内测试定义:

假设我有一个asdf系统:

(defsystem simple-system
  :serial t
  :components ((:module "src"
                        :components
                        ((:file "0-package")
                         (:file "1-tests-stubs")
                         (:file "2-code") ...))))

另一个测试第一个的系统:

(defsystem simple-system-tests
  :serial t
  :components ((:module "src"
                        :components
                        ((:file "0-package")
                         (:file "1-tests-real")
                         (:file "2-code") ...))))

它们之间的唯一区别在于simple-system1-tests-stubs simple-system-tests 1-tests-real 1-tests-stubs (defmacro def-test (&rest _args) nil)。 在1-tests-real中,我定义了一个宏simple-system,它可以获得真实的'在(declare (optimize (safety 0) (debug 0) (speed 3)))

中实施

现在我想用simple-system-tests编译(declare (optimize (safety 3) (debug 3) (speed 0))),用simple-system编译simple-system-tests

我该怎么做(在这里放置以及如何以通用的方式为这两个系统设置这些声明)?

如何在{{1}}中重用{{1}}的定义(不重复自己重新输入所有模块/组件)?

我必须确保所有文件都针对每个系统重新编译,具有不同的优化级别。

此外,如果每个系统文件只有在更改后才会重新编译(每个系统的编译文件的自己副本?),那将会很棒。

3 个答案:

答案 0 :(得分:3)

目前这是部分答案。

优化级别

您可以尝试使用:around-compile

(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
                        (...))))

文件说(强调我的):

  

使用此钩子,您可以实现以下效果:本地重命名包,绑定* readtables *和其他语法控制变量,处理警告和其他条件,宣布一致的优化设置,从而节省代码覆盖率信息,维护有关编译时序的元数据,设置gensym计数器和PRNG种子以及其他非确定性来源,覆盖源位置和/或时间戳系统,检查一些编译时副作用是否得到适当平衡等。

围绕系统中正在编译的每个文件执行操作;您可以为模块中的所有文件或特定文件隐藏:around-compile的值。

答案 1 :(得分:2)

安全性低的优化。

通常我会建议编译整个系统(库或应用程序),安全性为零,如下所示:

(declare (optimize (safety 0) (debug 0) (speed 3)))

将零安全性与组合声明结合使用可能会改变程序的语义,错误可能会导致程序崩溃。它甚至可能会打开安全漏洞。

我对生产代码的建议如下:

  • 使用speed = 3优化速度关键部件并保留通常的安全设置(2或3)。

  • 如果需要低安全设置以进一步提高速度,请仅在需要时进行声明。 Common Lisp提供了函数局部声明,还提供了一个特殊的运算符locally,其中还可以限制声明适用的代码区域。

优化设置可更改

* (defparameter *safety* 0)

这不起作用,因为安全值必须是数字:

*SAFETY*
* (defun foo (a) (declare (optimize (safety *safety*))) (1+ a))
; in: DEFUN FOO
;     (OPTIMIZE (SAFETY *SAFETY*))
; 
; caught WARNING:
;   Ignoring bad optimization value *SAFETY* in: (OPTIMIZE (SAFETY *SAFETY*))
; 
; compilation unit finished
;   caught 1 WARNING condition

FOO

但这可行,使用阅读时评估:

* (defun foo (a) (declare (optimize (safety #.*safety*))) (1+ a))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN

FOO

还可以插入整个声明:

* (defparameter *optimization-declaration* '(declare (optimize (safety 0))))

*OPTIMIZATION-DECLARATION*
* (defun foo (a) #.*optimization-declaration* (1+ a))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN

FOO
* 

答案 2 :(得分:0)

我希望这只是一个错字,在这些示例中,两个系统共享相同的文件0包。如果不是,你将会失败,这将是你的全部错误。