Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Feb 2011 00:36:52 -0800
From:      Giorgos Keramidas <>
To:        Vikash Badal <>
Cc:, Robert Bonomi <>
Subject:   Re: switching from gnu make to bsd make
Message-ID:  <xeia8vxlodi3.fsf@kobe.laptop>
References:  <> <> <>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help
On Fri, 11 Feb 2011 10:26:13 +0200, Vikash Badal <> wrote:
> Make all produces the follow output:
> make all
> cc -o bin/nntpd -lpthread -lmysqlclient_r -Wall -g -Iinclude
> -I/usr/local/include -I/usr/local/include/mysql -L/usr/local/lib
> -L/usr/local/lib/mysql obj/log.o obj/cleanup.o obj/config.o
> obj/leecherpool.o obj/mytime.o obj/nntp.o obj/upstream.o obj/mysleep.o
> obj/sqlpool.o obj/sql.o obj/signalhandler.o obj/daemon.o obj/list.o
> obj/tcpserver.o obj/tmpfiles.o obj/listenpool.o obj/workers.o
> obj/nntpd.o
> cc: obj/log.o: No such file or directory
> cc: obj/cleanup.o: No such file or directory
> cc: obj/config.o: No such file or directory
> cc: obj/leecherpool.o: No such file or directory
> cc: obj/mytime.o: No such file or directory
> cc: obj/nntp.o: No such file or directory
> cc: obj/upstream.o: No such file or directory
> cc: obj/mysleep.o: No such file or directory
> cc: obj/sqlpool.o: No such file or directory
> cc: obj/sql.o: No such file or directory
> cc: obj/signalhandler.o: No such file or directory
> cc: obj/daemon.o: No such file or directory
> cc: obj/list.o: No such file or directory
> cc: obj/tcpserver.o: No such file or directory
> cc: obj/tmpfiles.o: No such file or directory
> cc: obj/listenpool.o: No such file or directory
> cc: obj/workers.o: No such file or directory
> cc: obj/nntpd.o: No such file or directory
> *** Error code 1
> With gmake :
> $(OBJDIR)/%.o:${SRCDIR}/%.c
>         ${CC} -c ${CFLAGS} ${INCDIR} ${LIBDIR} $< -o $@
> This creates all the .o files I need

Does gmake also create the `obj/' directory automagically?  I kind of
doubt that, unless the gmake folks have started doing all sorts of magic
behind-your-back stuff.

You have no makefile rule to create `obj/' and no dependency of all the
object files to the object directory.

> How do I do this with bsd make ?

The canonical way of writing a program that depends on object files that
_may_ live in another object directory is to use the existing makefile
macros from `/usr/share/mk/bsd.*.mk'.  This means you will have to
re-organize your Makefile a bit though.

Instead of all the hand-crafted rules you are now trying to debug, which
are nice but will take ages to 'get the job done', you should probably
use a Makefile like this:

    PROG=       nntpd

    SRCS=       cleanup.c \
                config.c \
                leecherpool.c \
                list.c \
                listenpool.c \
                log.c \
                mysleep.c \
                mytime.c \
                nntpd.c \
                signalhandler.c \
                sql.c \
                tcpserver.c \
                upstream.c \

    MYSQLPREFIX?= /usr/local

    CFLAGS+=    -I${.CURDIR}/include \
                -I/usr/local/include \

    LDFLAGS+=   -L/usr/local/lib \

    LDADD+=     -lmysqlclient_r -lpthread

    .include <>

By using the `' rules, you can now type stuff like this:

1.  # Build everything, putting object files in the current directory.
    make all

2.  # Build and install everything, but use debugging CFLAGS and inhibit
    # the final 'strip' step of 'make install' by setting DEBUG_FLAGS.
    make CFLAGS='' DEBUG_FLAGS='-O0 -ggdb' all install

3.  # Clean everything.
    make clean

4.  # Build everything, but instead of installing in /usr/{bin,sbin}
    # install in a chroot under `/tmp/chroot', with the binaries
    # auto-mapped to `/tmp/chroot/usr/{bin,sbin}'.
    env DESTDIR='/tmp/chroot' make install

5.  # Set up a special 'object tree' under /tmp/obj, to keep the sources
    # clean from generated files.
    mkdir /tmp/obj

    # Point the bsd.*.mk glue to the new object tree.
    export MAKEOBJDIRPREFIX=/tmp/obj

    # Create a 'mirror' of the source tree under `/tmp/obj', so that
    # e.g. the object code for `/home/keramida/src/foo' will be saved at
    # `/tmp/obj/home/keramida/tmp/foo'.
    make obj

    # Try to build `.depend' files with source/header -> object file
    # dependencies.
    make depend

    # Biuld everything, saving object code in /tmp/obj
    make all

    # Clean up /tmp/obj. Then clean up current directory too.
    make cleandir
    make cleandir

The rules will take care of creating the object directory
paths; they will take care of generating the appropriate rules to build
with the sources in one place and the object files in another directory;
the macros will let you built multiple snapshots of the same source tree
in different places, e.g. one for 'release' builds and one for 'debug'
builds with different CFLAGS, etc.

Another important point is that if you _do_ the legwork of converting
the makefile rules from gmake to BSD make, you will have tons of
examples of how to do things by looking at the makefiles of FreeBSD
itself.  All our makefiles use,, and the rest of
the bsd.*.mk macros from `/usr/share/mk'.

Want to link to this message? Use this URL: <>