Makefiles generated by jmaker didn't work if generated classes didn't go
in the same directory than sources.
Here is a modification that had two variables and a function.

    - jmaker-dest-dir : directory where sources are to be compiled.
    - jmaker-source-path : directories where sources can be found.
     - jmaker-dir-package-part (&optional directory  path-list)  "return
the package part from a directory name and a source path list."

jmaker-dir-package-part() is used in template to generated full path
name to compiled classes.

to use it with jde:
make jmaker-dest-dir points to jmaker-dest-dir
and jmaker-source-path points to jde-db-source-directories

Eric.

-----------------------------------------------------------------------------------------

(require 'jde)
(require 'tempo)



(defconst jmaker-version "$Revision: 1.10 $"
  "jmaker version number.")

(defgroup jmaker nil
  "Java Makefile Maker Environment"
  :group 'tools
  :prefix "jmaker-")

(defcustom jmaker-dest-dir ""
  "Directory where source files are to be compiled"
  :group 'jmaker
  :type 'string)

(defcustom jmaker-source-path ""
  "List of source directory paths."
  :group 'jmaker
  :type '(repeat (file :tag "Path")))

(defcustom jmaker-makefile-buffer-template
  '(
    "\"####\" 'n"
    "\"#### Java Makefile automatically generated by jmaker \""
    "(jmaker-version-number) 'n"
    "\"#### Creation date: \" (current-time-string) 'n"
    "\"####\" 'n"
    "'n"
    "\"#### Java compiler settings\" 'n"
    "\"JAVAC       = \" jde-compiler  'n"
    "\"JAVAC_FLAGS = \" (jde-get-compile-options) 'n"
    "\"DEST_DIR = \" (jmaker-relative-dest-dir) 'n"
    "\"PACKAGE_DIR = \" (jmaker-dir-package-part) 'n"
    "'n"
    "\"#### Build Rules\" 'n"
    "\"$(DEST_DIR)$(PACKAGE_DIR)%.class: %.java\" 'n"
    "\"\\t$(JAVAC) $(JAVAC_FLAGS) $<\" 'n"
    "'n"
    "\"#### Global target\" 'n"
    "(jmaker-all-target)"
    "'n"
    "\"#### Single targets\" 'n"
    "(jmaker-file-targets)"
    "'n"
    "\"#### Cleanup\" 'n"
    "\"clean:\" 'n"
    "\"\\t$(RM) *.class\" 'n"
    "'n"
    "\"#### Rebuild\" 'n"
    "\"build:\\tclean all\" 'n"
    "'n"
    "\"#### Usage\" 'n"
    "\"help:\" 'n"
    "\"\\t@echo \\\"Usage: make [all|<single
target>|clean|build|help]\\\"\" 'n"
    "\"\\t@echo \\\"  all             - build all as needed
(default)\\\"\" 'n"
    "\"\\t@echo \\\"  <single target> - build the given file as
needed\\\"\" 'n"
    "\"\\t@echo \\\"  clean           - remove all .class files\\\"\"
'n"
    "\"\\t@echo \\\"  build           - build all inconditionnally\\\"\"
'n"
    "\"\\t@echo \\\"  help            - display this help\\\"\" 'n"
    "'n"
    )
  "*Template for Java Makefile.
Setting this variable defines a template instantiation
command `jmaker-insert-makefile', as a side-effect."
  :group 'jmaker
  :type '(repeat string)
  :set '(lambda (sym val)
          (defalias 'jmaker-insert-makefile
            (tempo-define-template "jmaker-makefile-buffer-template"
                                   (jde-gen-read-template val)
                                   nil
                                   "Insert a Java Makefile in the
current buffer."))
          (set-default sym val)))

(defcustom jmaker-meta-makefile-buffer-template
  '(
    "\"####\" 'n"
    "\"#### Java meta Makefile automatically generated by jmaker \""
    "(jmaker-version-number) 'n"
    "\"#### Creation date: \" (current-time-string) 'n"
    "\"####\" 'n"
    "'n"
    "\"#### Sub-Makefiles targets\" 'n"
    "(jmaker-sub-makefile-targets)"
    "'n"
    "\"#### Usage\" 'n"
    "\"help:\" 'n"
    "\"\\t@echo \\\"Usage: make [all|<single target>|help]\\\"\" 'n"
    "\"\\t@echo \\\"  all             - build all as needed
(default)\\\"\" 'n"
    "\"\\t@echo \\\"  <single target> - build the given target as
needed\\\"\" 'n"
    "\"\\t@echo \\\"  help            - display this help\\\"\" 'n"
    "'n"
    )
  "*Template for Java meta Makefile.
Setting this variable defines a template instantiation
command `jmaker-insert-meta-makefile', as a side-effect."
  :group 'jmaker
  :type '(repeat string)
  :set '(lambda (sym val)
          (defalias 'jmaker-insert-meta-makefile
            (tempo-define-template
"jmaker-meta-makefile-buffer-template"
                                   (jde-gen-read-template val)
                                   nil
                                   "Insert a Java Makefile.meta in the
current buffer."))
          (set-default sym val)))

(defun jmaker-customize ()
  "Show the jmaker customization global options panel."
  (interactive)
  (customize-group "jmaker"))

(defun jmaker-version-number ()
  "Returns jmaker version number."
  (string-match "[0123456789.]+" jmaker-version)
  (match-string 0 jmaker-version))

(defun jmaker-display-version ()
  "Displays jmaker version."
  (interactive)
  (message "Using 'jmaker' version %s." (jmaker-version-number)))

(defun jmaker-relative-dest-dir ()
  "return the compilation destination directory relative toward current
directory"
(file-relative-name jmaker-dest-dir default-directory)
)

(defun jmaker-dir-package-part (&optional directory  path-list)
  "return the package part from a directory name and a source path
list."
  (let* (
         (dir (or directory default-directory))
         (path (or path-list jmaker-source-path))
         (expanded-file-name (file-name-as-directory (expand-file-name
dir)))
         (m (string-match (concat "^" (regexp-quote (expand-file-name
(file-name-as-directory (car path)))) "\\(.*\\)") expanded-file-name))
         (path-cdr (cdr path)))
    (cond (m (file-name-directory (match-string 1 expanded-file-name)))
          (path-cdr (jmaker-dir-package-part dir path-cdr))
          (t nil))))

(defun jmaker-all-target ()
  "Returns a Makefile string for the `all' target. It is build with the
name
of all `.java' files in the current directory. If the current directory
contains
Sample1.java and Sample2.java `jmaker-all-target' returns:

all: \
  Sample1 \
  Sample2

"
  (concat "all:\t\\\n"
          (mapconcat '(lambda (name) (concat "\t" name))
                     (jmaker-get-java-names)
                     " \\\n")
          "\n"))

(defun jmaker-file-targets ()
  "Returns a Makefile string for java file targets. It is build with the
name
of all `.java' files in the current directory. If the current directory
contains
Sample1.java and Sample2.java `jmaker-file-targets' returns:

Sample1: Sample1.class
Sample2: Sample2.class

"
  (mapconcat '(lambda (name) (concat name ":\t"
(jmaker-relative-dest-dir) (jmaker-dir-package-part) name ".class\n"))
             (jmaker-get-java-names)
             ""))

(defun jmaker-get-java-names ()
  "Returns a list of all java file names without extension in the
current directory."
  (mapcar 'file-name-sans-extension
          (directory-files default-directory nil ".\\.java$")))

(defun jmaker-sub-makefile-targets ()
  "Returns a string which contains `Makefile' rules to recursively make
all `Makefile'
files found in the subdirectories of `default-directory'. The result
looks like the
following:

\"all: \
   test \
   test.essai1 \
   other

test: FORCE
  cd test; $(MAKE)

test.essai1: FORCE
  cd test/essai1; $(MAKE)

other: FORCE
  cd other; $(MAKE)

FORCE:
\"
"
  (let ((subdir-list (mapcar '(lambda (x) (directory-file-name
(file-name-directory x)))
                              (jmaker-get-makefiles-in-tree
default-directory))))
    (concat "all:\t\\\n"
            (mapconcat '(lambda (dir)
                          (concat "\t"
(jmaker-convert-directory-to-package dir)))
                       subdir-list
                       " \\\n")
            "\n\n"
            (mapconcat '(lambda (dir)
                          (concat (jmaker-convert-directory-to-package
dir)
                                  ":\tFORCE\n\tcd " dir "; $(MAKE)\n"))
                       subdir-list
                       "\n")
            "\nFORCE:\n"
            )
    )
  )

(defun jmaker-convert-directory-to-package (dir)
  "Converts the given directory to a Java package form
by replacing '/' by '.' and removing extra '/' at end."
  (mapconcat 'identity
             (split-string dir "/")
             "."))

(defun jmaker-get-makefiles-in-tree (root)
  "Returns the list of `Makefile' files found in the subdirectories of
the
given `root' directory. Each file path is relative to the `root'
directory."
  (message "Searching Makefiles, please wait...")
  (jmaker-get-makefiles-in-tree-aux root root))

(defun jmaker-get-makefiles-in-tree-aux (root dir)
  "Auxiliary function used by `jmaker-get-makefiles-in-tree'.
`root' is the top root directory. `dir' is a subdirectory in `root'
tree."
  (let ((dir (file-name-as-directory dir)))
    (mapcan  '(lambda (f)
               (let ((rel-f (concat dir f)))
                 (unless (or (string= f ".") (string= f "..")
                             (not (file-directory-p rel-f)))
                   (nconc
                    (and (file-readable-p (concat rel-f "/Makefile"))
                         (list (concat (file-relative-name rel-f root)
"/Makefile")))
                    (jmaker-get-makefiles-in-tree-aux root rel-f)))))
            (directory-files dir))))

(defun jmaker-generate-makefile ()
  "Generates a Java `Makefile' file which could be used to compile Java
files
in the current directory.
If the file `Makefile' already exists the command requires confirmation
to overwrite it."
  (interactive)
  (let ((makefile (concat (file-name-as-directory default-directory)
"Makefile")))
    (and (file-exists-p makefile)
         (or (y-or-n-p (format "File `%s' exists; overwrite? "
makefile))
             (error "Canceled")))
    (with-current-buffer (find-file-noselect makefile)
      (makefile-mode)
      (erase-buffer)
      (jmaker-insert-makefile)
      (goto-char (point-min))
      (switch-to-buffer (current-buffer)))))

(defun jmaker-generate-meta-makefile (root)
  "Generates the file `root'/Makefile.meta which could be used to
recursively make
all `Makefile' files found in the subdirectories of the given `root'
directory.
If the file `root'/Makefile.meta already exists the command requires
confirmation
to overwrite it."
  (interactive "DDirectory: ")
  (let ((makefile (concat (file-name-as-directory root)
"Makefile.meta")))
    (and (file-exists-p makefile)
         (or (y-or-n-p (format "File `%s' exists; overwrite? "
makefile))
             (error "Canceled")))
    (with-current-buffer (find-file-noselect makefile)
      (makefile-mode)
      (erase-buffer)
      (jmaker-insert-meta-makefile)
      (goto-char (point-min))
      (switch-to-buffer (current-buffer)))))

(defvar jmaker-menu
  (list "JMaker"
        (list "New"
              ["Makefile..."       jmaker-generate-makefile t]
              ["Meta-makefile..."  jmaker-generate-meta-makefile t]
              )
        ["Options..."              jmaker-customize t]
       ["-"                       ignore nil]
        (concat "jmaker " (jmaker-version-number))
        )
  "Menu for jmaker."
  )

(if (not jde-xemacsp)
    (easy-menu-do-define 'jmaker-menu
                         jde-mode-map
                         "Menu for jmaker."
                         jmaker-menu)
)

(provide 'jmaker)

Reply via email to