home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

Writing Apache Modules with Perl and C
By:   Lincoln Stein and Doug MacEachern
Published:   O'Reilly & Associates, Inc.  - March 1999

Copyright 1999 by O'Reilly & Associates, Inc.


   Show Contents   Previous Page   Next Page

Appendix C - Building Multifile C API Modules
Building Modules from Several Source Files

In this section...

Building Modules from Several Source Files with apxs


   Show Contents   Go to Top   Previous Page   Next Page

The Apache build system is easiest to use when each C API module fits into a single source file. However, if the design of your module requires it to be spread out among a series of source files, Apache can accommodate this, albeit with a little more preparation on your part.

If you are building within the Apache source tree, the easiest way to structure the module is to place all the source files in their own subdirectory of src/modules/. The build scheme will be to create a library file named "libyour_module.a" first, and then to link this with httpd.

In addition to the source code files, the subdirectory will contain a file named Makefile.tmpl containing instructions for building the module, and, optionally, a file named "libyour_module.module" containing configuration hints for the module. You will also create a dummy file named Makefile.libdir which has no other purpose than to tell the configuration system that you have provided your own build targets in Makefile.tmpl and to suppress the automatic target generation that the configuration process usually performs.

As a concrete illustration, we will take the mod_compress example from the previous section and split it up into two source code files. compress.c will contain the module definition and the handler code, while compress_util.c will contain various utilities for compressing and decompressing files. The module will be compiled into a library archive named libcompress.a, and the whole set of source files and makefiles will live in the subdirectory src/modules/compress. It is important for the name of the library to match the name of the subdirectory in which it lives, or Apache's automatic configuration process may not work correctly.

We begin by creating the src/modules/compress directory and moving the appropriate .c and .h files into it. We next create the dummy file Makefile.libdir. It may be empty, or it can contain the following text copied from the like-named file in mod_proxy:

  This is a place-holder which indicates to Configure that it shouldn't
 provide the default targets when building the Makefile in this directory.
 Instead it'll just prepend all the important variable definitions, and
 copy the Makefile.tmpl onto the end.

We now create a Makefile.tmpl file containing the appropriate build rules and targets. The easiest way to create one is to copy an existing one from an existing multifile module (such as mod_proxy) and modify it. Example C-1 shows the file we created for mod_compress. Almost all of this was copied verbatim from the mod_proxy. The only things that changed were the LIB definition, which was altered to refer to libcompress, the OBJS and OBJS_PIC definitions, which were altered to contain the list of object files to link, and the libcompress.a and libcompress.so build targets, which were modified to refer to libcompress rather than to libproxy. In addition, the list of header file dependencies that followed the #DO NOT REMOVE line were deleted. If you are using the gcc compiler, you can rebuild the appropriate dependencies by issuing the make depend command within the subdirectory once the configuration script has been run.

Lastly, we create the file libcompress.module containing the configuration hints for the module. Its contents are identical to the mod_compress.module file discussed in the first section of this chapter:

Name: compress_module
 LIBS="$LIBS -lz"
 echo " + using -lz for compression support"

To compile, link, and activate the multisource version of mod_compress, issue the following command at the top level of the Apache distribution:

% ./configure --activate-module=src/modules/compress/libcompress.a

libcompress.a will now be built and then linked statically to the httpd executable.

As an added bonus, you can request for libcompress to be a shared module, and it will be built correctly as a DSO. The configuration command is the same as you would normally use for other shared modules:

% ./configure --activate-module=src/modules/compress/libcompress.a \

Example C-1. Makefile.tmpl for the Multifile Version of the mod_compress Example Module

OBJS=compress.o compress_util.o
OBJS_PIC=compress.lo compress_util.lo
all: lib
lib: $(LIB)
libcompress.a: $(OBJS)
      rm -f $@
      ar cr $@ $(OBJS)
      $(RANLIB) $@
libcompress.so: $(OBJS_PIC)
      rm -f $@
.SUFFIXES: .o .lo
      $(CC) -c $(INCLUDES) $(CFLAGS) $<
      $(CC) -c $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $< && mv $*.o $*.lo
      rm -f $(OBJS) $(OBJS_PIC) $(LIB)
distclean: clean
       -rm -f Makefile
# We really don't expect end users to use this rule.  It works only with
# gcc, and rebuilds Makefile.tmpl.  You have to re-run Configure after
# using it.
      cp Makefile.tmpl Makefile.tmpl.bak \
      && sed -ne '1,/^# DO NOT REMOVE/p' Makefile.tmpl > Makefile.new \
      && gcc -MM $(INCLUDES) $(CFLAGS) *.c >> Makefile.new \
      && sed -e '1,$$s: $(INCDIR)/: $$(INCDIR)/:g' \
             -e '1,$$s: $(OSDIR)/: $$(OSDIR)/:g' Makefile.new \
          > Makefile.tmpl \
      && rm Makefile.new
$(OBJS) $(OBJS_PIC): Makefile

Building Modules from Several Source Files with apxs

   Show Contents   Go to Top   Previous Page   Next Page

You may also use the apxs system to create a DSO module from several source files. Once again, it's easiest to start with the dummy project created by apxs when you use the -g and -n options. After apxs creates the directory tree, create the .c and .h files you need, and edit the automatically created Makefile. We recommend that you add a new definition named SRC to the Makefile with a value equal to all the source files in your module. For the mod_compress example, SRC would look like this:

SRC = compress.c compress_util.c

Now find the build target that corresponds to the shared module object file, mod_compress.so in the current example, and change it according to this model:

#   compile the shared object file
mod_compress.so: $(SRC) Makefile
      $(APXS) -o $@ -c $(DEF) $(INC) $(LIB) $(SRC)

This makes the shared object depend on the source code files and on Makefile itself. The build rule invokes apxs with the -c (compile) option and the appropriate library files and sources to create the DSO module.

   Show Contents   Go to Top   Previous Page   Next Page
Copyright 1999 by O'Reilly & Associates, Inc.