tags:

views:

1264

answers:

10

I use emacs to do some coding, and text editing, When I create a new coding project, I simply create a new folder, and add source code into it. The problem is, with multi-forders, it is hard to change back to the top, and run the makefile. Is there any good method to do project management like eclipse or other IDE?

+2  A: 

I don't generally compile from within emacs anymore, but why can't you run a shell in a buffer just for running make. Keep that shell in the top level directory.

As for project management, what features are you looking for?

MadCoder
When you compile, you get the results in a compilation buffer, and you can easily navigate from the errors to the source.
justinhj
A: 

I'm not sure exactly what you're asking, but you might be looking for Speedbar.

Ken
A: 

Depends on the language. JDE is a good Java environment, Distel is a good Erlang environment. I'm sure there are good environments for other platforms as well. Across the board, though, you'll have to do more configuration in emacs than you will in an IDE like Eclipse. IMO, the payoff is worth it, though.

Travis Jensen
+5  A: 

I know your problem. If you have a Makefile in the same folder as your source, and you are in a source buffer, then 'compile' will build correctly.

But if your source is in a different folder then emacs can't find the Makefile.

One solution is to specify the Makefile's location by setting the 'default-directory' variable as a file variable in each source file.

You do this by adding a line like this at the top of the file (and reload it).

// -*- mode: C++; default-directory: "c:/somewhere/yourmakefiledirectory/" -*-
justinhj
+1  A: 

I recently started using project-root to manage my various directory trees. I've now bound F5 to (with-project-root (compile)) and the default-directory is automatically set to the root of any project that I've specified in my .emacs, based on whatever buffer I'm invoking the compile from.

Josh Matthews
+2  A: 

I use EDE from CEDET package - it can maintain different types of projects. I use it to work with CMake, together with custom compile-command (you can find it here - see for MyCompile function)

Alex Ott
A: 

How about entering the following when prompted for the compiling command:

"cd <root> ; make"

If it's a hassle to type often, it can be set in the "compile-command" variable -- though it will be remembered in a session after you type it once.

fell.inchoate
A: 

when I did this with Java, I used ANT, and ANT handled this elegantly with the "-find" switch.

Effectively what it did was look in the current directory for the build.xml file, until it found it. Very handy especially in Java projects because of their enforced directory structure.

For Make, I would create a similar replacement:

#!/bin/sh
# mymake -- my "hunt the makefile" make command
if [ -f Makefile ]
then
    exec make
else
    cur=`pwd`
    if [ $cur = "/" ]
    then
        echo "Can not find Makefile"
        exit 1
    fi
    newdir=`dirname $cur`
    cd $newdir
    exec mymake
fi
Will Hartung
+3  A: 

Below is the ;; compilation section of my .emacs file. I use CTRL+F7 for make, and F7 for make clean. It will search in the current directory and then in .. and so on for a file called "Makefile" to run make on.

Also not that F8 jumps the source window to the first error and CTRL+F8 takes you to the previous error. (BTW, if you think this is awesome, you should see what I've done for GDB integration)... :)

;; Compilation
(setq compilation-scroll-output 1) ;; automatically scroll the compilation windo
w
(setq compilation-window-height 10) ;; Set the compilation window height...
(setq compilation-finish-function ;; Auto-dismiss compilation buffer...
      (lambda (buf str)
        (if (string-match "exited abnormally" str)
            (message "compilation errors, press F6 to visit")
          ; no errors, make the compilation window go away after 2.5 sec
          (run-at-time 2.5 nil 'delete-windows-on buf)
          (message "No compilation errors!"))))

(require 'cl) ; If you don't have it already
(defun* get-closest-pathname (&optional (file "Makefile"))
  "This function walks up the current path until it finds Makefile and then retu
rns the path to it."
  (let ((root (expand-file-name "/")))
    (expand-file-name file
              (loop
            for d = default-directory then (expand-file-name ".." d)
            if (file-exists-p (expand-file-name file d))
            return d
            if (equal d root)
           return nil))))

(defun my-compile-func ()
  "This function does a compile."
  (interactive)
  (compile (format "make -C %s" (file-name-directory (get-closest-pathname)))))

(defun my-compile-clean-func ()
  "This function does a clean compile."
  (interactive)
  (compile (format "make -C %s clean" (file-name-directory (get-closest-pathname
)))))

(defun my-compile-package-func ()
  "This function builds an Endura package."
  (interactive)
  (compile (format "make -C %s package" (file-name-directory (get-closest-pathna
me)))))

(global-set-key [f7] 'my-compile-clean-func)
(global-set-key [C-f7] 'my-compile-func)
(global-set-key [S-f7] 'my-compile-package-func)
(global-set-key [f8] 'next-error)
(global-set-key [C-f8] 'previous-error)
dicroce
A: 

I would use eproject; http://github.com/jrockway/eproject

Here's an example from SO: http://stackoverflow.com/questions/978984/is-there-a-good-emacs-project-management-somewhere/979038#979038

Basically, it unifies the features of CEDET, project-root, and so on. You can declare project definitions in a number of ways, and access the data through a unified API. It also comes with some nice sugar, including ibuffer integration. (Filter ibuffer by project, see the project name next to the buffer name, etc.]

jrockway