Skip to content
grain-interface.lisp 11.4 KiB
Newer Older
#+xcvb (module (:depends-on ("utilities" "conditions")))
;;; A few generic functions
(defgeneric fullname (grain))
(defgeneric specified-fullname (grain))
(defgeneric image-setup (env))
(defgeneric build-commands-r (env))
(defgeneric included-dependencies (env))
(defgeneric (setf included-dependencies) (value env))
(defgeneric finalize-grain (grain))
(defgeneric object-namestring (env fullname &optional merge))
(defgeneric run-generator (env generator))

(defgeneric brc-pathnames (brc))

(defgeneric build-module-grain-for (grain)
  (:documentation "in which build module is this grain being defined"))

Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
(defgeneric effective-around-compile (grain)
  (:documentation "what hook if any to call around compilation in the target"))

(defgeneric effective-encoding (grain)
  (:documentation "what encoding to use for given grain"))

(defclass grain (simple-print-object-mixin)
  ((finalizedp :accessor grain-finalized-p :initform nil :initarg :finalizedp)
   (ordinal :type fixnum :accessor grain-ordinal))
  (:documentation "Unit of abstract state intent"))

(defclass buildable-grain (grain)
  ((name-digest
    :accessor grain-name-digest
    :documentation "digest of the full name, including all static dependencies")
   (build-digest
    :accessor grain-build-digest
    :documentation "digest of the build command with actual dependencies")
   (content-digest
    :accessor grain-content-digest
    :documentation "digest of the contents of the grain.")
   (build-timestamp
    :accessor grain-build-timestamp
    :initform nil
    :documentation "timestamp at which the grain was built.")
   (generator
    :initarg :generator
    :initform nil
    :accessor grain-generator)
   (computation
    :initarg :computation
    :accessor grain-computation)
   (computation-index ;; index of the grain amongst the outputs of the computation
    :initarg :computation-index
    :accessor grain-computation-index)
   (users
    :initform nil
    :accessor grain-users))
  (:documentation "Mixin for a grain you can build (for V2)"))

(defclass persistent-grain (buildable-grain)
  (:documentation "Files and other persistent data grain"))

(defclass transient-grain (buildable-grain)
  ()
  (:documentation "Non persistent data grain"))

(defclass named-grain (grain)
  ((fullname
    ;; no :initarg, so that :fullname can mean specified-fullname in builds...
(defclass explicitly-named-grain (named-grain)
  ((fullname :initarg :fullname)))

(defclass loaded-grain ()
  ((issued-build-commands
    :documentation "hashset of load commands issued in this world"
    :reader issued-build-commands :initarg :issued-build-commands)
   (included-dependencies
    :documentation "hashset of grains included in this world"
    :reader included-dependencies :initarg :included-dependencies))
  (:documentation "grain in which other grains are loaded"))

(defclass world-grain (transient-grain explicitly-named-grain loaded-grain)
  ;; The fullname is a plist of the following form,
  ;; with keywords always present and in that order:
  ;; `(:world :setup ,setup :commands-r ,commands-r)
  ((hash
    :documentation "precomputed hash of the fullname"
    :reader world-hash :initarg :hash))
  ;; used by the farmer
  (:documentation "state of a running Lisp process in which grains are loaded"))
(defclass phony-grain (transient-grain explicitly-named-grain)
  (:documentation "virtual grain used for side-effects"))
(defclass file-grain (persistent-grain named-grain)
    :documentation "The truepath to the file that the module was declared in")
   (pathname
    :documentation "The truepath to the file that the module was declared in"))
(defclass explicitly-named-file-grain (file-grain explicitly-named-grain)
  ()
  (:documentation "File grains with an explicit name"))

(defclass loadable-grain ()
  ((load-dependencies :reader load-dependencies)))

(defclass loadable-file-grain (explicitly-named-grain loadable-grain file-grain)
  ((load-dependencies :initarg :load-dependencies)))

(defclass image-grain (explicitly-named-file-grain)
  ((world :accessor image-world :initarg :world))
  (:documentation "Dumped Image"))

(defclass library-grain (loadable-file-grain loaded-grain)
  ()
  (:documentation "any kind of library for a build under ECL"))

(defclass dynamic-library-grain (library-grain)
  ()
  (:documentation "dynamic library for a build under ECL"))

(defclass static-library-grain (library-grain)
  ()
  (:documentation "static library for a build under ECL"))

(defclass executable-grain (image-grain)
  ((parent
    :initarg :parent
    :accessor grain-parent
    :type build-module-grain))
  (:documentation "Executable Image, or script around image???"))

(defclass executable-generator ()
  ((build :initarg :build :reader generator-build)
   (target :initarg :target :reader generator-target)
   (pre-image-dump
    :initarg :pre-image-dump
    :reader pre-image-dump
    :documentation "string to read and evaluate before dumping an image")
   (post-image-restart
    :initarg :post-image-restart
    :reader post-image-restart
    :documentation "string to read and evaluate after image is started, before the main function")
   (entry-point
    :initarg :entry-point
    :reader entry-point
    :documentation "string specifying the nullary main function for the application")
   (depends-on :initarg :depends-on :reader generator-depends-on)))

(defclass documented-grain (grain)
  ((author
    :initarg :author
    :documentation "The author of the grain")
    :documentation "The maintainer(s) of the file")
   (version
    :documentation "The version number of the file")
   (licence
    :documentation "The licence being used for the file")
   (description
    :documentation "A short description of the file")
   (long-description
    ;;:reader long-description
    :documentation "A detailed description of the file"))
  (:documentation "Documented grain"))
(defclass source-grain (explicitly-named-file-grain)
  ((name
    :initarg :name
    :accessor source-grain-name)
   (in
    :initarg :in
    :accessor source-grain-in))
  (:documentation "Data file (source) grain."))

(defclass documented-file-grain (file-grain documented-grain)
  ()
  (:documentation "documented file grain"))

(defclass lisp-module-grain (documented-file-grain loadable-grain)
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
    :type (or null build-registry-entry)
    :documentation "parent build.xcvb file for this grain")
   (compile-depends-on
    :initarg :compile-depends-on)
    :initarg :depends-on)
   (cload-depends-on
    :initarg :cload-depends-on)
    :initarg :load-depends-on)
   (build-depends-on
    :initarg :build-depends-on
    :documentation "A list of dependencies that apply to all files in the
system specified by this build.xcvb file.
These dependencies will be loaded first thing
into an image that will be used for all future compile/load operations")
   (compile-dependencies
    :reader compile-dependencies)
   (cload-dependencies
    :reader cload-dependencies)
   (build-dependencies
    :reader build-dependencies
    :documentation "A normalized version of the above")
   (around-compile
    :initarg :around-compile
    :reader around-compile
    :documentation "a string that, if read after reading the compile dependencies, evaluates in function context to either NIL or a function taking a thunk and returning the values of calling the thunk in a proper some context")
   (encoding
    :initarg :encoding
    :initform nil
    :reader specified-encoding
    :documentation "a keyword specifying the encoding to use for the grain, as per asdf-encodings")
   (extension-forms
    :initarg :extension-forms
    :accessor grain-extension-forms
    :documentation "extension forms to the build specification"))
  (:documentation "Lisp source or build file"))

(defclass lisp-file-grain (lisp-module-grain source-grain explicitly-named-grain)
Francois-Rene Rideau's avatar
Francois-Rene Rideau committed
  ((parent
    :initarg :parent
    :type build-module-grain))
  (:documentation "Lisp file grain"))

(defclass build-module-grain (lisp-module-grain build-registry-entry)
  ((specified-fullname
    :initarg :fullname
    :initform nil
    :reader specified-fullname)
   (nicknames
    :initarg :nicknames
    :reader nicknames
    :initform nil
    :documentation "A short name to be used to refer to the module")
    :initarg :supersedes-asdf
    :reader supersedes-asdf
    :initform nil
    :documentation "A list of ASDF systems superseded by this module, and optional xcvb name")
   (asdf-supersessions
    :reader asdf-supersessions
    :documentation "Parsed version of supersedes-asdf, A-list for asdf name to xcvb name")
   (build-depends-on
   (build-pre-image
    :initarg :pre-image
    :accessor build-pre-image
    :initform nil
    :type boolean
    :documentation "Should we build a specific pre-image for this build?")
   (build-image
    :initarg :build-image
    :accessor build-image
    :initform nil
    :documentation "Should we build a Lisp image with that build loaded?"))
  (:documentation "build.xcvb file grain"))
(defclass fasl-grain (loadable-file-grain)
  ()
  (:documentation "Lisp FASL file grain"))
(defclass cfasl-grain (loadable-file-grain)
  ()
  (:documentation "Lisp CFASL file grain"))
(defclass lisp-object-grain (loadable-file-grain)
  ()
  (:documentation "Linkable compiled Lisp object file grain for ECL"))
(defclass asdf-grain (transient-grain explicitly-named-grain build-registry-entry)
  ((name
    :initarg :name
    :reader asdf-grain-system-name)
   (implementation
    :initarg :implementation
    :reader asdf-grain-implementation))
(defclass require-grain (transient-grain explicitly-named-grain build-registry-entry)
  ((name
    :initarg :name
    :reader require-grain-name))
  (:documentation "Required feature"))
(defclass lisp-generator ()
  ((build :initarg :build :reader generator-build)
   (targets :initarg :targets :reader generator-targets)
   (dependencies :initarg :dependencies :reader generator-dependencies)))

;;; For build registry

(defclass build-registry-entry ()
  ((root
    :initarg :root :accessor bre-root
    :documentation "root path under which the entry was found")))

(defclass invalid-build-registry-entry (build-registry-entry simple-print-object-mixin)
  ((fullname
    :initarg :fullname :reader fullname)))

(defclass build-registry-conflict (invalid-build-registry-entry)
    :initarg :pathnames :reader brc-pathnames
    :documentation "pathnames of conflicting build files with the same name")))

(defclass invalid-build-file (invalid-build-registry-entry)
    :initarg :pathname :reader grain-pathname
    :documentation "pathname of build file with conflicting ancestor")
   (reason
    :initarg :reason :reader invalid-build-reason)))

(defmacro module (&rest options)
  ;; Make sure that module declarations don't have an effect when compiled,
  ;; only when read by XCVB.
  (declare (ignore options))
  nil)