Import NetBSD mkdep

This commit is contained in:
Arun Thomas 2011-07-22 17:28:27 +02:00
parent 01b152d6d9
commit 06617e7fdf
21 changed files with 885 additions and 53 deletions

View file

@ -17,7 +17,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
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 \

View file

@ -1,4 +1,4 @@
SCRIPTS= mkdep.sh
SCRIPTS= ackmkdep.sh
MAN=
.include <bsd.prog.mk>

View file

@ -1,6 +1,6 @@
#!/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.)
@ -14,8 +14,8 @@ case $# in
# 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 ...

View file

@ -1,3 +1,11 @@
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:

View file

@ -11,7 +11,7 @@ MAN= acd.1 anm.1 ar.1 ash.1 asize.1 at.1 banner.1 basename.1 \
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 \

View file

@ -3,15 +3,16 @@ NOOBJ= # defined
.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

View file

@ -15,7 +15,6 @@ MKDEP_SUFFIXES?= .o
# 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/} \
@ -32,43 +31,35 @@ ${__DPSRCS.d}: ${__DPSRCS.notd} ${DPSRCS}
.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}
${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}
.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}
${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}
.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) # }
@ -79,10 +70,10 @@ cleandepend: .PHONY
.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

View file

@ -153,10 +153,14 @@ LINKSMODE?= ${LIBMODE}
.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

View file

@ -360,12 +360,16 @@ LINKSMODE?= ${BINMODE}
.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

88
share/mk/minix.ackdep.mk Normal file
View file

@ -0,0 +1,88 @@
# $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

View file

@ -2,7 +2,7 @@ LCOV=lcov.$(PROG)
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

View file

@ -9,3 +9,4 @@ usr.bin/indent src/usr.bin/indent
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

View file

@ -3,9 +3,9 @@
.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>

9
usr.bin/mkdep/Makefile Normal file
View file

@ -0,0 +1,9 @@
# $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>

87
usr.bin/mkdep/findcc.c Normal file
View file

@ -0,0 +1,87 @@
/* $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;
}

7
usr.bin/mkdep/findcc.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef __minix
#define DEFAULT_CC "cc"
#else
#define DEFAULT_CC "clang"
#endif
char *findcc(const char *);

134
usr.bin/mkdep/mkdep.1 Normal file
View file

@ -0,0 +1,134 @@
.\" $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.)

498
usr.bin/mkdep/mkdep.c Normal file
View file

@ -0,0 +1,498 @@
/* $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;
}