What I really want is the in-source tests definitions:
Let's suppose I have an asdf system:
(defsystem simple-system
:serial t
:components ((:module "src"
:components
((:file "0-package")
(:file "1-tests-stubs")
(:file "2-code") ...))))
And another system to test the first:
(defsystem simple-system-tests
:serial t
:components ((:module "src"
:components
((:file "0-package")
(:file "1-tests-real")
(:file "2-code") ...))))
The only difference between them is that in the simple-system
I have 1-tests-stubs
where in the simple-system-tests
I have 1-tests-real
.
In 1-tests-stubs
I define a macro (defmacro def-test (&rest _args) nil)
which gets a 'real' implementation in the 1-tests-real
.
Now I want to compile the simple-system
with (declare (optimize (safety 0) (debug 0) (speed 3)))
and the simple-system-tests
with the opposite (declare (optimize (safety 3) (debug 3) (speed 0)))
.
How can I do that(where to put and how to set these declarations in a generic way for these two systems)?
How can I reuse the definition of simple-system
in the simple-system-tests
(not to repeat myself retyping all modules/components)?
And I must be sure that all files are recompiled with different optimization levels for each system.
Also, it would be great if for each system files will be recompiled only if they were changed(Own copy of compiled files for each system?).
Optimization levels
You can try using :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
(...))))
The documentation says (emphasis mine):
Using this hook, you may achieve such effects as: locally renaming packages, binding *readtables* and other syntax-controlling variables, handling warnings and other conditions, proclaiming consistent optimization settings, saving code coverage information, maintaining meta-data about compilation timings, setting gensym counters and PRNG seeds and other sources of non-determinism, overriding the source-location and/or timestamping systems, checking that some compile-time side-effects were properly balanced, etc.
The action is performed around each file that is being compiled in the system; you can shadow the value of :around-compile
for all files in a module, or specific files.
Optimization with low safety.
Generally I would not recommend to compile a whole system (a library or application) with zero safety like this:
(declare (optimize (safety 0) (debug 0) (speed 3)))
Using zero safety in combination to type declarations may alter semantics of the program and errors may crash the program. It might even open up security holes.
My recommendation for production code is this:
optimize speed critical parts with
speed
= 3 and leave the usual safety settings (2 or 3).if a low safety setting then is needed for even further speed improvements, declare it only where it is needed. Common Lisp provides function local declarations and also a special operator locally where one further can restrict the code area where declarations apply.
Making optimization settings changeable
* (defparameter *safety* 0)
This does not work, because safety values need to be numbers:
*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
But this works, using read-time evaluation:
* (defun foo (a) (declare (optimize (safety #.*safety*))) (1+ a))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN
FOO
One can also insert whole declarations:
* (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
*
I hope it's just a typo that in these examples, the same file 0-package is shared by two systems. If it isn't, you're going to lose badly and it will be all your fault.
来源:https://stackoverflow.com/questions/45730012/common-lisp-asdf-tests-compile-system-with-different-optimization-levels