diff --git a/asdf.lisp b/asdf.lisp
index c6ad0bc..256a11a 100644
--- a/asdf.lisp
+++ b/asdf.lisp
@@ -289,6 +289,7 @@
             #:apply-output-translations
             #:compile-file*
             #:compile-file-pathname*
+            #:*compile-file-function*
             #:enable-asdf-binary-locations-compatibility
             #:*default-source-registries*
             #:initialize-source-registry
@@ -767,8 +768,6 @@ with given pathname and if it exists return its truename."
                             :directory `(:absolute ,@path))))
         (translate-pathname absolute-pathname wild-root (wilden new-base))))))
 
-(defgeneric* compile-file* (x &key output-file &allow-other-keys))
-
 ;;;; -------------------------------------------------------------------------
 ;;;; ASDF Interface, in terms of generic functions.
 (defgeneric* find-system (system &optional error-p))
@@ -1907,6 +1906,11 @@ recursive calls to traverse.")
   (setf (gethash (type-of operation) (component-operation-times c))
         (get-universal-time)))
 
+(declaim (ftype (function ((or pathname string)
+                           &rest t &key (:output-file t) &allow-other-keys)
+                          (values t t t))
+                compile-file*))
+
 ;;; perform is required to check output-files to find out where to put
 ;;; its answers, in case it has been overridden for site policy
 (defmethod perform ((operation compile-op) (c cl-source-file))
@@ -3193,12 +3197,14 @@ effectively disabling the output translation facility."
   (when (and x (probe-file x))
     (delete-file x)))
 
-(defmethod compile-file* (input-file &rest keys &key output-file &allow-other-keys)
+(defvar *compile-file-function* 'compile-file)
+
+(defun* compile-file* (input-file &rest keys &key output-file &allow-other-keys)
   (let* ((output-file (or output-file (apply 'compile-file-pathname* input-file keys)))
          (tmp-file (tmpize-pathname output-file))
          (status :error))
     (multiple-value-bind (output-truename warnings-p failure-p)
-        (apply 'compile-file input-file :output-file tmp-file keys)
+        (apply *compile-file-function* input-file :output-file tmp-file keys)
       (cond
         (failure-p
          (setf status *compile-file-failure-behaviour*))
@@ -3217,17 +3223,22 @@ effectively disabling the output translation facility."
          (setf output-truename nil)))
       (values output-truename warnings-p failure-p))))
 
+;; In ECL, for each file that is compiled natively, we produce two
+;; files: an object file and a FASL file built from that one. This
+;; simplifies all extensions in asdf-ecl.lisp. Alternative compilers
+;; such as bytecode compilers or non C based ones may hook here and
+;; change the set of files produced.
 #+(and ecl (not ecl-bytecmp))
-(defmethod compile-file* :around (input-file &rest keys &key output-file &allow-other-keys)
-  (declare (ignore output-file))
-  (multiple-value-bind (object-file flags1 flags2)
-      (apply #'call-next-method input-file :system-p t keys)
-    (values (and object-file
-                 (c::build-fasl (compile-file-pathname object-file :type :fasl)
-                                :lisp-files (list object-file))
-                           object-file)
-            flags1
-            flags2)))
+(setf *compile-file-function*
+      #'(lambda (input-file &rest keys)
+          (multiple-value-bind (object-file flags1 flags2)
+              (apply 'compile-file input-file (list* :system-p t keys))
+            (values (and object-file
+                         (c::build-fasl (compile-file-pathname object-file :type :fasl)
+                                        :lisp-files (list object-file))
+                         object-file)
+                    flags1
+                    flags2))))
 
 #+abcl
 (defun* translate-jar-pathname (source wildcard)
