mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-27 10:54:40 +00:00
Synch EDE to CEDET 1.0.
* cedet-idutils.el (cedet-idutils-make-command): New option. (cedet-idutils-mkid-call): (cedet-idutils-create/update-database): New functions. * cedet-cscope.el (cedet-cscope-create): (cedet-cscope-create/update-database): New functions. (cedet-cscope-support-for-directory): Make interactive. * cedet-global.el (cedet-global-gtags-command): New option. (cedet-gnu-global-gtags-call) (cedet-gnu-global-create/update-database): New functions. * ede.el (ede-save-cache): Fix recentf-exclude expression. (ede-make-dist): Always use toplevel project. (ede-buffer-object): If we fail to find an object in the current project, loop upward looking for a match. If no target is found, use most local project. (ede-buffer-belongs-to-target-p) (ede-buffer-belongs-to-project-p): New functions. (ede-initialize-state-current-buffer): New function. (ede-target-forms-menu, ede-project-buffers): Use them. (ede-minor-mode, ede-reset-all-buffers): Use it. (project-interactive-select-target, project-add-file): Don't use ede-project-force-load. (ede-buffer-object): New arg PROJSYM. (ede-minor-mode): Remove ede-directory-project-p test. (ede-initialize-state-current-buffer): Don't test for ede-directory-project-p if there is a matching open project. (ede-customize-forms-menu): Prevent error if there is no project. (ede-load-project-file): Set ede-constructing to the thing being constructed, instead of t. (ede-project-force-load): Deleted. * ede/base.el: * ede/auto.el: * ede/custom.el: New files. * ede/autoconf-edit.el (autoconf-find-last-macro) (autoconf-parameters-for-macro): Parse multiline parameters of macros. Optionally ignore case and at bol for macro. (autoconf-parameter-strip): Use greedy match for newlines. (autoconf-new-automake-string): Deleted. (autoconf-new-program): Use SRecode to fill an empty file. * ede/cpp-root.el (ede-create-lots-of-projects-under-dir): New function. * ede/files.el (ede-flush-project-hash): New command. (ede-convert-path): Add optional PROJECT arg. (ede-directory-project-p): Obey ".ede-ignore". (ede-expand-filename-local) (ede-expand-filename-impl-via-subproj): New methods. (ede-expand-filename-impl): Use them. (ede-project-root, ede-project-root-directory): Move to ede/auto.el. * ede/locate.el (ede-locate-flush-hash): (ede-locate-create/update-root-database): New methods. (initialize-instance): Use ede-locate-flush-hash. * ede/pmake.el (ede-proj-makefile-insert-variables): If this is the top project and not a metasubproject, set TOP to CURDIR. (ede-proj-makefile-insert-variables): Output a target's object list whether or not the vars are already in the Makefile. (ede-pmake-insert-variable-once): New macro. * ede/project-am.el (project-am-with-makefile-current): Add recentf-exclude. (project-am-load-makefile): Obey an optional suggested name. (project-am-expand-subdirlist): New function. (project-am-makefile::project-rescan): Use it. Combine SUBDIRS and DIST_SUBDIRS. (project-am-meta-type-alist): A list to scan better Makefile.am (project-am-scan-for-targets): Scan also over project-am-meta-type-alist. (ede-system-include-path): Simple implementation. (ede-find-target): Deleted. EDE core takes care of this. (ede-buffer-mine): Create the searched filename as relative. (project-am-load): Simplify, using autoconf-edit. (project-am-extract-package-info): Fix separators. * ede/proj.el (project-run-target): New method. (project-make-dist, project-compile-project): Use ede-proj-automake-p to determine which kind of compile to use. (project-rescan): Call ede-load-project-file. (ede-buffer-mine): Add more file names that belong to the project. (ede-proj-compilers): Improve error message. * ede/proj-obj.el (ede-ld-linker): Use the LDDEPS variable. (ede-source-c++): Add more C++ extensions. (ede-proj-target-makefile-objectcode): Quote initforms. Support lex and yacc. * ede/proj-prog.el (ede-proj-makefile-insert-rules): Removed. (ede-proj-makefile-insert-variables): New, add LDDEPS. (ede-proj-makefile-insert-automake-post-variables): Add LDADD variable. Use ldlibs-local slot. Add a -l to ldlibs strings. (ede-proj-target-makefile-program): Swap order of two slots so they show up in the same order as in the command line. (ede-proj-target-makefile-program): Add ldlibs-local slot. * ede/proj-shared.el (ede-g++-libtool-shared-compiler): Fix inference rule to use cpp files. (ede-proj-target-makefile-shared-object): Quote initforms. * ede/proj-misc.el (ede-proj-target-makefile-miscelaneous): * ede/proj-info.el (ede-proj-target-makefile-info): * ede/proj-aux.el (ede-proj-target-aux): * ede/proj-archive.el (ede-proj-target-makefile-archive): * ede/proj-elisp.el (ede-proj-target-elisp) (ede-proj-target-elisp-autoloads): Quote initforms. * ede/srecode.el (ede-srecode-setup): Load autoconf templates. * ede/shell.el (ede-shell-buffer): Fix buffer name. * ede/pconf.el (ede-proj-configure-synchronize): If user events occur while waiting for the compile process to finish, pull them in and discard those events.
This commit is contained in:
parent
9e0d4f9ef1
commit
cb85c0d8be
@ -1,3 +1,127 @@
|
||||
2010-09-21 Eric Ludlam <zappo@gnu.org>
|
||||
|
||||
Synch EDE to CEDET 1.0.
|
||||
|
||||
* cedet-idutils.el (cedet-idutils-make-command): New option.
|
||||
(cedet-idutils-mkid-call):
|
||||
(cedet-idutils-create/update-database): New functions.
|
||||
|
||||
* cedet-cscope.el (cedet-cscope-create):
|
||||
(cedet-cscope-create/update-database): New functions.
|
||||
(cedet-cscope-support-for-directory): Make interactive.
|
||||
|
||||
* cedet-global.el (cedet-global-gtags-command): New option.
|
||||
(cedet-gnu-global-gtags-call)
|
||||
(cedet-gnu-global-create/update-database): New functions.
|
||||
|
||||
* ede.el (ede-save-cache): Fix recentf-exclude expression.
|
||||
(ede-make-dist): Always use toplevel project.
|
||||
(ede-buffer-object): If we fail to find an object in the current
|
||||
project, loop upward looking for a match. If no target is found,
|
||||
use most local project.
|
||||
(ede-buffer-belongs-to-target-p)
|
||||
(ede-buffer-belongs-to-project-p): New functions.
|
||||
(ede-initialize-state-current-buffer): New function.
|
||||
(ede-target-forms-menu, ede-project-buffers): Use them.
|
||||
(ede-minor-mode, ede-reset-all-buffers): Use it.
|
||||
(project-interactive-select-target, project-add-file): Don't use
|
||||
ede-project-force-load.
|
||||
(ede-buffer-object): New arg PROJSYM.
|
||||
(ede-minor-mode): Remove ede-directory-project-p test.
|
||||
(ede-initialize-state-current-buffer): Don't test for
|
||||
ede-directory-project-p if there is a matching open project.
|
||||
(ede-customize-forms-menu): Prevent error if there is no project.
|
||||
(ede-load-project-file): Set ede-constructing to the thing being
|
||||
constructed, instead of t.
|
||||
(ede-project-force-load): Deleted.
|
||||
|
||||
* ede/base.el:
|
||||
* ede/auto.el:
|
||||
* ede/custom.el: New files.
|
||||
|
||||
* ede/autoconf-edit.el (autoconf-find-last-macro)
|
||||
(autoconf-parameters-for-macro): Parse multiline parameters of
|
||||
macros. Optionally ignore case and at bol for macro.
|
||||
(autoconf-parameter-strip): Use greedy match for newlines.
|
||||
(autoconf-new-automake-string): Deleted.
|
||||
(autoconf-new-program): Use SRecode to fill an empty file.
|
||||
|
||||
* ede/cpp-root.el (ede-create-lots-of-projects-under-dir): New
|
||||
function.
|
||||
|
||||
* ede/files.el (ede-flush-project-hash): New command.
|
||||
(ede-convert-path): Add optional PROJECT arg.
|
||||
(ede-directory-project-p): Obey ".ede-ignore".
|
||||
(ede-expand-filename-local)
|
||||
(ede-expand-filename-impl-via-subproj): New methods.
|
||||
(ede-expand-filename-impl): Use them.
|
||||
(ede-project-root, ede-project-root-directory): Move to
|
||||
ede/auto.el.
|
||||
|
||||
* ede/locate.el (ede-locate-flush-hash):
|
||||
(ede-locate-create/update-root-database): New methods.
|
||||
(initialize-instance): Use ede-locate-flush-hash.
|
||||
|
||||
* ede/pmake.el (ede-proj-makefile-insert-variables): If this is
|
||||
the top project and not a metasubproject, set TOP to CURDIR.
|
||||
(ede-proj-makefile-insert-variables): Output a target's object
|
||||
list whether or not the vars are already in the Makefile.
|
||||
(ede-pmake-insert-variable-once): New macro.
|
||||
|
||||
* ede/project-am.el (project-am-with-makefile-current): Add
|
||||
recentf-exclude.
|
||||
(project-am-load-makefile): Obey an optional suggested name.
|
||||
(project-am-expand-subdirlist): New function.
|
||||
(project-am-makefile::project-rescan): Use it. Combine SUBDIRS
|
||||
and DIST_SUBDIRS.
|
||||
(project-am-meta-type-alist): A list to scan better Makefile.am
|
||||
(project-am-scan-for-targets): Scan also over
|
||||
project-am-meta-type-alist.
|
||||
(ede-system-include-path): Simple implementation.
|
||||
(ede-find-target): Deleted. EDE core takes care of this.
|
||||
(ede-buffer-mine): Create the searched filename as relative.
|
||||
(project-am-load): Simplify, using autoconf-edit.
|
||||
(project-am-extract-package-info): Fix separators.
|
||||
|
||||
* ede/proj.el (project-run-target): New method.
|
||||
(project-make-dist, project-compile-project): Use
|
||||
ede-proj-automake-p to determine which kind of compile to use.
|
||||
(project-rescan): Call ede-load-project-file.
|
||||
(ede-buffer-mine): Add more file names that belong to the project.
|
||||
(ede-proj-compilers): Improve error message.
|
||||
|
||||
* ede/proj-obj.el (ede-ld-linker): Use the LDDEPS variable.
|
||||
(ede-source-c++): Add more C++ extensions.
|
||||
(ede-proj-target-makefile-objectcode): Quote initforms. Support
|
||||
lex and yacc.
|
||||
|
||||
* ede/proj-prog.el (ede-proj-makefile-insert-rules): Removed.
|
||||
(ede-proj-makefile-insert-variables): New, add LDDEPS.
|
||||
(ede-proj-makefile-insert-automake-post-variables): Add LDADD
|
||||
variable. Use ldlibs-local slot. Add a -l to ldlibs strings.
|
||||
(ede-proj-target-makefile-program): Swap order of two slots so
|
||||
they show up in the same order as in the command line.
|
||||
(ede-proj-target-makefile-program): Add ldlibs-local slot.
|
||||
|
||||
* ede/proj-shared.el (ede-g++-libtool-shared-compiler): Fix
|
||||
inference rule to use cpp files.
|
||||
(ede-proj-target-makefile-shared-object): Quote initforms.
|
||||
|
||||
* ede/proj-misc.el (ede-proj-target-makefile-miscelaneous):
|
||||
* ede/proj-info.el (ede-proj-target-makefile-info):
|
||||
* ede/proj-aux.el (ede-proj-target-aux):
|
||||
* ede/proj-archive.el (ede-proj-target-makefile-archive):
|
||||
* ede/proj-elisp.el (ede-proj-target-elisp)
|
||||
(ede-proj-target-elisp-autoloads): Quote initforms.
|
||||
|
||||
* ede/srecode.el (ede-srecode-setup): Load autoconf templates.
|
||||
|
||||
* ede/shell.el (ede-shell-buffer): Fix buffer name.
|
||||
|
||||
* ede/pconf.el (ede-proj-configure-synchronize): If user events
|
||||
occur while waiting for the compile process to finish, pull them
|
||||
in and discard those events.
|
||||
|
||||
2010-09-19 Eric Ludlam <zappo@gnu.org>
|
||||
|
||||
Synch Semantic to CEDET 1.0.
|
||||
|
@ -72,6 +72,12 @@ SCOPE is the scope of the search, such as 'project or 'subdirs."
|
||||
)
|
||||
(cedet-cscope-call (list "-d" "-L" idx searchtext))))
|
||||
|
||||
(defun cedet-cscope-create (flags)
|
||||
"Create a CScope database at the current directory.
|
||||
FLAGS are additional flags to pass to cscope beyond the
|
||||
options -cR."
|
||||
(cedet-cscope-call (append (list "-cR") flags)))
|
||||
|
||||
(defun cedet-cscope-call (flags)
|
||||
"Call CScope with the list of FLAGS."
|
||||
(let ((b (get-buffer-create "*CEDET CScope*"))
|
||||
@ -112,13 +118,19 @@ Return a fully qualified filename."
|
||||
If DIR is not supplied, use the current default directory.
|
||||
This works by running cscope on a bogus symbol, and looking for
|
||||
the error code."
|
||||
(interactive "DDirectory: ")
|
||||
(save-excursion
|
||||
(let ((default-directory (or dir default-directory)))
|
||||
(set-buffer (cedet-cscope-call (list "-d" "-L" "-7" "moose")))
|
||||
(goto-char (point-min))
|
||||
(if (looking-at "[^ \n]*cscope: ")
|
||||
nil
|
||||
t))))
|
||||
(let ((ans (looking-at "[^ \n]*cscope: ")))
|
||||
(if (called-interactively-p 'interactive)
|
||||
(if ans
|
||||
(message "No support for CScope in %s" default-directory)
|
||||
(message "CScope is supported in %s" default-directory))
|
||||
(if ans
|
||||
nil
|
||||
t))))))
|
||||
|
||||
(defun cedet-cscope-version-check (&optional noerror)
|
||||
"Check the version of the installed CScope command.
|
||||
@ -150,6 +162,14 @@ return nil."
|
||||
(message "CScope %s - Good enough for CEDET." rev))
|
||||
t)))))
|
||||
|
||||
(defun cedet-cscope-create/update-database (&optional dir)
|
||||
"Create a CScope database in DIR.
|
||||
CScope will automatically choose incremental rebuild if
|
||||
there is already a database in DIR."
|
||||
(interactive "DDirectory: ")
|
||||
(let ((default-directory dir))
|
||||
(cedet-cscope-create nil)))
|
||||
|
||||
(provide 'cedet-cscope)
|
||||
|
||||
;; arch-tag: 9973f1ad-f13b-4399-bc67-7f488478d78d
|
||||
|
@ -33,6 +33,12 @@
|
||||
:type 'string
|
||||
:group 'cedet)
|
||||
|
||||
(defcustom cedet-global-gtags-command "gtags"
|
||||
"Command name for the GNU Global gtags executable.
|
||||
GTAGS is used to create the tags table queried by the 'global' command."
|
||||
:type 'string
|
||||
:group 'cedet)
|
||||
|
||||
;;; Code:
|
||||
(defun cedet-gnu-global-search (searchtext texttype type scope)
|
||||
"Perform a search with GNU Global, return the created buffer.
|
||||
@ -75,6 +81,19 @@ SCOPE is the scope of the search, such as 'project or 'subdirs."
|
||||
flags)
|
||||
b))
|
||||
|
||||
(defun cedet-gnu-global-gtags-call (flags)
|
||||
"Create GNU Global TAGS using gtags with FLAGS."
|
||||
(let ((b (get-buffer-create "*CEDET Global gtags*"))
|
||||
(cd default-directory)
|
||||
)
|
||||
(with-current-buffer b
|
||||
(setq default-directory cd)
|
||||
(erase-buffer))
|
||||
(apply 'call-process cedet-global-gtags-command
|
||||
nil b nil
|
||||
flags)
|
||||
b))
|
||||
|
||||
(defun cedet-gnu-global-expand-filename (filename)
|
||||
"Expand the FILENAME with GNU Global.
|
||||
Return a fully qualified filename."
|
||||
@ -152,6 +171,18 @@ return nil."
|
||||
;; Return the results
|
||||
(nreverse hits))))
|
||||
|
||||
(defun cedet-gnu-global-create/update-database (&optional dir)
|
||||
"Create a GNU Global database in DIR.
|
||||
If a database already exists, then just update it."
|
||||
(interactive "DDirectory: ")
|
||||
(let ((root (cedet-gnu-global-root dir)))
|
||||
(if root (setq dir root))
|
||||
(let ((default-directory dir))
|
||||
(cedet-gnu-global-gtags-call
|
||||
(when root
|
||||
'("-i");; Incremental update flag.
|
||||
)))))
|
||||
|
||||
(provide 'cedet-global)
|
||||
|
||||
;; arch-tag: 0d0d3ac2-91ef-4820-bb2b-1d59ccf38392
|
||||
|
@ -43,6 +43,11 @@
|
||||
:type 'string
|
||||
:group 'cedet)
|
||||
|
||||
(defcustom cedet-idutils-make-command "mkid"
|
||||
"Command name for the ID Utils executable for creating token databases."
|
||||
:type 'string
|
||||
:group 'cedet)
|
||||
|
||||
(defun cedet-idutils-search (searchtext texttype type scope)
|
||||
"Perform a search with ID Utils, return the created buffer.
|
||||
SEARCHTEXT is text to find.
|
||||
@ -104,6 +109,20 @@ Return the created buffer with with program output."
|
||||
flags)
|
||||
b))
|
||||
|
||||
(defun cedet-idutils-mkid-call (flags)
|
||||
"Call ID Utils mkid with the list of FLAGS.
|
||||
Return the created buffer with with program output."
|
||||
(let ((b (get-buffer-create "*CEDET mkid*"))
|
||||
(cd default-directory)
|
||||
)
|
||||
(with-current-buffer b
|
||||
(setq default-directory cd)
|
||||
(erase-buffer))
|
||||
(apply 'call-process cedet-idutils-make-command
|
||||
nil b nil
|
||||
flags)
|
||||
b))
|
||||
|
||||
;;; UTIL CALLS
|
||||
;;
|
||||
(defun cedet-idutils-expand-filename (filename)
|
||||
@ -171,6 +190,12 @@ return nil."
|
||||
(message "ID Utils %s - Good enough for CEDET." rev))
|
||||
t)))))
|
||||
|
||||
(defun cedet-idutils-create/update-database (&optional dir)
|
||||
"Create an IDUtils database in DIR.
|
||||
IDUtils must start from scratch when updating a database."
|
||||
(interactive "DDirectory: ")
|
||||
(let ((default-directory dir))
|
||||
(cedet-idutils-mkid-call nil)))
|
||||
|
||||
(provide 'cedet-idutils)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
128
lisp/cedet/ede/auto.el
Normal file
128
lisp/cedet/ede/auto.el
Normal file
@ -0,0 +1,128 @@
|
||||
;;; ede/auto.el --- Autoload features for EDE
|
||||
|
||||
;; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; EDE Autoloads are a way to refer to different project types without
|
||||
;; loading those projects into Emacs.
|
||||
;;
|
||||
;; These routines are used to detect a project in a filesystem before
|
||||
;; handing over control to the usual EDE project system.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'eieio)
|
||||
|
||||
(defclass ede-project-autoload ()
|
||||
((name :initarg :name
|
||||
:documentation "Name of this project type")
|
||||
(file :initarg :file
|
||||
:documentation "The lisp file belonging to this class.")
|
||||
(proj-file :initarg :proj-file
|
||||
:documentation "Name of a project file of this type.")
|
||||
(proj-root :initarg :proj-root
|
||||
:type function
|
||||
:documentation "A function symbol to call for the project root.
|
||||
This function takes no arguments, and returns the current directories
|
||||
root, if available. Leave blank to use the EDE directory walking
|
||||
routine instead.")
|
||||
(initializers :initarg :initializers
|
||||
:initform nil
|
||||
:documentation
|
||||
"Initializers passed to the project object.
|
||||
These are used so there can be multiple types of projects
|
||||
associated with a single object class, based on the initilizeres used.")
|
||||
(load-type :initarg :load-type
|
||||
:documentation "Fn symbol used to load this project file.")
|
||||
(class-sym :initarg :class-sym
|
||||
:documentation "Symbol representing the project class to use.")
|
||||
(new-p :initarg :new-p
|
||||
:initform t
|
||||
:documentation
|
||||
"Non-nil if this is an option when a user creates a project.")
|
||||
)
|
||||
"Class representing minimal knowledge set to run preliminary EDE functions.
|
||||
When more advanced functionality is needed from a project type, that projects
|
||||
type is required and the load function used.")
|
||||
|
||||
(defvar ede-project-class-files
|
||||
(list
|
||||
(ede-project-autoload "edeproject-makefile"
|
||||
:name "Make" :file 'ede/proj
|
||||
:proj-file "Project.ede"
|
||||
:load-type 'ede-proj-load
|
||||
:class-sym 'ede-proj-project)
|
||||
(ede-project-autoload "edeproject-automake"
|
||||
:name "Automake" :file 'ede/proj
|
||||
:proj-file "Project.ede"
|
||||
:initializers '(:makefile-type Makefile.am)
|
||||
:load-type 'ede-proj-load
|
||||
:class-sym 'ede-proj-project)
|
||||
(ede-project-autoload "automake"
|
||||
:name "automake" :file 'ede/project-am
|
||||
:proj-file "Makefile.am"
|
||||
:load-type 'project-am-load
|
||||
:class-sym 'project-am-makefile
|
||||
:new-p nil))
|
||||
"List of vectors defining how to determine what type of projects exist.")
|
||||
|
||||
;;; EDE project-autoload methods
|
||||
;;
|
||||
(defmethod ede-project-root ((this ede-project-autoload))
|
||||
"If a project knows its root, return it here.
|
||||
Allows for one-project-object-for-a-tree type systems."
|
||||
nil)
|
||||
|
||||
(defmethod ede-project-root-directory ((this ede-project-autoload)
|
||||
&optional file)
|
||||
"If a project knows its root, return it here.
|
||||
Allows for one-project-object-for-a-tree type systems.
|
||||
Optional FILE is the file to test. If there is no FILE, use
|
||||
the current buffer."
|
||||
(when (not file)
|
||||
(setq file default-directory))
|
||||
(when (slot-boundp this :proj-root)
|
||||
(let ((rootfcn (oref this proj-root)))
|
||||
(when rootfcn
|
||||
(condition-case nil
|
||||
(funcall rootfcn file)
|
||||
(error
|
||||
(funcall rootfcn)))
|
||||
))))
|
||||
|
||||
(defmethod ede-dir-to-projectfile ((this ede-project-autoload) dir)
|
||||
"Return a full file name of project THIS found in DIR.
|
||||
Return nil if the project file does not exist."
|
||||
(let* ((d (file-name-as-directory dir))
|
||||
(root (ede-project-root-directory this d))
|
||||
(pf (oref this proj-file))
|
||||
(f (cond ((stringp pf)
|
||||
(expand-file-name pf (or root d)))
|
||||
((and (symbolp pf) (fboundp pf))
|
||||
(funcall pf (or root d)))))
|
||||
)
|
||||
(when (and f (file-exists-p f))
|
||||
f)))
|
||||
|
||||
|
||||
(provide 'ede/auto)
|
||||
|
||||
;;; ede/auto.el ends here
|
@ -27,20 +27,8 @@
|
||||
|
||||
;;; Code:
|
||||
(require 'autoconf)
|
||||
|
||||
(defvar autoconf-new-automake-string
|
||||
"dnl Process this file with autoconf to produce a configure script
|
||||
|
||||
AC_INIT(%s)
|
||||
AM_INIT_AUTOMAKE([%s], 0)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl End the configure script.
|
||||
AC_OUTPUT(Makefile, [date > stamp-h] )\n"
|
||||
"This string is used to initialize a new configure.in.
|
||||
The default is designed to be used with automake.
|
||||
The first %s will be filled with the test file.
|
||||
The second %s will be filled with the program name.")
|
||||
(declare-function ede-srecode-setup "ede/srecode")
|
||||
(declare-function ede-srecode-insert "ede/srecode")
|
||||
|
||||
(defun autoconf-new-program (rootdir program testfile)
|
||||
"Initialize a new configure.in in ROOTDIR for PROGRAM using TESTFILE.
|
||||
@ -49,6 +37,7 @@ PROGRAM is the program to be configured.
|
||||
TESTFILE is the file used with AC_INIT.
|
||||
configure the initial configure script using `autoconf-new-automake-string'"
|
||||
(interactive "DRoot Dir: \nsProgram: \nsTest File: ")
|
||||
(require 'ede/srecode)
|
||||
(if (bufferp rootdir)
|
||||
(set-buffer rootdir)
|
||||
(let ((cf1 (expand-file-name "configure.in" rootdir))
|
||||
@ -62,7 +51,12 @@ configure the initial configure script using `autoconf-new-automake-string'"
|
||||
(find-file cf2)))
|
||||
;; Note, we only ask about overwrite if a string/path is specified.
|
||||
(erase-buffer)
|
||||
(insert (format autoconf-new-automake-string testfile program)))
|
||||
(ede-srecode-setup)
|
||||
(ede-srecode-insert
|
||||
"file:ede-empty"
|
||||
"TEST_FILE" testfile
|
||||
"PROGRAM" program)
|
||||
)
|
||||
|
||||
(defvar autoconf-preferred-macro-order
|
||||
'("AC_INIT"
|
||||
@ -151,42 +145,44 @@ From the autoconf manual:
|
||||
(beginning-of-line)
|
||||
(looking-at (concat "\\(A[CM]_" macro "\\|" macro "\\)"))))
|
||||
|
||||
(defun autoconf-find-last-macro (macro)
|
||||
(defun autoconf-find-last-macro (macro &optional ignore-bol)
|
||||
"Move to the last occurrence of MACRO in FILE, and return that point.
|
||||
The last macro is usually the one in which we would like to insert more
|
||||
items such as CHECK_HEADERS."
|
||||
(let ((op (point)))
|
||||
(let ((op (point)) (atbol (if ignore-bol "" "^")))
|
||||
(goto-char (point-max))
|
||||
(if (re-search-backward (concat "^" (regexp-quote macro) "\\s-*\\((\\|$\\)") nil t)
|
||||
(if (re-search-backward (concat atbol (regexp-quote macro) "\\s-*\\((\\|$\\)") nil t)
|
||||
(progn
|
||||
(beginning-of-line)
|
||||
(unless ignore-bol (beginning-of-line))
|
||||
(point))
|
||||
(goto-char op)
|
||||
nil)))
|
||||
|
||||
(defun autoconf-parameter-strip (param)
|
||||
"Strip the parameter PARAM of whitespace and miscellaneous characters."
|
||||
(when (string-match "^\\s-*\\[?\\s-*" param)
|
||||
;; force greedy match for \n.
|
||||
(when (string-match "\\`\n*\\s-*\\[?\\s-*" param)
|
||||
(setq param (substring param (match-end 0))))
|
||||
(when (string-match "\\s-*\\]?\\s-*$" param)
|
||||
(when (string-match "\\s-*\\]?\\s-*\\'" param)
|
||||
(setq param (substring param 0 (match-beginning 0))))
|
||||
param)
|
||||
|
||||
(defun autoconf-parameters-for-macro (macro)
|
||||
(defun autoconf-parameters-for-macro (macro &optional ignore-bol ignore-case)
|
||||
"Retrieve the parameters to MACRO.
|
||||
Returns a list of the arguments passed into MACRO as strings."
|
||||
(save-excursion
|
||||
(when (autoconf-find-last-macro macro)
|
||||
(forward-sexp 1)
|
||||
(mapcar
|
||||
#'autoconf-parameter-strip
|
||||
(when (looking-at "(")
|
||||
(let* ((start (+ (point) 1))
|
||||
(end (save-excursion
|
||||
(forward-sexp 1)
|
||||
(- (point) 1)))
|
||||
(ans (buffer-substring-no-properties start end)))
|
||||
(split-string ans "," t)))))))
|
||||
(let ((case-fold-search ignore-case))
|
||||
(save-excursion
|
||||
(when (autoconf-find-last-macro macro ignore-bol)
|
||||
(forward-sexp 1)
|
||||
(mapcar
|
||||
#'autoconf-parameter-strip
|
||||
(when (looking-at "(")
|
||||
(let* ((start (+ (point) 1))
|
||||
(end (save-excursion
|
||||
(forward-sexp 1)
|
||||
(- (point) 1)))
|
||||
(ans (buffer-substring-no-properties start end)))
|
||||
(split-string ans "," t))))))))
|
||||
|
||||
(defun autoconf-position-for-macro (macro)
|
||||
"Position the cursor where a new MACRO could be inserted.
|
||||
|
636
lisp/cedet/ede/base.el
Normal file
636
lisp/cedet/ede/base.el
Normal file
@ -0,0 +1,636 @@
|
||||
;;; ede/base.el --- Baseclasses for EDE.
|
||||
|
||||
;; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; Baseclasses for EDE.
|
||||
;;
|
||||
;; Contains all the base structures needed by EDE.
|
||||
|
||||
;;; Code:
|
||||
(require 'eieio)
|
||||
(require 'eieio-speedbar)
|
||||
(require 'ede/auto)
|
||||
|
||||
;; Defined in ede.el:
|
||||
(defvar ede-projects)
|
||||
(defvar ede-object)
|
||||
(defvar ede-object-root-project)
|
||||
|
||||
(declare-function data-debug-new-buffer "data-debug")
|
||||
(declare-function data-debug-insert-object-slots "eieio-datadebug")
|
||||
(declare-function ede-parent-project "ede" (&optional obj))
|
||||
(declare-function ede-current-project "ede" (&optional dir))
|
||||
|
||||
;;; TARGET
|
||||
;;
|
||||
;; The TARGET is an entity in a project that knows about files
|
||||
;; and features of those files.
|
||||
|
||||
(defclass ede-target (eieio-speedbar-directory-button)
|
||||
((buttonface :initform speedbar-file-face) ;override for superclass
|
||||
(name :initarg :name
|
||||
:type string
|
||||
:custom string
|
||||
:label "Name"
|
||||
:group (default name)
|
||||
:documentation "Name of this target.")
|
||||
;; @todo - I think this should be "dir", and not "path".
|
||||
(path :initarg :path
|
||||
:type string
|
||||
;:custom string
|
||||
;:label "Path to target"
|
||||
;:group (default name)
|
||||
:documentation "The path to the sources of this target.
|
||||
Relative to the path of the project it belongs to.")
|
||||
(source :initarg :source
|
||||
:initform nil
|
||||
;; I'd prefer a list of strings.
|
||||
:type list
|
||||
:custom (repeat (string :tag "File"))
|
||||
:label "Source Files"
|
||||
:group (default source)
|
||||
:documentation "Source files in this target.")
|
||||
(versionsource :initarg :versionsource
|
||||
:initform nil
|
||||
:type list
|
||||
:custom (repeat (string :tag "File"))
|
||||
:label "Source Files with Version String"
|
||||
:group (source)
|
||||
:documentation
|
||||
"Source files with a version string in them.
|
||||
These files are checked for a version string whenever the EDE version
|
||||
of the master project is changed. When strings are found, the version
|
||||
previously there is updated.")
|
||||
;; Class level slots
|
||||
;;
|
||||
(sourcetype :allocation :class
|
||||
:type list ;; list of symbols
|
||||
:documentation
|
||||
"A list of `ede-sourcecode' objects this class will handle.
|
||||
This is used to match target objects with the compilers they can use, and
|
||||
which files this object is interested in."
|
||||
:accessor ede-object-sourcecode)
|
||||
(keybindings :allocation :class
|
||||
:initform (("D" . ede-debug-target))
|
||||
:documentation
|
||||
"Keybindings specialized to this type of target."
|
||||
:accessor ede-object-keybindings)
|
||||
(menu :allocation :class
|
||||
:initform ( [ "Debug target" ede-debug-target
|
||||
(ede-buffer-belongs-to-target-p) ]
|
||||
[ "Run target" ede-run-target
|
||||
(ede-buffer-belongs-to-target-p) ]
|
||||
)
|
||||
:documentation "Menu specialized to this type of target."
|
||||
:accessor ede-object-menu)
|
||||
)
|
||||
"A target is a structure that describes a file set that produces something.
|
||||
Targets, as with 'Make', is an entity that will manage a file set
|
||||
and knows how to compile or otherwise transform those files into some
|
||||
other desired outcome.")
|
||||
|
||||
;;; PROJECT/PLACEHOLDER
|
||||
;;
|
||||
;; Project placeholders are minimum parts of a project used
|
||||
;; by the project cache. The project cache can refer to these placeholders,
|
||||
;; and swap them out with the real-deal when that project is loaded.
|
||||
;;
|
||||
(defclass ede-project-placeholder (eieio-speedbar-directory-button)
|
||||
((name :initarg :name
|
||||
:initform "Untitled"
|
||||
:type string
|
||||
:custom string
|
||||
:label "Name"
|
||||
:group (default name)
|
||||
:documentation "The name used when generating distribution files.")
|
||||
(version :initarg :version
|
||||
:initform "1.0"
|
||||
:type string
|
||||
:custom string
|
||||
:label "Version"
|
||||
:group (default name)
|
||||
:documentation "The version number used when distributing files.")
|
||||
(directory :type string
|
||||
:initarg :directory
|
||||
:documentation "Directory this project is associated with.")
|
||||
(dirinode :documentation "The inode id for :directory.")
|
||||
(file :type string
|
||||
:initarg :file
|
||||
:documentation "File name where this project is stored.")
|
||||
(rootproject ; :initarg - no initarg, don't save this slot!
|
||||
:initform nil
|
||||
:type (or null ede-project-placeholder-child)
|
||||
:documentation "Pointer to our root project.")
|
||||
)
|
||||
"Placeholder object for projects not loaded into memory.
|
||||
Projects placeholders will be stored in a user specific location
|
||||
and querying them will cause the actual project to get loaded.")
|
||||
|
||||
;;; PROJECT
|
||||
;;
|
||||
;; An EDE project controls a set of TARGETS, and can also contain
|
||||
;; multiple SUBPROJECTS.
|
||||
;;
|
||||
;; The project defines a set of features that need to be built from
|
||||
;; files, in addition as to controlling what to do with the file set,
|
||||
;; such as creating distributions, compilation, and web sites.
|
||||
;;
|
||||
;; Projects can also affect how EDE works, by changing what appears in
|
||||
;; the EDE menu, or how some keys are bound.
|
||||
;;
|
||||
(defclass ede-project (ede-project-placeholder)
|
||||
((subproj :initform nil
|
||||
:type list
|
||||
:documentation "Sub projects controlled by this project.
|
||||
For Automake based projects, each directory is treated as a project.")
|
||||
(targets :initarg :targets
|
||||
:type list
|
||||
:custom (repeat (object :objectcreatefcn ede-new-target-custom))
|
||||
:label "Local Targets"
|
||||
:group (targets)
|
||||
:documentation "List of top level targets in this project.")
|
||||
(locate-obj :type (or null ede-locate-base-child)
|
||||
:documentation
|
||||
"A locate object to use as a backup to `ede-expand-filename'.")
|
||||
(tool-cache :initarg :tool-cache
|
||||
:type list
|
||||
:custom (repeat object)
|
||||
:label "Tool: "
|
||||
:group tools
|
||||
:documentation "List of tool cache configurations in this project.
|
||||
This allows any tool to create, manage, and persist project-specific settings.")
|
||||
(mailinglist :initarg :mailinglist
|
||||
:initform ""
|
||||
:type string
|
||||
:custom string
|
||||
:label "Mailing List Address"
|
||||
:group name
|
||||
:documentation
|
||||
"An email address where users might send email for help.")
|
||||
(web-site-url :initarg :web-site-url
|
||||
:initform ""
|
||||
:type string
|
||||
:custom string
|
||||
:label "Web Site URL"
|
||||
:group name
|
||||
:documentation "URL to this projects web site.
|
||||
This is a URL to be sent to a web site for documentation.")
|
||||
(web-site-directory :initarg :web-site-directory
|
||||
:initform ""
|
||||
:custom string
|
||||
:label "Web Page Directory"
|
||||
:group name
|
||||
:documentation
|
||||
"A directory where web pages can be found by Emacs.
|
||||
For remote locations use a path compatible with ange-ftp or EFS.
|
||||
You can also use TRAMP for use with rcp & scp.")
|
||||
(web-site-file :initarg :web-site-file
|
||||
:initform ""
|
||||
:custom string
|
||||
:label "Web Page File"
|
||||
:group name
|
||||
:documentation
|
||||
"A file which contains the home page for this project.
|
||||
This file can be relative to slot `web-site-directory'.
|
||||
This can be a local file, use ange-ftp, EFS, or TRAMP.")
|
||||
(ftp-site :initarg :ftp-site
|
||||
:initform ""
|
||||
:type string
|
||||
:custom string
|
||||
:label "FTP site"
|
||||
:group name
|
||||
:documentation
|
||||
"FTP site where this project's distribution can be found.
|
||||
This FTP site should be in Emacs form, as needed by `ange-ftp', but can
|
||||
also be of a form used by TRAMP for use with scp, or rcp.")
|
||||
(ftp-upload-site :initarg :ftp-upload-site
|
||||
:initform ""
|
||||
:type string
|
||||
:custom string
|
||||
:label "FTP Upload site"
|
||||
:group name
|
||||
:documentation
|
||||
"FTP Site to upload new distributions to.
|
||||
This FTP site should be in Emacs form as needed by `ange-ftp'.
|
||||
If this slot is nil, then use `ftp-site' instead.")
|
||||
(configurations :initarg :configurations
|
||||
:initform ("debug" "release")
|
||||
:type list
|
||||
:custom (repeat string)
|
||||
:label "Configuration Options"
|
||||
:group (settings)
|
||||
:documentation "List of available configuration types.
|
||||
Individual target/project types can form associations between a configuration,
|
||||
and target specific elements such as build variables.")
|
||||
(configuration-default :initarg :configuration-default
|
||||
:initform "debug"
|
||||
:custom string
|
||||
:label "Current Configuration"
|
||||
:group (settings)
|
||||
:documentation "The default configuration.")
|
||||
(local-variables :initarg :local-variables
|
||||
:initform nil
|
||||
:custom (repeat (cons (sexp :tag "Variable")
|
||||
(sexp :tag "Value")))
|
||||
:label "Project Local Variables"
|
||||
:group (settings)
|
||||
:documentation "Project local variables")
|
||||
(keybindings :allocation :class
|
||||
:initform (("D" . ede-debug-target)
|
||||
("R" . ede-run-target))
|
||||
:documentation "Keybindings specialized to this type of target."
|
||||
:accessor ede-object-keybindings)
|
||||
(menu :allocation :class
|
||||
:initform
|
||||
(
|
||||
[ "Update Version" ede-update-version ede-object ]
|
||||
[ "Version Control Status" ede-vc-project-directory ede-object ]
|
||||
[ "Edit Project Homepage" ede-edit-web-page
|
||||
(and ede-object (oref (ede-toplevel) web-site-file)) ]
|
||||
[ "Browse Project URL" ede-web-browse-home
|
||||
(and ede-object
|
||||
(not (string= "" (oref (ede-toplevel) web-site-url)))) ]
|
||||
"--"
|
||||
[ "Rescan Project Files" ede-rescan-toplevel t ]
|
||||
[ "Edit Projectfile" ede-edit-file-target
|
||||
(ede-buffer-belongs-to-project-p) ]
|
||||
)
|
||||
:documentation "Menu specialized to this type of target."
|
||||
:accessor ede-object-menu)
|
||||
)
|
||||
"Top level EDE project specification.
|
||||
All specific project types must derive from this project."
|
||||
:method-invocation-order :depth-first)
|
||||
|
||||
;;; Important macros for doing commands.
|
||||
;;
|
||||
(defmacro ede-with-projectfile (obj &rest forms)
|
||||
"For the project in which OBJ resides, execute FORMS."
|
||||
(list 'save-window-excursion
|
||||
(list 'let* (list
|
||||
(list 'pf
|
||||
(list 'if (list 'obj-of-class-p
|
||||
obj 'ede-target)
|
||||
;; @todo -I think I can change
|
||||
;; this to not need ede-load-project-file
|
||||
;; but I'm not sure how to test well.
|
||||
(list 'ede-load-project-file
|
||||
(list 'oref obj 'path))
|
||||
obj))
|
||||
'(dbka (get-file-buffer (oref pf file))))
|
||||
'(if (not dbka) (find-file (oref pf file))
|
||||
(switch-to-buffer dbka))
|
||||
(cons 'progn forms)
|
||||
'(if (not dbka) (kill-buffer (current-buffer))))))
|
||||
(put 'ede-with-projectfile 'lisp-indent-function 1)
|
||||
|
||||
;;; The EDE persistent cache.
|
||||
;;
|
||||
;; The cache is a way to mark where all known projects live without
|
||||
;; loading those projects into memory, or scanning for them each time
|
||||
;; emacs starts.
|
||||
;;
|
||||
(defcustom ede-project-placeholder-cache-file
|
||||
(locate-user-emacs-file "ede-projects.el" ".projects.ede")
|
||||
"File containing the list of projects EDE has viewed."
|
||||
:group 'ede
|
||||
:type 'file)
|
||||
|
||||
(defvar ede-project-cache-files nil
|
||||
"List of project files EDE has seen before.")
|
||||
|
||||
(defun ede-save-cache ()
|
||||
"Save a cache of EDE objects that Emacs has seen before."
|
||||
(interactive)
|
||||
(let ((p ede-projects)
|
||||
(c ede-project-cache-files)
|
||||
(recentf-exclude '( (lambda (f) t) ))
|
||||
)
|
||||
(condition-case nil
|
||||
(progn
|
||||
(set-buffer (find-file-noselect ede-project-placeholder-cache-file t))
|
||||
(erase-buffer)
|
||||
(insert ";; EDE project cache file.
|
||||
;; This contains a list of projects you have visited.\n(")
|
||||
(while p
|
||||
(when (and (car p) (ede-project-p p))
|
||||
(let ((f (oref (car p) file)))
|
||||
(when (file-exists-p f)
|
||||
(insert "\n \"" f "\""))))
|
||||
(setq p (cdr p)))
|
||||
(while c
|
||||
(insert "\n \"" (car c) "\"")
|
||||
(setq c (cdr c)))
|
||||
(insert "\n)\n")
|
||||
(condition-case nil
|
||||
(save-buffer 0)
|
||||
(error
|
||||
(message "File %s could not be saved."
|
||||
ede-project-placeholder-cache-file)))
|
||||
(kill-buffer (current-buffer))
|
||||
)
|
||||
(error
|
||||
(message "File %s could not be read."
|
||||
ede-project-placeholder-cache-file))
|
||||
|
||||
)))
|
||||
|
||||
(defun ede-load-cache ()
|
||||
"Load the cache of EDE projects."
|
||||
(save-excursion
|
||||
(let ((cachebuffer nil))
|
||||
(condition-case nil
|
||||
(progn
|
||||
(setq cachebuffer
|
||||
(find-file-noselect ede-project-placeholder-cache-file t))
|
||||
(set-buffer cachebuffer)
|
||||
(goto-char (point-min))
|
||||
(let ((c (read (current-buffer)))
|
||||
(new nil)
|
||||
(p ede-projects))
|
||||
;; Remove loaded projects from the cache.
|
||||
(while p
|
||||
(setq c (delete (oref (car p) file) c))
|
||||
(setq p (cdr p)))
|
||||
;; Remove projects that aren't on the filesystem
|
||||
;; anymore.
|
||||
(while c
|
||||
(when (file-exists-p (car c))
|
||||
(setq new (cons (car c) new)))
|
||||
(setq c (cdr c)))
|
||||
;; Save it
|
||||
(setq ede-project-cache-files (nreverse new))))
|
||||
(error nil))
|
||||
(when cachebuffer (kill-buffer cachebuffer))
|
||||
)))
|
||||
|
||||
;;; Get the cache usable.
|
||||
|
||||
;; @TODO - Remove this cache setup, or use this for something helpful.
|
||||
;;(add-hook 'kill-emacs-hook 'ede-save-cache)
|
||||
;;(when (not noninteractive)
|
||||
;; ;; No need to load the EDE cache if we aren't interactive.
|
||||
;; ;; This occurs during batch byte-compiling of other tools.
|
||||
;; (ede-load-cache))
|
||||
|
||||
|
||||
;;; METHODS
|
||||
;;
|
||||
;; The methods in ede-base handle project related behavior, and DO NOT
|
||||
;; related to EDE mode commands directory, such as keybindings.
|
||||
;;
|
||||
;; Mode related methods are in ede.el. These methods are related
|
||||
;; project specific activities not directly tied to a keybinding.
|
||||
(defmethod ede-subproject-relative-path ((proj ede-project) &optional parent-in)
|
||||
"Get a path name for PROJ which is relative to the parent project.
|
||||
If PARENT is specified, then be relative to the PARENT project.
|
||||
Specifying PARENT is useful for sub-sub projects relative to the root project."
|
||||
(let* ((parent (or parent-in (ede-parent-project proj)))
|
||||
(dir (file-name-directory (oref proj file))))
|
||||
(if (and parent (not (eq parent proj)))
|
||||
(file-relative-name dir (file-name-directory (oref parent file)))
|
||||
"")))
|
||||
|
||||
(defmethod ede-subproject-p ((proj ede-project))
|
||||
"Return non-nil if PROJ is a sub project."
|
||||
;; @TODO - Use this in more places, and also pay attention to
|
||||
;; metasubproject in ede-proj.el
|
||||
(ede-parent-project proj))
|
||||
|
||||
|
||||
;;; Default descriptive methods for EDE classes
|
||||
;;
|
||||
;; These are methods which you might want to override, but there is
|
||||
;; no need to in most situations because they are either a) simple, or
|
||||
;; b) cosmetic.
|
||||
|
||||
(defmethod ede-name ((this ede-target))
|
||||
"Return the name of THIS target."
|
||||
(oref this name))
|
||||
|
||||
(defmethod ede-target-name ((this ede-target))
|
||||
"Return the name of THIS target, suitable for make or debug style commands."
|
||||
(oref this name))
|
||||
|
||||
(defmethod ede-name ((this ede-project))
|
||||
"Return a short-name for THIS project file.
|
||||
Do this by extracting the lowest directory name."
|
||||
(oref this name))
|
||||
|
||||
(defmethod ede-description ((this ede-project))
|
||||
"Return a description suitable for the minibuffer about THIS."
|
||||
(format "Project %s: %d subprojects, %d targets."
|
||||
(ede-name this) (length (oref this subproj))
|
||||
(length (oref this targets))))
|
||||
|
||||
(defmethod ede-description ((this ede-target))
|
||||
"Return a description suitable for the minibuffer about THIS."
|
||||
(format "Target %s: with %d source files."
|
||||
(ede-name this) (length (oref this source))))
|
||||
|
||||
;;; HEADERS/DOC
|
||||
;;
|
||||
;; Targets and projects are often associated with other files, such as
|
||||
;; header files, documentation files and the like. Have strong
|
||||
;; associations can make useful user commands to quickly navigate
|
||||
;; between the files base on their assocaitions.
|
||||
;;
|
||||
(defun ede-header-file ()
|
||||
"Return the header file for the current buffer.
|
||||
Not all buffers need headers, so return nil if no applicable."
|
||||
(if ede-object
|
||||
(ede-buffer-header-file ede-object (current-buffer))
|
||||
nil))
|
||||
|
||||
(defmethod ede-buffer-header-file ((this ede-project) buffer)
|
||||
"Return nil, projects don't have header files."
|
||||
nil)
|
||||
|
||||
(defmethod ede-buffer-header-file ((this ede-target) buffer)
|
||||
"There are no default header files in EDE.
|
||||
Do a quick check to see if there is a Header tag in this buffer."
|
||||
(with-current-buffer buffer
|
||||
(if (re-search-forward "::Header:: \\([a-zA-Z0-9.]+\\)" nil t)
|
||||
(buffer-substring-no-properties (match-beginning 1)
|
||||
(match-end 1))
|
||||
(let ((src (ede-target-sourcecode this))
|
||||
(found nil))
|
||||
(while (and src (not found))
|
||||
(setq found (ede-buffer-header-file (car src) (buffer-file-name))
|
||||
src (cdr src)))
|
||||
found))))
|
||||
|
||||
(defun ede-documentation-files ()
|
||||
"Return the documentation files for the current buffer.
|
||||
Not all buffers need documentations, so return nil if no applicable.
|
||||
Some projects may have multiple documentation files, so return a list."
|
||||
(if ede-object
|
||||
(ede-buffer-documentation-files ede-object (current-buffer))
|
||||
nil))
|
||||
|
||||
(defmethod ede-buffer-documentation-files ((this ede-project) buffer)
|
||||
"Return all documentation in project THIS based on BUFFER."
|
||||
;; Find the info node.
|
||||
(ede-documentation this))
|
||||
|
||||
(defmethod ede-buffer-documentation-files ((this ede-target) buffer)
|
||||
"Check for some documentation files for THIS.
|
||||
Also do a quick check to see if there is a Documentation tag in this BUFFER."
|
||||
(with-current-buffer buffer
|
||||
(if (re-search-forward "::Documentation:: \\([a-zA-Z0-9.]+\\)" nil t)
|
||||
(buffer-substring-no-properties (match-beginning 1)
|
||||
(match-end 1))
|
||||
;; Check the master project
|
||||
(let ((cp (ede-toplevel)))
|
||||
(ede-buffer-documentation-files cp (current-buffer))))))
|
||||
|
||||
(defmethod ede-documentation ((this ede-project))
|
||||
"Return a list of files that provide documentation.
|
||||
Documentation is not for object THIS, but is provided by THIS for other
|
||||
files in the project."
|
||||
(let ((targ (oref this targets))
|
||||
(proj (oref this subproj))
|
||||
(found nil))
|
||||
(while targ
|
||||
(setq found (append (ede-documentation (car targ)) found)
|
||||
targ (cdr targ)))
|
||||
(while proj
|
||||
(setq found (append (ede-documentation (car proj)) found)
|
||||
proj (cdr proj)))
|
||||
found))
|
||||
|
||||
(defmethod ede-documentation ((this ede-target))
|
||||
"Return a list of files that provide documentation.
|
||||
Documentation is not for object THIS, but is provided by THIS for other
|
||||
files in the project."
|
||||
nil)
|
||||
|
||||
(defun ede-html-documentation-files ()
|
||||
"Return a list of HTML documentation files associated with this project."
|
||||
(ede-html-documentation (ede-toplevel))
|
||||
)
|
||||
|
||||
(defmethod ede-html-documentation ((this ede-project))
|
||||
"Return a list of HTML files provided by project THIS."
|
||||
|
||||
)
|
||||
|
||||
;;; Default "WANT" methods.
|
||||
;;
|
||||
;; These methods are used to determine if a target "wants", or could
|
||||
;; somehow handle a file, or some source type.
|
||||
;;
|
||||
(defmethod ede-want-file-p ((this ede-target) file)
|
||||
"Return non-nil if THIS target wants FILE."
|
||||
;; By default, all targets reference the source object, and let it decide.
|
||||
(let ((src (ede-target-sourcecode this)))
|
||||
(while (and src (not (ede-want-file-p (car src) file)))
|
||||
(setq src (cdr src)))
|
||||
src))
|
||||
|
||||
(defmethod ede-want-file-source-p ((this ede-target) file)
|
||||
"Return non-nil if THIS target wants FILE."
|
||||
;; By default, all targets reference the source object, and let it decide.
|
||||
(let ((src (ede-target-sourcecode this)))
|
||||
(while (and src (not (ede-want-file-source-p (car src) file)))
|
||||
(setq src (cdr src)))
|
||||
src))
|
||||
|
||||
(defmethod ede-target-sourcecode ((this ede-target))
|
||||
"Return the sourcecode objects which THIS permits."
|
||||
(let ((sc (oref this sourcetype))
|
||||
(rs nil))
|
||||
(while (and (listp sc) sc)
|
||||
(setq rs (cons (symbol-value (car sc)) rs)
|
||||
sc (cdr sc)))
|
||||
rs))
|
||||
|
||||
|
||||
;;; Debugging.
|
||||
;;
|
||||
(defun ede-adebug-project ()
|
||||
"Run adebug against the current EDE project.
|
||||
Display the results as a debug list."
|
||||
(interactive)
|
||||
(require 'data-debug)
|
||||
(when (ede-current-project)
|
||||
(data-debug-new-buffer "*Analyzer ADEBUG*")
|
||||
(data-debug-insert-object-slots (ede-current-project) "")
|
||||
))
|
||||
|
||||
(defun ede-adebug-project-parent ()
|
||||
"Run adebug against the current EDE parent project.
|
||||
Display the results as a debug list."
|
||||
(interactive)
|
||||
(require 'data-debug)
|
||||
(when (ede-parent-project)
|
||||
(data-debug-new-buffer "*Analyzer ADEBUG*")
|
||||
(data-debug-insert-object-slots (ede-parent-project) "")
|
||||
))
|
||||
|
||||
(defun ede-adebug-project-root ()
|
||||
"Run adebug against the current EDE parent project.
|
||||
Display the results as a debug list."
|
||||
(interactive)
|
||||
(require 'data-debug)
|
||||
(when (ede-toplevel)
|
||||
(data-debug-new-buffer "*Analyzer ADEBUG*")
|
||||
(data-debug-insert-object-slots (ede-toplevel) "")
|
||||
))
|
||||
|
||||
|
||||
|
||||
;;; TOPLEVEL PROJECT
|
||||
;;
|
||||
;; The toplevel project is a way to identify the EDE structure that belongs
|
||||
;; to the top of a project.
|
||||
|
||||
(defun ede-toplevel (&optional subproj)
|
||||
"Return the ede project which is the root of the current project.
|
||||
Optional argument SUBPROJ indicates a subproject to start from
|
||||
instead of the current project."
|
||||
(or ede-object-root-project
|
||||
(let* ((cp (or subproj (ede-current-project))))
|
||||
(or (and cp (ede-project-root cp))
|
||||
(progn
|
||||
(while (ede-parent-project cp)
|
||||
(setq cp (ede-parent-project cp)))
|
||||
cp)))))
|
||||
|
||||
|
||||
;;; Hooks & Autoloads
|
||||
;;
|
||||
;; These let us watch various activities, and respond appropriately.
|
||||
|
||||
;; (add-hook 'edebug-setup-hook
|
||||
;; (lambda ()
|
||||
;; (def-edebug-spec ede-with-projectfile
|
||||
;; (form def-body))))
|
||||
|
||||
(provide 'ede/base)
|
||||
|
||||
;; Local variables:
|
||||
;; generated-autoload-file: "loaddefs.el"
|
||||
;; generated-autoload-load-name: "ede/base"
|
||||
;; End:
|
||||
|
||||
;;; ede/base.el ends here
|
@ -237,6 +237,18 @@ ROOTPROJ is nil, since there is only one project."
|
||||
;; Snoop through our master list.
|
||||
(ede-cpp-root-file-existing dir))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'ede-project-class-files
|
||||
(ede-project-autoload "cpp-root"
|
||||
:name "CPP ROOT"
|
||||
:file 'ede-cpp-root
|
||||
:proj-file 'ede-cpp-root-project-file-for-dir
|
||||
:proj-root 'ede-cpp-root-project-root
|
||||
:load-type 'ede-cpp-root-load
|
||||
:class-sym 'ede-cpp-root
|
||||
:new-p nil)
|
||||
t)
|
||||
|
||||
;;; CLASSES
|
||||
;;
|
||||
;; EDE sets up projects with two kinds of objects.
|
||||
@ -504,6 +516,21 @@ Also set up the lexical preprocessor map."
|
||||
"Get the pre-processor map for project THIS."
|
||||
(ede-preprocessor-map (ede-target-parent this)))
|
||||
|
||||
;;; Quick Hack
|
||||
(defun ede-create-lots-of-projects-under-dir (dir projfile &rest attributes)
|
||||
"Create a bunch of projects under directory DIR.
|
||||
PROJFILE is a file name sans directory that indicates a subdirectory
|
||||
is a project directory.
|
||||
Generic ATTRIBUTES, such as :include-path can be added.
|
||||
Note: This needs some work."
|
||||
(let ((files (directory-files dir t)))
|
||||
(dolist (F files)
|
||||
(if (file-exists-p (expand-file-name projfile F))
|
||||
`(ede-cpp-root-project (file-name-nondirectory F)
|
||||
:name (file-name-nondirectory F)
|
||||
:file (expand-file-name projfile F)
|
||||
attributes)))))
|
||||
|
||||
(provide 'ede/cpp-root)
|
||||
|
||||
;; Local variables:
|
||||
|
215
lisp/cedet/ede/custom.el
Normal file
215
lisp/cedet/ede/custom.el
Normal file
@ -0,0 +1,215 @@
|
||||
;;; ede.el --- customization of EDE projects.
|
||||
|
||||
;; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; Customization commands/hooks for EDE.
|
||||
;;
|
||||
;; EIEIO supports customizing objects, and EDE uses this to allow
|
||||
;; users to change basic settings in their projects.
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
;;; Customization
|
||||
;;
|
||||
;; Routines for customizing projects and targets.
|
||||
|
||||
(require 'ede)
|
||||
(eval-when-compile (require 'eieio-custom))
|
||||
|
||||
(defvar eieio-ede-old-variables nil
|
||||
"The old variables for a project.")
|
||||
|
||||
;;; Customization Commands
|
||||
;;
|
||||
;; These commands initialize custoization of EDE control objects.
|
||||
|
||||
;;;###autoload
|
||||
(defun ede-customize-project ()
|
||||
"Edit fields of the current project through EIEIO & Custom."
|
||||
(interactive)
|
||||
(require 'eieio-custom)
|
||||
(let* ((ov (oref (ede-current-project) local-variables))
|
||||
(cp (ede-current-project)))
|
||||
(ede-customize cp)
|
||||
(make-local-variable 'eieio-ede-old-variables)
|
||||
(setq eieio-ede-old-variables ov)))
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'customize-project 'ede-customize-project)
|
||||
|
||||
;;;###autoload
|
||||
(defun ede-customize-current-target()
|
||||
"Edit fields of the current target through EIEIO & Custom."
|
||||
(interactive)
|
||||
(require 'eieio-custom)
|
||||
(if (not (obj-of-class-p ede-object ede-target))
|
||||
(error "Current file is not part of a target"))
|
||||
(ede-customize-target ede-object))
|
||||
|
||||
;;;###autoload
|
||||
(defalias 'customize-target 'ede-customize-current-target)
|
||||
|
||||
(defun ede-customize-target (obj)
|
||||
"Edit fields of the current target through EIEIO & Custom.
|
||||
OBJ is the target object to customize."
|
||||
(require 'eieio-custom)
|
||||
(if (and obj (not (obj-of-class-p obj ede-target)))
|
||||
(error "No logical target to customize"))
|
||||
(ede-customize obj))
|
||||
|
||||
(defmethod ede-customize ((proj ede-project))
|
||||
"Customize the EDE project PROJ."
|
||||
(eieio-customize-object proj 'default))
|
||||
|
||||
(defmethod ede-customize ((target ede-target))
|
||||
"Customize the EDE TARGET."
|
||||
(eieio-customize-object target 'default))
|
||||
|
||||
;;; Target Sorting
|
||||
;;
|
||||
;; Target order can be important, but custom doesn't support a way
|
||||
;; to resort items in a list. This function by David Engster allows
|
||||
;; targets to be re-arranged.
|
||||
|
||||
(defvar ede-project-sort-targets-order nil
|
||||
"Variable for tracking target order in `ede-project-sort-targets'.")
|
||||
|
||||
;;;###autoload
|
||||
(defun ede-project-sort-targets ()
|
||||
"Create a custom-like buffer for sorting targets of current project."
|
||||
(interactive)
|
||||
(let ((proj (ede-current-project))
|
||||
(count 1)
|
||||
current order)
|
||||
(switch-to-buffer (get-buffer-create "*EDE sort targets*"))
|
||||
(erase-buffer)
|
||||
(setq ede-object-project proj)
|
||||
(widget-create 'push-button
|
||||
:notify (lambda (&rest ignore)
|
||||
(let ((targets (oref ede-object-project targets))
|
||||
cur newtargets)
|
||||
(while (setq cur (pop ede-project-sort-targets-order))
|
||||
(setq newtargets (append newtargets
|
||||
(list (nth cur targets)))))
|
||||
(oset ede-object-project targets newtargets))
|
||||
(ede-commit-project ede-object-project)
|
||||
(kill-buffer))
|
||||
" Accept ")
|
||||
(widget-insert " ")
|
||||
(widget-create 'push-button
|
||||
:notify (lambda (&rest ignore)
|
||||
(kill-buffer))
|
||||
" Cancel ")
|
||||
(widget-insert "\n\n")
|
||||
(setq ede-project-sort-targets-order nil)
|
||||
(mapc (lambda (x)
|
||||
(add-to-ordered-list
|
||||
'ede-project-sort-targets-order
|
||||
x x))
|
||||
(number-sequence 0 (1- (length (oref proj targets)))))
|
||||
(ede-project-sort-targets-list)
|
||||
(use-local-map widget-keymap)
|
||||
(widget-setup)
|
||||
(goto-char (point-min))))
|
||||
|
||||
(defun ede-project-sort-targets-list ()
|
||||
"Sort the target list while using `ede-project-sort-targets'."
|
||||
(save-excursion
|
||||
(let ((count 0)
|
||||
(targets (oref ede-object-project targets))
|
||||
(inhibit-read-only t)
|
||||
(inhibit-modification-hooks t))
|
||||
(goto-char (point-min))
|
||||
(forward-line 2)
|
||||
(delete-region (point) (point-max))
|
||||
(while (< count (length targets))
|
||||
(if (> count 0)
|
||||
(widget-create 'push-button
|
||||
:notify `(lambda (&rest ignore)
|
||||
(let ((cur ede-project-sort-targets-order))
|
||||
(add-to-ordered-list
|
||||
'ede-project-sort-targets-order
|
||||
(nth ,count cur)
|
||||
(1- ,count))
|
||||
(add-to-ordered-list
|
||||
'ede-project-sort-targets-order
|
||||
(nth (1- ,count) cur) ,count))
|
||||
(ede-project-sort-targets-list))
|
||||
" Up ")
|
||||
(widget-insert " "))
|
||||
(if (< count (1- (length targets)))
|
||||
(widget-create 'push-button
|
||||
:notify `(lambda (&rest ignore)
|
||||
(let ((cur ede-project-sort-targets-order))
|
||||
(add-to-ordered-list
|
||||
'ede-project-sort-targets-order
|
||||
(nth ,count cur) (1+ ,count))
|
||||
(add-to-ordered-list
|
||||
'ede-project-sort-targets-order
|
||||
(nth (1+ ,count) cur) ,count))
|
||||
(ede-project-sort-targets-list))
|
||||
" Down ")
|
||||
(widget-insert " "))
|
||||
(widget-insert (concat " " (number-to-string (1+ count)) ".: "
|
||||
(oref (nth (nth count ede-project-sort-targets-order)
|
||||
targets) name) "\n"))
|
||||
(setq count (1+ count))))))
|
||||
|
||||
;;; Customization hooks
|
||||
;;
|
||||
;; These hooks are used when finishing up a customization.
|
||||
(defmethod eieio-done-customizing ((proj ede-project))
|
||||
"Call this when a user finishes customizing PROJ."
|
||||
(let ((ov eieio-ede-old-variables)
|
||||
(nv (oref proj local-variables)))
|
||||
(setq eieio-ede-old-variables nil)
|
||||
(while ov
|
||||
(if (not (assoc (car (car ov)) nv))
|
||||
(save-excursion
|
||||
(mapc (lambda (b)
|
||||
(set-buffer b)
|
||||
(kill-local-variable (car (car ov))))
|
||||
(ede-project-buffers proj))))
|
||||
(setq ov (cdr ov)))
|
||||
(mapc (lambda (b) (ede-set-project-variables proj b))
|
||||
(ede-project-buffers proj))))
|
||||
|
||||
;; These two methods should be implemented by subclasses of
|
||||
;; project and targets in order to account for user specified
|
||||
;; changes.
|
||||
(defmethod eieio-done-customizing ((target ede-target))
|
||||
"Call this when a user finishes customizing TARGET."
|
||||
nil)
|
||||
|
||||
(defmethod ede-commit-project ((proj ede-project))
|
||||
"Commit any change to PROJ to its file."
|
||||
nil
|
||||
)
|
||||
|
||||
(provide 'ede/custom)
|
||||
|
||||
;; Local variables:
|
||||
;; generated-autoload-file: "loaddefs.el"
|
||||
;; generated-autoload-load-name: "ede/custom"
|
||||
;; End:
|
||||
|
||||
;;; ede/custom.el ends here
|
@ -88,7 +88,7 @@ negative, force off."
|
||||
(let ((files (dired-get-marked-files t)))
|
||||
(while files
|
||||
(project-add-file target (car files))
|
||||
;; Find the buffer for this files, and set it's ede-object
|
||||
;; Find the buffer for this files, and set its ede-object
|
||||
(if (get-file-buffer (car files))
|
||||
(with-current-buffer (get-file-buffer (car files))
|
||||
(setq ede-object nil)
|
||||
|
@ -133,6 +133,18 @@ ROOTPROJ is nil, since there is only one project."
|
||||
)
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'ede-project-class-files
|
||||
(ede-project-autoload "emacs"
|
||||
:name "EMACS ROOT"
|
||||
:file 'ede-emacs
|
||||
:proj-file "src/emacs.c"
|
||||
:proj-root 'ede-emacs-project-root
|
||||
:load-type 'ede-emacs-load
|
||||
:class-sym 'ede-emacs-project
|
||||
:new-p nil)
|
||||
t)
|
||||
|
||||
(defclass ede-emacs-target-c (ede-target)
|
||||
()
|
||||
"EDE Emacs Project target for C code.
|
||||
@ -150,7 +162,7 @@ All directories need at least one target.")
|
||||
|
||||
(defmethod initialize-instance ((this ede-emacs-project)
|
||||
&rest fields)
|
||||
"Make sure the :file is fully expanded."
|
||||
"Make sure the targets slot is bound."
|
||||
(call-next-method)
|
||||
(unless (slot-boundp this 'targets)
|
||||
(oset this :targets nil)))
|
||||
|
@ -38,6 +38,7 @@
|
||||
(declare-function ede-locate-file-in-hash "ede/locate")
|
||||
(declare-function ede-locate-add-file-to-hash "ede/locate")
|
||||
(declare-function ede-locate-file-in-project "ede/locate")
|
||||
(declare-function ede-locate-flush-hash "ede/locate")
|
||||
|
||||
(defvar ede--disable-inode nil
|
||||
"Set to 't' to simulate systems w/out inode support.")
|
||||
@ -57,44 +58,29 @@ the current EDE project."
|
||||
(ede-project-root-directory (ede-current-project))))
|
||||
(find-file fname)))
|
||||
|
||||
(defun ede-flush-project-hash ()
|
||||
"Flush the file locate hash for the current project."
|
||||
(interactive)
|
||||
(require 'ede/locate)
|
||||
(let* ((loc (ede-get-locator-object (ede-current-project))))
|
||||
(ede-locate-flush-hash loc)))
|
||||
|
||||
;;; Placeholders for ROOT directory scanning on base objects
|
||||
;;
|
||||
(defmethod ede-project-root ((this ede-project-placeholder))
|
||||
"If a project knows it's root, return it here.
|
||||
"If a project knows its root, return it here.
|
||||
Allows for one-project-object-for-a-tree type systems."
|
||||
(oref this rootproject))
|
||||
|
||||
(defmethod ede-project-root-directory ((this ede-project-placeholder)
|
||||
&optional file)
|
||||
"If a project knows it's root, return it here.
|
||||
"If a project knows its root, return it here.
|
||||
Allows for one-project-object-for-a-tree type systems.
|
||||
Optional FILE is the file to test. It is ignored in preference
|
||||
of the anchor file for the project."
|
||||
(file-name-directory (expand-file-name (oref this file))))
|
||||
|
||||
|
||||
(defmethod ede-project-root ((this ede-project-autoload))
|
||||
"If a project knows it's root, return it here.
|
||||
Allows for one-project-object-for-a-tree type systems."
|
||||
nil)
|
||||
|
||||
(defmethod ede-project-root-directory ((this ede-project-autoload)
|
||||
&optional file)
|
||||
"If a project knows it's root, return it here.
|
||||
Allows for one-project-object-for-a-tree type systems.
|
||||
Optional FILE is the file to test. If there is no FILE, use
|
||||
the current buffer."
|
||||
(when (not file)
|
||||
(setq file default-directory))
|
||||
(when (slot-boundp this :proj-root)
|
||||
(let ((rootfcn (oref this proj-root)))
|
||||
(when rootfcn
|
||||
(condition-case nil
|
||||
(funcall rootfcn file)
|
||||
(error
|
||||
(funcall rootfcn)))
|
||||
))))
|
||||
|
||||
(defmethod ede--project-inode ((proj ede-project-placeholder))
|
||||
"Get the inode of the directory project PROJ is in."
|
||||
(if (slot-boundp proj 'dirinode)
|
||||
@ -262,27 +248,30 @@ Do this whenever a new project is created, as opposed to loaded."
|
||||
(defun ede-directory-project-p (dir &optional force)
|
||||
"Return a project description object if DIR has a project.
|
||||
Optional argument FORCE means to ignore a hash-hit of 'nomatch.
|
||||
This depends on an up to date `ede-project-class-files' variable."
|
||||
(let* ((dirtest (expand-file-name dir))
|
||||
(match (ede-directory-project-from-hash dirtest)))
|
||||
(cond
|
||||
((and (eq match 'nomatch) (not force))
|
||||
nil)
|
||||
((and match (not (eq match 'nomatch)))
|
||||
match)
|
||||
(t
|
||||
(let ((types ede-project-class-files)
|
||||
(ret nil))
|
||||
;; Loop over all types, loading in the first type that we find.
|
||||
(while (and types (not ret))
|
||||
(if (ede-dir-to-projectfile (car types) dirtest)
|
||||
(progn
|
||||
;; We found one! Require it now since we will need it.
|
||||
(require (oref (car types) file))
|
||||
(setq ret (car types))))
|
||||
(setq types (cdr types)))
|
||||
(ede-directory-project-add-description-to-hash dirtest (or ret 'nomatch))
|
||||
ret)))))
|
||||
This depends on an up to date `ede-project-class-files' variable.
|
||||
Any directory that contains the file .ede-ignore will allways
|
||||
return nil."
|
||||
(when (not (file-exists-p (expand-file-name ".ede-ignore" dir)))
|
||||
(let* ((dirtest (expand-file-name dir))
|
||||
(match (ede-directory-project-from-hash dirtest)))
|
||||
(cond
|
||||
((and (eq match 'nomatch) (not force))
|
||||
nil)
|
||||
((and match (not (eq match 'nomatch)))
|
||||
match)
|
||||
(t
|
||||
(let ((types ede-project-class-files)
|
||||
(ret nil))
|
||||
;; Loop over all types, loading in the first type that we find.
|
||||
(while (and types (not ret))
|
||||
(if (ede-dir-to-projectfile (car types) dirtest)
|
||||
(progn
|
||||
;; We found one! Require it now since we will need it.
|
||||
(require (oref (car types) file))
|
||||
(setq ret (car types))))
|
||||
(setq types (cdr types)))
|
||||
(ede-directory-project-add-description-to-hash dirtest (or ret 'nomatch))
|
||||
ret))))))
|
||||
|
||||
;;; TOPLEVEL
|
||||
;;
|
||||
@ -324,7 +313,7 @@ nil is returned if the current directory is not a part of a project."
|
||||
;; If PROJ didn't know, or there is no PROJ, then
|
||||
|
||||
;; Loop up to the topmost project, and then load that single
|
||||
;; project, and it's sub projects. When we are done, identify the
|
||||
;; project, and its sub projects. When we are done, identify the
|
||||
;; sub-project object belonging to file.
|
||||
(while (and (not ans) newpath proj)
|
||||
(setq toppath newpath
|
||||
@ -338,24 +327,6 @@ nil is returned if the current directory is not a part of a project."
|
||||
)
|
||||
(or ans toppath))))))
|
||||
|
||||
;;; TOPLEVEL PROJECT
|
||||
;;
|
||||
;; The toplevel project is a way to identify the EDE structure that belongs
|
||||
;; to the top of a project.
|
||||
|
||||
(defun ede-toplevel (&optional subproj)
|
||||
"Return the ede project which is the root of the current project.
|
||||
Optional argument SUBPROJ indicates a subproject to start from
|
||||
instead of the current project."
|
||||
(or ede-object-root-project
|
||||
(let* ((cp (or subproj (ede-current-project)))
|
||||
)
|
||||
(or (and cp (ede-project-root cp))
|
||||
(progn
|
||||
(while (ede-parent-project cp)
|
||||
(setq cp (ede-parent-project cp)))
|
||||
cp)))))
|
||||
|
||||
;;; DIRECTORY CONVERSION STUFF
|
||||
;;
|
||||
(defmethod ede-convert-path ((this ede-project) path)
|
||||
@ -372,11 +343,13 @@ Argument THIS is the project to convert PATH to."
|
||||
(substring fptf (match-end 0))
|
||||
(error "Cannot convert relativize path %s" fp))))))
|
||||
|
||||
(defmethod ede-convert-path ((this ede-target) path)
|
||||
(defmethod ede-convert-path ((this ede-target) path &optional project)
|
||||
"Convert path in a standard way for a given project.
|
||||
Default to making it project relative.
|
||||
Argument THIS is the project to convert PATH to."
|
||||
(let ((proj (ede-target-parent this)))
|
||||
Argument THIS is the project to convert PATH to.
|
||||
Optional PROJECT is the project that THIS belongs to. Associating
|
||||
a target to a project is expensive, so using this can speed things up."
|
||||
(let ((proj (or project (ede-target-parent this))))
|
||||
(if proj
|
||||
(let ((p (ede-convert-path proj path))
|
||||
(lp (or (oref this path) "")))
|
||||
@ -406,7 +379,8 @@ FILENAME should be just a filename which occurs in a directory controlled
|
||||
by this project.
|
||||
Optional argument FORCE forces the default filename to be provided even if it
|
||||
doesn't exist.
|
||||
If FORCE equals 'newfile, then the cache is ignored."
|
||||
If FORCE equals 'newfile, then the cache is ignored and a new file in THIS
|
||||
is returned."
|
||||
(require 'ede/locate)
|
||||
(let* ((loc (ede-get-locator-object this))
|
||||
(ha (ede-locate-file-in-hash loc filename))
|
||||
@ -467,17 +441,8 @@ doesn't exist."
|
||||
(proj (oref this subproj))
|
||||
(found nil))
|
||||
;; find it Locally.
|
||||
(setq found
|
||||
(cond ((file-exists-p (expand-file-name filename path))
|
||||
(expand-file-name filename path))
|
||||
((file-exists-p (expand-file-name (concat "include/" filename) path))
|
||||
(expand-file-name (concat "include/" filename) path))
|
||||
(t
|
||||
(while (and (not found) proj)
|
||||
(setq found (when (car proj)
|
||||
(ede-expand-filename (car proj) filename))
|
||||
proj (cdr proj)))
|
||||
found)))
|
||||
(setq found (or (ede-expand-filename-local this filename)
|
||||
(ede-expand-filename-impl-via-subproj this filename)))
|
||||
;; Use an external locate tool.
|
||||
(when (not found)
|
||||
(require 'ede/locate)
|
||||
@ -485,6 +450,30 @@ doesn't exist."
|
||||
;; Return it
|
||||
found))
|
||||
|
||||
(defmethod ede-expand-filename-local ((this ede-project) filename)
|
||||
"Expand filename locally to project THIS with filesystem tests."
|
||||
(let ((path (ede-project-root-directory this)))
|
||||
(cond ((file-exists-p (expand-file-name filename path))
|
||||
(expand-file-name filename path))
|
||||
((file-exists-p (expand-file-name (concat "include/" filename) path))
|
||||
(expand-file-name (concat "include/" filename) path)))))
|
||||
|
||||
(defmethod ede-expand-filename-impl-via-subproj ((this ede-project) filename)
|
||||
"Return a fully qualified file name based on project THIS.
|
||||
FILENAME should be just a filename which occurs in a directory controlled
|
||||
by this project."
|
||||
(let ((proj (list (ede-toplevel this)))
|
||||
(found nil))
|
||||
;; find it Locally.
|
||||
(while (and (not found) proj)
|
||||
(let ((thisproj (car proj)))
|
||||
(setq proj (append (cdr proj) (oref thisproj subproj)))
|
||||
(setq found (when thisproj
|
||||
(ede-expand-filename-local thisproj filename)))
|
||||
))
|
||||
;; Return it
|
||||
found))
|
||||
|
||||
(defmethod ede-expand-filename ((this ede-target) filename &optional force)
|
||||
"Return a fully qualified file name based on target THIS.
|
||||
FILENAME should be a filename which occurs in a directory in which THIS works.
|
||||
|
442
lisp/cedet/ede/generic.el
Normal file
442
lisp/cedet/ede/generic.el
Normal file
@ -0,0 +1,442 @@
|
||||
;;; ede/generic.el --- Base Support for generic build systems
|
||||
|
||||
;; Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric M. Ludlam <eric@siege-engine.com>
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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
|
||||
;; supporting alternate build systems in a simple way, automatically.
|
||||
;;
|
||||
;; The structure is for the ede-generic baseclass, which is augmented
|
||||
;; by simple sub-classes that can be created by users on an as needed
|
||||
;; basis. The generic system will have targets for many language
|
||||
;; types, and create the targets on an as needed basis. All
|
||||
;; sub-project types will recycle the same generic target types.
|
||||
;;
|
||||
;; The generic target types will only be implemented for languages
|
||||
;; where having EDE support actually matters, with a single MISC to
|
||||
;; represent anything else.
|
||||
;;
|
||||
;; TOO MANY PROJECTS DETECTED:
|
||||
;;
|
||||
;; If enabling ede-generic support starts identifying too many
|
||||
;; projects, drop a file called `.ede-ignore' into any directory where
|
||||
;; you do not want a project to be.
|
||||
;;
|
||||
;; Customization:
|
||||
;;
|
||||
;; Since these projects are all so increadibly 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
|
||||
;; hold the basics. Generic projects will identify and use these
|
||||
;; config files.
|
||||
;;
|
||||
;; Adding support for new projects:
|
||||
;;
|
||||
;; To add support to EDE Generic for new project types is very quick.
|
||||
;; See the end of this file for examples such as CMake and SCons.
|
||||
;;
|
||||
;; Support consists of one class for your project, specifying the file
|
||||
;; name used by the project system you want to support. It also
|
||||
;; should implement th method `ede-generic-setup-configuration' to
|
||||
;; prepopulate the configurable portion of the generic project with
|
||||
;; build details.
|
||||
;;
|
||||
;; Lastly, call `ede-generic-new-autoloader' to setup your project so
|
||||
;; EDE can use it.
|
||||
;;
|
||||
;; Adding support for new types of source code:
|
||||
;;
|
||||
;; Sources of different types are supported with a simple class which
|
||||
;; 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.
|
||||
;; The ede-generic-target-c-cpp has some example methods setting up
|
||||
;; the pre-processor map and system include path.
|
||||
;;
|
||||
;; NOTE: It is not necessary to modify ede-generic.el to add any of
|
||||
;; the above described support features.
|
||||
|
||||
(require 'eieio-opt)
|
||||
(require 'ede)
|
||||
(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")))
|
||||
)
|
||||
"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."
|
||||
;; Doesn't already exist, so lets make one.
|
||||
(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)
|
||||
))
|
||||
|
||||
;;; Base Classes for the system
|
||||
(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)
|
||||
;; 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)))
|
||||
|
||||
;;; A list of different targets
|
||||
(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.")
|
||||
|
||||
;; MISC must always be last since it will always match the file.
|
||||
(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.")
|
||||
|
||||
;;; Automatic target aquisition.
|
||||
(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)
|
||||
)
|
||||
;; Pick a matching class type.
|
||||
(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))
|
||||
;; find a pre-existing matching target
|
||||
(setq ans (ede-generic-find-matching-target cls dir targets))
|
||||
;; Create a new instance if there wasn't one
|
||||
(when (not ans)
|
||||
(setq ans (make-instance
|
||||
cls
|
||||
:name (oref cls shortname)
|
||||
:path dir
|
||||
:source nil))
|
||||
(object-add-to-list proj :targets ans)
|
||||
)
|
||||
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
|
||||
;; different projects on disk.
|
||||
(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.
|
||||
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))
|
||||
|
||||
;;;###autoload
|
||||
(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)
|
||||
)
|
||||
|
||||
|
||||
;;; SPECIFIC TYPES OF GENERIC BUILDS
|
||||
;;
|
||||
|
||||
;;; MAKEFILE
|
||||
|
||||
(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 ")
|
||||
)
|
||||
|
||||
|
||||
;;; SCONS
|
||||
(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 ")
|
||||
)
|
||||
|
||||
|
||||
;;; CMAKE
|
||||
(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)
|
||||
|
||||
;; Local variables:
|
||||
;; generated-autoload-file: "loaddefs.el"
|
||||
;; generated-autoload-load-name: "ede/generic"
|
||||
;; End:
|
||||
|
||||
;;; ede/generic.el ends here
|
@ -112,6 +112,18 @@ ROOTPROJ is nil, since there is only one project."
|
||||
)
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'ede-project-class-files
|
||||
(ede-project-autoload "linux"
|
||||
:name "LINUX ROOT"
|
||||
:file 'ede-linux
|
||||
:proj-file "scripts/ver_linux"
|
||||
:proj-root 'ede-linux-project-root
|
||||
:load-type 'ede-linux-load
|
||||
:class-sym 'ede-linux-project
|
||||
:new-p nil)
|
||||
t)
|
||||
|
||||
(defclass ede-linux-target-c (ede-target)
|
||||
()
|
||||
"EDE Linux Project target for C code.
|
||||
@ -124,7 +136,7 @@ All directories need at least one target.")
|
||||
|
||||
(defmethod initialize-instance ((this ede-linux-project)
|
||||
&rest fields)
|
||||
"Make sure the :file is fully expanded."
|
||||
"Make sure the targets slot is bound."
|
||||
(call-next-method)
|
||||
(unless (slot-boundp this 'targets)
|
||||
(oset this :targets nil)))
|
||||
|
@ -121,7 +121,7 @@ based on `ede-locate-setup-options'."
|
||||
;; Basic setup.
|
||||
(call-next-method)
|
||||
;; Make sure we have a hash table.
|
||||
(oset loc hash (make-hash-table :test 'equal))
|
||||
(ede-locate-flush-hash loc)
|
||||
)
|
||||
|
||||
(defmethod ede-locate-ok-in-project :static ((loc ede-locate-base)
|
||||
@ -129,6 +129,10 @@ based on `ede-locate-setup-options'."
|
||||
"Is it ok to use this project type under ROOT."
|
||||
t)
|
||||
|
||||
(defmethod ede-locate-flush-hash ((loc ede-locate-base))
|
||||
"For LOC, flush hashtable and start from scratch."
|
||||
(oset loc hash (make-hash-table :test 'equal)))
|
||||
|
||||
(defmethod ede-locate-file-in-hash ((loc ede-locate-base)
|
||||
filestring)
|
||||
"For LOC, is the file FILESTRING in our hashtable?"
|
||||
@ -160,6 +164,13 @@ that created this EDE locate object."
|
||||
nil
|
||||
)
|
||||
|
||||
(defmethod ede-locate-create/update-root-database :STATIC
|
||||
((loc ede-locate-base) root)
|
||||
"Create or update the database for the current project.
|
||||
You cannot create projects for the baseclass."
|
||||
(error "Cannot create/update a database of type %S"
|
||||
(object-name loc)))
|
||||
|
||||
;;; LOCATE
|
||||
;;
|
||||
;; Using the standard unix "locate" command.
|
||||
@ -242,6 +253,11 @@ that created this EDE locate object."
|
||||
(let ((default-directory (oref loc root)))
|
||||
(cedet-gnu-global-expand-filename filesubstring)))
|
||||
|
||||
(defmethod ede-locate-create/update-root-database :STATIC
|
||||
((loc ede-locate-global) root)
|
||||
"Create or update the GNU Global database for the current project."
|
||||
(cedet-gnu-global-create/update-database root))
|
||||
|
||||
;;; IDUTILS
|
||||
;;
|
||||
(defclass ede-locate-idutils (ede-locate-base)
|
||||
@ -280,6 +296,11 @@ that created this EDE locate object."
|
||||
(let ((default-directory (oref loc root)))
|
||||
(cedet-idutils-expand-filename filesubstring)))
|
||||
|
||||
(defmethod ede-locate-create/update-root-database :STATIC
|
||||
((loc ede-locate-idutils) root)
|
||||
"Create or update the GNU Global database for the current project."
|
||||
(cedet-idutils-create/update-database root))
|
||||
|
||||
;;; CSCOPE
|
||||
;;
|
||||
(defclass ede-locate-cscope (ede-locate-base)
|
||||
@ -315,6 +336,11 @@ that created this EDE locate object."
|
||||
(let ((default-directory (oref loc root)))
|
||||
(cedet-cscope-expand-filename filesubstring)))
|
||||
|
||||
(defmethod ede-locate-create/update-root-database :STATIC
|
||||
((loc ede-locate-cscope) root)
|
||||
"Create or update the GNU Global database for the current project."
|
||||
(cedet-cscope-create/update-database root))
|
||||
|
||||
(provide 'ede/locate)
|
||||
|
||||
;; Local variables:
|
||||
|
@ -126,7 +126,11 @@ don't do it. A value of nil means to just do it.")
|
||||
|
||||
(while compilation-in-progress
|
||||
(accept-process-output)
|
||||
(sit-for 1))
|
||||
;; If sit for indicates that input is waiting, then
|
||||
;; read and discard whatever it is that is going on.
|
||||
(when (not (sit-for 1))
|
||||
(read-event nil nil .1)
|
||||
))
|
||||
|
||||
(with-current-buffer "*compilation*"
|
||||
(goto-char (point-max))
|
||||
|
@ -262,6 +262,18 @@ Execute BODY in a location where a value can be placed."
|
||||
(goto-char (point-max))))
|
||||
(put 'ede-pmake-insert-variable-shared 'lisp-indent-function 1)
|
||||
|
||||
(defmacro ede-pmake-insert-variable-once (varname &rest body)
|
||||
"Add VARNAME into the current Makefile if it doesn't exist.
|
||||
Execute BODY in a location where a value can be placed."
|
||||
`(let ((addcr t) (v ,varname))
|
||||
(unless (re-search-backward (concat "^" v "\\s-*=") nil t)
|
||||
(insert v "=")
|
||||
,@body
|
||||
(if addcr (insert "\n"))
|
||||
(goto-char (point-max)))
|
||||
))
|
||||
(put 'ede-pmake-insert-variable-once 'lisp-indent-function 1)
|
||||
|
||||
;;; SOURCE VARIABLE NAME CONSTRUCTION
|
||||
|
||||
(defsubst ede-pmake-varname (obj)
|
||||
@ -369,10 +381,14 @@ NOTE: Not yet in use! This is part of an SRecode conversion of
|
||||
conf-table))
|
||||
(let* ((top "")
|
||||
(tmp this))
|
||||
;; Use relative paths for subdirs.
|
||||
(while (ede-parent-project tmp)
|
||||
(setq tmp (ede-parent-project tmp)
|
||||
top (concat "../" top)))
|
||||
(insert "\ntop=" top))
|
||||
;; If this is the top, then use CURDIR.
|
||||
(if (and (not (oref this metasubproject)) (string= top ""))
|
||||
(insert "\ntop=\"$(CURDIR)\"/")
|
||||
(insert "\ntop=" top)))
|
||||
(insert "\nede_FILES=" (file-name-nondirectory (oref this file)) " "
|
||||
(file-name-nondirectory (ede-proj-dist-makefile this)) "\n"))
|
||||
|
||||
@ -425,14 +441,13 @@ sources variable."
|
||||
(link (ede-proj-linkers this))
|
||||
(name (ede-proj-makefile-target-name this))
|
||||
(src (oref this source)))
|
||||
(ede-proj-makefile-insert-object-variables (car comp) name src)
|
||||
(dolist (obj comp)
|
||||
(ede-compiler-only-once obj
|
||||
(ede-proj-makefile-insert-variables obj)))
|
||||
(ede-proj-makefile-insert-object-variables (car comp) name src)
|
||||
(while link
|
||||
(ede-linker-only-once (car link)
|
||||
(ede-proj-makefile-insert-variables (car link)))
|
||||
(setq link (cdr link)))))
|
||||
(dolist (linker link)
|
||||
(ede-linker-only-once linker
|
||||
(ede-proj-makefile-insert-variables linker)))))
|
||||
|
||||
(defmethod ede-proj-makefile-insert-automake-pre-variables
|
||||
((this ede-proj-target))
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
(defclass ede-proj-target-makefile-archive
|
||||
(ede-proj-target-makefile-objectcode)
|
||||
((availablelinkers :initform (ede-archive-linker)))
|
||||
((availablelinkers :initform '(ede-archive-linker)))
|
||||
"This target generates an object code archive.")
|
||||
|
||||
(defvar ede-archive-linker
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
;;; Code:
|
||||
(defclass ede-proj-target-aux (ede-proj-target)
|
||||
((sourcetype :initform (ede-aux-source)))
|
||||
((sourcetype :initform '(ede-aux-source)))
|
||||
"This target consists of aux files such as READMEs and COPYING.")
|
||||
|
||||
(defvar ede-aux-source
|
||||
|
@ -36,8 +36,8 @@
|
||||
((menu :initform nil)
|
||||
(keybindings :initform nil)
|
||||
(phony :initform t)
|
||||
(sourcetype :initform (ede-source-emacs))
|
||||
(availablecompilers :initform (ede-emacs-compiler ede-xemacs-compiler))
|
||||
(sourcetype :initform '(ede-source-emacs))
|
||||
(availablecompilers :initform '(ede-emacs-compiler ede-xemacs-compiler))
|
||||
(aux-packages :initarg :aux-packages
|
||||
:initform nil
|
||||
:type list
|
||||
@ -259,7 +259,7 @@ is found, such as a `-version' variable, or the standard header."
|
||||
;; Autoload generators
|
||||
;;
|
||||
(defclass ede-proj-target-elisp-autoloads (ede-proj-target-elisp)
|
||||
((availablecompilers :initform (ede-emacs-cedet-autogen-compiler))
|
||||
((availablecompilers :initform '(ede-emacs-cedet-autogen-compiler))
|
||||
(aux-packages :initform ("cedet-autogen"))
|
||||
(phony :initform t)
|
||||
(autoload-file :initarg :autoload-file
|
||||
|
@ -31,9 +31,9 @@
|
||||
(defclass ede-proj-target-makefile-info (ede-proj-target-makefile)
|
||||
((menu :initform nil)
|
||||
(keybindings :initform nil)
|
||||
(availablecompilers :initform (ede-makeinfo-compiler
|
||||
ede-texi2html-compiler))
|
||||
(sourcetype :initform (ede-makeinfo-source))
|
||||
(availablecompilers :initform '(ede-makeinfo-compiler
|
||||
ede-texi2html-compiler))
|
||||
(sourcetype :initform '(ede-makeinfo-source))
|
||||
(mainmenu :initarg :mainmenu
|
||||
:initform ""
|
||||
:type string
|
||||
|
@ -35,8 +35,8 @@
|
||||
|
||||
;; FIXME this isn't how you spell "miscellaneous". :(
|
||||
(defclass ede-proj-target-makefile-miscelaneous (ede-proj-target-makefile)
|
||||
((sourcetype :initform (ede-misc-source))
|
||||
(availablecompilers :initform (ede-misc-compile))
|
||||
((sourcetype :initform '(ede-misc-source))
|
||||
(availablecompilers :initform '(ede-misc-compile))
|
||||
(submakefile :initarg :submakefile
|
||||
:initform ""
|
||||
:type string
|
||||
|
@ -39,28 +39,32 @@
|
||||
(configuration-variables :initform ("debug" . (("CFLAGS" . "-g")
|
||||
("LDFLAGS" . "-g"))))
|
||||
;; @TODO - add an include path.
|
||||
(availablecompilers :initform (ede-gcc-compiler
|
||||
ede-g++-compiler
|
||||
ede-gfortran-compiler
|
||||
ede-gfortran-module-compiler
|
||||
;; More C and C++ compilers, plus
|
||||
;; fortran or pascal can be added here
|
||||
))
|
||||
(availablelinkers :initform (ede-g++-linker
|
||||
ede-cc-linker
|
||||
ede-gfortran-linker
|
||||
ede-ld-linker
|
||||
;; Add more linker thingies here.
|
||||
))
|
||||
(sourcetype :initform (ede-source-c
|
||||
ede-source-c++
|
||||
ede-source-f77
|
||||
ede-source-f90
|
||||
;; ede-source-other
|
||||
;; This object should take everything that
|
||||
;; gets compiled into objects like fortran
|
||||
;; and pascal.
|
||||
))
|
||||
(availablecompilers :initform '(ede-gcc-compiler
|
||||
ede-g++-compiler
|
||||
ede-gfortran-compiler
|
||||
ede-gfortran-module-compiler
|
||||
ede-lex-compiler
|
||||
ede-yacc-compiler
|
||||
;; More C and C++ compilers, plus
|
||||
;; fortran or pascal can be added here
|
||||
))
|
||||
(availablelinkers :initform '(ede-g++-linker
|
||||
ede-cc-linker
|
||||
ede-ld-linker
|
||||
ede-gfortran-linker
|
||||
;; Add more linker thingies here.
|
||||
))
|
||||
(sourcetype :initform '(ede-source-c
|
||||
ede-source-c++
|
||||
ede-source-f77
|
||||
ede-source-f90
|
||||
ede-source-lex
|
||||
ede-source-yacc
|
||||
;; ede-source-other
|
||||
;; This object should take everything that
|
||||
;; gets compiled into objects like fortran
|
||||
;; and pascal.
|
||||
))
|
||||
)
|
||||
"Abstract class for Makefile based object code generating targets.
|
||||
Belonging to this group assumes you could make a .o from an element source
|
||||
@ -115,15 +119,15 @@ file.")
|
||||
:name "cc"
|
||||
:sourcetype '(ede-source-c)
|
||||
:variables '(("C_LINK" . "$(CC) $(CFLAGS) $(LDFLAGS) -L."))
|
||||
:commands '("$(C_LINK) -o $@ $^")
|
||||
:commands '("$(C_LINK) -o $@ $^ $(LDDEPS)")
|
||||
:objectextention "")
|
||||
"Linker for C sourcecode.")
|
||||
|
||||
(defvar ede-source-c++
|
||||
(ede-sourcecode "ede-source-c++"
|
||||
:name "C++"
|
||||
:sourcepattern "\\.\\(cpp\\|cc\\|cxx\\)$"
|
||||
:auxsourcepattern "\\.\\(hpp\\|hh?\\|hxx\\)$"
|
||||
:sourcepattern "\\.\\(c\\(pp?\\|c\\|xx\\|++\\)\\|C\\\(PP\\)?\\)$"
|
||||
:auxsourcepattern "\\.\\(hpp?\\|hh?\\|hxx\\|H\\)$"
|
||||
:garbagepattern '("*.o" "*.obj" ".deps/*.P" ".lo"))
|
||||
"C++ source code definition.")
|
||||
|
||||
@ -158,11 +162,43 @@ file.")
|
||||
;; Only use this linker when c++ exists.
|
||||
:sourcetype '(ede-source-c++)
|
||||
:variables '(("CXX_LINK" . "$(CXX) $(CFLAGS) $(LDFLAGS) -L."))
|
||||
:commands '("$(CXX_LINK) -o $@ $^")
|
||||
:commands '("$(CXX_LINK) -o $@ $^ $(LDDEPS)")
|
||||
:autoconf '("AC_PROG_CXX")
|
||||
:objectextention "")
|
||||
"Linker needed for c++ programs.")
|
||||
|
||||
;;; LEX
|
||||
(defvar ede-source-lex
|
||||
(ede-sourcecode "ede-source-lex"
|
||||
:name "lex"
|
||||
:sourcepattern "\\.l\\(l\\|pp\\|++\\)")
|
||||
"Lex source code definition.
|
||||
No garbage pattern since it creates C or C++ code.")
|
||||
|
||||
(defvar ede-lex-compiler
|
||||
(ede-object-compiler
|
||||
"ede-lex-compiler"
|
||||
;; Can we support regular makefiles too??
|
||||
:autoconf '("AC_PROG_LEX")
|
||||
:sourcetype '(ede-source-lex))
|
||||
"Compiler used for Lexical source.")
|
||||
|
||||
;;; YACC
|
||||
(defvar ede-source-yacc
|
||||
(ede-sourcecode "ede-source-yacc"
|
||||
:name "yacc"
|
||||
:sourcepattern "\\.y\\(y\\|pp\\|++\\)")
|
||||
"Yacc source code definition.
|
||||
No garbage pattern since it creates C or C++ code.")
|
||||
|
||||
(defvar ede-yacc-compiler
|
||||
(ede-object-compiler
|
||||
"ede-yacc-compiler"
|
||||
;; Can we support regular makefiles too??
|
||||
:autoconf '("AC_PROG_YACC")
|
||||
:sourcetype '(ede-source-yacc))
|
||||
"Compiler used for yacc/bison grammar files source.")
|
||||
|
||||
;;; Fortran Compiler/Linker
|
||||
;;
|
||||
;; Contributed by David Engster
|
||||
@ -233,7 +269,7 @@ file.")
|
||||
:name "ld"
|
||||
:variables '(("LD" . "ld")
|
||||
("LD_LINK" . "$(LD) $(LDFLAGS) -L."))
|
||||
:commands '("$(LD_LINK) -o $@ $^")
|
||||
:commands '("$(LD_LINK) -o $@ $^ $(LDDEPS)")
|
||||
:objectextention "")
|
||||
"Linker needed for c++ programs.")
|
||||
|
||||
|
@ -34,14 +34,14 @@
|
||||
;;; Code:
|
||||
(defclass ede-proj-target-makefile-program
|
||||
(ede-proj-target-makefile-objectcode)
|
||||
((ldlibs :initarg :ldlibs
|
||||
:initform nil
|
||||
:type list
|
||||
:custom (repeat (string :tag "Library"))
|
||||
:documentation
|
||||
"Libraries, such as \"m\" or \"Xt\" which this program depends on.
|
||||
The linker flag \"-l\" is automatically prepended. Do not include a \"lib\"
|
||||
prefix, or a \".so\" suffix.
|
||||
((ldlibs-local :initarg :ldlibs-local
|
||||
:initform nil
|
||||
:type list
|
||||
:custom (repeat (string :tag "Local Library"))
|
||||
:documentation
|
||||
"Libraries that are part of this project.
|
||||
The full path to these libraries should be specified, such as:
|
||||
../lib/libMylib.la or ../ar/myArchive.a
|
||||
|
||||
Note: Currently only used for Automake projects."
|
||||
)
|
||||
@ -51,10 +51,21 @@ Note: Currently only used for Automake projects."
|
||||
:custom (repeat (string :tag "Link Flag"))
|
||||
:documentation
|
||||
"Additional flags to add when linking this target.
|
||||
Use ldlibs to add addition libraries. Use this to specify specific
|
||||
options to the linker.
|
||||
Use this to specify specific options to the linker.
|
||||
A Common use may be to add -L to specify in-project locations of libraries
|
||||
specified with ldlibs.")
|
||||
(ldlibs :initarg :ldlibs
|
||||
:initform nil
|
||||
:type list
|
||||
:custom (repeat (string :tag "Library"))
|
||||
:documentation
|
||||
"Libraries, such as \"m\" or \"Xt\" which this program depends on.
|
||||
The linker flag \"-l\" is automatically prepended. Do not include a \"lib\"
|
||||
prefix, or a \".so\" suffix.
|
||||
Use the 'ldflags' slot to specify where in-project libraries might be.
|
||||
|
||||
Note: Not currently used. This bug needs to be fixed.")
|
||||
Note: Currently only used for Automake projects."
|
||||
)
|
||||
)
|
||||
"This target is an executable program.")
|
||||
|
||||
@ -70,27 +81,24 @@ Note: Not currently used. This bug needs to be fixed.")
|
||||
"Insert bin_PROGRAMS variables needed by target THIS."
|
||||
(ede-pmake-insert-variable-shared
|
||||
(concat (ede-name this) "_LDADD")
|
||||
(mapc (lambda (c) (insert " -l" c)) (oref this ldlibs)))
|
||||
;; For other targets THIS depends on
|
||||
;;
|
||||
;; NOTE: FIX THIS
|
||||
;;
|
||||
;;(ede-pmake-insert-variable-shared
|
||||
;; (concat (ede-name this) "_DEPENDENCIES")
|
||||
;; (mapcar (lambda (d) (insert d)) (oref this FOOOOOOOO)))
|
||||
(mapc (lambda (l) (insert " " l)) (oref this ldlibs-local))
|
||||
(mapc (lambda (c) (insert " " c)) (oref this ldflags))
|
||||
(when (oref this ldlibs)
|
||||
(mapc (lambda (d) (insert " -l" d)) (oref this ldlibs)))
|
||||
)
|
||||
(call-next-method))
|
||||
|
||||
(defmethod ede-proj-makefile-insert-rules ((this ede-proj-target-makefile-program))
|
||||
"Insert rules needed by THIS target."
|
||||
(let ((ede-proj-compiler-object-linkflags
|
||||
(mapconcat 'identity (oref this ldflags) " ")))
|
||||
(defmethod ede-proj-makefile-insert-variables ((this ede-proj-target-makefile-program))
|
||||
"Insert variables needed by the compiler THIS."
|
||||
(call-next-method)
|
||||
(let ((lf (mapconcat 'identity (oref this ldflags) " ")))
|
||||
(with-slots (ldlibs) this
|
||||
(if ldlibs
|
||||
(setq ede-proj-compiler-object-linkflags
|
||||
(concat ede-proj-compiler-object-linkflags
|
||||
" -l"
|
||||
(mapconcat 'identity ldlibs " -l")))))
|
||||
(call-next-method)))
|
||||
(setq lf
|
||||
(concat lf " -l" (mapconcat 'identity ldlibs " -l")))))
|
||||
;; LDFLAGS as needed.
|
||||
(when (and lf (not (string= "" lf)))
|
||||
(ede-pmake-insert-variable-once "LDDEPS" (insert lf)))))
|
||||
|
||||
(defmethod project-debug-target ((obj ede-proj-target-makefile-program))
|
||||
"Debug a program target OBJ."
|
||||
|
@ -34,15 +34,15 @@
|
||||
;;; Code:
|
||||
(defclass ede-proj-target-makefile-shared-object
|
||||
(ede-proj-target-makefile-program)
|
||||
((availablecompilers :initform (ede-gcc-libtool-shared-compiler
|
||||
;;ede-gcc-shared-compiler
|
||||
ede-g++-libtool-shared-compiler
|
||||
;;ede-g++-shared-compiler
|
||||
))
|
||||
(availablelinkers :initform (ede-cc-linker-libtool
|
||||
ede-g++-linker-libtool
|
||||
;; Add more linker thingies here.
|
||||
))
|
||||
((availablecompilers :initform '(ede-gcc-libtool-shared-compiler
|
||||
;;ede-gcc-shared-compiler
|
||||
ede-g++-libtool-shared-compiler
|
||||
;;ede-g++-shared-compiler
|
||||
))
|
||||
(availablelinkers :initform '(ede-cc-linker-libtool
|
||||
ede-g++-linker-libtool
|
||||
;; Add more linker thingies here.
|
||||
))
|
||||
(ldflags :custom (repeat (string :tag "Libtool flag"))
|
||||
:documentation
|
||||
"Additional flags to add when linking this shared library.
|
||||
@ -124,7 +124,7 @@ Use ldlibs to add addition libraries.")
|
||||
:rules (list (ede-makefile-rule
|
||||
"c++-inference-rule-libtool"
|
||||
:target "%.o"
|
||||
:dependencies "%.c"
|
||||
:dependencies "%.cpp"
|
||||
:rules '("@echo '$(LTCOMPILE) -o $@ $<'; \\"
|
||||
"$(LTCOMPILE) -o $@ $<"
|
||||
)
|
||||
|
@ -29,7 +29,6 @@
|
||||
;; rebuild. The targets provided in ede-proj can be augmented with
|
||||
;; additional target types inherited directly from `ede-proj-target'.
|
||||
|
||||
;; (eval-and-compile '(require 'ede))
|
||||
(require 'ede/proj-comp)
|
||||
(require 'ede/make)
|
||||
|
||||
@ -336,7 +335,9 @@ Argument TARGET is the project we are completing customization on."
|
||||
(or (string= (file-name-nondirectory (oref this file)) f)
|
||||
(string= (ede-proj-dist-makefile this) f)
|
||||
(string-match "Makefile\\(\\.\\(in\\|am\\)\\)?$" f)
|
||||
(string-match "config\\(ure\\.in\\|\\.stutus\\)?$" f)
|
||||
(string-match "config\\(ure\\.\\(in\\|ac\\)\\|\\.status\\)?$" f)
|
||||
(string-match "config.h\\(\\.in\\)?" f)
|
||||
(member f '("AUTHORS" "NEWS" "COPYING" "INSTALL" "README"))
|
||||
)))
|
||||
|
||||
(defmethod ede-buffer-mine ((this ede-proj-target) buffer)
|
||||
@ -398,11 +399,11 @@ Argument TARGET is the project we are completing customization on."
|
||||
:source nil)))
|
||||
|
||||
(defmethod project-delete-target ((this ede-proj-target))
|
||||
"Delete the current target THIS from it's parent project."
|
||||
"Delete the current target THIS from its parent project."
|
||||
(let ((p (ede-current-project))
|
||||
(ts (oref this source)))
|
||||
;; Loop across all sources. If it exists in a buffer,
|
||||
;; clear it's object.
|
||||
;; clear its object.
|
||||
(while ts
|
||||
(let* ((default-directory (oref this path))
|
||||
(b (get-file-buffer (car ts))))
|
||||
@ -413,7 +414,7 @@ Argument TARGET is the project we are completing customization on."
|
||||
(setq ede-object nil)
|
||||
(ede-apply-object-keymap))))))
|
||||
(setq ts (cdr ts)))
|
||||
;; Remove THIS from it's parent.
|
||||
;; Remove THIS from its parent.
|
||||
;; The two vectors should be pointer equivalent.
|
||||
(oset p targets (delq this (oref p targets)))
|
||||
(ede-proj-save (ede-current-project))))
|
||||
@ -447,15 +448,13 @@ FILE must be massaged by `ede-convert-path'."
|
||||
|
||||
(defmethod project-make-dist ((this ede-proj-project))
|
||||
"Build a distribution for the project based on THIS target."
|
||||
;; I'm a lazy bum, so I'll make a makefile for doing this sort
|
||||
;; of thing, and rely only on that small section of code.
|
||||
(let ((pm (ede-proj-dist-makefile this))
|
||||
(df (project-dist-files this)))
|
||||
(if (and (file-exists-p (car df))
|
||||
(not (y-or-n-p "Dist file already exists. Rebuild? ")))
|
||||
(error "Try `ede-update-version' before making a distribution"))
|
||||
(ede-proj-setup-buildenvironment this)
|
||||
(if (string= (file-name-nondirectory pm) "Makefile.am")
|
||||
(if (ede-proj-automake-p this)
|
||||
(setq pm (expand-file-name "Makefile"
|
||||
(file-name-directory pm))))
|
||||
(compile (concat ede-make-command " -f " pm " dist"))))
|
||||
@ -473,7 +472,7 @@ Argument COMMAND is the command to use when compiling."
|
||||
(let ((pm (ede-proj-dist-makefile proj))
|
||||
(default-directory (file-name-directory (oref proj file))))
|
||||
(ede-proj-setup-buildenvironment proj)
|
||||
(if (string= (file-name-nondirectory pm) "Makefile.am")
|
||||
(if (ede-proj-automake-p proj)
|
||||
(setq pm (expand-file-name "Makefile"
|
||||
(file-name-directory pm))))
|
||||
(compile (concat ede-make-command" -f " pm " all"))))
|
||||
@ -539,7 +538,15 @@ Converts all symbols into the objects to be used."
|
||||
(if (ede-want-any-source-files-p (symbol-value (car st)) sources)
|
||||
(let ((c (ede-proj-find-compiler avail (car st))))
|
||||
(if c (setq comp (cons c comp)))))
|
||||
(setq st (cdr st)))))
|
||||
(setq st (cdr st)))
|
||||
;; Provide a good error msg.
|
||||
(unless comp
|
||||
(error "Could not find compiler match for source code extension \"%s\".
|
||||
You may need to add support for this type of file."
|
||||
(if sources
|
||||
(file-name-extension (car sources))
|
||||
"")))
|
||||
))
|
||||
;; Return the disovered compilers
|
||||
comp)))
|
||||
|
||||
@ -664,18 +671,9 @@ Optional argument FORCE will force items to be regenerated."
|
||||
(let ((root (or (ede-project-root this) this))
|
||||
)
|
||||
(setq ede-projects (delq root ede-projects))
|
||||
(ede-proj-load (ede-project-root-directory root))
|
||||
(ede-load-project-file (ede-project-root-directory root))
|
||||
))
|
||||
|
||||
(defmethod project-rescan ((this ede-proj-target) readstream)
|
||||
"Rescan target THIS from the read list READSTREAM."
|
||||
(setq readstream (cdr (cdr readstream))) ;; constructor/name
|
||||
(while readstream
|
||||
(let ((tag (car readstream))
|
||||
(val (car (cdr readstream))))
|
||||
(eieio-oset this tag val))
|
||||
(setq readstream (cdr (cdr readstream)))))
|
||||
|
||||
(provide 'ede/proj)
|
||||
|
||||
;; arch-tag: eb8a40f8-0d2c-41c4-b273-af04101d1cdf
|
||||
|
@ -30,27 +30,19 @@
|
||||
;; fashion.
|
||||
;;
|
||||
;; project-am uses the structure defined in all good GNU projects with
|
||||
;; the Automake file as it's base template, and then maintains that
|
||||
;; the Automake file as its base template, and then maintains that
|
||||
;; information during edits, automatically updating the automake file
|
||||
;; where appropriate.
|
||||
|
||||
|
||||
;; (eval-and-compile
|
||||
;; ;; Compatibility for makefile mode.
|
||||
;; (condition-case nil
|
||||
;; (require 'makefile "make-mode")
|
||||
;; (error (require 'make-mode "make-mode")))
|
||||
|
||||
;; ;; Requiring the .el files prevents incomplete builds.
|
||||
;; (require 'eieio "eieio.el")
|
||||
;; (require 'ede "ede.el"))
|
||||
|
||||
(require 'make-mode)
|
||||
(require 'ede)
|
||||
(require 'ede/make)
|
||||
(require 'ede/makefile-edit)
|
||||
(require 'semantic/find) ;; for semantic-find-tags-by-...
|
||||
(require 'ede/autoconf-edit)
|
||||
|
||||
(declare-function autoconf-parameters-for-macro "ede/autoconf-edit")
|
||||
(declare-function ede-shell-run-something "ede/shell")
|
||||
(eval-when-compile (require 'compile))
|
||||
|
||||
;;; Code:
|
||||
@ -104,7 +96,7 @@
|
||||
;; ("ltlibcustom" project-am-lib ".*?_LTLIBRARIES" t)
|
||||
)
|
||||
"Alist of type names and the type of object to create for them.
|
||||
Each entry is of th form:
|
||||
Each entry is of the form:
|
||||
(EMACSNAME CLASS AUTOMAKEVAR INDIRECT)
|
||||
where EMACSNAME is a name for Emacs to use.
|
||||
CLASS is the EDE target class to represent the target.
|
||||
@ -113,6 +105,23 @@ AUTOMAKEVAR is the Automake variable to identify. This cannot be a
|
||||
INDIRECT is optional. If it is non-nil, then the variable in
|
||||
question lists other variables that need to be looked up.")
|
||||
|
||||
|
||||
(defconst project-am-meta-type-alist
|
||||
'((project-am-program "_PROGRAMS$" t)
|
||||
(project-am-lib "_\\(LIBS\\|LIBRARIES\\|LTLIBRARIES\\)$" t)
|
||||
|
||||
;; direct primary target use a dummy object (man target)
|
||||
;; update to: * 3.3 Uniform in automake-1.11 info node.
|
||||
(project-am-man "_\\(DATA\\|HEADERS\\|PYTHON\\|JAVA\\|SCRIPTS\\|MANS\\|TEXINFOS\\)$" nil)
|
||||
)
|
||||
"Alist of meta-target type, each entry has form:
|
||||
(CLASS REGEXPVAR INDIRECT)
|
||||
where CLASS is the EDE target class for target.
|
||||
REGEXPVAR is the regexp used in `semantic-find-tags-by-name-regexp'.
|
||||
INDIRECT is optional. If it is non-nil, then the variable in it have
|
||||
other meta-variable based on this name.")
|
||||
|
||||
|
||||
(defclass project-am-target (ede-target)
|
||||
nil
|
||||
"Base target class for everything in project-am.")
|
||||
@ -291,16 +300,6 @@ buffer being in order to provide a smart default target type."
|
||||
;; Rescan the object in this makefile.
|
||||
(project-rescan ede-object))))
|
||||
|
||||
;(defun project-am-rescan-toplevel ()
|
||||
; "Rescan all projects in which the current buffer resides."
|
||||
; (interactive)
|
||||
; (let* ((tlof (project-am-find-topmost-level default-directory))
|
||||
; (tlo (project-am-load tlof))
|
||||
; (ede-deep-rescan t)) ; scan deep in this case.
|
||||
; ;; tlo is the top level object for whatever file we are in
|
||||
; ;; or nil. If we have an object, call the rescan method.
|
||||
; (if tlo (project-am-rescan tlo))))
|
||||
|
||||
;;
|
||||
;; NOTE TO SELF
|
||||
;;
|
||||
@ -404,6 +403,7 @@ Argument COMMAND is the command to use for compiling the target."
|
||||
|
||||
(defmethod project-run-target ((obj project-am-objectcode))
|
||||
"Run the current project target in comint buffer."
|
||||
(require 'ede/shell)
|
||||
(let ((tb (get-buffer-create " *padt*"))
|
||||
(dd (oref obj path))
|
||||
(cmd nil))
|
||||
@ -427,45 +427,17 @@ Argument COMMAND is the command to use for compiling the target."
|
||||
|
||||
;;; Project loading and saving
|
||||
;;
|
||||
(defun project-am-load (project &optional rootproj)
|
||||
"Read an automakefile PROJECT into our data structure.
|
||||
Make sure that the tree down to our makefile is complete so that there
|
||||
is cohesion in the project. Return the project file (or sub-project).
|
||||
(defun project-am-load (directory &optional rootproj)
|
||||
"Read an automakefile DIRECTORY into our data structure.
|
||||
If a given set of projects has already been loaded, then do nothing
|
||||
but return the project for the directory given.
|
||||
Optional ROOTPROJ is the root EDE project."
|
||||
;; @TODO - rationalize this to the newer EDE way of doing things.
|
||||
(setq project (expand-file-name project))
|
||||
(let* ((ede-constructing t)
|
||||
(fn (project-am-find-topmost-level (file-name-as-directory project)))
|
||||
(amo nil)
|
||||
(trimmed (if (string-match (regexp-quote fn)
|
||||
project)
|
||||
(replace-match "" t t project)
|
||||
""))
|
||||
(subdir nil))
|
||||
(setq amo (object-assoc (expand-file-name "Makefile.am" fn)
|
||||
'file ede-projects))
|
||||
(if amo
|
||||
(error "Synchronous error in ede/project-am objects")
|
||||
(let ((project-am-constructing t))
|
||||
(setq amo (project-am-load-makefile fn))))
|
||||
(if (not amo)
|
||||
nil
|
||||
;; Now scan down from amo, and find the current directory
|
||||
;; from the PROJECT file.
|
||||
(while (< 0 (length trimmed))
|
||||
(if (string-match "\\([a-zA-Z0-9.-]+\\)/" trimmed)
|
||||
(setq subdir (match-string 0 trimmed)
|
||||
trimmed (replace-match "" t t trimmed))
|
||||
(error "Error scanning down path for project"))
|
||||
(setq amo (project-am-subtree
|
||||
amo
|
||||
(expand-file-name "Makefile.am"
|
||||
(expand-file-name subdir fn)))
|
||||
fn (expand-file-name subdir fn)))
|
||||
amo)
|
||||
))
|
||||
(let* ((ede-constructiong t)
|
||||
(amo (object-assoc (expand-file-name "Makefile.am" directory)
|
||||
'file ede-projects)))
|
||||
(when (not amo)
|
||||
(setq amo (project-am-load-makefile directory)))
|
||||
amo))
|
||||
|
||||
(defun project-am-find-topmost-level (dir)
|
||||
"Find the topmost automakefile starting with DIR."
|
||||
@ -486,17 +458,19 @@ Kill the makefile if it was not loaded before the load."
|
||||
(fb nil)
|
||||
(kb (get-file-buffer fn)))
|
||||
(if (not (file-exists-p fn))
|
||||
nil
|
||||
(save-excursion
|
||||
(if kb (setq fb kb)
|
||||
;; We need to find-file this thing, but don't use
|
||||
;; any semantic features.
|
||||
(let ((semantic-init-hook nil))
|
||||
(setq fb (find-file-noselect fn)))
|
||||
)
|
||||
(set-buffer fb)
|
||||
(prog1 ,@forms
|
||||
(if (not kb) (kill-buffer (current-buffer))))))))
|
||||
nil
|
||||
(save-excursion
|
||||
(if kb (setq fb kb)
|
||||
;; We need to find-file this thing, but don't use
|
||||
;; any semantic features.
|
||||
(let ((semantic-init-hook nil)
|
||||
(recentf-exclude '( (lambda (f) t) ))
|
||||
)
|
||||
(setq fb (find-file-noselect fn)))
|
||||
)
|
||||
(set-buffer fb)
|
||||
(prog1 ,@forms
|
||||
(if (not kb) (kill-buffer (current-buffer))))))))
|
||||
(put 'project-am-with-makefile-current 'lisp-indent-function 1)
|
||||
|
||||
(add-hook 'edebug-setup-hook
|
||||
@ -505,14 +479,18 @@ Kill the makefile if it was not loaded before the load."
|
||||
(form def-body))))
|
||||
|
||||
|
||||
(defun project-am-load-makefile (path)
|
||||
(defun project-am-load-makefile (path &optional suggestedname)
|
||||
"Convert PATH into a project Makefile, and return its project object.
|
||||
It does not check for existing project objects. Use `project-am-load'."
|
||||
It does not check for existing project objects. Use `project-am-load'.
|
||||
Optional argument SUGGESTEDNAME will be the project name.
|
||||
This is used when subprojects are made in named subdirectories."
|
||||
(project-am-with-makefile-current path
|
||||
(if (and ede-object (project-am-makefile-p ede-object))
|
||||
ede-object
|
||||
(let* ((pi (project-am-package-info path))
|
||||
(pn (or (nth 0 pi) (project-am-last-dir fn)))
|
||||
(sfn (when suggestedname
|
||||
(project-am-last-dir suggestedname)))
|
||||
(pn (or sfn (nth 0 pi) (project-am-last-dir fn)))
|
||||
(ver (or (nth 1 pi) "0.0"))
|
||||
(bug (nth 2 pi))
|
||||
(cof (nth 3 pi))
|
||||
@ -530,21 +508,6 @@ It does not check for existing project objects. Use `project-am-load'."
|
||||
ampf))))
|
||||
|
||||
;;; Methods:
|
||||
(defmethod ede-find-target ((amf project-am-makefile) buffer)
|
||||
"Fetch the target belonging to BUFFER."
|
||||
(or (call-next-method)
|
||||
(let ((targ (oref amf targets))
|
||||
(sobj (oref amf subproj))
|
||||
(obj nil))
|
||||
(while (and targ (not obj))
|
||||
(if (ede-buffer-mine (car targ) buffer)
|
||||
(setq obj (car targ)))
|
||||
(setq targ (cdr targ)))
|
||||
(while (and sobj (not obj))
|
||||
(setq obj (project-am-buffer-object (car sobj) buffer)
|
||||
sobj (cdr sobj)))
|
||||
obj)))
|
||||
|
||||
(defmethod project-targets-for-file ((proj project-am-makefile))
|
||||
"Return a list of targets the project PROJ."
|
||||
(oref proj targets))
|
||||
@ -554,44 +517,110 @@ It does not check for existing project objects. Use `project-am-load'."
|
||||
CURRPROJ is the current project being scanned.
|
||||
DIR is the directory to apply to new targets."
|
||||
(let* ((otargets (oref currproj targets))
|
||||
;; `ntargets' results in complete targets list
|
||||
;; not only the new targets by diffing.
|
||||
(ntargets nil)
|
||||
(tmp nil)
|
||||
)
|
||||
(mapc
|
||||
;; Map all the different types
|
||||
(lambda (typecar)
|
||||
(let ((macro (nth 2 typecar))
|
||||
(class (nth 1 typecar))
|
||||
(indirect (nth 3 typecar))
|
||||
;(name (car typecar))
|
||||
)
|
||||
(if indirect
|
||||
;; Map all the found objects
|
||||
(mapc (lambda (lstcar)
|
||||
(setq tmp (object-assoc lstcar 'name otargets))
|
||||
(when (not tmp)
|
||||
(setq tmp (apply class lstcar :name lstcar
|
||||
:path dir nil)))
|
||||
(project-rescan tmp)
|
||||
(setq ntargets (cons tmp ntargets)))
|
||||
(makefile-macro-file-list macro))
|
||||
;; Non-indirect will have a target whos sources
|
||||
;; are actual files, not names of other targets.
|
||||
(let ((files (makefile-macro-file-list macro)))
|
||||
(when files
|
||||
(setq tmp (object-assoc macro 'name otargets))
|
||||
(when (not tmp)
|
||||
(setq tmp (apply class macro :name macro
|
||||
:path dir nil)))
|
||||
(project-rescan tmp)
|
||||
(setq ntargets (cons tmp ntargets))
|
||||
))
|
||||
)
|
||||
))
|
||||
project-am-type-alist)
|
||||
ntargets))
|
||||
|
||||
(defmethod project-rescan ((this project-am-makefile))
|
||||
(mapc
|
||||
;; Map all the different types
|
||||
(lambda (typecar)
|
||||
(let ((macro (nth 2 typecar))
|
||||
(class (nth 1 typecar))
|
||||
(indirect (nth 3 typecar))
|
||||
)
|
||||
(if indirect
|
||||
;; Map all the found objects
|
||||
(mapc (lambda (lstcar)
|
||||
(setq tmp (object-assoc lstcar 'name otargets))
|
||||
(when (not tmp)
|
||||
(setq tmp (apply class lstcar :name lstcar
|
||||
:path dir nil)))
|
||||
(project-rescan tmp)
|
||||
(setq ntargets (cons tmp ntargets)))
|
||||
(makefile-macro-file-list macro))
|
||||
;; Non-indirect will have a target whos sources
|
||||
;; are actual files, not names of other targets.
|
||||
(let ((files (makefile-macro-file-list macro)))
|
||||
(when files
|
||||
(setq tmp (object-assoc macro 'name otargets))
|
||||
(when (not tmp)
|
||||
(setq tmp (apply class macro :name macro
|
||||
:path dir nil)))
|
||||
(project-rescan tmp)
|
||||
(setq ntargets (cons tmp ntargets))
|
||||
))
|
||||
)
|
||||
))
|
||||
project-am-type-alist)
|
||||
|
||||
;; At now check variables for meta-target regexp
|
||||
;; We have to check ntargets to avoid useless rescan.
|
||||
;; Also we have check otargets to prevent duplication.
|
||||
(mapc
|
||||
(lambda (typecar)
|
||||
(let ((class (nth 0 typecar))
|
||||
(metaregex (nth 1 typecar))
|
||||
(indirect (nth 2 typecar)))
|
||||
(if indirect
|
||||
;; Map all the found objects
|
||||
(mapc
|
||||
(lambda (lstcar)
|
||||
(unless (object-assoc lstcar 'name ntargets)
|
||||
(or
|
||||
(setq tmp (object-assoc lstcar 'name otargets))
|
||||
(setq tmp (apply class lstcar :name lstcar
|
||||
:path dir nil)))
|
||||
(project-rescan tmp)
|
||||
(setq ntargets (cons tmp ntargets))))
|
||||
;; build a target list to map over
|
||||
(let (atargets)
|
||||
(dolist (TAG
|
||||
(semantic-find-tags-by-name-regexp
|
||||
metaregex (semantic-find-tags-by-class
|
||||
'variable (semantic-fetch-tags))))
|
||||
;; default-value have to be a list
|
||||
(when (cadr (assoc ':default-value TAG))
|
||||
(setq atargets
|
||||
(append
|
||||
(nreverse (cadr (assoc ':default-value TAG)))
|
||||
atargets))))
|
||||
(nreverse atargets)))
|
||||
|
||||
;; else not indirect, TODO: FIX various direct meta type in a sane way.
|
||||
(dolist (T (semantic-find-tags-by-name-regexp
|
||||
metaregex (semantic-find-tags-by-class
|
||||
'variable (semantic-fetch-tags))))
|
||||
(unless (setq tmp (object-assoc (car T) 'name ntargets))
|
||||
(or (setq tmp (object-assoc (car T) 'name otargets))
|
||||
;; we are really new
|
||||
(setq tmp (apply class (car T) :name (car T)
|
||||
:path dir nil)))
|
||||
(project-rescan tmp)
|
||||
(setq ntargets (cons tmp ntargets))))
|
||||
)))
|
||||
project-am-meta-type-alist)
|
||||
ntargets))
|
||||
|
||||
(defun project-am-expand-subdirlist (place subdirs)
|
||||
"Store in PLACE the SUBDIRS expanded from variables.
|
||||
Strip out duplicates, and recurse on variables."
|
||||
(mapc (lambda (sp)
|
||||
(let ((var (makefile-extract-varname-from-text sp)))
|
||||
(if var
|
||||
;; If it is a variable, expand that variable, and keep going.
|
||||
(project-am-expand-subdirlist
|
||||
place (makefile-macro-file-list var))
|
||||
;; Else, add SP in if it isn't a dup.
|
||||
(if (member sp (symbol-value place))
|
||||
nil ; don't do it twice.
|
||||
(set place (cons sp (symbol-value place))) ;; add
|
||||
))))
|
||||
subdirs)
|
||||
)
|
||||
|
||||
(defmethod project-rescan ((this project-am-makefile) &optional suggestedname)
|
||||
"Rescan the makefile for all targets and sub targets."
|
||||
(project-am-with-makefile-current (file-name-directory (oref this file))
|
||||
;;(message "Scanning %s..." (oref this file))
|
||||
@ -601,10 +630,10 @@ DIR is the directory to apply to new targets."
|
||||
(bug (nth 2 pi))
|
||||
(cof (nth 3 pi))
|
||||
(osubproj (oref this subproj))
|
||||
(csubproj (or
|
||||
;; If DIST_SUBDIRS doesn't exist, then go for the
|
||||
;; static list of SUBDIRS. The DIST version should
|
||||
;; contain SUBDIRS plus extra stuff.
|
||||
;; 1/30/10 - We need to append these two lists together,
|
||||
;; then strip out duplicates. Expanding this list (via
|
||||
;; references to other variables should also strip out dups
|
||||
(csubproj (append
|
||||
(makefile-macro-file-list "DIST_SUBDIRS")
|
||||
(makefile-macro-file-list "SUBDIRS")))
|
||||
(csubprojexpanded nil)
|
||||
@ -615,79 +644,57 @@ DIR is the directory to apply to new targets."
|
||||
(tmp nil)
|
||||
(ntargets (project-am-scan-for-targets this dir))
|
||||
)
|
||||
|
||||
(and pn (string= (directory-file-name
|
||||
(oref this directory))
|
||||
(directory-file-name
|
||||
(project-am-find-topmost-level
|
||||
(oref this directory))))
|
||||
(oset this name pn)
|
||||
(and pv (oset this version pv))
|
||||
(and bug (oset this mailinglist bug))
|
||||
(oset this configureoutputfiles cof))
|
||||
|
||||
; ;; LISP is different. Here there is only one kind of lisp (that I know of
|
||||
; ;; anyway) so it doesn't get mapped when it is found.
|
||||
; (if (makefile-move-to-macro "lisp_LISP")
|
||||
; (let ((tmp (project-am-lisp "lisp"
|
||||
; :name "lisp"
|
||||
; :path dir)))
|
||||
; (project-rescan tmp)
|
||||
; (setq ntargets (cons tmp ntargets))))
|
||||
;
|
||||
(if suggestedname
|
||||
(oset this name (project-am-last-dir suggestedname))
|
||||
;; Else, setup toplevel project info.
|
||||
(and pn (string= (directory-file-name
|
||||
(oref this directory))
|
||||
(directory-file-name
|
||||
(project-am-find-topmost-level
|
||||
(oref this directory))))
|
||||
(oset this name pn)
|
||||
(and pv (oset this version pv))
|
||||
(and bug (oset this mailinglist bug))
|
||||
(oset this configureoutputfiles cof)))
|
||||
;; Now that we have this new list, chuck the old targets
|
||||
;; and replace it with the new list of targets I just created.
|
||||
(oset this targets (nreverse ntargets))
|
||||
;; We still have a list of targets. For all buffers, make sure
|
||||
;; their object still exists!
|
||||
|
||||
;; FIGURE THIS OUT
|
||||
|
||||
(mapc (lambda (sp)
|
||||
(let ((var (makefile-extract-varname-from-text sp))
|
||||
)
|
||||
(if (not var)
|
||||
(setq csubprojexpanded (cons sp csubprojexpanded))
|
||||
;; If it is a variable, expand that variable, and keep going.
|
||||
(let ((varexp (makefile-macro-file-list var)))
|
||||
(dolist (V varexp)
|
||||
(setq csubprojexpanded (cons V csubprojexpanded)))))
|
||||
))
|
||||
csubproj)
|
||||
|
||||
(project-am-expand-subdirlist 'csubprojexpanded csubproj)
|
||||
;; Ok, now lets look at all our sub-projects.
|
||||
(mapc (lambda (sp)
|
||||
(let* ((subdir (file-name-as-directory
|
||||
(expand-file-name
|
||||
sp (file-name-directory (oref this :file)))))
|
||||
(submake (expand-file-name
|
||||
"Makefile.am"
|
||||
subdir)))
|
||||
(if (string= submake (oref this :file))
|
||||
nil ;; don't recurse.. please!
|
||||
|
||||
;; For each project id found, see if we need to recycle,
|
||||
;; and if we do not, then make a new one. Check the deep
|
||||
;; rescan value for behavior patterns.
|
||||
(setq tmp (object-assoc
|
||||
submake
|
||||
'file osubproj))
|
||||
(if (not tmp)
|
||||
(setq tmp
|
||||
(condition-case nil
|
||||
;; In case of problem, ignore it.
|
||||
(project-am-load-makefile subdir)
|
||||
(error nil)))
|
||||
;; If we have tmp, then rescan it only if deep mode.
|
||||
(if ede-deep-rescan
|
||||
(project-rescan tmp)))
|
||||
;; Tac tmp onto our list of things to keep, but only
|
||||
;; if tmp was found.
|
||||
(when tmp
|
||||
;;(message "Adding %S" (object-print tmp))
|
||||
(setq nsubproj (cons tmp nsubproj)))))
|
||||
)
|
||||
(nreverse csubprojexpanded))
|
||||
(let* ((subdir (file-name-as-directory
|
||||
(expand-file-name
|
||||
sp (file-name-directory (oref this :file)))))
|
||||
(submake (expand-file-name
|
||||
"Makefile.am"
|
||||
subdir)))
|
||||
(if (string= submake (oref this :file))
|
||||
nil ;; don't recurse.. please!
|
||||
;; For each project id found, see if we need to recycle,
|
||||
;; and if we do not, then make a new one. Check the deep
|
||||
;; rescan value for behavior patterns.
|
||||
(setq tmp (object-assoc
|
||||
submake
|
||||
'file osubproj))
|
||||
(if (not tmp)
|
||||
(setq tmp
|
||||
(condition-case nil
|
||||
;; In case of problem, ignore it.
|
||||
(project-am-load-makefile subdir subdir)
|
||||
(error nil)))
|
||||
;; If we have tmp, then rescan it only if deep mode.
|
||||
(if ede-deep-rescan
|
||||
(project-rescan tmp subdir)))
|
||||
;; Tac tmp onto our list of things to keep, but only
|
||||
;; if tmp was found.
|
||||
(when tmp
|
||||
;;(message "Adding %S" (object-print tmp))
|
||||
(setq nsubproj (cons tmp nsubproj)))))
|
||||
)
|
||||
(nreverse csubprojexpanded))
|
||||
(oset this subproj nsubproj)
|
||||
;; All elements should be updated now.
|
||||
)))
|
||||
@ -696,12 +703,16 @@ DIR is the directory to apply to new targets."
|
||||
(defmethod project-rescan ((this project-am-program))
|
||||
"Rescan object THIS."
|
||||
(oset this :source (makefile-macro-file-list (project-am-macro this)))
|
||||
(unless (oref this :source)
|
||||
(oset this :source (list (concat (oref this :name) ".c"))))
|
||||
(oset this :ldadd (makefile-macro-file-list
|
||||
(concat (oref this :name) "_LDADD"))))
|
||||
|
||||
(defmethod project-rescan ((this project-am-lib))
|
||||
"Rescan object THIS."
|
||||
(oset this :source (makefile-macro-file-list (project-am-macro this))))
|
||||
(oset this :source (makefile-macro-file-list (project-am-macro this)))
|
||||
(unless (oref this :source)
|
||||
(oset this :source (list (concat (file-name-sans-extension (oref this :name)) ".c")))))
|
||||
|
||||
(defmethod project-rescan ((this project-am-texinfo))
|
||||
"Rescan object THIS."
|
||||
@ -726,19 +737,6 @@ DIR is the directory to apply to new targets."
|
||||
(defmethod project-rescan ((this project-am-extra-dist))
|
||||
"Rescan object THIS."
|
||||
(oset this :source (makefile-macro-file-list "EXTRA_DIST")))
|
||||
;; NOTE: The below calls 'file' then checks that it is some sort of
|
||||
;; text file. The file command may not be available on all platforms
|
||||
;; and some files may not exist yet. (ie - auto-generated)
|
||||
|
||||
;;(mapc
|
||||
;; (lambda (f)
|
||||
;; ;; prevent garbage to be parsed, could we use :aux ?
|
||||
;; (if (and (not (member f (oref this :source)))
|
||||
;; (string-match-p "ASCII\\|text"
|
||||
;; (shell-command-to-string
|
||||
;; (concat "file " f))))
|
||||
;; (oset this :source (cons f (oref this :source)))))
|
||||
;; (makefile-macro-file-list "EXTRA_DIST")))
|
||||
|
||||
(defmethod project-am-macro ((this project-am-objectcode))
|
||||
"Return the default macro to 'edit' for this object type."
|
||||
@ -808,22 +806,24 @@ nil means that this buffer belongs to no-one."
|
||||
|
||||
(defmethod ede-buffer-mine ((this project-am-objectcode) buffer)
|
||||
"Return t if object THIS lays claim to the file in BUFFER."
|
||||
(member (file-name-nondirectory (buffer-file-name buffer))
|
||||
(member (file-relative-name (buffer-file-name buffer) (oref this :path))
|
||||
(oref this :source)))
|
||||
|
||||
(defmethod ede-buffer-mine ((this project-am-texinfo) buffer)
|
||||
"Return t if object THIS lays claim to the file in BUFFER."
|
||||
(let ((bfn (buffer-file-name buffer)))
|
||||
(or (string= (oref this :name) (file-name-nondirectory bfn))
|
||||
(member (file-name-nondirectory bfn) (oref this :include)))))
|
||||
(let ((bfn (file-relative-name (buffer-file-name buffer)
|
||||
(oref this :path))))
|
||||
(or (string= (oref this :name) bfn)
|
||||
(member bfn (oref this :include)))))
|
||||
|
||||
(defmethod ede-buffer-mine ((this project-am-man) buffer)
|
||||
"Return t if object THIS lays claim to the file in BUFFER."
|
||||
(string= (oref this :name) (buffer-file-name buffer)))
|
||||
(string= (oref this :name)
|
||||
(file-relative-name (buffer-file-name buffer) (oref this :path))))
|
||||
|
||||
(defmethod ede-buffer-mine ((this project-am-lisp) buffer)
|
||||
"Return t if object THIS lays claim to the file in BUFFER."
|
||||
(member (file-name-nondirectory (buffer-file-name buffer))
|
||||
(member (file-relative-name (buffer-file-name buffer) (oref this :path))
|
||||
(oref this :source)))
|
||||
|
||||
(defmethod project-am-subtree ((ampf project-am-makefile) subdir)
|
||||
@ -954,7 +954,6 @@ Kill the Configure buffer if it was not already in a buffer."
|
||||
(cond
|
||||
;; Try configure.in or configure.ac
|
||||
(conf-in
|
||||
(require 'ede/autoconf-edit)
|
||||
(project-am-with-config-current conf-in
|
||||
(let ((aci (autoconf-parameters-for-macro "AC_INIT"))
|
||||
(aia (autoconf-parameters-for-macro "AM_INIT_AUTOMAKE"))
|
||||
@ -980,7 +979,7 @@ Kill the Configure buffer if it was not already in a buffer."
|
||||
(t acf))))
|
||||
(if (> (length outfiles) 1)
|
||||
(setq configfiles outfiles)
|
||||
(setq configfiles (split-string (car outfiles) " " t)))
|
||||
(setq configfiles (split-string (car outfiles) "\\s-" t)))
|
||||
)
|
||||
))
|
||||
)
|
||||
@ -1005,6 +1004,18 @@ Calculates the info with `project-am-extract-package-info'."
|
||||
(when top (setq dir (oref top :directory)))
|
||||
(project-am-extract-package-info dir)))
|
||||
|
||||
;; for simple per project include path extension
|
||||
(defmethod ede-system-include-path ((this project-am-makefile))
|
||||
"Return `project-am-localvars-include-path', usually local variable
|
||||
per file or in .dir-locals.el or similar."
|
||||
(bound-and-true-p project-am-localvars-include-path))
|
||||
|
||||
(defmethod ede-system-include-path ((this project-am-target))
|
||||
"Return `project-am-localvars-include-path', usually local variable
|
||||
per file or in .dir-locals.el or similar."
|
||||
(bound-and-true-p project-am-localvars-include-path))
|
||||
|
||||
|
||||
(provide 'ede/project-am)
|
||||
|
||||
;; arch-tag: 528db935-f186-4240-b647-e305c5b784a2
|
||||
|
@ -70,7 +70,7 @@ COMMAND is a text string representing the thing to be run."
|
||||
(defmethod ede-shell-buffer ((target ede-target))
|
||||
"Get the buffer for running shell commands for TARGET."
|
||||
(let ((name (ede-name target)))
|
||||
(get-buffer-create (format "*EDE Shell %s" name))))
|
||||
(get-buffer-create (format "*EDE Shell %s*" name))))
|
||||
|
||||
(provide 'ede/shell)
|
||||
|
||||
|
@ -21,6 +21,10 @@
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; NOTE: EDE Simple Projects are considered obsolete. Use generic
|
||||
;; projects instead. They have much better automatic support and
|
||||
;; simpler configuration.
|
||||
;;
|
||||
;; A vast majority of projects use non-EDE project techniques, such
|
||||
;; as hand written Makefiles, or other IDE's.
|
||||
;;
|
||||
@ -41,6 +45,14 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(add-to-list 'ede-project-class-files
|
||||
(ede-project-autoload "simple-overlay"
|
||||
:name "Simple" :file 'ede-simple
|
||||
:proj-file 'ede-simple-projectfile-for-dir
|
||||
:load-type 'ede-simple-load
|
||||
:class-sym 'ede-simple-project)
|
||||
t)
|
||||
|
||||
(defcustom ede-simple-save-directory "~/.ede"
|
||||
"*Directory where simple EDE project overlays are saved."
|
||||
:group 'ede
|
||||
|
@ -108,7 +108,7 @@ Argument DIR is the directory from which to derive the list of objects."
|
||||
;;; Some special commands useful in EDE
|
||||
;;
|
||||
(defun ede-speedbar-remove-file-from-target ()
|
||||
"Remove the file at point from it's target."
|
||||
"Remove the file at point from its target."
|
||||
(interactive)
|
||||
(if (stringp (speedbar-line-token))
|
||||
(progn
|
||||
|
@ -43,7 +43,9 @@
|
||||
(srecode-map-update-map t)
|
||||
;; We don't call this unless we need it. Load in the templates.
|
||||
(srecode-load-tables-for-mode 'makefile-mode)
|
||||
(srecode-load-tables-for-mode 'makefile-mode 'ede))
|
||||
(srecode-load-tables-for-mode 'makefile-mode 'ede)
|
||||
(srecode-load-tables-for-mode 'autoconf-mode)
|
||||
(srecode-load-tables-for-mode 'autoconf-mode 'ede))
|
||||
|
||||
(defmacro ede-srecode-insert-with-dictionary (template &rest forms)
|
||||
"Insert TEMPLATE after executing FORMS with a dictionary.
|
||||
|
Loading…
Reference in New Issue
Block a user