intr ipcrm ipcs irdpd isoread join kill last leave \
less lex life loadkeys loadramdisk logger login look lp \
lpd ls lspci M mail make MAKEDEV man \
- mdb mdocml mesg mined mkdep mkdir mkfifo mkfs.mfs mknod \
+ mdb mdocml mesg mined ackmkdep mkdir mkfifo mkfs.mfs mknod \
mkproto modem mount mt netconf newroot nice acknm nohup \
nonamed od packman passwd paste patch pax \
ping postinstall poweroff pr prep printf printroot \
-SCRIPTS= mkdep.sh
+SCRIPTS= ackmkdep.sh
MAN=
.include <bsd.prog.mk>
#!/bin/sh
#
-# mkdep 1.1 - Generate Makefile dependencies. Author: Kees J. Bot
+# ackmkdep 1.1 - Generate Makefile dependencies. Author: Kees J. Bot
#
# Does what 'cc -M' should do, but no compiler gets it right, they all
# strip the leading path of the '.o' file.)
# Display help ...
0)
- echo "Usage: mkdep 'cpp command' file ..." >&2
- echo " mkdep directory" >&2
+ echo "Usage: ackmkdep 'cpp command' file ..." >&2
+ echo " ackmkdep directory" >&2
;;
# Create .depend files ...
+20110722:
+ To install the new mkdep:
+ # cp /usr/bin/mkdep /usr/bin/ackmkdep
+ # make elf-libraries
+ # cd usr.bin/mkdep
+ # touch findcc.d mkdep.d .depend
+ # make install
+
20110716:
To install libterminfo and terminfo database, you need
the new stat:
install.1 isodir.1 isoinfo.1 isoread.1 join.1 kill.1 \
last.1 leave.1 loadfont.1 loadkeys.1 logger.1 login.1 \
look.1 lp.1 ls.1 lspci.1 M.1 mail.1 \
- mesg.1 mixer.1 mkdep.1 mkdir.1 mkfs.1 \
+ mesg.1 mixer.1 ackmkdep.1 mkdir.1 mkfs.1 \
mkproto.1 modem.1 mount.1 mt.1 nice.1 nm.1 nohup.1 od.1 \
ossinfo.1 ossmix.1 ossplay.1 ossrecord.1 osstest.1 passwd.1 \
paste.1 ping.1 playwave.1 postmort.1 pr.1 prep.1 \
.include <bsd.own.mk>
.if ${MKSHARE} != "no"
-FILES= bsd.ack.mk bsd.dep.mk bsd.files.mk \
- bsd.gcc.mk bsd.inc.mk \
+FILES= bsd.dep.mk bsd.files.mk \
+ bsd.inc.mk \
bsd.init.mk bsd.kinc.mk bsd.klinks.mk bsd.lib.mk \
bsd.links.mk bsd.man.mk bsd.obj.mk bsd.own.mk \
- bsd.prog.mk bsd.subdir.mk bsd.sys.mk bsd.gcov.mk \
- pkgsrchooks.mk sys.mk
+ bsd.prog.mk bsd.subdir.mk bsd.sys.mk \
+ sys.mk
# MINIX-specific files
-FILES+= minix.bootprog.mk minix.service.mk
+FILES+= minix.bootprog.mk minix.service.mk minix.ackdep.mk \
+ minix.ack.mk minix.gcc.mk minix.gcov.mk pkgsrchooks.mk
FILESDIR=/usr/share/mk
.endif
# some of the rules involve .h sources, so remove them from mkdep line
.if defined(SRCS) # {
-#_TRADITIONAL_CPP?=-traditional-cpp
__acpp_flags= ${_TRADITIONAL_CPP}
__DPSRCS.all= ${SRCS:C/\.(c|m|s|S|C|cc|cpp|cxx)$/.d/} \
.depend: ${__DPSRCS.d}
${_MKTARGET_CREATE}
rm -f .depend
-# ${MKDEP} -d -f ${.TARGET} -s ${MKDEP_SUFFIXES:Q} ${__DPSRCS.d}
- cat ${__DPSRCS.d} > ${.TARGET}
+ ${MKDEP} -d -f ${.TARGET} -s ${MKDEP_SUFFIXES:Q} ${__DPSRCS.d}
.SUFFIXES: .d .s .S .c .C .cc .cpp .cxx .m
.c.d:
${_MKTARGET_CREATE}
-# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
-# ${CFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
-# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
-# mkdep -- ${MKDEPFLAGS} \
-# ${CFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
-# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC} > ${.TARGET}
- mkdep "$(CC) ${CFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
- ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} -E" ${.IMPSRC} > ${.TARGET}
-
-# .m.d:
-# ${_MKTARGET_CREATE}
-# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
-# ${OBJCFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
-# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
+ ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+ ${CFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+ ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
+
+.m.d:
+ ${_MKTARGET_CREATE}
+ ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+ ${OBJCFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+ ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
.s.d .S.d:
${_MKTARGET_CREATE}
-# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
-# ${AFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
-# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${__acpp_flags} ${.IMPSRC}
- mkdep "$(CC) ${AFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
- ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} -E" ${.IMPSRC} > ${.TARGET}
-
-# .C.d .cc.d .cpp.d .cxx.d:
-# ${_MKTARGET_CREATE}
-# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
-# ${CXXFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
-# ${DESTDIR:D-nostdinc++ ${CPPFLAG_ISYSTEMXX} \
-# ${DESTDIR}/usr/include/g++} \
-# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
+ ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+ ${AFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+ ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${__acpp_flags} ${.IMPSRC}
+
+.C.d .cc.d .cpp.d .cxx.d:
+ ${_MKTARGET_CREATE}
+ ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+ ${CXXFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+ ${DESTDIR:D-nostdinc++ ${CPPFLAG_ISYSTEMXX} \
+ ${DESTDIR}/usr/include/g++} \
+ ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
.endif # defined(SRCS) # }
.endif
##### Custom rules
-# .if !target(tags)
-# tags: ${SRCS}
-# .if defined(SRCS)
-# -cd ${.CURDIR}; ctags -f /dev/stdout ${.ALLSRC:N*.h} | \
-# ${TOOL_SED} "s;\${.CURDIR}/;;" > tags
-# .endif
-# .endif
+.if !target(tags)
+tags: ${SRCS}
+.if defined(SRCS)
+ -cd ${.CURDIR}; ctags -f /dev/stdout ${.ALLSRC:N*.h} | \
+ ${TOOL_SED} "s;\${.CURDIR}/;;" > tags
+.endif
+.endif
.include <bsd.files.mk>
.include <bsd.inc.mk>
.include <bsd.links.mk>
+.if ${COMPILER_TYPE} == "ack"
+.include <minix.ackdep.mk>
+.elif ${COMPILER_TYPE} == "gnu"
.include <bsd.dep.mk>
+.endif
.if ${COMPILER_TYPE} == "ack"
-.include <bsd.ack.mk>
+.include <minix.ack.mk>
.elif ${COMPILER_TYPE} == "gnu"
-.include <bsd.gcc.mk>
+.include <minix.gcc.mk>
.endif
.include <bsd.inc.mk>
.include <bsd.links.mk>
.include <bsd.sys.mk>
+.if ${COMPILER_TYPE} == "ack"
+.include <minix.ackdep.mk>
+.elif ${COMPILER_TYPE} == "gnu"
.include <bsd.dep.mk>
+.endif
.if ${COMPILER_TYPE} == "ack"
-.include <bsd.ack.mk>
+.include <minix.ack.mk>
.elif ${COMPILER_TYPE} == "gnu"
-.include <bsd.gcc.mk>
+.include <minix.gcc.mk>
.endif
--- /dev/null
+# $NetBSD: bsd.dep.mk,v 1.68 2008/10/25 22:27:36 apb Exp $
+
+##### Basic targets
+cleandir: cleandepend
+realdepend: beforedepend .depend afterdepend
+.ORDER: beforedepend .depend afterdepend
+
+beforedepend .depend afterdepend: # ensure existence
+
+##### Default values
+MKDEP= ackmkdep
+MKDEP_SUFFIXES?= .o
+
+##### Build rules
+# some of the rules involve .h sources, so remove them from mkdep line
+
+.if defined(SRCS) # {
+#_TRADITIONAL_CPP?=-traditional-cpp
+__acpp_flags= ${_TRADITIONAL_CPP}
+
+__DPSRCS.all= ${SRCS:C/\.(c|m|s|S|C|cc|cpp|cxx)$/.d/} \
+ ${DPSRCS:C/\.(c|m|s|S|C|cc|cpp|cxx)$/.d/}
+__DPSRCS.d= ${__DPSRCS.all:O:u:M*.d}
+__DPSRCS.notd= ${__DPSRCS.all:O:u:N*.d}
+
+.NOPATH: .depend ${__DPSRCS.d}
+
+.if !empty(__DPSRCS.d) # {
+${__DPSRCS.d}: ${__DPSRCS.notd} ${DPSRCS}
+.endif # }
+
+.depend: ${__DPSRCS.d}
+ ${_MKTARGET_CREATE}
+ rm -f .depend
+# ${MKDEP} -d -f ${.TARGET} -s ${MKDEP_SUFFIXES:Q} ${__DPSRCS.d}
+ cat ${__DPSRCS.d} > ${.TARGET}
+
+.SUFFIXES: .d .s .S .c .C .cc .cpp .cxx .m
+
+.c.d:
+ ${_MKTARGET_CREATE}
+# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+# ${CFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
+# mkdep -- ${MKDEPFLAGS} \
+# ${CFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC} > ${.TARGET}
+ ${MKDEP} "$(CC) ${CFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+ ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} -E" ${.IMPSRC} > ${.TARGET}
+
+# .m.d:
+# ${_MKTARGET_CREATE}
+# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+# ${OBJCFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
+
+.s.d .S.d:
+ ${_MKTARGET_CREATE}
+# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+# ${AFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${__acpp_flags} ${.IMPSRC}
+ ${MKDEP} "$(CC) ${AFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+ ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} -E" ${.IMPSRC} > ${.TARGET}
+
+# .C.d .cc.d .cpp.d .cxx.d:
+# ${_MKTARGET_CREATE}
+# ${MKDEP} -f ${.TARGET} -- ${MKDEPFLAGS} \
+# ${CXXFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
+# ${DESTDIR:D-nostdinc++ ${CPPFLAG_ISYSTEMXX} \
+# ${DESTDIR}/usr/include/g++} \
+# ${CPPFLAGS} ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC}
+
+.endif # defined(SRCS) # }
+
+##### Clean rules
+cleandepend: .PHONY
+.if defined(SRCS)
+ rm -f .depend ${__DPSRCS.d} ${.CURDIR}/tags ${CLEANDEPEND}
+.endif
+
+##### Custom rules
+# .if !target(tags)
+# tags: ${SRCS}
+# .if defined(SRCS)
+# -cd ${.CURDIR}; ctags -f /dev/stdout ${.ALLSRC:N*.h} | \
+# ${TOOL_SED} "s;\${.CURDIR}/;;" > tags
+# .endif
+# .endif
CLEANFILES+= *.gcno *.gcda $(LCOV)
.if ${MKCOVERAGE} == "yes"
-CFLAGS+=-fno-builtin -fprofile-arcs -ftest-coverage
+CFLAGS+=-fno-builtin -fprofile-arcs -ftest-coverage
LDADD+= -lgcov
COMPILER_TYPE=gnu
CC=gcc
usr.bin/sed src/usr.bin/sed
usr.bin/stat src/usr.bin/stat
usr.bin/tic src/usr.bin/tic
+usr.bin/mkdep src/usr.bin/mkdep
.include <bsd.own.mk>
# NetBSD imports
-SUBDIR= indent m4 mkimage stat tic sed
+SUBDIR= indent m4 stat tic sed mkdep
# Non-NetBSD imports
-SUBDIR+= ministat
+SUBDIR+= ministat mkimage
.include <bsd.subdir.mk>
--- /dev/null
+# $NetBSD: Makefile,v 1.17 2009/04/12 14:23:30 lukem Exp $
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+#CFLAGS+=-g
+MAN= mkdep.1
+PROG= mkdep
+SRCS= mkdep.c findcc.c
+
+.include <bsd.prog.mk>
--- /dev/null
+/* $NetBSD: findcc.c,v 1.5 2009/04/12 14:23:30 lukem Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matthias Scheler.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+#if !defined(lint)
+__COPYRIGHT("@(#) Copyright (c) 1999 The NetBSD Foundation, Inc.\
+ All rights reserved.");
+__RCSID("$NetBSD: findcc.c,v 1.5 2009/04/12 14:23:30 lukem Exp $");
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "findcc.h"
+
+char *
+findcc(progname)
+ const char *progname;
+{
+ char *path, *dir, *next;
+ char buffer[MAXPATHLEN];
+
+ if ((next = strchr(progname, ' ')) != NULL) {
+ *next = '\0';
+ }
+
+ if (strchr(progname, '/') != NULL)
+ return access(progname, X_OK) ? NULL : strdup(progname);
+
+ if (((path = getenv("PATH")) == NULL) ||
+ ((path = strdup(path)) == NULL))
+ return NULL;
+
+ dir = path;
+ while (dir != NULL) {
+ if ((next = strchr(dir, ':')) != NULL)
+ *next++ = '\0';
+
+ if (snprintf(buffer, sizeof(buffer),
+ "%s/%s", dir, progname) < (int)sizeof(buffer)) {
+ if (!access(buffer, X_OK)) {
+ free(path);
+ return strdup(buffer);
+ }
+ }
+ dir = next;
+ }
+
+ free(path);
+ return NULL;
+}
+
--- /dev/null
+#ifndef __minix
+#define DEFAULT_CC "cc"
+#else
+#define DEFAULT_CC "clang"
+#endif
+
+char *findcc(const char *);
--- /dev/null
+.\" $NetBSD: mkdep.1,v 1.15 2010/10/15 05:46:48 dholland Exp $
+.\"
+.\" Copyright (c) 1987, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mkdep.1 8.1 (Berkeley) 6/6/93
+.\"
+.Dd October 15, 2010
+.Dt MKDEP 1
+.Os
+.Sh NAME
+.Nm mkdep
+.Nd construct Makefile dependency list
+.Sh SYNOPSIS
+.Nm
+.Op Fl aDdopq
+.Op Fl f Ar file
+.Op Fl s Ar suffixes
+.Li --
+.Op Ar flags
+.Ar file ...
+.Sh DESCRIPTION
+.Nm
+takes a set of flags for the C compiler and a list
+of C source files as arguments and constructs a set of include
+file dependencies which are written into the file ``.depend''.
+An example of its use in a Makefile might be:
+.Bd -literal -offset indent
+CFLAGS= -O -I../include
+SRCS= file1.c file2.c
+
+depend:
+ mkdep -- ${CFLAGS} ${SRCS}
+.Ed
+.Pp
+where the macro SRCS is the list of C source files and the macro
+CFLAGS is the list of flags for the C compiler.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl a
+Append to the output file,
+so that multiple
+.Nm Ns 's
+may be run from a single Makefile.
+.It Fl D
+Post process (as
+.Fl d )
+but read the list of filenames from stdin.
+.It Fl d
+Post process and merge previously created (for example by
+.Dq cc -MD x.c )
+depend files into a single file.
+.It Fl f
+Write the include file dependencies to
+.Ar file ,
+instead of the default ``.depend''.
+.It Fl o
+Add an additional .OPTIONAL line for each dependant file.
+.It Fl p
+Cause
+.Nm
+to produce dependencies of the form:
+.Bd -literal -offset indent
+program: program.c
+.Ed
+.Pp
+so that subsequent makes will produce
+.Ar program
+directly from its C module rather than using an intermediate
+.Pa \&.o
+module.
+This is useful for programs whose source is contained in a single
+module.
+.Fl p
+is equivalent to specifying a null suffix with
+.Fl s .
+.It Fl q
+Do not print a warning for inaccessible files when
+.Fl d
+is given.
+.It Fl s
+Expand each target filename to a list, replacing the
+.Ql \&.o
+suffix with each element of
+.Ar suffixes .
+The list of suffixes may be space or comma separated.
+.El
+.Sh FILES
+.Bl -tag -width .depend -compact
+.It Pa .depend
+File containing list of dependencies.
+.El
+.Sh SEE ALSO
+.Xr cc 1 ,
+.Xr cpp 1 ,
+.Xr make 1
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 Tahoe .
+.Sh BUGS
+Some characters special to
+.Xr make 1 ,
+most notably the comment character, are not escaped correctly if they
+appear in file names.
+This can lead to unparseable output or silently cause dependencies to
+be lost.
+.\" (This problem is actually in gcc -M.)
--- /dev/null
+/* $NetBSD: mkdep.c,v 1.35 2010/05/26 18:07:34 christos Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matthias Scheler.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+#if !defined(lint)
+__COPYRIGHT("@(#) Copyright (c) 1999 The NetBSD Foundation, Inc.\
+ All rights reserved.");
+__RCSID("$NetBSD: mkdep.c,v 1.35 2010/05/26 18:07:34 christos Exp $");
+#endif /* not lint */
+
+#ifndef __minix
+#include <sys/mman.h>
+#endif
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "findcc.h"
+
+typedef struct opt opt_t;
+struct opt {
+ opt_t *left;
+ opt_t *right;
+ int len;
+ int count;
+ char name[4];
+};
+
+typedef struct {
+ size_t len;
+ char suff[12];
+} suff_list_t;
+
+/* tree of includes for -o processing */
+opt_t *opt;
+int width;
+
+#define DEFAULT_PATH _PATH_DEFPATH
+#define DEFAULT_FILENAME ".depend"
+
+static void save_for_optional(const char *, const char *);
+static int write_optional(int, opt_t *, int);
+
+
+static inline void *
+deconst(const void *p)
+{
+ return (const char *)p - (const char *)0 + (char *)0;
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "usage: %s [-aDdopq] [-f file] [-s suffixes] -- [flags] file ...\n",
+ getprogname());
+ exit(EXIT_FAILURE);
+}
+
+static int
+run_cc(int argc, char **argv, const char **fname)
+{
+ const char *CC, *tmpdir;
+ char * volatile pathname;
+ static char tmpfilename[MAXPATHLEN];
+ char **args;
+ int tmpfd;
+ pid_t pid, cpid;
+ int status;
+
+ if ((CC = getenv("CC")) == NULL)
+ CC = DEFAULT_CC;
+ if ((pathname = findcc(CC)) == NULL)
+ if (!setenv("PATH", DEFAULT_PATH, 1))
+ pathname = findcc(CC);
+ if (pathname == NULL)
+ err(EXIT_FAILURE, "%s: not found", CC);
+ if ((args = malloc((argc + 3) * sizeof(char *))) == NULL)
+ err(EXIT_FAILURE, "malloc");
+
+ args[0] = deconst(CC);
+ args[1] = deconst("-M");
+ (void)memcpy(&args[2], argv, (argc + 1) * sizeof(char *));
+
+ if ((tmpdir = getenv("TMPDIR")) == NULL)
+ tmpdir = _PATH_TMP;
+ (void)snprintf(tmpfilename, sizeof (tmpfilename), "%s/%s", tmpdir,
+ "mkdepXXXXXX");
+ if ((tmpfd = mkstemp(tmpfilename)) < 0) {
+ warn("unable to create temporary file %s", tmpfilename);
+ exit(EXIT_FAILURE);
+ }
+ (void)unlink(tmpfilename);
+ *fname = tmpfilename;
+
+ switch (cpid = vfork()) {
+ case 0:
+ (void)dup2(tmpfd, STDOUT_FILENO);
+ (void)close(tmpfd);
+
+ (void)execv(pathname, args);
+ _exit(EXIT_FAILURE);
+ /* NOTREACHED */
+
+ case -1:
+ err(EXIT_FAILURE, "unable to fork");
+ }
+
+ free(pathname);
+ free(args);
+
+ while (((pid = wait(&status)) != cpid) && (pid >= 0))
+ continue;
+
+ if (status)
+ errx(EXIT_FAILURE, "compile failed.");
+
+ return tmpfd;
+}
+
+static const char *
+read_fname(void)
+{
+ static char *fbuf;
+ static int fbuflen;
+ int len, ch;
+
+ for (len = 0; (ch = getchar()) != EOF; len++) {
+ if (isspace(ch)) {
+ if (len != 0)
+ break;
+ len--;
+ continue;
+ }
+ if (len >= fbuflen - 1) {
+ fbuf = realloc(fbuf, fbuflen += 32);
+ if (fbuf == NULL)
+ err(EXIT_FAILURE, "no memory");
+ }
+ fbuf[len] = ch;
+ }
+ if (len == 0)
+ return NULL;
+ fbuf[len] = 0;
+ return fbuf;
+}
+
+int
+main(int argc, char **argv)
+{
+ int aflag, dflag, oflag, qflag;
+ const char *filename;
+ int dependfile;
+ char *buf, *lim, *ptr, *line, *suf, *colon, *eol;
+ int ok_ind, ch;
+ size_t sz;
+ int fd;
+ size_t slen;
+ const char *fname;
+ const char *suffixes = NULL, *s;
+ suff_list_t *suff_list = NULL, *sl;
+#ifdef __minix
+ size_t nr;
+#endif
+
+ suf = NULL; /* XXXGCC -Wuninitialized [sun2] */
+ sl = NULL; /* XXXGCC -Wuninitialized [sun2] */
+
+ setlocale(LC_ALL, "");
+ setprogname(argv[0]);
+
+ aflag = O_WRONLY | O_APPEND | O_CREAT | O_TRUNC;
+ dflag = 0;
+ oflag = 0;
+ qflag = 0;
+ filename = DEFAULT_FILENAME;
+ dependfile = -1;
+
+ opterr = 0; /* stop getopt() bleating about errors. */
+ for (;;) {
+ ok_ind = optind;
+ ch = getopt(argc, argv, "aDdf:opqs:");
+ switch (ch) {
+ case -1:
+ ok_ind = optind;
+ break;
+ case 'a': /* Append to output file */
+ aflag &= ~O_TRUNC;
+ continue;
+ case 'D': /* Process *.d files (don't run cc -M) */
+ dflag = 2; /* Read names from stdin */
+ opterr = 1;
+ continue;
+ case 'd': /* Process *.d files (don't run cc -M) */
+ dflag = 1;
+ opterr = 1;
+ continue;
+ case 'f': /* Name of output file */
+ filename = optarg;
+ continue;
+ case 'o': /* Mark dependant files .OPTIONAL */
+ oflag = 1;
+ continue;
+ case 'p': /* Program mode (x.o: -> x:) */
+ suffixes = "";
+ continue;
+ case 'q': /* Quiet */
+ qflag = 1;
+ continue;
+ case 's': /* Suffix list */
+ suffixes = optarg;
+ continue;
+ default:
+ if (dflag)
+ usage();
+ /* Unknown arguments are passed to "${CC} -M" */
+ break;
+ }
+ break;
+ }
+
+ argc -= ok_ind;
+ argv += ok_ind;
+ if ((argc == 0 && !dflag) || (argc != 0 && dflag == 2))
+ usage();
+
+ if (suffixes != NULL) {
+ /* parse list once and save names and lengths */
+ /* allocate an extra entry to mark end of list */
+ for (sz = 1, s = suffixes; *s != 0; s++)
+ if (*s == '.')
+ sz++;
+ suff_list = calloc(sz, sizeof *suff_list);
+ if (suff_list == NULL)
+ err(2, "malloc");
+ sl = suff_list;
+ for (s = suffixes; (s = strchr(s, '.')); s += sz, sl++) {
+ sz = strcspn(s, ", ");
+ if (sz > sizeof sl->suff)
+ errx(2, "suffix too long");
+ sl->len = sz;
+ memcpy(sl->suff, s, sz);
+ }
+ }
+
+ dependfile = open(filename, aflag, 0666);
+ if (dependfile == -1)
+ err(EXIT_FAILURE, "unable to %s to file %s\n",
+ aflag & O_TRUNC ? "write" : "append", filename);
+
+ while (dflag == 2 || *argv != NULL) {
+ if (dflag) {
+ if (dflag == 2) {
+ fname = read_fname();
+ if (fname == NULL)
+ break;
+ } else
+ fname = *argv++;
+ fd = open(fname, O_RDONLY, 0);
+ if (fd == -1) {
+ if (!qflag)
+ warn("ignoring %s", fname);
+ continue;
+ }
+ } else {
+ fd = run_cc(argc, argv, &fname);
+ /* consume all args... */
+ argv += argc;
+ }
+
+ sz = lseek(fd, 0, SEEK_END);
+ if (sz == 0) {
+ close(fd);
+ continue;
+ }
+#ifndef __minix
+ buf = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+ close(fd);
+
+ if (buf == MAP_FAILED)
+ err(EXIT_FAILURE, "unable to mmap file %s", fname);
+#else
+ buf = malloc(sz);
+ if (buf == NULL)
+ err(EXIT_FAILURE, "malloc");
+ if ((nr = pread(fd, buf, sz, 0)) != sz)
+ err(EXIT_FAILURE, "read error %s", fname);
+ close(fd);
+#endif
+ lim = buf + sz - 1;
+
+ /* Remove leading "./" from filenames */
+ for (ptr = buf; ptr < lim; ptr++) {
+ if (ptr[1] != '.' || ptr[2] != '/'
+ || !isspace((unsigned char)ptr[0]))
+ continue;
+ ptr[1] = ' ';
+ ptr[2] = ' ';
+ }
+
+ for (line = eol = buf; eol <= lim;) {
+ while (eol <= lim && *eol++ != '\n')
+ /* Find end of this line */
+ continue;
+ if (line == eol - 1) {
+ /* empty line - ignore */
+ line = eol;
+ continue;
+ }
+ if (eol[-2] == '\\')
+ /* Assemble continuation lines */
+ continue;
+ for (colon = line; *colon != ':'; colon++) {
+ if (colon >= eol) {
+ colon = NULL;
+ break;
+ }
+ }
+ if (isspace((unsigned char)*line) || colon == NULL) {
+ /* No dependency - just transcribe line */
+ write(dependfile, line, eol - line);
+ line = eol;
+ continue;
+ }
+ if (suff_list != NULL) {
+ /* Find the .o: */
+ /* First allow for any whitespace */
+ for (suf = colon; suf > buf; suf--) {
+ if (!isspace((unsigned char)suf[-1]))
+ break;
+ }
+ if (suf == buf)
+ errx(EXIT_FAILURE,
+ "Corrupted file `%s'", fname);
+ /* Then look for any valid suffix */
+ for (sl = suff_list; sl->len != 0; sl++) {
+ if (!memcmp(suf - sl->len, sl->suff,
+ sl->len))
+ break;
+ }
+ /*
+ * Not found, check for .o, since the
+ * original file will have it.
+ */
+ if (sl->len == 0 && suff_list->len != 0) {
+ if (memcmp(suf - 2, ".o", 2) == 0)
+ slen = 2;
+ else
+ slen = 0;
+ } else
+ slen = sl->len;
+ }
+ if (suff_list != NULL && slen != 0) {
+ suf -= slen;
+ for (sl = suff_list; sl->len != 0; sl++) {
+ if (sl != suff_list)
+ write(dependfile, " ", 1);
+ write(dependfile, line, suf - line);
+ write(dependfile, sl->suff, sl->len);
+ }
+ write(dependfile, colon, eol - colon);
+ } else
+ write(dependfile, line, eol - line);
+
+ if (oflag)
+ save_for_optional(colon + 1, eol);
+ line = eol;
+ }
+#ifndef __minix
+ munmap(buf, sz);
+#else
+ free(buf);
+#endif
+ }
+
+ if (oflag && opt != NULL) {
+ write(dependfile, ".OPTIONAL:", 10);
+ width = 9;
+ sz = write_optional(dependfile, opt, 0);
+ /* 'depth' is about 39 for an i386 kernel */
+ /* fprintf(stderr, "Recursion depth %d\n", sz); */
+ }
+ close(dependfile);
+
+ exit(EXIT_SUCCESS);
+}
+
+
+/*
+ * Only save each file once - the kernel .depend is 3MB and there is
+ * no point doubling its size.
+ * The data seems to be 'random enough' so the simple binary tree
+ * only has a reasonable depth.
+ */
+static void
+save_for_optional(const char *start, const char *limit)
+{
+ opt_t **l, *n;
+ const char *name, *end;
+ int c;
+
+ while (start < limit && strchr(" \t\n\\", *start))
+ start++;
+ for (name = start; ; name = end) {
+ while (name < limit && strchr(" \t\n\\", *name))
+ name++;
+ for (end = name; end < limit && !strchr(" \t\n\\", *end);)
+ end++;
+ if (name >= limit)
+ break;
+ if (end[-1] == 'c' && end[-2] == '.' && name == start)
+ /* ignore dependency on the files own .c */
+ continue;
+ for (l = &opt;;) {
+ n = *l;
+ if (n == NULL) {
+ n = malloc(sizeof *n + (end - name));
+ n->left = n->right = 0;
+ n->len = end - name;
+ n->count = 1;
+ n->name[0] = ' ';
+ memcpy(n->name + 1, name, end - name);
+ *l = n;
+ break;
+ }
+ c = (end - name) - n->len;
+ if (c == 0)
+ c = memcmp(n->name + 1, name, (end - name));
+ if (c == 0) {
+ /* Duplicate */
+ n->count++;
+ break;
+ }
+ if (c < 0)
+ l = &n->left;
+ else
+ l = &n->right;
+ }
+ }
+}
+
+static int
+write_optional(int fd, opt_t *node, int depth)
+{
+ int d1 = ++depth;
+
+ if (node->left)
+ d1 = write_optional(fd, node->left, d1);
+ if (width > 76 - node->len) {
+ write(fd, " \\\n ", 4);
+ width = 1;
+ }
+ width += 1 + node->len;
+ write(fd, node->name, 1 + node->len);
+ if (node->right)
+ depth = write_optional(fd, node->right, depth);
+ return d1 > depth ? d1 : depth;
+}