Program Development Using GNU C++ and Emacs: An Introduction H. Allen Adams Microsoft Visual C++ is not the only C++ compiler in the world today. In fact, much of the programming world uses variants of GNU C++, one of the many Unix-like tools developed as part of the GNU project, which emphasizes (and insists on) openly available source code. (GNU stands for ``GNU's Not Unix'' which stresses its contrast with the proprietary policies of Unix developers in keeping source code secret.) Another GNU tool is the Emacs editor, which is one of the most popular editors for use in programming. In fact, Emacs provides an IDE (Integrated Development Environment) for editing, compiling, running, and debugging programs, comparable in many ways to Microsoft Visual Studio. It has the advantage of being available on both Windows and most Unix platforms, one of the consequences of the GNU project's open source policy. Emacs is often called an "operating system cleverly disguised as a word-processor" because of all the features and tools built-in to it. In class, we will not be using Emacs to its full potential, as learning all about Emacs requires a great deal of time and several 500 page manuals. Instead, we'll learn the most basic and often used commands. If you are interested in learning more about Emacs, there is an extensive built-in tutorial and documentation you can explore on your own. In this document, we'll assume that you have already started Cygwin on your Windows machine and you are working at a bash prompt. The same commands will also work on just about any Unix system you'll ever use. Starting the Program: Emacs is started by typing 'emacs' at a bash prompt. Typing 'emacs' with no arguments starts Emacs and displays a brief help file. Typing 'emacs ' starts Emacs and loads the specified file. When Emacs starts, you'll notice that the screen is divided into two sections. On top, filling most of the screen, is a large FILE BUFFER. This is where files are loaded and edited. At the bottom of the screen, taking only one line is the MINIBUFFER, which is where you give arguments to certain commands we'll talk about later. The minibuffer is probably your best friend in Emacs: Commands are entered there, and messages and instructions are also displayed there. With Cygwin in Windows, you can also start Emacs directly by using the shortcut in the Start menu. Control Keys and Keyboard Shortcuts: Emacs commands are accessed by means of keyboard shortcuts, some of which are quite complicated. There are two major classes of keyboard shortcuts, CONTROL keys and META keys. Control keys use the key on your keyboard, and Meta keys use the key on most keyboards. Most shortcuts combine control and meta keys with extra keys. For instance, to undo the last command, you use C-x u. This means that you press 'x' while holding down the key, then release both and press 'u'. On most keyboards, meta keys are invoked using the key. However, unlike control keys, when invoking meta keys you do not have to hold down the key to execute them. So, the command M-v for page up is executed by pressing then pressing 'v'. Confused? Don't worry, with practice, it becomes easier. A (very) short tutorial: Before we go into the nitty-gritty of using Emacs, let's run through a quick example. We'll create and edit the followining little program, grades.cpp // A program to compute the average of five grades #include int main() { int grade, sum, n, average; n = 0; sum = 0; while (n < 5) { cout << "Enter a grade" << endl; cin >> grade; sum = sum + grade; n++; } average = sum / 5; cout << "The average is " << average << endl; return 0; } For those of you who like to use your mouse, most of these commands are (usually) available from the pull-down menus. If you are using Emacs via a remote connection to a Unix server through a dumb terminal, though, you will need to use the keyboard shortcuts exclusively. We'll only discuss the keyboard shortcuts here. 1. Start Emacs by typing 'emacs' at a bash prompt and pressing . 2. Use the shortcut C-x C-f. This is the FIND FILE shortcut. One of the oddest things about Emacs is that you use this same command for both opening existing files and creating new ones. After invoking the shortcut, the cursor will move down to the minibuffer at the bottom of the screen. There should be a prompt much like this: Find file: ~/ Type "grades.cpp" and press . The file buffer should now display an empty file. 3. Type the program given on page 2 of Worksheet #1 into the buffer. 4. Use the shortcut C-x C-s to save the file. Now that the file has been saved, we can compile and run it. 5. To invoke the compiler, we'll use the META-x compile command. Press M-x (Escape, then 'x'). In the minibuffer, type "compile" and press . At this point, the minibuffer will display something like: Compile command: make -k This is the default compilation command which assumes we've created a makefile (like a project in MS Visual Studio) for the program. We'll discuss makefiles briefly later, but for now we'll invoke the compiler directly. 6. Use or to erase this command and type "g++ grades.cpp -o grades" and press This command will compile the program and create an executable file called "grades". A new window should open at this point and display the compilation process. Notice that the original file buffer with your code in it is still present, but smaller and on top. If your code is completely correct, you'll get a message like Compilation finished at Tue Jan 11 16:37:39 In this case, you can hide the compilation window by using the shortcut C-x 1. If the program did not compile, you will see instead a list of errors with line numbers. Fix the errors in your code and compile again until it works. You can easily find the line in your source code an error message refers to using the shortcut C-x ` (that's C-x followed by the BACKQUOTE key). When you use it the first time the cursor is placed on the line that the first error message refers to; typing C-x ` again moves the cursor to the position of the second error, and so on. Note that as you do this, each error message is moved to the top of the compilation window. The previous error messages aren't lost; they are still in the compilation buffer. You can move the cursor back and forth between the source code window and the compilation window using C-x o. If you have the cursor in the compilation window and on an error message, hitting moves the cursor back to the source code window and places it on the line the error message refers to. (Use this technique when there are a lot of messages and you want to look at one somewhere in the middle without having to go through all the previous ones, as you would using C-x `.) 7. Once the program compiles, you need to start a shell in which to run it. Again, we'll use a META-x command: M-x shell Now, you'll notice another bash prompt running from within Emacs! To execute your program, type "./grades" and press . The program should now run. NOTE: If you run into infinite-loop problems, you'll have to type C-c _twice_ to terminate the program. To switch back to the code window, use the SWITCH-TO-BUFFER shortcut C-x b. This will cause the minibuffer to ask you which buffer to switch to. By default, this should be grades.cpp. If so, press . If not, type "grades.cpp" and press and you'll be back at your source code. To switch back to the shell, do the same thing, but type "*shell*" instead of "grades.cpp". TIP: If you don't know the name of the buffer you want, press in the minibuffer; you'll then get a list of all the buffers you can select. That's it for the ultra-short tutorial. You've now created, saved, edited, compiled and run a program. To exit Emacs, use the shortcut C-x C-c. Now for a (slightly) more in-depth look at the tools we just used. Buffers and Windows: Each open file in Emacs has a buffer all to itself. Other items, like the shell, compilation results and so forth also have buffers, but they act exactly like file buffers. Each buffer can have a window associated with it which can be used to edit the contents of that buffer. In the example above, in step 2 we created a new buffer called "grades.cpp" to hold the source code for our program. This buffer was automatically given a window. At the bottom of each window is a long black bar which has some useful information. The two most important pieces of information for our purposes are the filename, located just to the left of the center, and the current line number, located just to the right of center. To switch between buffers, use the SWITCH-TO-BUFFER command (C-x b). As we saw when we compiled, more than one window can be displayed onscreen at the same time. Sometimes, as with compilation, this happens automatically. But, we can also do this manually using some simple commands: To display only one buffer (default): C-x 1 This will cause which ever buffer currently containing the cursor to fill the whole screen. To display two buffers top and bottom: C-x 2 By default, this opens another window with the same buffer. Using file and buffer commands different buffers can be displayed instead. Two buffers, side-by-side: C-x 3 To move the cursor back and forth between buffers: C-x o To change the buffer displayed in the current window: C-x b The differences between buffers and windows can seem a little confusing at first. Just remember that a buffer contains some kind of information and a window displays information from a buffer onscreen. File Commands: Open / Create File: C-x C-f Save File: C-x C-s Save file under different name: C-x C-w Save all open files: C-x s Close the current file: C-x k Editing Commands: Page Down: C-v Page Up: M-v Move to the beginning of the line: C-a Move to the end of the line: C-e Move to the beginning of file: M-< Move to the end of file: M-> Cut Line: C-k Paste: C-y Undo: C-x u Program Commands: Exiting the program: C-x C-c Canceling any minibuffer command: C-g Getting Help: M-x help Full Documentation: M-x info Compilation: Compile: M-x compile Go to next compilation error: C-x ` If you'd like to learn more about Emacs, consult the tutorial: M-x help-with-tutorial M-x help t t A Note about Makefiles: Often, especially in larger programs, code is split between several files. When developing in Microsoft Visual Studio, all these multiple files are handled and compiled automatically. When using Emacs and g++, however, we need to do a little extra work. On most systems, compilation of multiple source files is done through the use of a tool called 'make' and makefiles. Let's do another example: (I'm assuming you still have Emacs up and running with grades.cpp in a buffer somewhere. If not, start Emacs and load grades.cpp with C-x C-f.) 1. Use C-x C-f to create a new file. Call this new file "makefile". 2. Type in the following data _exactly_ (you may ignore the line labels if you like) (NOTE: lines four and seven begin with . This is important.): CC=g++ #line 1 #line 2 grades: grades.o #line 3 $(CC) -o grades.exe grades.o #line 4 #line 5 grades.o: grades.cpp #line 6 $(CC) -c grades.cpp #line 7 3. Save the file. (C-x C-s) 4. Now, we'll compile the program again , only this time we'll do it a bit differently. Invoke the compile command (M-x compile) but this time enter "make" and press . If everything worked properly, your grades program should compile as it did before. What happened? The answer is, of course, the makefile. This file contains a list of instructions for the 'make' tool to carry out in order to compile the program. 'Make' does this by means of "targets". In our makefile there are two targets, one for the executable program and another for something called grades.o. We'll get to what these do in a moment, but first let's look at what each line does. CC=g++ #line 1 This line defines the compiler we're going to use. As will usually the case, this is g++. grades: grades.o #line 3 This line defines the first target, the executable program. It also tells make that in order to build this target, the file 'grades.o' is required. This means that if grades.o exists and is up-to-date, 'grades' will be created. If not, make will create 'grades.o' using other rules (line 6). If more than one file were required for this target, we would list them all on the same line separated by spaces. $(CC) -o grades.exe grades.o #line 4 Following each target definition is a list of steps to create the target. Each of these steps MUST begin with a character for it to be recognized.In this case, we're telling make to invoke g++ and create an executable called 'grades' out of the file 'grades.o'. You should notice that this line is somewhat similar to our original compilation command above. This is not an accident. grades.o: grades.cpp #line 6 Again, we're defining a target, 'grades.o' which requires the source file we wrote, 'grades.cpp'. $(CC) -c grades.cpp #line 7 The command for this target also invokes g++, but this time it takes our source file and compiles it only "halfway", which creates an OBJECT FILE called 'grades.o'. 'grades.o' is then compiled the rest of the way into an executable with the 'grades' target. You're probably wondering why we bother with .o files instead of compiling the source directly. The reason is efficiency. This method doesn't end up being faster for small programs with only one source file, but in larger projects compilation time can be much reduced. Here's why. Let's say that instead of the simple grades program we have so far, we have a more complicated one that links into some sort of database, the code for which is in 'database.cpp'. In this case our makefile might look something like this: CC=g++ #line 1 #line 2 grades: grades.o database.o #line 3 $(CC) -o grades.exe grades.o database.o #line 4 #line 5 grades.o: grades.cpp #line 6 $(CC) -c grades.cpp #line 7 #line 8 database.o: database.cpp #line 9 $(CC) -c database.cpp #line 10 Now, let's say you compile the program for the first time. What happens? First, make looks for the 'grades' target and sees that it needs two files, 'grades.o' and 'database.o', neither of which exists. So, then it looks at the target 'grades.o' and builds it from 'grades.cpp'. Then, it does the same for 'database.o'. Now that both files exist, it can combine them into a single executable. At this point, you run the executable and see that some minor fixes need to made. All of these changes are in 'grades.cpp', so 'database.cpp' is not changed at all. After making the changes, you compile again. What happens this time? You might think that the whole process is repeated, but it isn't. Since 'database.cpp' has not changed since the last time you compiled, make knows that 'database.o' is already up-to-date. This means that only 'grades.o' needs to be rebuilt! It's this method of only compiling those files which need to be compiled which saves so much time in large projects.