GNU Emacs supports integrated compiling and debugging. This brings
with it such conveniences as jumping from a compiler error message
directly to the offending location in the source code, and
source-level debugging in Emacs buffers. Some people argue that
turning an editor into a development environment like that is an
ill-fated endeavour from the start; they hold that a development
environment should be a stand-alone program of which the editor is an
integrated component. Be that as it may, many of us, including myself,
use GNU Emacs' compiling and debugging features.

Unfortunately, if you use GNU Emacs out of the box, compiling and debugging come
with some annoyances. My personal pet peeves are:

In an integrated development environment such as Microsoft Visual Studio, the first
thing you do is open a project (or "solution" in Microsoft speak). After that, tasks
such as compiling an individual source file, building the whole thing, starting a
debug session, etc. can be kicked off with function keys. One never has to to type
a compile, make, or debug command anymore. For me, that does make a big difference
in productivity.

Many compilers, including gcc, output error messages where the file location of the
error is given as a relative path. That causes trouble in large projects, where source
files are scattered over several directories. In that case, jumping from the error
messages in the compilation output buffer to the respective locations in the source
files via next-error (pressing Ctrl-x `) has a
problem: depending on your setup, it can either work when compiling individual
source files, or it can work when compiling the entire project, but not for both.

The Devenv Emulation package removes these annoyances and adds some
minor conveniences. Among other things, it provides function key
bindings that are modeled after Microsoft Visual Studio.

Besides download and installation, all
that is required to get the benefit of Devenv Emulation is to give
Emacs some information about your current project build environment.
Typically, this is done in the Emacs initialization file. See the
documentation below for details.

Devenv Emulation can be downloaded from
here.
To install Devenv Emulation, place the file
devenv-emulation.elc in some directory DIR. Add the line

(load-file "DIR/devenv-emulation.elc")

to your Emacs initialization file, where you have replaced the string
"DIR" in the load-file call with the actual directory
where devenv-emulation.elc resides. "DIR" may of course be omitted
if devenv-emulation.elc is in a directory where Emacs looks for lisp
files. Be sure to load devenv-emulation.elc and notdevenv-emulation.el. It is customary but not necessary to put the
.el file in the same directory as the .elc file.

To use Devenv Emulation, you must give Emacs some information about
your current project build environment. That is the equivalent of
opening a project in an integrated development environment. Typically,
this is done in the Emacs initialization file. However, all the
settings described below can be made or modified at any time during an
Emacs session.

Remember, one of the main reasons for using Devenv Emulation is to deal
with compilers (such as gcc) that give the error loactions in their
messages relative to the compilation directory. There is one prerequisite
on your build environment for Devenv Emulation to do its job in that
situation: the compilation directory, that is, the working directory under
which the compiler gets called, must be the same across all targets. It
would be very hard to make Emacs' integrated compiling work properly and
consistently if the error locations weren't always relative to the same
directory. What this means is that you must not use the cd
command in your makefile(s), or if you do, then change to the same directory
everytime.

You must tell Devenv Emulation about your active compilation directory
with a line like

(setq devenv-emulation-active-compilation-directory "~/HelloWorld/")

The directory can be specified in unexpanded form, as in the example above, and
it may be given with or without the trailing slash.
This variable setting, like all the other ones described below, can
also be made interactively with M-x set-variable.

One of the benefits of Devenv Emulation is that you can compile
individual source files or make the entire project by hitting a
function key, and you can make other targets by calling a Lisp
function via a key combination.

For this to work, you must tell Devenv Emulation what your make command is.
The simplest way to achieve this is to specify an
active project name with a variable setting like this:

(setq devenv-emulation-active-project-name "hello_world")

Devenv Emulation will then perform the following
lookup when it is told to make a target:

If the active compilation directory
contains a script whose name is the active
project name with "make_" prepended to it, then
that script will be called with the target name as the only
argument. (See Section "Target Names"
below for an explanation of where Devenv Emulation gets the target
name from.) In our example so far, Devenv Emulation would call

make_hello_world <target_name>

with ~/HelloWorld as the current directory.

If the script as described in 1. above does not exist, Devenv
Emulation assumes that your active
compilation directory contains a makefile whose extension is
.mak and whose basename is the same as the
active project name, and that you want to
call the standard make program on this makefile.
In our example, Devenv Emulation would call

make -f hello_world.mak <target_name>

with ~/HelloWorld as the current directory.

If none of these two alternatives is good for you, you can specify a different
compile command altogether like this:

If this variable is non-nil, it supersedes the lookup described in
1. and 2. above. Again, the target name will be passed as the only
argument, and the working directory for the call will be the
active compilation directory.

Devenv Emulation provides a function that prompts the user for a
target to be made. Furthermore, it has predefined functions to make
the entire project, to clean the entire project for a full rebuild,
and to compile the source file that is being visited in the current
buffer. (See Section "Functions and Key
Bindings" below for more details.)

The default target names that Devenv Emulation uses for making and cleaning the entire
project are "all" and "clean". You can change these by setting
variables as follows:

The default target name for compiling the source file that is visited in the current
buffer is obtained by appending .o to the basename of the
source file. For example, the target name for compiling hello_world.cpp
is hello_world.o. You can specify a different extension for the target
name as follows:

(setq devenv-emulation-object-file-extension ".obj")

Note that the period is part of the extension that you set. Hence, you can use this
to remove the extension of the source file altogether, or to append something to
the basename of the file. Similarly, you can append a prefix to the target name:

(setq devenv-emulation-object-file-prefix "release/")

Together, the two settings above will cause the target name for the source file
hello_world.cpp to become release/hello_world.obj.

If you need more elaborate rules to turn source file names into the corresponding
target names, you can do so by defining the lisp function
devenv-emulation-file-name-2-target. If this function is defined,
the full, expanded path of the source file will be passed to it, and the return
value will be used as the corresponding target name. In the following example,
the target name used for each source file will be the full path name of the source file,
with the file extension set to "obj":

Note that you can use this function to make the target names for your source
files dependent on some global variable setting. This can be useful, for example,
to switch between debug mode and release mode.

When it comes to starting a debug session, Devenv Emulation assumes by
default that your executable for debugging is in the
active compilation directory, and that its name is
identical to the active project name. In our
example, the debugger would try to debug

~/HelloWorld/hello_world

If this is not good for you, you can specify the full pathname of your
executable by assigning it to the variable
devenv-emulation-active-executable. Here's an example
that modifies the default behavior so that the executable is found in
the subdirectory "bin" of the
active compilation directory
and has the extension "exe":

If you find yourself having to switch frequently between different projects or
different modes such as relase mode and debug mode, you will want to have an
easy way to switch between different settings for the Devenv Emulation package.
Even if you don't know much about Emacs Lisp programming, you can easily achieve
this by wrapping each set of settings in a function call. The following is an
excerpt from a .emacs file that allows to switch interactively between
release mode and debug mode for a project that was created under Windows with
the Qt qmake program:

Devenv Emulation is not worth a whole lot unless you make some key bindings.
The suggested default bindings are collected in the function
devenv-emulation-set-key-bindings. It is recommended that
you make these key bindings globally, by calling

Given the abundance of GNU Emacs packages and modes, it may happen
that some package's or mode's key bindings conflict with Devenv
Emulation's bindings. In that case, you have two options. For one thing,
you can easily modify the key bindings to your preference by copying,
modifying, and renaming the Emacs Lisp function
devenv-emulation-set-key-bindings out of the source file
devenv-emulation.el.

Alternately, you can override the offending package's or mode's key
bindings. To override other packages' key bindings, make the call to
devenv-emulation-set-key-bindings last in you Emacs
initialization file. To trump a mode's key bindings, you need to call
devenv-emulation-set-key-bindings on the current local
map as the last function in that mode's hook, like this:

Make a specific target. Prompts for a target name. The default is the previously
chosen target. Minibuffer history is kept specifically for target names.
If you want minibuffer completion to be available, you must tell Devenv
Emulation what your targets are. This is done with a function call like this:

Start debugging. If there is no active debug session, then gdb is called on
the active executable, and the GUD buffer is displayed. The active executable
is not started, so you get a chance to set breakpoints. Pressing F5
again will then start the active executable under the debugger, that is, it will
pass the command "run" to gdb.

Shift-F5

Kill the active executable if it is being debugged, that is, pass the command
"kill" to gdb.

F9

Set a breakpoint at the source line that the point is on (Emacs function gud-break).

Shift-F9

Delete the breakpoint(s) on the current source line (Emacs function gud-remove).

Ctrl-F9

Set a temporary breakpoint on the current source line (Emacs function gud-tbreak).

F10

Execute current source line (Emacs function gud-next).

Shift-F10

Continue execution (Emacs function gud-cont).

F11

Execute until another source line is reached (Emacs function gud-step).

Shift-F11

Run until the selected stack frame returns (Emacs function gud-finish).

Switch to buffer *compilation* if it exists. If a GUD buffer is visible,
then that window is used. If not, the compilation buffer is shown in a
new window that is displayed in the same manner as when a compilation is
first started.

Ctrl-C d

Switch to the GUD buffer if it exists. If a compilation buffer is visible,
then that window is used. If not, the GUD buffer is shown in a
new window that is displayed in the same manner as when a debug session is
first started.