Building libmilter as a Shared Library on FreeBSD

By Weldon Whipple <weldon@whipple.org>


Introduction

Before I became heavily involved with FreeBSD, I used to build each new version of sendmail from the standard tarball downloaded from sendmail.org's web site. On FreeBSD I have continued to build sendmail from the standard sendmail.org distribution.

This approach worked well until I began having problems building milters. I realized that I hadn't been rebuilding libmilter with each sendmail upgrade; I also noticed that the standard libmilter on FreeBSD boxes is a shared object (/usr/lib/libmilter.so). The same library in the sendmail distribution builds as a static library (/usr/lib/libmilter.a). I was able to eliminate some of the milter problems by building libmilter from the sendmail distribution as a shared library, rather than as a static library.

This document outlines how I use the standard sendmail distribution to build libmilter as a shared object on FreeBSD.

Step-by-Step

Before using these steps, download the sendmail tarball from sendmail.org and build sendmail, following the instructions at sendmail.org and in various reference sources.
  1. Copy the file /usr/ports/mail/sendmail/files/sharedlibrary.m4 into the /devtools/M4/UNIX directory of the sendmail source distribution.
    If you are missing the /usr/ports directory structure, you may need to use the cvsup command to create a copy of /usr/ports directory. Alternately, I have included a copy of sharedlibrary.m4 in the appendix to this document.
  2. In the sendmail base directory, issue the command:
    
       % cp -Rf libmilter libsharedmilter
    
  3. In the Makefile.m4 file in the new libsharedmilter directory, change the line
    
       bldPRODUCT_START(`library', `libmilter')
    
    to
    
       bldPRODUCT_START(`sharedlibrary', `libmilter')
    
  4. Still in the libsharedmilter directory, issue the following:
    
       % setenv MILTER_SOVER 3
       % ./Build
       % su     # Unless you are already root
       # ./Build install
    
    The setenv command above assumes that you are using the tcsh or csh shell; if you are using bash or Bourne (sh), try "export MILTER_SOVER=3"
    You might use a number other than 3 as the milter shared object version (MILTER_SOVER)--which is suffixed to the end of the file name of the libmilter shared object library. When I first used these instructions, I found an existing libmilter shared object named /usr/lib/libmilter.so.2, so I incremented the suffix to 3.
  5. Still as root, adjust the libmilter.so symlink to point to the new libmilter shared object.
    The following continue my example of using 3 as the milter shared object version.
    
       # ln -sf libmilter.so.3 /usr/lib/libmilter.so
    
  6. It probably doesn't hurt to issue the ldconfig command to update the list of "hints" for the dynamic linker:
    
       # /sbin/ldconfig -m /usr/lib
    
  7. If your existing milters were built with the old libmilter.so, restart sendmail and check /var/log/maillog to make sure the milters still work. To restart sendmail:
    
       cd /etc/mail
       make restart
    

Feedback

Please send corrections or suggestions to me!

Appendix

This is what the sharedlibrary.m4 macro looked like at the time I wrote these instructions:


# Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers.
#       All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
#  Definitions for Makefile construction for sendmail
#
#       $Id: library.m4,v 8.10 2001/02/14 04:39:38 gshapiro Exp $
#
divert(0)dnl
include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/links.m4')dnl
bldLIST_PUSH_ITEM(`bldC_PRODUCTS', bldCURRENT_PRODUCT)dnl
bldPUSH_TARGET(bldCURRENT_PRODUCT.so)dnl
bldPUSH_INSTALL_TARGET(`install-'bldCURRENT_PRODUCT)dnl
bldPUSH_CLEAN_TARGET(bldCURRENT_PRODUCT`-clean')dnl

include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/defines.m4')
divert(bldTARGETS_SECTION)
bldCURRENT_PRODUCT.so: ${BEFORE} ${bldCURRENT_PRODUCT`OBJS'}
        ${LD} ${LDOPTS_SO} -o bldCURRENT_PRODUCT.so confSONAME bldCURRENT_PRODUCT.so.${MILTER_SOVER} ${bldCURRENT_PRODUCT`OBJS'}
ifdef(`bldLINK_SOURCES', `bldMAKE_SOURCE_LINKS(bldLINK_SOURCES)')

install-`'bldCURRENT_PRODUCT: bldCURRENT_PRODUCT.so
ifdef(`bldINSTALLABLE', `       ${INSTALL} -c -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} bldCURRENT_PRODUCT.so ${DESTDIR}${LIBDIR}/bldCURRENT_PRODUCT.so.${MILTER_SOVER}')

bldCURRENT_PRODUCT-clean:
        rm -f ${OBJS} bldCURRENT_PRODUCT.so ${MANPAGES}

divert(0)
COPTS+= confCCOPTS_SO