Date: Sat, 22 Sep 2012 21:12:44 -0700 From: Garrett Cooper <yanegomi@gmail.com> To: freebsd-toolchain@freebsd.org Cc: freebsd-hackers@freebsd.org, Bruce Evans <brde@optusnet.com.au> Subject: Re: [CFT/RFC]: refactor bsd.prog.mk to understand multiple programs instead of a singular program Message-ID: <CAGH67wSuX7zJrTb5GehQWHKqYKog-aTwkiNw5CSJLrzftzKTaA@mail.gmail.com> In-Reply-To: <CAGH67wRkOmy7rWLkxXnT2155PuSQpwOMyu7dTAKeO1WW2dju7g@mail.gmail.com> References: <CAGH67wRkOmy7rWLkxXnT2155PuSQpwOMyu7dTAKeO1WW2dju7g@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Sun, Sep 2, 2012 at 11:01 PM, Garrett Cooper <yanegomi@gmail.com> wrote:
> Hello,
> I've been a bit busy working on porting over ATF from NetBSD, and
> one of the pieces that's currently not available in FreeBSD that's
> available in NetBSD is the ability to understand and compile multiple
> programs. In order to do this I had to refactor bsd.prog.mk (a lot).
> The attached patch is the end result so far, and I was wondering if
> anyone could please review it and/or test it (outside of me doing so).
> I wrote over 40 tests, but it's not exercising everything, and I would
> like for someone to please review/test this out who has an interest in
> NLS support (ala bsd.nls.mk) in particular. AFAICT this is the only
> gap that I couldn't resolve right away (there isn't a ton of recent
> documentation on how to use bsd.nls.mk).
> I'll run a micro benchmark and buildworld a few times (in
> progress) with and without the change to measure the performance
> effect.
> Any assistance would be much appreciated.
I've attached an updated version of the patch (run through
buildworld successfully multiple times; make universe successfully;
going to submit for an -exp run). I needed to modify bsd.crunchgen.mk
to grok OBJS.${PROG}, but apart from that backwards compatibility has
been maintained -- sans-INSTALLFLAGS_EDIT (does anyone still use that
undocumented functionality?).
Performance wise, it's slightly slower on my W3520 with the
change, but not by much (~20 seconds).
As always, questions and comments are welcome, and if someone has
a chance, please review the proposed patch.
Thanks!
-Garrett
Without the change:
$ python calc_runtime.py bw.*_without.log | ministat -w 72
x <stdin>
+------------------------------------------------------------------------+
| x |
|x x x x x xx x x|
| |_________________________A_________M________________| |
+------------------------------------------------------------------------+
N Min Max Median Avg Stddev
x 10 919 1010 972 958.9 33.994934
With the change:
$ python calc_runtime.py bw.*.log | ministat -w 72
x <stdin>
+------------------------------------------------------------------------+
| x |
|xx x x x x x xx|
| |___________________________A_________________M_________| |
+------------------------------------------------------------------------+
N Min Max Median Avg Stddev
x 10 940 1002 988 972.3 24.476973
make universe results:
# make universe MAKE_JUST_WORLDS=y
--------------------------------------------------------------
>>> make universe started on Tue Sep 18 09:30:04 PDT 2012
--------------------------------------------------------------
>> amd64 started on Tue Sep 18 09:30:04 PDT 2012
>> amd64.amd64 buildworld started on Tue Sep 18 09:30:04 PDT 2012
>> amd64.amd64 buildworld completed on Tue Sep 18 11:20:19 PDT 2012
>> amd64 completed on Tue Sep 18 11:20:19 PDT 2012
>> arm started on Tue Sep 18 11:20:19 PDT 2012
>> arm.arm buildworld started on Tue Sep 18 11:20:19 PDT 2012
>> arm.arm buildworld completed on Tue Sep 18 12:25:24 PDT 2012
>> arm.armeb buildworld started on Tue Sep 18 12:25:24 PDT 2012
>> arm.armeb buildworld completed on Tue Sep 18 13:30:25 PDT 2012
>> arm.armv6 buildworld started on Tue Sep 18 13:30:25 PDT 2012
>> arm.armv6 buildworld completed on Tue Sep 18 14:35:14 PDT 2012
>> arm.armv6eb buildworld started on Tue Sep 18 14:35:14 PDT 2012
>> arm.armv6eb buildworld completed on Tue Sep 18 15:40:05 PDT 2012
>> arm completed on Tue Sep 18 15:40:05 PDT 2012
>> i386 started on Tue Sep 18 15:40:05 PDT 2012
>> i386.i386 buildworld started on Tue Sep 18 15:40:05 PDT 2012
>> i386.i386 buildworld completed on Tue Sep 18 16:56:06 PDT 2012
>> i386 completed on Tue Sep 18 16:56:06 PDT 2012
>> ia64 started on Tue Sep 18 16:56:06 PDT 2012
>> ia64.ia64 buildworld started on Tue Sep 18 16:56:06 PDT 2012
>> ia64.ia64 buildworld completed on Tue Sep 18 18:27:49 PDT 2012
>> ia64 completed on Tue Sep 18 18:27:49 PDT 2012
>> mips started on Tue Sep 18 18:27:49 PDT 2012
>> mips.mipsel buildworld started on Tue Sep 18 18:27:49 PDT 2012
>> mips.mipsel buildworld completed on Tue Sep 18 19:34:50 PDT 2012
>> mips.mips buildworld started on Tue Sep 18 19:34:50 PDT 2012
>> mips.mips buildworld completed on Tue Sep 18 20:41:49 PDT 2012
>> mips.mips64el buildworld started on Tue Sep 18 20:41:49 PDT 2012
>> mips.mips64el buildworld completed on Tue Sep 18 21:49:21 PDT 2012
>> mips.mips64 buildworld started on Tue Sep 18 21:49:21 PDT 2012
>> mips.mips64 buildworld completed on Tue Sep 18 22:57:13 PDT 2012
>> mips.mipsn32 buildworld started on Tue Sep 18 22:57:13 PDT 2012
>> mips.mipsn32 buildworld completed on Wed Sep 19 00:04:43 PDT 2012
>> mips completed on Wed Sep 19 00:04:43 PDT 2012
>> pc98 started on Wed Sep 19 00:04:43 PDT 2012
>> pc98.i386 buildworld started on Wed Sep 19 00:04:43 PDT 2012
>> pc98.i386 buildworld completed on Wed Sep 19 01:20:42 PDT 2012
>> pc98 completed on Wed Sep 19 01:20:42 PDT 2012
>> powerpc started on Wed Sep 19 01:20:42 PDT 2012
>> powerpc.powerpc buildworld started on Wed Sep 19 01:20:42 PDT 2012
>> powerpc.powerpc buildworld completed on Wed Sep 19 02:37:34 PDT 2012
>> powerpc.powerpc64 buildworld started on Wed Sep 19 02:37:34 PDT 2012
>> powerpc.powerpc64 buildworld completed on Wed Sep 19 04:28:10 PDT 2012
>> powerpc completed on Wed Sep 19 04:28:10 PDT 2012
>> sparc64 started on Wed Sep 19 04:28:10 PDT 2012
>> sparc64.sparc64 buildworld started on Wed Sep 19 04:28:10 PDT 2012
>> sparc64.sparc64 buildworld completed on Wed Sep 19 05:42:30 PDT 2012
>> sparc64 completed on Wed Sep 19 05:42:30 PDT 2012
--------------------------------------------------------------
>>> make universe completed on Wed Sep 19 05:42:30 PDT 2012
(started Tue Sep 18 09:30:04 PDT 2012)
--------------------------------------------------------------
[-- Attachment #2 --]
Index: share/mk/bsd.crunchgen.mk
===================================================================
--- share/mk/bsd.crunchgen.mk (revision 240689)
+++ share/mk/bsd.crunchgen.mk (working copy)
@@ -13,6 +13,7 @@
# local architecture.
#
# Special options can be specified for individual programs
+# CRUNCH_OBJVAR_$(P): OBJS variable for program $(P); defaults to OBJS.${PROG}.
# CRUNCH_SRCDIR_$(P): base source directory for program $(P)
# CRUNCH_BUILDOPTS_$(P): additional build options for $(P)
# CRUNCH_ALIAS_$(P): additional names to be used for $(P)
@@ -49,6 +50,7 @@
# except for those that get suppressed.
.for D in $(CRUNCH_SRCDIRS)
.for P in $(CRUNCH_PROGS_$(D))
+CRUNCH_OBJVAR_${P}?= 'OBJS.$${PROG}'
.ifdef CRUNCH_SRCDIR_${P}
$(OUTPUTS): $(CRUNCH_SRCDIR_${P})/Makefile
.else
@@ -95,6 +97,7 @@
.else
echo special $(P) buildopts DIRPRFX=${DIRPRFX}${P}/ >>$(.TARGET)
.endif
+ echo special $(P) objvar $(CRUNCH_OBJVAR_${P}) >> $(.TARGET)
.for A in $(CRUNCH_ALIAS_$(P))
echo ln $(P) $(A) >>$(.TARGET)
.endfor
Index: share/mk/bsd.dtrace.mk
===================================================================
--- share/mk/bsd.dtrace.mk (revision 240689)
+++ share/mk/bsd.dtrace.mk (working copy)
@@ -42,7 +42,7 @@
DPADD+=${LIBELF}
LDADD+=-lelf
-.if defined(PROG)
+.if defined(PROG) || defined(PROGS)
_DTRACELINKING=${OBJS}
OBJS+=${DTRACEOBJS}
.else
Index: share/mk/bsd.prog.mk
===================================================================
--- share/mk/bsd.prog.mk (revision 240689)
+++ share/mk/bsd.prog.mk (working copy)
@@ -5,222 +5,336 @@
.SUFFIXES: .out .o .c .cc .cpp .cxx .C .m .y .l .ln .s .S .asm
-# XXX The use of COPTS in modern makefiles is discouraged.
+.if ${MK_MAN} == "no"
+NO_MAN=
+.endif
+
+# Legacy knobs
+.if defined(PROG) || defined(PROG_CXX)
+. if defined(PROG)
+PROGS= ${PROG}
+. endif
+. if defined(PROG_CXX)
+PROGS= ${PROG_CXX}
+PROGS_CXX= ${PROG_CXX}
+. endif
+# Loop once to keep pattern and avoid namespace pollution
+. for _P in ${PROGS}
+. if defined(INTERNALPROG)
+INTERNALPROG.${_P}=
+. endif
+. if !defined(NO_MAN)
+. if defined(MAN)
+MAN.${_P}= ${MAN}
+. else
+. for sect in 1 1aout 2 3 4 5 6 7 8 9
+. if defined(MAN${sect})
+MAN.${_P}= ${MAN${sect}}
+. endif
+. endfor
+. endif
+. endif # defined(NO_MAN)
+. if defined(NLSNAME) && !empty(NLSNAME)
+NLSNAME.${P}:= ${NLSNAME}
+. endif
+. if defined(OBJS)
+OBJS.${_P}:= ${OBJS}
+. endif
+. if defined(PRECIOUSPROG)
+PRECIOUSPROG.${_P}=
+. endif
+. if defined(PROGNAME)
+PROGNAME.${_P}= ${PROGNAME}
+. endif
+. if defined(SRCS)
+SRCS.${_P}:= ${SRCS}
+. endif
+. endfor
+.else # !defined(PROG) && !defined(PROG_CXX)
+. if defined(PROGS_CXX) && !empty(PROGS_CXX)
+PROGS+= ${PROGS_CXX}
+. endif
+.endif # defined(PROG) || defined(PROG_CXX)
+
+.if defined(PROGS_CXX) && !empty(PROGS_CXX)
+. for _P in ${PROGS_CXX}
+PROG_CXX.${_P}=
+. endfor
+.endif
+
+# Avoid recursive variables
+.undef NLSNAME
+
.if defined(COPTS)
CFLAGS+=${COPTS}
.endif
+.if defined(DEBUG_FLAGS)
+. if ${MK_CTF} != "no" && ${DEBUG_FLAGS:M-g} != ""
+CTFFLAGS+= -g
+. endif
+CFLAGS+=${DEBUG_FLAGS}
+CXXFLAGS+=${DEBUG_FLAGS}
+.endif
+
+STRIP?= -s
+
.if ${MK_ASSERT_DEBUG} == "no"
CFLAGS+= -DNDEBUG
NO_WERROR=
.endif
-.if defined(DEBUG_FLAGS)
-CFLAGS+=${DEBUG_FLAGS}
-CXXFLAGS+=${DEBUG_FLAGS}
+.for _P in ${PROGS}
-.if ${MK_CTF} != "no" && ${DEBUG_FLAGS:M-g} != ""
-CTFFLAGS+= -g
-.endif
-.endif
+BINDIR.${_P}?= ${BINDIR}
+BINGRP.${_P}?= ${BINGRP}
+BINMODE.${_P}?= ${BINMODE}
+BINOWN.${_P}?= ${BINOWN}
-.if defined(CRUNCH_CFLAGS)
-CFLAGS+=${CRUNCH_CFLAGS}
-.endif
+CFLAGS.${_P}+= ${CFLAGS}
+CXXFLAGS.${_P}+= ${CXXFLAGS}
+DPADD.${_P}+= ${DPADD}
+LDADD.${_P}+= ${LDADD}
+LDFLAGS.${_P}+= ${LDFLAGS}
-.if !defined(DEBUG_FLAGS)
-STRIP?= -s
-.endif
+INSTALLFLAGS.${_P}?= ${INSTALLFLAGS}
-.if defined(NO_SHARED) && (${NO_SHARED} != "no" && ${NO_SHARED} != "NO")
-LDFLAGS+= -static
-.endif
+. if defined(PRECIOUSPROG.${_P})
+. if !defined(NO_FSCHG) && !defined(NO_FSCHG.${_P})
+INSTALLFLAGS.${_P}+= -fschg
+. endif
+INSTALLFLAGS.${_P}+= -S
+. endif
-.if defined(PROG_CXX)
-PROG= ${PROG_CXX}
-.endif
+NO_SHARED.${_P}?= ${NO_SHARED}
-.if defined(PROG)
-.if defined(SRCS)
+. if !defined(NLSDIR.${_P})
+NLSDIR.${_P}:= ${NLSDIR}
+. endif
+. undef NLSDIR
-OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
+. if !empty(NO_SHARED.${_P}) && ${NO_SHARED.${_P}:tl} != "no"
+LDFLAGS.${_P}+= -static
+. endif
-.if target(beforelinking)
-${PROG}: ${OBJS} beforelinking
-.else
-${PROG}: ${OBJS}
-.endif
-.if defined(PROG_CXX)
- ${CXX} ${CXXFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
-.else
- ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
-.endif
-.if ${MK_CTF} != "no"
- ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
-.endif
+. if defined(SRCS.${_P})
-.else # !defined(SRCS)
+_SRCS:= ${SRCS.${_P}}
+OBJS.${_P}+= ${_SRCS:N*.h:R:S/$/.o/g}
-.if !target(${PROG})
-.if defined(PROG_CXX)
-SRCS= ${PROG}.cc
-.else
-SRCS= ${PROG}.c
-.endif
+. if target(beforelinking)
+${_P}: ${OBJS.${_P}} beforelinking
+. else
+${_P}: ${OBJS.${_P}}
+. endif
+. if defined(PROG_CXX.${_P})
+ ${CXX} ${CXXFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
+ ${LDADD.${_P}}
+. else
+ ${CC} ${CFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
+ ${LDADD.${_P}}
+. endif
+. if ${MK_CTF} != "no"
+ ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS.${_P}}
+. endif
+. else # !defined(SRCS.${_P})
+
+. if !target(${_P})
+. if defined(PROG_CXX.${_P})
+SRCS.${_P}?= ${_P}.cc
+. else
+SRCS.${_P}?= ${_P}.c
+. endif
+
# Always make an intermediate object file because:
# - it saves time rebuilding when only the library has changed
# - the name of the object gets put into the executable symbol table instead of
# the name of a variable temporary object.
# - it's useful to keep objects around for crunching.
-OBJS= ${PROG}.o
+OBJS.${_P}:= ${_P}.o
-.if target(beforelinking)
-${PROG}: ${OBJS} beforelinking
-.else
-${PROG}: ${OBJS}
-.endif
-.if defined(PROG_CXX)
- ${CXX} ${CXXFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
-.else
- ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
-.endif
-.if ${MK_CTF} != "no"
- ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
-.endif
-.endif
+. if target(beforelinking)
+${_P}: ${OBJS.${_P}} beforelinking
+. else
+${_P}: ${OBJS.${_P}}
+. endif # target(beforelinking)
+. if defined(PROG_CXX.${_P})
+ ${CXX} ${CXXFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
+ ${LDADD.${_P}}
+. else
+ ${CC} ${CFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
+ ${LDADD.${_P}}
+. endif
+. if ${MK_CTF} != "no"
+ ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS.${_P}}
+. endif
-.endif
+. endif # !target(${_P})
-.if ${MK_MAN} != "no" && !defined(MAN) && \
- !defined(MAN1) && !defined(MAN2) && !defined(MAN3) && \
- !defined(MAN4) && !defined(MAN5) && !defined(MAN6) && \
- !defined(MAN7) && !defined(MAN8) && !defined(MAN9) && \
- !defined(MAN1aout)
-MAN= ${PROG}.1
-MAN1= ${MAN}
-.endif
-.endif
+. endif # defined(SRCS.${_P})
-all: objwarn ${PROG} ${SCRIPTS}
-.if ${MK_MAN} != "no"
+CLEANFILES+= ${OBJS.${_P}}
+
+.endfor # for _P in ${PROGS}
+
+all: objwarn ${PROGS} ${SCRIPTS}
+
+.if !defined(NO_MAN)
+. for _P in ${PROGS}
+MAN.${_P}?= ${_P}.1
+MAN:= ${MAN.${_P}}
+. include <bsd.man.mk>
+. endfor
+. if target(_manpages) # bsd.man.mk was included
all: _manpages
+. endif
.endif
-.if defined(PROG)
-CLEANFILES+= ${PROG}
-.endif
+CLEANFILES+= ${PROGS}
-.if defined(OBJS)
-CLEANFILES+= ${OBJS}
-.endif
-
.include <bsd.libnames.mk>
-.if defined(PROG)
_EXTRADEPEND:
-.if defined(LDFLAGS) && !empty(LDFLAGS:M-nostdlib)
-.if defined(DPADD) && !empty(DPADD)
- echo ${PROG}: ${DPADD} >> ${DEPENDFILE}
-.endif
-.else
- echo ${PROG}: ${LIBC} ${DPADD} >> ${DEPENDFILE}
-.if defined(PROG_CXX)
-.if !empty(CXXFLAGS:M-stdlib=libc++)
- echo ${PROG}: ${LIBCPLUSPLUS} >> ${DEPENDFILE}
-.else
- echo ${PROG}: ${LIBSTDCPLUSPLUS} >> ${DEPENDFILE}
-.endif
-.endif
-.endif
-.endif
+.for _P in ${PROGS}
+. if !empty(LDFLAGS.${P}:M-nostdlib)
+. if !empty(DPADD.${_P})
+ echo ${_P}: ${DPADD.${_P}} >> ${DEPENDFILE}
+. endif
+. else
+ echo ${_P}: ${LIBC} ${DPADD.${_P}} >> ${DEPENDFILE}
+. if defined(PROG_CXX.${_P})
+. if !empty(CXXFLAGS.${P}:M-stdlib=libc++)
+ echo ${_P}: ${LIBCPLUSPLUS} >> ${DEPENDFILE}
+. else
+ echo ${_P}: ${LIBSTDCPLUSPLUS} >> ${DEPENDFILE}
+. endif
+. endif
+. endif
+.endfor
.if !target(install)
-.if defined(PRECIOUSPROG)
-.if !defined(NO_FSCHG)
-INSTALLFLAGS+= -fschg
-.endif
-INSTALLFLAGS+= -S
-.endif
+. if !target(realinstall)
-_INSTALLFLAGS:= ${INSTALLFLAGS}
-.for ie in ${INSTALLFLAGS_EDIT}
-_INSTALLFLAGS:= ${_INSTALLFLAGS${ie}}
-.endfor
+. for _P in ${PROGS}
-.if !target(realinstall) && !defined(INTERNALPROG)
-realinstall: _proginstall
-.ORDER: beforeinstall _proginstall
-_proginstall:
-.if defined(PROG)
-.if defined(PROGNAME)
- ${INSTALL} ${STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
- ${_INSTALLFLAGS} ${PROG} ${DESTDIR}${BINDIR}/${PROGNAME}
-.else
- ${INSTALL} ${STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
- ${_INSTALLFLAGS} ${PROG} ${DESTDIR}${BINDIR}
-.endif
-.endif
-.endif # !target(realinstall)
+. if !defined(INTERNALPROG.${_P})
-.if defined(SCRIPTS) && !empty(SCRIPTS)
-realinstall: _scriptsinstall
-.ORDER: beforeinstall _scriptsinstall
+.ORDER: beforeinstall _proginstall.${_P}
+_proginstall.${_P}:
+. if defined(PROGNAME.${_P})
+ ${INSTALL} ${STRIP} -o ${BINOWN.${_P}} -g ${BINGRP.${_P}} \
+ -m ${BINMODE.${_P}} ${INSTALLFLAGS.${_P}} ${_P} \
+ ${DESTDIR}${BINDIR.${_P}}/${PROGNAME.${_P}}
+. else
+ ${INSTALL} ${STRIP} -o ${BINOWN.${_P}} -g ${BINGRP.${_P}} \
+ -m ${BINMODE.${_P}} ${INSTALLFLAGS.${_P}} ${_P} \
+ ${DESTDIR}${BINDIR.${_P}}
+. endif
+realinstall: _proginstall.${_P}
+
+. endif # !defined(INTERNALPROG.${_P})
+
+. endfor # for _P in ${PROGS}
+
+. endif # !target(realinstall)
+
+. if defined(SCRIPTS) && !empty(SCRIPTS)
SCRIPTSDIR?= ${BINDIR}
SCRIPTSOWN?= ${BINOWN}
SCRIPTSGRP?= ${BINGRP}
SCRIPTSMODE?= ${BINMODE}
-.for script in ${SCRIPTS}
-.if defined(SCRIPTSNAME)
-SCRIPTSNAME_${script:T}?= ${SCRIPTSNAME}
-.else
-SCRIPTSNAME_${script:T}?= ${script:T:R}
-.endif
-SCRIPTSDIR_${script:T}?= ${SCRIPTSDIR}
-SCRIPTSOWN_${script:T}?= ${SCRIPTSOWN}
-SCRIPTSGRP_${script:T}?= ${SCRIPTSGRP}
-SCRIPTSMODE_${script:T}?= ${SCRIPTSMODE}
-_scriptsinstall: _SCRIPTSINS_${script:T}
-_SCRIPTSINS_${script:T}: ${script}
- ${INSTALL} -o ${SCRIPTSOWN_${.ALLSRC:T}} \
- -g ${SCRIPTSGRP_${.ALLSRC:T}} -m ${SCRIPTSMODE_${.ALLSRC:T}} \
+. for S in ${SCRIPTS}
+
+realinstall: scriptsinstall
+.ORDER: beforeinstall scriptsinstall
+
+. if defined(SCRIPTSNAME)
+SCRIPTSNAME_${S}?= ${SCRIPTSNAME}
+. else
+SCRIPTSNAME_${S}?= ${S:T:R}
+. endif
+
+SCRIPTSDIR_${S}?= ${SCRIPTSDIR}
+SCRIPTSOWN_${S}?= ${SCRIPTSOWN}
+SCRIPTSGRP_${S}?= ${SCRIPTSGRP}
+SCRIPTSMODE_${S}?= ${SCRIPTSMODE}
+
+scriptsinstall: ${DESTDIR}${SCRIPTSDIR_${S}}/${SCRIPTSNAME_${S}}
+
+${DESTDIR}${SCRIPTSDIR_${S}}/${SCRIPTSNAME_${S}}: ${S}
+ ${INSTALL} -o ${SCRIPTSOWN_${S}} \
+ -g ${SCRIPTSGRP_${S}} \
+ -m ${SCRIPTSMODE_${S}} \
${.ALLSRC} \
- ${DESTDIR}${SCRIPTSDIR_${.ALLSRC:T}}/${SCRIPTSNAME_${.ALLSRC:T}}
-.endfor
+ ${.TARGET}
+
+. endfor # for S in ${SCRIPTS}
+
+. endif # defined(SCRIPTS) && !empty(SCRIPTS)
+
+.endif # !target(install)
+
+.if !defined(NO_MAN)
+. if target(_manpages) # bsd.man.mk was included
+realinstall: _maninstall
+. endif
.endif
-NLSNAME?= ${PROG}
+# Wrap bsd.nls.mk because I can't force that Makefile snippet to work only with
+# ${PROGS}.
+.for _P in ${PROGS}
+NLSNAME.${_P}?= ${_P}
+NLS:= ${NLS.${_P}}
+NLSDIR:= ${NLSDIR.${_P}}
+NLSNAME:= ${NLSNAME.${_P}}
.include <bsd.nls.mk>
+.endfor
.include <bsd.files.mk>
.include <bsd.incs.mk>
.include <bsd.links.mk>
-.if ${MK_MAN} != "no"
-realinstall: _maninstall
-.ORDER: beforeinstall _maninstall
-.endif
+.if !target(lint)
+. for _P in ${PROGS}
+. if !target(lint.${_P})
+. if defined(PROG_CXX.${_P})
+lint.${_P}:
+. else
+_CFLAGS:= ${CFLAGS.${_P}}
+_SRCS:= ${SRCS.${_P}}
+lint.${_P}: ${_SRCS:M*.c}
+ ${LINT} ${LINTFLAGS} ${_CFLAGS:M-[DIU]*} ${.ALLSRC}
+. endif
+. endif
+lint: lint.${_P}
-.endif
+. endfor
+.endif # !target(lint)
-.if !target(lint)
-lint: ${SRCS:M*.c}
-.if defined(PROG)
- ${LINT} ${LINTFLAGS} ${CFLAGS:M-[DIU]*} ${.ALLSRC}
-.endif
-.endif
+.for _P in ${PROGS}
+CFLAGS:= ${CFLAGS.${_P}}
+CXXFLAGS:= ${CXXFLAGS.${_P}}
+SRCS:= ${SRCS.${_P}}
+. include <bsd.dep.mk>
+# bsd.dep.mk mangles SRCS
+SRCS.${_P}:= ${SRCS}
+.endfor
-.if ${MK_MAN} != "no"
-.include <bsd.man.mk>
+# XXX: emulate the old bsd.prog.mk by allowing Makefiles that didn't set
+# ${PROG*} to function with this Makefile snippet.
+.if empty(PROGS)
+. include <bsd.dep.mk>
.endif
-.include <bsd.dep.mk>
-
-.if defined(PROG) && !exists(${.OBJDIR}/${DEPENDFILE})
-${OBJS}: ${SRCS:M*.h}
+.if !exists(${.OBJDIR}/${DEPENDFILE})
+. for _P in ${PROGS}
+_SRCS:= ${SRCS.${_P}}
+${OBJS.${_P}}: ${_SRCS:M*.h}
+. endfor
.endif
.include <bsd.obj.mk>
Index: share/mk/bsd.README
===================================================================
--- share/mk/bsd.README (revision 240689)
+++ share/mk/bsd.README (working copy)
@@ -207,98 +207,157 @@
It sets/uses the following variables:
-BINGRP Binary group.
+Variables global to all programs:
-BINOWN Binary owner.
+CLEANFILES Additional files to remove and
+CLEANDIRS additional directories to remove during clean and cleandir
+ targets. "rm -f" and "rm -rf" used respectively.
-BINMODE Binary mode.
+DEBUG_FLAGS debugging specific CFLAGS/LDFLAGS; if set any binaries
+ produced will not be stripped. See also: WITH_CTF
-CLEANFILES Additional files to remove and
-CLEANDIRS additional directories to remove during clean and cleandir
- targets. "rm -f" and "rm -rf" used respectively.
+FILES A list of non-executable files.
+ The installation is controlled by the FILESNAME, FILESOWN,
+ FILESGRP, FILESMODE, FILESDIR variables that can be
+ further specialized by FILES<VAR>_<file>.
-CFLAGS Flags to the compiler when creating C objects.
+LINKS The list of binary links; should be full pathnames, the
+ linked-to file coming first, followed by the linked
+ file. The files are hard-linked. For example, to link
+ /bin/test and /bin/[, use:
-FILES A list of non-executable files.
- The installation is controlled by the FILESNAME, FILESOWN,
- FILESGRP, FILESMODE, FILESDIR variables that can be
- further specialized by FILES<VAR>_<file>.
+ LINKS= ${DESTDIR}/bin/test ${DESTDIR}/bin/[
-LDADD Additional loader objects. Usually used for libraries.
- For example, to load with the compatibility and utility
- libraries, use:
+PROG The name of the program to build. If not supplied,
+ nothing is built.
+PROG_CXX If defined, the name of the C++ program to build. Also
+ causes <bsd.prog.mk> to link the program with the
+ standard C++ library. PROG_CXX overrides the value
+ of PROG if PROG is also set.
+
+STRIP The flag passed to the install program to cause the
+ binary to be stripped. This is to be used when
+ building your own install script so that the entire
+ system can be made stripped/not-stripped using a
+ single knob.
+
+SUBDIR A list of subdirectories that should be built as well.
+ Each of the targets will execute the same target in the
+ subdirectories.
+
+The following variables can be tuned for specific program use (you will need
+to suffix variable declarations with .${PROG}, e.g. PROG= foo -> SRCS.foo):
+
+BINDIR Binary directory.
+
+BINGRP Binary group.
+
+BINOWN Binary owner.
+
+BINMODE Binary mode.
+
+CFLAGS Flags to the compiler when creating C objects.
+
+DPADD Additional dependencies for the program. Usually used
+ for libraries. For example, to depend on the
+ compatibility and utility libraries use:
+
+ DPADD=${LIBCOMPAT} ${LIBUTIL}
+
+ There is a predefined identifier for each
+ (non-profiled, non-shared) library and object. Library
+ file names are transformed to identifiers by removing
+ the extension and converting to upper case.
+
+ There are no special identifiers for profiled or shared
+ libraries or objects. The identifiers for the standard
+ libraries are used in DPADD. This works correctly iff
+ all the libraries are built at the same time.
+ Unfortunately, it causes unnecessary relinks to shared
+ libraries when only the static libraries have changed.
+ Dependencies on shared libraries should be only on the
+ library version numbers.
+
+INSTALLFLAGS install(1) flags.
+
+LDADD Additional loader objects. Usually used for libraries.
+ For example, to load with the compatibility and utility
+ libraries, use:
+
LDADD=-lutil -lcompat
-LDFLAGS Additional loader flags.
+LDFLAGS Additional loader flags.
-LINKS The list of binary links; should be full pathnames, the
- linked-to file coming first, followed by the linked
- file. The files are hard-linked. For example, to link
- /bin/test and /bin/[, use:
+MAN Manual pages (should end in .1 - .9). If no MAN
+ variable is defined, "MAN=<PROG>.1" is assumed.
- LINKS= ${DESTDIR}/bin/test ${DESTDIR}/bin/[
+NO_FSCHG Do not call install(1) with -f schg.
-MAN Manual pages (should end in .1 - .9). If no MAN variable
- is defined, "MAN=${PROG}.1" is assumed.
+PRECIOUSPROG Install with -S (safe copy) and handle NO_FSCHG
+ variable case as well.
-PROG The name of the program to build. If not supplied, nothing
- is built.
+PROG_CXX C++ application name(s); the sources for the
+ application(s) are compiled via ${CXX}
-PROG_CXX If defined, the name of the program to build. Also
- causes <bsd.prog.mk> to link the program with the
- standard C++ library. PROG_CXX overrides the value
- of PROG if PROG is also set.
+PROGNAME The name that the above program will be installed, if
+ different from <PROG>.
-PROGNAME The name that the above program will be installed as, if
- different from ${PROG}.
+SRCS List of source files to build the program. If SRCS is
+ not defined, it's assumed to be ${PROG}.c or, if
+ PROG_CXX is defined, ${PROG_CXX}.cc.
-SRCS List of source files to build the program. If SRCS is not
- defined, it's assumed to be ${PROG}.c or, if PROG_CXX is
- defined, ${PROG_CXX}.cc.
+SCRIPTS A list of interpreter scripts [file.{sh,csh,pl,awk,...}].
+ The installation is controlled by the SCRIPTSNAME, SCRIPTSOWN,
+ SCRIPTSGRP, SCRIPTSMODE, SCRIPTSDIR variables that can be
+ further specialized by SCRIPTS<VAR>_<script>.
-DPADD Additional dependencies for the program. Usually used for
- libraries. For example, to depend on the compatibility and
- utility libraries use:
+The following variables can be tuned for specific scripts; you will need
+to suffix variable declarations with _<SCRIPT>, e.g.
+SCRIPT -> foo, -> SCRIPTDIR_foo. In all cases, the per-script variables
+default to the equivalent global SCRIPT* variable and fallback to the
+BIN* equivalents, e.g. SCRIPTDIR_foo falls back to SCRIPTDIR if SCRIPTDIR_foo
+is not defined, then BINDIR if SCRIPTDIR is not defined:
- DPADD=${LIBCOMPAT} ${LIBUTIL}
+SCRIPTSDIR Directory to install a script to.
- There is a predefined identifier for each (non-profiled,
- non-shared) library and object. Library file names are
- transformed to identifiers by removing the extension and
- converting to upper case.
+SCRIPTGRP Group to set for a script.
- There are no special identifiers for profiled or shared
- libraries or objects. The identifiers for the standard
- libraries are used in DPADD. This works correctly iff all
- the libraries are built at the same time. Unfortunately,
- it causes unnecessary relinks to shared libraries when
- only the static libraries have changed. Dependencies on
- shared libraries should be only on the library version
- numbers.
+SCRIPTMODE Mode to apply to a script.
-STRIP The flag passed to the install program to cause the binary
- to be stripped. This is to be used when building your
- own install script so that the entire system can be made
- stripped/not-stripped using a single nob.
+SCRIPTOWN Owner to set for a script.
-SUBDIR A list of subdirectories that should be built as well.
- Each of the targets will execute the same target in the
- subdirectories.
+Legacy variables are as follows:
-SCRIPTS A list of interpreter scripts [file.{sh,csh,pl,awk,...}].
- The installation is controlled by the SCRIPTSNAME, SCRIPTSOWN,
- SCRIPTSGRP, SCRIPTSMODE, SCRIPTSDIR variables that can be
- further specialized by SCRIPTS<VAR>_<script>.
+COPTS Optimization flags appended to CFLAGS; highly
+ discouraged in modern Makefiles.
+PROG Legacy form of `PROGS`
+
+PROG_CXX Legacy form of `PROGS_CXX`
+
+The following variables are wrapped to be made `PROGS aware`:
+
+NLS See bsd.nls.mk description for more details.
+NLSDIR
+NLSNAME
+
+Developer convenience variables:
+
+WITH_ASSERT_DEBUG Compile with CFLAGS+=-DNDEBUG
+
The include file <bsd.prog.mk> includes the file named "../Makefile.inc"
-if it exists, as well as the include file <bsd.man.mk>.
+if it exists, as well as the include file <bsd.man.mk>. Furthermore, if
+WITH_NLS is defined and NLS.<PROG> is also defined, then bsd.nls.mk is
+included as well.
Some simple examples:
+1. Single C Program:
+
To build foo from foo.c with a manual page foo.1, use:
- PROG= foo
+ PROGS= foo
.include <bsd.prog.mk>
@@ -314,6 +373,34 @@
SRCS= a.c b.c c.c d.c
+2. Single C++ Program:
+
+To build bar with bar.cc with a manual page bar.1, use:
+
+ PROGS_CXX= bar
+
+ .include <bsd.prog.mk>
+
+All other constructs are the same as in the Single C Program case.
+
+3. Multiple C programs:
+
+To build foo from foo.c and bar with bar.c, use:
+
+ PROGS= foo bar
+
+ .include <bsd.prog.mk>
+
+To build foo from bar.c and bar with foo.c, use:
+
+ PROGS= foo bar
+
+ SRCS.foo= bar.c
+
+ SRCS.bar= foo.c
+
+ .include <bsd.prog.mk>
+
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The include file <bsd.subdir.mk> contains the default targets for building
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGH67wSuX7zJrTb5GehQWHKqYKog-aTwkiNw5CSJLrzftzKTaA>
