COMPILED-FILE-P
Sam Steingold
ANSI Common Lisp standard function compile-file
.
A facility to determine whether a file is a valid compiled file for the specific implementation.
Build tools, like defsystem
or asdf
,
have to determine whether a file needs to be recompiled.
Obviously, when the compiled file is older than the source file, recompilation is in order.
Alas, there are other situations when this might be necessary, e.g.,
when the implementation changes the compiled file format or when two
implementations use the same name for their compiled files
(.fasl
is used by both SBCL
and ACL
).
Implementation-dependent.
Probably tiny: an implementation must be able to check for compiled file validity, so all it takes is to export the necessary functionality, e.g.:
#+clisp (defun compiled-file-p (file-name) (with-open-file (in file-name :direction :input :if-does-not-exist nil) (and in (char= #\( (peek-char nil in)) (let ((form (ignore-errors (read in nil nil)))) (and (consp form) (eq (car form) 'SYSTEM::VERSION) (null (nth-value 1 (ignore-errors (eval form)))))))))
Users will suffer random errors when trying to load invalid binary files.
Function
(compiled-file-p file-name) ==> valid-p
Returns
true
false
Implementations are required to inspect the contents (e.g., checking just the pathname type is not sufficient). Although the completeness of the inspection is not required, this function should be able to detect, e.g., file format changes between versions.
type-error
when the argument is not a pathname designator.(compiled-file-p "foo.lisp") ==> NIL (compiled-file-p (compile-file "foo.lisp")) ==> T
See above.
This used to be CLRFI-2 (in 2004).
The trivial implementation:
(defun compiled-file-p (file-name) (not (nth-value 1 (ignore-errors (load file-name)))))
is wrong because,
load
may fail even though the file is valid:
even when foo.lisp
contains calls to error
,(compiled-file-p (compile-file "foo.lisp"))should still return
T
.