]> code.delx.au - gnu-emacs/blobdiff - lisp/cedet/ede/generic.el
Update copyright year to 2015
[gnu-emacs] / lisp / cedet / ede / generic.el
index 360b15499ca74d61778e2ea3ed766d5fbb61ee73..4d1e0e20707ba370c9eaa305636a209535ee38a7 100644 (file)
@@ -1,6 +1,6 @@
 ;;; ede/generic.el --- Base Support for generic build systems
 
-;; Copyright (C) 2010-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2010-2015 Free Software Foundation, Inc.
 
 ;; Author: Eric M. Ludlam <eric@siege-engine.com>
 
@@ -22,7 +22,7 @@
 ;;; Commentary:
 ;;
 ;; There are a lot of build systems out there, and EDE can't support
-;; them all fully.  The ede-generic.el system is the base for
+;; them all fully.  The ede/generic.el system is the base for
 ;; supporting alternate build systems in a simple way, automatically.
 ;;
 ;; The structure is for the ede-generic baseclass, which is augmented
 ;;
 ;; Customization:
 ;;
-;; Since these projects are all so increadibly generic, a user will
+;; Since these projects are all so incredibly generic, a user will
 ;; need to configure some aspects of the project by hand.  In order to
 ;; enable this without configuring the project objects directly (which
-;; are auto-generated) a special ede-generic-confg object is defined to
+;; are auto-generated) a special ede-generic-config object is defined to
 ;; hold the basics.  Generic projects will identify and use these
 ;; config files.
 ;;
@@ -70,7 +70,7 @@
 ;; subclasses `ede-generic-target'.  The slots `shortname' and
 ;; `extension' should be given new initial values.
 ;;
-;; Optionally, any target method used by EDE can then be overriden.
+;; Optionally, any target method used by EDE can then be overridden.
 ;; The ede-generic-target-c-cpp has some example methods setting up
 ;; the pre-processor map and system include path.
 ;;
 ;; the above described support features.
 
 (require 'eieio-opt)
-(require 'ede)
+(require 'ede/config)
+(require 'ede/shell)
 (require 'semantic/db)
 
 ;;; Code:
 ;;
 ;; Start with the configuration system
-(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.")
-   ;; Generic customizations
-   (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 target customixations
-   (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")))
+(defclass ede-generic-config (ede-extra-config
+                             ede-extra-config-build
+                             ede-extra-config-program
+                             ede-extra-config-c)
+  ((file-header-line :initform ";; EDE Generic Project Configuration")
    )
   "User Configuration object for a generic project.")
 
 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."
-  ;; Doesn't already exist, so lets make one.
-  (let* ((alobj ede-constructing)
-        (this nil))
+  ;; Doesn't already exist, so let's make one.
+  (let* ((alobj ede-constructing))
     (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)
+    ;;;
+    ;; TODO - find the root dir. 
+    (let ((rootdir dir))
+      (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 rootdir)
+              :file (expand-file-name (oref alobj :proj-file)
+                                      rootdir)))
     ))
 
 ;;; Base Classes for the system
-(defclass ede-generic-target (ede-target)
+(defclass ede-generic-target (ede-target-with-config
+                             ede-target-with-config-build
+                             ede-target-with-config-program)
   ((shortname :initform ""
             :type string
             :allocation :class
@@ -166,16 +132,18 @@ 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 ""
+(defclass ede-generic-project (ede-project-with-config
+                              ede-project-with-config-build
+                              ede-project-with-config-program
+                              ede-project-with-config-c
+                              ede-project-with-config-java)
+  ((config-class :initform ede-generic-config)
+   (config-file-basename :initform "EDEConfig.el")
+   (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)
@@ -188,37 +156,18 @@ The class allocated value is replace by different sub classes.")
     (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)
-           ;; Load in the configuration
-           (setq config (eieio-persistent-read fname))
-         ;; Create a new one.
-         (setq config (ede-generic-config
-                       "Configuration"
-                       :file fname))
-         ;; Set initial values based on project.
-         (ede-generic-setup-configuration proj config))
-       ;; Link things together.
-       (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)))
+(defmethod ede-project-root ((this ede-generic-project))
+  "Return my root."
+  this)
+
+(defmethod ede-find-subproject-for-directory ((proj ede-generic-project)
+                                             dir)
+  "Return PROJ, for handling all subdirs below DIR."
+  proj)
 
 ;;; A list of different targets
-(defclass ede-generic-target-c-cpp (ede-generic-target)
+(defclass ede-generic-target-c-cpp (ede-generic-target
+                                   ede-target-with-config-c)
   ((shortname :initform "C/C++")
    (extension :initform "\\([ch]\\(pp\\|xx\\|\\+\\+\\)?\\|cc\\|hh\\|CC?\\)"))
   "EDE Generic Project target for C and C++ code.
@@ -242,6 +191,13 @@ All directories need at least one target.")
   "EDE Generic Project target for texinfo code.
 All directories need at least one target.")
 
+(defclass ede-generic-target-java (ede-generic-target
+                                  ede-target-with-config-java)
+  ((shortname :initform "Java")
+   (extension :initform "java"))
+  "EDE Generic Project target for texinfo code.
+All directories need at least one target.")
+
 ;; MISC must always be last since it will always match the file.
 (defclass ede-generic-target-misc (ede-generic-target)
   ((shortname :initform "Misc")
@@ -249,7 +205,7 @@ All directories need at least one target.")
   "EDE Generic Project target for Misc files.
 All directories need at least one target.")
 
-;;; Automatic target aquisition.
+;;; Automatic target acquisition.
 (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))
@@ -276,7 +232,7 @@ If one doesn't exist, create a new one for this directory."
        (let* ((classsym (intern (car C)))
               (extreg (oref classsym extension)))
          (when (and (not (string= extreg ""))
-                    (string-match (concat "^" extreg "$") ext))
+                    (string-match (concat "\\`\\(?:" extreg "\\)\\'") ext))
            (setq cls classsym)))))
     (when (not cls) (setq cls 'ede-generic-target-misc))
     ;; find a pre-existing matching target
@@ -292,66 +248,6 @@ If one doesn't exist, create a new one for this directory."
       )
     ans))
 
-;;; C/C++ support
-(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
-        )
-    ;; Preprocessor files
-    (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)))
-         )))
-    ;; The core 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)))
-
-;;; Customization
-;;
-(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."
-  ;; Nothing unique for the targets, use the project.
-  (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)
-  ;; Loop over all the open buffers, and re-apply.
-  (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))
-
 ;;; Creating Derived Projects:
 ;;
 ;; Derived projects need an autoloader so that EDE can find the
@@ -359,34 +255,60 @@ the new configuration."
 (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 thsi project type.
+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)
-              ;; Generics must go at the end, since more specific types
-              ;; can create Makefiles also.
-              t))
+  (ede-add-project-autoload
+   (ede-project-autoload internal-name
+                        :name external-name
+                        :file 'ede/generic
+                        :proj-file projectfile
+                        :root-only nil
+                        :load-type 'ede-generic-load
+                        :class-sym class
+                        :new-p nil
+                        ;; NOTE: This project type is SAFE because it handles
+                        ;; the user-query before loading its config file.  These
+                        ;; project types are useful without the config file so
+                        ;; do the safe part until the user creates a saved config
+                        ;; file for it.
+                        :safe-p t)
+   ;; Generics must go at the end, since more specific types
+   ;; can create Makefiles also.
+   'generic))
 
 ;;;###autoload
 (defun ede-enable-generic-projects ()
   "Enable generic project loaders."
   (interactive)
-  (ede-generic-new-autoloader "edeproject-makefile" "Make"
+  (ede-generic-new-autoloader "generic-makefile" "Make"
                              "Makefile" 'ede-generic-makefile-project)
-  (ede-generic-new-autoloader "edeproject-scons" "SCons"
+  (ede-generic-new-autoloader "generic-scons" "SCons"
                              "SConstruct" 'ede-generic-scons-project)
-  (ede-generic-new-autoloader "edeproject-cmake" "CMake"
+  (ede-generic-new-autoloader "generic-cmake" "CMake"
                              "CMakeLists" 'ede-generic-cmake-project)
+
+  ;; Super Generic found via revision control tags.
+  (ede-generic-new-autoloader "generic-git" "Git"
+                             ".git" 'ede-generic-vc-project)
+  (ede-generic-new-autoloader "generic-bzr" "Bazaar"
+                             ".bzr" 'ede-generic-vc-project)
+  (ede-generic-new-autoloader "generic-hg" "Mercurial"
+                             ".hg" 'ede-generic-vc-project)
+  (ede-generic-new-autoloader "generic-svn" "Subversions"
+                             ".svn" 'ede-generic-vc-project)
+  (ede-generic-new-autoloader "generic-cvs" "CVS"
+                             "CVS" 'ede-generic-vc-project)
+
+  ;; Take advantage of existing 'projectile' based projects.
+  ;; @TODO - if projectile supports compile commands etc, can we
+  ;; read that out?  Howto if projectile is not part of core emacs.
+  (ede-generic-new-autoloader "generic-projectile" ".projectile"
+                             ".projectile" 'ede-generic-vc-project)
+
   )
 
 \f
@@ -432,6 +354,15 @@ the class `ede-generic-project' project."
   (oset config debug-command "gdb ")
   )
 
+;;; Generic Version Control System
+(defclass ede-generic-vc-project (ede-generic-project)
+  ()
+  "Generic project found via Version Control files.")
+
+(defmethod ede-generic-setup-configuration ((proj ede-generic-vc-project) config)
+  "Setup a configuration for projects identified by revision control."
+  )
+
 (provide 'ede/generic)
 
 ;; Local variables: