Next Previous Contents

3. Compiling CircleMUD

3.1 Why do I get many syntax errors with Sun's ``cc'' compiler?

Because Circle is written in ANSI C, and Sun's standard cc compiler isn't capable of compiling ANSI C code. You can try acc, Sun's ANSI C compiler, but it costs extra money to get it from Sun so your sysadmin may not have installed it. Most don't. The best solution is to get the GCC compiler from the GNU FTP site and install it, if you have enough time and space.

3.2 Why do I get all sorts of errors with ``crypt'' functions and header files?

(This information applies ONLY to Version 3.0 of the code.) CircleMUD normally uses the UNIX crypt() function to enrypt players' passwords. Because of export restrictions imposed by the U.S., some systems do not have the crypt() function. ``configure'' will usually be able to figure out whether or not your system has crypt(), but if it guesses incorrectly and you see problems with the crypt() function or headers, you can manually disable password encryption by going into the sysdep.h source file and uncommenting the line that reads:

        #define NOCRYPT
Be warned, however, that doing this causes the MUD to store players' passwords in plaintext rather than as encrypted strings. Also, if you move from a system which has crypt to one that doesn't, players won't be able to log in with their old passwords!

3.3 When I try to compile, why do I get a lot of undefined symbols referenced in comm.o for functions like socket, accept, and bind?

SVR4 systems require the socket and nsl libraries for network programs. You shouldn't see this error any more with version 3.0 because ``configure'' should automatically use those libraries for you; however, if you still have problems, try adding ``-lsocket -lnsl'' to the line in the Makefile that links all the object files together into the 'circle' binary.

If you're using V2.20 and you have this error, the best thing to do is simply to use V3.0 instead. If you insist on using 2.20, go into the Makefile and search for the comment next to ``SVR4''.

3.4 Every time I try to compile Circle (or any other piece of software) under Linux, it gives me errors and says it cannot find include header files in the linux/ and asm/ directories. What can I do?

Under Linux, you cannot compile any program unless you install the kernel source code because the kernel source includes the ANSI C header files. You need the files in /usr/include/linux, which are distributed separately from the rest of /usr/include.

The easiest way to do this if you're using the Slackware Linux distribution is simply to install the 'K' series of disks which is the kernel source.

Otherwise, you'll have to set up your include files manually. The easiest way to get these is to download kernel source from ftp.kernel.org. Get the kernel source that matches the kernel you're running (type `uname -a' to find your kernel version). Then unpack the kernel into the /usr/src directory. It's 6 megabytes compressed, 25 megabytes uncompressed.

Read the README file that comes with the kernel, and make the symbolic links you need for /usr/include/asm and /usr/include/linux.

Now compile the MUD. This will take care of most of the errors. You may have to do `make config' and `make dep' in /usr/src/linux as well, in order to make linux/config.h and other files that get generated by these steps.

You can remove the whole kernel source tree except for include/ at this point and get most of your 25 megs back.

(Thanks to Michael Chastain for providing this answer.)

3.5 I'm getting compilation errors from a header file, and I didn't even change it?

Okay, if you really didn't change ``structs.h'' then the error isn't in ``structs.h''. I think I've seen 2 cases where this has happened, the first, is that the header file you included right before the header file messing has an error in it. I can't really say much beyond that, but look for a missing semicolon, are any other errors you can find.

If you include files out of order, it can mess things up. For example, B.h has stuff in it that is defined in A.h, and if you include B.h before A.h, you can get errors, your best bet here is to mess with the order of the headers, making sure you put ``conf.h'' and ``sysdep.h'' at the top, followed by ``structs.h'', ``utils.h'', etc. Any file specific headers should be the last one included just for coding style.

3.6 I'm trying to compile the mud on Windows '95 and am having problems, what can I do?

The first thing to do is to make sure you are compiling a recent version of the source code. Patch Level 11 and onwards all support Windows '95 winsock sockets now. Second, you should ensure that you have carefully read the README.WIN file for instructions on what to include. Next, ensure that you are using a C compiler that supports long filenames (for example, MSVC 4.0 does, MSVC 1.0 does not). If you happen to be trying to patch something into your code, you should use patch for DOS. This does not support long filenames (but can be used with short filenames).

3.7 How can I do a ``grep'' on Windows 95?

  1. Select ``start menu''->``find''->``files or folders''
  2. Enter the files/dirs to search in.
  3. Select ``Advanced''
  4. In the ``Containing Text'' input box, type in the text you want.
  5. Double click on a match to bring up the file that matched.
Even better is to use MSVC's find command (if you have it).

3.8 While compiling the mud, why do I get errors like ``foo.c:1231: Undefined symbol `_whereamI' referenced from text segment''

You forgot to include a source file into the make. Go edit your Makefile and make sure all the necessary *.c files are in there, in particular, whichever C file defines the function that the compiler is complaining is undefined. If all else fails, try deleting all the *.o files and recompiling from scratch.

3.9 What is a parse error and how do I fix it?

A parsing error is often a missing or extra semicolon, parenthesis, or bracket ({).

If the parse error is before a semicolon at the end of a line of code, it is something on that line.

If it is at the beginning of a line within a function, it is usually a missing semicolon on the previous line.

If it is at the beginning of a function, count your brackets (especially the {} ones) in the previous function.

I can't think of any other parse errors. These are the ones I commonly see. With a bit of practice, they are very easy to locate and fix. For a more detailed explanation, check out the C Language FAQ.

3.10 I have this piece of code that calls bcopy(), bzero(), and bcmp() and it won't compile, so what can I do?

All three of these functions are fairly standard on BSD systems. However, they are not considered to be very portable, and thus should be redefined. For example, the equivalents for SYSV are:

#define bcopy(from,to,len)      memmove(to,from,len)
#define bzero(mem,len)          memset(mem,0,len)
#define bcmp(a,b,len)           memcmp(a,b,len)

3.11 My compiler doesn't have ``strdup()'', what can I do?

Use Circle's built-in str_dup() function instead.

3.12 I am having trouble with my ``makefile'', what could be the problem?

If you used cut and paste to insert items into your makefile, it is likely that you accidentally put spaces at the beginning of lines where tabs are needed. This is how the makefile must be constructed:

foo.o: foo.c conf.h sysdep.h structs.h utils.h interpreter.h \
  handler.h db.h
{TAB}$(CC) -c $(CFLAGS)
To add these lines properly, you can use gcc to assist you with the following shell script (from Daniel Koepke):
#!/bin/sh
gcc -MM $1 >> Makefile
echo "{TAB}\$(CC) -c \$(CFLAGS) $1" >> Makefile
To use this script, replace {TAB} with a tab, and then run the script like: add_file foo.c

3.13 How can I handle directories in C?

Note that this seems only to be valid for UNIX OSes. Handling of directories is accomplished through the dirent.h and sys/types.h files. The function opendir() returns a ``DIR*'' pointer (it's like but not the same as the ``FILE *'' pointer) when you pass it the name of a directory to open or NULL if it can't open the dir. After the directory has been opened, you can step through the files or search for particular files, etc. using readdir(), seekdir(), and scandir(). When you reach the end of the directory list, you can either go back to the start with rewinddir() or close the directory with closedir(). The following code (which has not been tested) should open a directory and go through it one by one and prints the filenames:

  struct dirent * ffile;
  DIR * my_dir;

  if (!(my_dir = opendir("foo")))
    return;

  while (1) {
    if (!(dirent = readdir(my_dir)))
      break;
    printf("%s\n", dirent->d_name);
  }

  closedir(my_dir);
The dirent structure contains only two useful elements, the file's name (d_name) and the files length (d_reclen).

Thanks to Daniel Koepke for the above.


Next Previous Contents