123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- (require 'eieio-opt)
- (require 'ede)
- (require 'semantic/db)
- (defclass ede-generic-config (eieio-persistent)
- ((extension :initform ".ede")
- (file-header-line :initform ";; EDE Generic Project Configuration")
- (project :initform nil
- :documentation
- "The project this config is bound to.")
-
- (build-command :initarg :build-command
- :initform "make -k"
- :type string
- :custom string
- :group (default build)
- :documentation
- "Command used for building this project.")
- (debug-command :initarg :debug-command
- :initform "gdb "
- :type string
- :custom string
- :group (default build)
- :documentation
- "Command used for debugging this project.")
-
- (c-include-path :initarg :c-include-path
- :initform nil
- :type list
- :custom (repeat (string :tag "Path"))
- :group c
- :documentation
- "The include path used by C/C++ projects.")
- (c-preprocessor-table :initarg :c-preprocessor-table
- :initform nil
- :type list
- :custom (repeat (cons (string :tag "Macro")
- (string :tag "Value")))
- :group c
- :documentation
- "Preprocessor Symbols for this project.")
- (c-preprocessor-files :initarg :c-preprocessor-files
- :initform nil
- :type list
- :custom (repeat (string :tag "Include File")))
- )
- "User Configuration object for a generic project.")
- (defun ede-generic-load (dir &optional rootproj)
- "Return a Generic Project object if there is a match.
- Return nil if there isn't one.
- Argument DIR is the directory it is created for.
- ROOTPROJ is nil, since there is only one project."
-
- (let* ((alobj ede-constructing)
- (this nil))
- (when (not alobj) (error "Cannot load generic project without the autoload instance"))
- (setq this
- (funcall (oref alobj class-sym)
- (symbol-name (oref alobj class-sym))
- :name (file-name-nondirectory
- (directory-file-name dir))
- :version "1.0"
- :directory (file-name-as-directory dir)
- :file (expand-file-name (oref alobj :proj-file)) ))
- (ede-add-project-to-global-list this)
- ))
- (defclass ede-generic-target (ede-target)
- ((shortname :initform ""
- :type string
- :allocation :class
- :documentation
- "Something prepended to the target name.")
- (extension :initform ""
- :type string
- :allocation :class
- :documentation
- "Regular expression representing the extension used for this target.
- subclasses of this base target will override the default value.")
- )
- "Baseclass for all targets belonging to the generic ede system."
- :abstract t)
- (defclass ede-generic-project (ede-project)
- ((buildfile :initform ""
- :type string
- :allocation :class
- :documentation "The file name that identifies a project of this type.
- The class allocated value is replace by different sub classes.")
- (config :initform nil
- :type (or null ede-generic-config)
- :documentation
- "The configuration object for this project.")
- )
- "The baseclass for all generic EDE project types."
- :abstract t)
- (defmethod initialize-instance ((this ede-generic-project)
- &rest fields)
- "Make sure the targets slot is bound."
- (call-next-method)
- (unless (slot-boundp this 'targets)
- (oset this :targets nil))
- )
- (defmethod ede-generic-get-configuration ((proj ede-generic-project))
- "Return the configuration for the project PROJ."
- (let ((config (oref proj config)))
- (when (not config)
- (let ((fname (expand-file-name "EDEConfig.el"
- (oref proj :directory))))
- (if (file-exists-p fname)
-
- (setq config (eieio-persistent-read fname))
-
- (setq config (ede-generic-config
- "Configuration"
- :file fname))
-
- (ede-generic-setup-configuration proj config))
-
- (oset proj config config)
- (oset config project proj)))
- config))
- (defmethod ede-generic-setup-configuration ((proj ede-generic-project) config)
- "Default configuration setup method."
- nil)
- (defmethod ede-commit-project ((proj ede-generic-project))
- "Commit any change to PROJ to its file."
- (let ((config (ede-generic-get-configuration proj)))
- (ede-commit config)))
- (defclass ede-generic-target-c-cpp (ede-generic-target)
- ((shortname :initform "C/C++")
- (extension :initform "\\([ch]\\(pp\\|xx\\|\\+\\+\\)?\\|cc\\|hh\\|CC?\\)"))
- "EDE Generic Project target for C and C++ code.
- All directories need at least one target.")
- (defclass ede-generic-target-el (ede-generic-target)
- ((shortname :initform "ELisp")
- (extension :initform "el"))
- "EDE Generic Project target for Emacs Lisp code.
- All directories need at least one target.")
- (defclass ede-generic-target-fortran (ede-generic-target)
- ((shortname :initform "Fortran")
- (extension :initform "[fF]9[05]\\|[fF]\\|for"))
- "EDE Generic Project target for Fortran code.
- All directories need at least one target.")
- (defclass ede-generic-target-texi (ede-generic-target)
- ((shortname :initform "Texinfo")
- (extension :initform "texi"))
- "EDE Generic Project target for texinfo code.
- All directories need at least one target.")
- (defclass ede-generic-target-misc (ede-generic-target)
- ((shortname :initform "Misc")
- (extension :initform ""))
- "EDE Generic Project target for Misc files.
- All directories need at least one target.")
- (defun ede-generic-find-matching-target (class dir targets)
- "Find a target that is a CLASS and is in DIR in the list of TARGETS."
- (let ((match nil))
- (dolist (T targets)
- (when (and (object-of-class-p T class)
- (string= (oref T :path) dir))
- (setq match T)
- ))
- match))
- (defmethod ede-find-target ((proj ede-generic-project) buffer)
- "Find an EDE target in PROJ for BUFFER.
- If one doesn't exist, create a new one for this directory."
- (let* ((ext (file-name-extension (buffer-file-name buffer)))
- (classes (eieio-build-class-alist 'ede-generic-target t))
- (cls nil)
- (targets (oref proj targets))
- (dir default-directory)
- (ans nil)
- )
-
- (when ext
- (dolist (C classes)
- (let* ((classsym (intern (car C)))
- (extreg (oref classsym extension)))
- (when (and (not (string= extreg ""))
- (string-match (concat "^" extreg "$") ext))
- (setq cls classsym)))))
- (when (not cls) (setq cls 'ede-generic-target-misc))
-
- (setq ans (ede-generic-find-matching-target cls dir targets))
-
- (when (not ans)
- (setq ans (make-instance
- cls
- :name (oref cls shortname)
- :path dir
- :source nil))
- (object-add-to-list proj :targets ans)
- )
- ans))
- (defmethod ede-preprocessor-map ((this ede-generic-target-c-cpp))
- "Get the pre-processor map for some generic C code."
- (let* ((proj (ede-target-parent this))
- (root (ede-project-root proj))
- (config (ede-generic-get-configuration proj))
- filemap
- )
-
- (dolist (G (oref config :c-preprocessor-files))
- (let ((table (semanticdb-file-table-object
- (ede-expand-filename root G))))
- (when table
- (when (semanticdb-needs-refresh-p table)
- (semanticdb-refresh-table table))
- (setq filemap (append filemap (oref table lexical-table)))
- )))
-
- (setq filemap (append filemap (oref config :c-preprocessor-table)))
- filemap
- ))
- (defmethod ede-system-include-path ((this ede-generic-target-c-cpp))
- "Get the system include path used by project THIS."
- (let* ((proj (ede-target-parent this))
- (config (ede-generic-get-configuration proj)))
- (oref config c-include-path)))
- (defmethod ede-customize ((proj ede-generic-project))
- "Customize the EDE project PROJ."
- (let ((config (ede-generic-get-configuration proj)))
- (eieio-customize-object config)))
- (defmethod ede-customize ((target ede-generic-target))
- "Customize the EDE TARGET."
-
- (ede-customize-project))
- (defmethod eieio-done-customizing ((config ede-generic-config))
- "Called when EIEIO is done customizing the configuration object.
- We need to go back through the old buffers, and update them with
- the new configuration."
- (ede-commit config)
-
- (ede-map-targets
- (oref config project)
- (lambda (target)
- (ede-map-target-buffers
- target
- (lambda (b)
- (with-current-buffer b
- (ede-apply-target-options)))))))
- (defmethod ede-commit ((config ede-generic-config))
- "Commit all changes to the configuration to disk."
- (eieio-persistent-save config))
- (defun ede-generic-new-autoloader (internal-name external-name
- projectfile class)
- "Add a new EDE Autoload instance for identifying a generic project.
- INTERNAL-NAME is a long name that identifies this project type.
- EXTERNAL-NAME is a shorter human readable name to describe the project.
- PROJECTFILE is a file name that identifies a project of this type to EDE, such as
- a Makefile, or SConstruct file.
- CLASS is the EIEIO class that is used to track this project. It should subclass
- the class `ede-generic-project' project."
- (add-to-list 'ede-project-class-files
- (ede-project-autoload internal-name
- :name external-name
- :file 'ede/generic
- :proj-file projectfile
- :load-type 'ede-generic-load
- :class-sym class
- :new-p nil)
-
-
- t))
- (defun ede-enable-generic-projects ()
- "Enable generic project loaders."
- (interactive)
- (ede-generic-new-autoloader "edeproject-makefile" "Make"
- "Makefile" 'ede-generic-makefile-project)
- (ede-generic-new-autoloader "edeproject-scons" "SCons"
- "SConstruct" 'ede-generic-scons-project)
- (ede-generic-new-autoloader "edeproject-cmake" "CMake"
- "CMakeLists" 'ede-generic-cmake-project)
- )
- (defclass ede-generic-makefile-project (ede-generic-project)
- ((buildfile :initform "Makefile")
- )
- "Generic Project for makefiles.")
- (defmethod ede-generic-setup-configuration ((proj ede-generic-makefile-project) config)
- "Setup a configuration for Make."
- (oset config build-command "make -k")
- (oset config debug-command "gdb ")
- )
- (defclass ede-generic-scons-project (ede-generic-project)
- ((buildfile :initform "SConstruct")
- )
- "Generic Project for scons.")
- (defmethod ede-generic-setup-configuration ((proj ede-generic-scons-project) config)
- "Setup a configuration for SCONS."
- (oset config build-command "scons")
- (oset config debug-command "gdb ")
- )
- (defclass ede-generic-cmake-project (ede-generic-project)
- ((buildfile :initform "CMakeLists")
- )
- "Generic Project for cmake.")
- (defmethod ede-generic-setup-configuration ((proj ede-generic-cmake-project) config)
- "Setup a configuration for CMake."
- (oset config build-command "cmake")
- (oset config debug-command "gdb ")
- )
- (provide 'ede/generic)
|