Subject: Building multiple progs from a single directory
To: None <tech-toolchain@NetBSD.org>
From: Julio M. Merino Vidal <jmmv84@gmail.com>
List: tech-toolchain
Date: 07/08/2007 17:34:54
--Apple-Mail-5--556735670
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed
Hello,
[ Please CC me any replies ]
[ CCing Marting because he is my SoC mentor ]
I see that some of our bsd.*.mk files support building different
targets or installing different sets of files as part of a single
run. The clearest example is SCRIPTS, or the ability to install
include files in different target directories.
As part of my SoC project, I'm now adding a bsd.test.mk file that
allows me to easily build test programs. It seems to me that keeping
each test program in its own directory will be overkill, given that
test programs should be fine-grained and thus there will be many of
them. For example, I now have an "atf/units" directory with unit-
tests for different atf modules; each unit-test is a test program,
and there currently are 6 of them. Certainly more to come.
Following the current principle of one program per source directory
will make our source tree explode in the number of required inodes to
host it -- an extra Makefile plus a directory for each of these tiny
programs!
My bsd.test.mk file is built on top of bsd.prog.mk file for
simplicity (and because I see no reason to do it otherwise). In
order to get the above to work, I have adapted our bsd.prog.mk file
to support building several different programs in the same directory.
What I have done is add a couple of new variables, PROGS and
PROGS_CXX, that take the list of programs to build. Then, the SRCS,
OBJS, PROGNAME and similar variables are specialized to belong to
each individual program by appending a .<prog> suffix. Of course
compatibility is kept with the old Makefiles so that the current tree
does not need to be modified. Furthermore, it is possible to build
each program on its own by saying 'make foo' where foo is the program
name. Similarly it is also possible to only install or clean a
specific one.
I have attached the preliminary patch to achieve this. It is still
somewhat ugly (have to adjust line wrappings, reorder things a bit,
etc.) and it may still be bogus. I'm now running a full release
build from scratch to see how everything behaves.
Before I work more on this, I want to ask: are there any strong
objections to this change? If not I'll come back later on with a
cleaner patch :-)
Thanks,
--Apple-Mail-5--556735670
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
x-unix-mode=0644;
name=patch.diff
Content-Disposition: attachment;
filename=patch.diff
Index: bsd.prog.mk
===================================================================
RCS file: /cvsroot/src/share/mk/bsd.prog.mk,v
retrieving revision 1.220
diff -u -p -r1.220 bsd.prog.mk
--- bsd.prog.mk 25 Jan 2007 23:04:28 -0000 1.220
+++ bsd.prog.mk 8 Jul 2007 15:31:31 -0000
@@ -7,26 +7,49 @@
.include <bsd.shlib.mk>
.include <bsd.gcc.mk>
-.if defined(PROG_CXX)
-PROG= ${PROG_CXX}
-.endif
-
-.if defined(PAXCTL_FLAGS)
-PAXCTL_FLAGS.${PROG}?= ${PAXCTL_FLAGS}
-.endif
+#
+# Definitions and targets shared among all programs built by a single
+# Makefile.
+#
##### Basic targets
realinstall: proginstall scriptsinstall
clean: cleanprog
-##### PROG specific flags.
-COPTS+= ${COPTS.${PROG}}
-CPPFLAGS+= ${CPPFLAGS.${PROG}}
-CXXFLAGS+= ${CXXFLAGS.${PROG}}
-OBJCOPTS+= ${OBJCOPTS.${PROG}}
-LDADD+= ${LDADD.${PROG}}
-LDFLAGS+= ${LDFLAGS.${PROG}}
-LDSTATIC+= ${LDSTATIC.${PROG}}
+.gdbinit:
+ rm -f .gdbinit
+.if defined(DESTDIR) && !empty(DESTDIR)
+ echo "set solib-absolute-prefix ${DESTDIR}" > .gdbinit
+.else
+ touch .gdbinit
+.endif
+.for __gdbinit in ${GDBINIT}
+ echo "source ${__gdbinit}" >> .gdbinit
+.endfor
+
+cleanextra: .PHONY
+.if defined(CLEANFILES) && !empty(CLEANFILES)
+ rm -f ${CLEANFILES}
+.endif
+
+cleanobjs: .PHONY
+
+cleanprog: .PHONY cleanobjs cleanextra
+ rm -f a.out [Ee]rrs mklog core *.core .gdbinit
+
+.if defined(SHAREDSTRINGS)
+CLEANFILES+=strings
+.c.o:
+ ${CC} -E ${CPPFLAGS} ${CFLAGS} ${.IMPSRC} | xstr -c -
+ @${CC} ${CPPFLAGS} ${CFLAGS} -c x.c -o ${.TARGET}
+ @rm -f x.c
+
+.cc.o .cpp.o .cxx.o .C.o:
+ ${CXX} -E ${CPPFLAGS} ${CXXFLAGS} ${.IMPSRC} | xstr -c -
+ @mv -f x.c x.cc
+ @${CXX} ${CPPFLAGS} ${CXXFLAGS} -c x.cc -o ${.TARGET}
+ @rm -f x.cc
+.endif
##### Default values
CPPFLAGS+= ${DESTDIR:D-nostdinc ${CPPFLAG_ISYSTEM} ${DESTDIR}/usr/include}
@@ -123,48 +146,10 @@ LIB${_lib:tu}= ${DESTDIR}/usr/X11R6/lib/
.endif
.endfor
-
-##### Build and install rules
-.if defined(SHAREDSTRINGS)
-CLEANFILES+=strings
-.c.o:
- ${CC} -E ${CPPFLAGS} ${CFLAGS} ${.IMPSRC} | xstr -c -
- @${CC} ${CPPFLAGS} ${CFLAGS} -c x.c -o ${.TARGET}
- @rm -f x.c
-
-.cc.o .cpp.o .cxx.o .C.o:
- ${CXX} -E ${CPPFLAGS} ${CXXFLAGS} ${.IMPSRC} | xstr -c -
- @mv -f x.c x.cc
- @${CXX} ${CPPFLAGS} ${CXXFLAGS} -c x.cc -o ${.TARGET}
- @rm -f x.cc
-.endif
-
-.if defined(PROG) # {
-.if defined(PROG_CXX)
-SRCS?= ${PROG}.cc
-.else
-SRCS?= ${PROG}.c
-.endif
-
-PROGNAME?= ${PROG}
-
.if defined(RESCUEDIR)
CPPFLAGS+= -DRESCUEDIR=\"${RESCUEDIR}\"
.endif
-_YPSRCS= ${SRCS:M*.[ly]:C/\..$/.c/} ${YHEADER:D${SRCS:M*.y:.y=.h}}
-
-DPSRCS+= ${_YPSRCS}
-CLEANFILES+= ${_YPSRCS}
-
-.if !empty(SRCS:N*.h:N*.sh:N*.fth)
-OBJS+= ${SRCS:N*.h:N*.sh:N*.fth:R:S/$/.o/g}
-LOBJS+= ${LSRCS:.c=.ln} ${SRCS:M*.c:.c=.ln}
-.endif
-
-.if defined(OBJS) && !empty(OBJS) # {
-.NOPATH: ${OBJS} ${PROG} ${_YPSRCS}
-
_PROGLDOPTS=
.if ${SHLINKDIR} != "/usr/libexec" # XXX: change or remove if ld.so moves
.if ${OBJECT_FMT} == "ELF"
@@ -180,126 +165,209 @@ _PROGLDOPTS+= -Wl,-rpath-link,${DESTDIR}
-L${DESTDIR}${SHLIBINSTALLDIR}
.endif
+__proginstall: .USE
+ ${_MKTARGET_INSTALL}
+ ${INSTALL_FILE} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ ${STRIPFLAG} ${.ALLSRC} ${.TARGET}
+
+__progdebuginstall: .USE
+ ${_MKTARGET_INSTALL}
+ ${INSTALL_FILE} -o ${DEBUGOWN} -g ${DEBUGGRP} -m ${DEBUGMODE} \
+ ${.ALLSRC} ${.TARGET}
+
+
+
+#
+# Backwards compatibility with Makefiles that assume that bsd.prog.mk
+# can only build a single binary.
+#
+
.if defined(PROG_CXX)
-_CCLINK= ${CXX}
-.else
-_CCLINK= ${CC}
+PROG= ${PROG_CXX}
.endif
-.if ${MKDEBUG} != "no" && ${OBJECT_FMT} == "ELF" && !commands(${PROG})
-_PROGDEBUG= ${PROGNAME}.debug
+.if defined(PROG)
+. if defined(PROGNAME)
+PROGNAME.${PROG}:= ${PROGNAME}
+. endif
+. if defined(SRCS)
+SRCS.${PROG}:= ${SRCS}
+. endif
+.endif
+
+# Turn the single-program PROG and PROG_CXX variables into their multi-word
+# counterparts, PROGS and PROGS_CXX.
+.if defined(PROG_CXX) && !defined(PROGS_CXX)
+PROGS_CXX= ${PROG_CXX}
.endif
-
-.gdbinit:
- rm -f .gdbinit
-.if defined(DESTDIR) && !empty(DESTDIR)
- echo "set solib-absolute-prefix ${DESTDIR}" > .gdbinit
-.else
- touch .gdbinit
+.if defined(PROG) && !defined(PROGS)
+PROGS= ${PROG}
.endif
-.for __gdbinit in ${GDBINIT}
- echo "source ${__gdbinit}" >> .gdbinit
+
+
+
+#
+# Per-program definitions and targets.
+#
+
+# Definitions specific to C programs.
+.for _P in ${PROGS}
+SRCS.${_P}?= ${_P}.c
+_CCLINK.${_P}= ${CC}
.endfor
-${OBJS} ${LOBJS}: ${DPSRCS}
+# Definitions specific to C++ programs.
+.for _P in ${PROGS_CXX}
+SRCS.${_P}?= ${_P}.cc
+_CCLINK.${_P}= ${CXX}
+.endfor
+
+# Language-independent definitions.
+.for _P in ${PROGS} ${PROGS_CXX} # {
+
+PROGNAME.${_P}?= ${_P}
-${PROG}: .gdbinit ${LIBCRT0} ${OBJS} ${LIBC} ${LIBCRTBEGIN} ${LIBCRTEND} ${DPADD}
-.if !commands(${PROG})
+.if ${MKDEBUG} != "no" && ${OBJECT_FMT} == "ELF" && !commands(${_P})
+_PROGDEBUG.${_P}:= ${PROGNAME.${_P}}.debug
+.endif
+
+.if defined(PAXCTL_FLAGS)
+PAXCTL_FLAGS.${_P}?= ${PAXCTL_FLAGS}
+.endif
+
+##### PROG specific flags.
+COPTS+= ${COPTS.${_P}}
+CPPFLAGS+= ${CPPFLAGS.${_P}}
+CXXFLAGS+= ${CXXFLAGS.${_P}}
+OBJCOPTS+= ${OBJCOPTS.${_P}}
+LDADD+= ${LDADD.${_P}}
+LDFLAGS+= ${LDFLAGS.${_P}}
+LDSTATIC+= ${LDSTATIC.${_P}}
+
+_COPTS.${_P}= ${COPTS} ${COPTS.${_P}}
+_CPPFLAGS.${_P}= ${CPPFLAGS} ${CPPFLAGS.${_P}}
+_CXXFLAGS.${_P}= ${CXXFLAGS} ${CXXFLAGS.${_P}}
+_OBJCOPTS.${_P}= ${OBJCOPTS} ${OBJCOPTS.${_P}}
+_LDADD.${_P}= ${LDADD} ${LDADD.${_P}}
+_LDFLAGS.${_P}= ${LDFLAGS} ${LDFLAGS.${_P}}
+_LDSTATIC.${_P}= ${LDSTATIC} ${LDSTATIC.${_P}}
+
+##### Build and install rules
+SRCS+= ${SRCS.${_P}} # For bsd.dep.mk
+
+_YPSRCS.${_P}= ${SRCS.${_P}:M*.[ly]:C/\..$/.c/} ${YHEADER:D${SRCS.${_P}:M*.y:.y=.h}}
+
+DPSRCS+= ${_YPSRCS.${_P}}
+CLEANFILES+= ${_YPSRCS.${_P}}
+
+.if !empty(SRCS.${_P}:N*.h:N*.sh:N*.fth)
+OBJS.${_P}+= ${SRCS.${_P}:N*.h:N*.sh:N*.fth:R:S/$/.o/g}
+LOBJS.${_P}+= ${LSRCS:.c=.ln} ${SRCS.${_P}:M*.c:.c=.ln}
+.endif
+
+.if defined(OBJS.${_P}) && !empty(OBJS.${_P}) # {
+.NOPATH: ${OBJS.${_P}} ${_P} ${_YPSRCS.${_P}}
+
+${OBJS.${_P}} ${LOBJS.${_P}}: ${DPSRCS}
+
+${_P}: .gdbinit ${LIBCRT0} ${OBJS.${_P}} ${LIBC} ${LIBCRTBEGIN} ${LIBCRTEND} ${DPADD}
+.if !commands(${_P})
${_MKTARGET_LINK}
.if defined(DESTDIR)
- ${_CCLINK} -Wl,-nostdlib \
- ${LDFLAGS} ${LDSTATIC} -o ${.TARGET} ${_PROGLDOPTS} \
+ ${_CCLINK.${_P}} -Wl,-nostdlib \
+ ${_LDFLAGS.${_P}} ${_LDSTATIC.${_P}} -o ${.TARGET} ${_PROGLDOPTS} \
-B${_GCC_CRTDIR}/ -B${DESTDIR}/usr/lib/ \
- ${OBJS} ${LDADD} \
+ ${OBJS.${_P}} ${_LDADD.${_P}} \
-L${_GCC_LIBGCCDIR} -L${DESTDIR}/usr/lib
.else
- ${_CCLINK} ${LDFLAGS} ${LDSTATIC} -o ${.TARGET} ${_PROGLDOPTS} ${OBJS} ${LDADD}
+ ${_CCLINK.${_P}} ${_LDFLAGS.${_P}} ${_LDSTATIC.${_P}} -o ${.TARGET} ${_PROGLDOPTS} ${OBJS.${_P}} ${_LDADD.${_P}}
.endif # defined(DESTDIR)
-.if defined(PAXCTL_FLAGS.${PROG})
- ${PAXCTL} ${PAXCTL_FLAGS.${PROG}} ${.TARGET}
+.if defined(PAXCTL_FLAGS.${_P})
+ ${PAXCTL} ${PAXCTL_FLAGS.${_P}} ${.TARGET}
.endif
-.endif # !commands(${PROG})
+.endif # !commands(${_P})
-${PROG}.ro: ${OBJS} ${DPADD}
+${_P}.ro: ${OBJS.${_P}} ${DPADD}
${_MKTARGET_LINK}
- ${LD} -r -dc -o ${.TARGET} ${OBJS}
+ ${LD} -r -dc -o ${.TARGET} ${OBJS.${_P}}
-.if defined(_PROGDEBUG)
-${_PROGDEBUG}: ${PROG}
+.if defined(_PROGDEBUG.${_P})
+${_PROGDEBUG}.${_P}: ${_P}
${_MKTARGET_CREATE}
- ${OBJCOPY} --only-keep-debug ${PROG} ${_PROGDEBUG}
- ${OBJCOPY} -R .gnu_debuglink --add-gnu-debuglink=${_PROGDEBUG} ${PROG} \
- || rm -f ${_PROGDEBUG}
+ ${OBJCOPY} --only-keep-debug ${_P} ${_PROGDEBUG.${_P}}
+ ${OBJCOPY} -R .gnu_debuglink --add-gnu-debuglink=${_PROGDEBUG.${_P}} ${_P} \
+ || rm -f ${_PROGDEBUG.${_P}}
.endif
-.endif # defined(OBJS) && !empty(OBJS) # }
+.endif # defined(OBJS.${_P}) && !empty(OBJS.${_P}) # }
-.if !defined(MAN)
-MAN= ${PROG}.1
-.endif # !defined(MAN)
-.endif # defined(PROG) # }
+.if !defined(MAN.${_P})
+MAN.${_P}= ${_P}.1
+.endif # !defined(MAN.${_P})
+MAN+= ${MAN.${_P}}
-realall: ${PROG} ${_PROGDEBUG} ${SCRIPTS}
+realall: ${_P} ${_PROGDEBUG.${_P}}
-cleanprog: .PHONY cleanobjs cleanextra
- rm -f a.out [Ee]rrs mklog core *.core .gdbinit ${PROG} ${_PROGDEBUG}
+cleanprog: cleanprog-${_P}
+cleanprog-${_P}:
+ rm -f ${_P} ${_PROGDEBUG.${_P}}
-cleanobjs: .PHONY
-.if defined(OBJS) && !empty(OBJS)
- rm -f ${OBJS} ${LOBJS}
-.endif
-
-cleanextra: .PHONY
-.if defined(CLEANFILES) && !empty(CLEANFILES)
- rm -f ${CLEANFILES}
+.if defined(OBJS.${_P}) && !empty(OBJS.${_P})
+cleanobjs: cleanobjs-${_P}
+cleanobjs-${_P}:
+ rm -f ${OBJS.${_P}} ${LOBJS.${_P}}
.endif
-.if defined(PROG) && !target(proginstall) # {
+_PROG_INSTALL+= proginstall-${_P}
-proginstall:: ${DESTDIR}${BINDIR}/${PROGNAME} ${_PROGDEBUG:D${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG}}
-.PRECIOUS: ${DESTDIR}${BINDIR}/${PROGNAME} ${_PROGDEBUG:D${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG}}
-
-__proginstall: .USE
- ${_MKTARGET_INSTALL}
- ${INSTALL_FILE} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
- ${STRIPFLAG} ${.ALLSRC} ${.TARGET}
-
-__progdebuginstall: .USE
- ${_MKTARGET_INSTALL}
- ${INSTALL_FILE} -o ${DEBUGOWN} -g ${DEBUGGRP} -m ${DEBUGMODE} \
- ${.ALLSRC} ${.TARGET}
+.if !target(proginstall-${_P}) # {
+proginstall-${_P}:: ${DESTDIR}${BINDIR}/${PROGNAME.${_P}} \
+ ${_PROGDEBUG.${_P}:D${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG.${_P}}}
+.PRECIOUS: ${DESTDIR}${BINDIR}/${PROGNAME.${_P}} \
+ ${_PROGDEBUG.${_P}:D${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG.${_P}}}
.if ${MKUPDATE} == "no"
-${DESTDIR}${BINDIR}/${PROGNAME}! ${PROG} __proginstall
-.if !defined(BUILD) && !make(all) && !make(${PROG})
-${DESTDIR}${BINDIR}/${PROGNAME}! .MADE
-.endif
-.if defined(_PROGDEBUG)
-${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG}! ${_PROGDEBUG} __progdebuginstall
-.if !defined(BUILD) && !make(all) && !make(${PROG})
-${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG}! .MADE
+${DESTDIR}${BINDIR}/${PROGNAME.${_P}}! ${_P} __proginstall
+.if !defined(BUILD) && !make(all) && !make(${_P})
+${DESTDIR}${BINDIR}/${PROGNAME.${_P}}! .MADE
+.endif
+.if defined(_PROGDEBUG.${_P})
+${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG.${_P}}! ${_PROGDEBUG.${_P}} __progdebuginstall
+.if !defined(BUILD) && !make(all) && !make(${_P})
+${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG.${_P}}! .MADE
.endif
-.endif # define(_PROGDEBUG)
+.endif # define(_PROGDEBUG.${_P})
.else # MKUPDATE != no
-${DESTDIR}${BINDIR}/${PROGNAME}: ${PROG} __proginstall
-.if !defined(BUILD) && !make(all) && !make(${PROG})
-${DESTDIR}${BINDIR}/${PROGNAME}: .MADE
-.endif
-.if defined(_PROGDEBUG)
-${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG}: ${_PROGDEBUG} __progdebuginstall
-.if !defined(BUILD) && !make(all) && !make(${PROG})
-${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG}: .MADE
+${DESTDIR}${BINDIR}/${PROGNAME.${_P}}: ${_P} __proginstall
+.if !defined(BUILD) && !make(all) && !make(${_P})
+${DESTDIR}${BINDIR}/${PROGNAME.${_P}}: .MADE
+.endif
+.if defined(_PROGDEBUG.${_P})
+${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG.${_P}}: ${_PROGDEBUG.${_P}} __progdebuginstall
+.if !defined(BUILD) && !make(all) && !make(${_P})
+${DESTDIR}${DEBUGDIR}${BINDIR}/${_PROGDEBUG.${_P}}: .MADE
.endif
-.endif # defined(_PROGDEBUG)
+.endif # defined(_PROGDEBUG.${_P})
.endif # MKUPDATE != no
-.endif # defined(PROG) && !target(proginstall) # }
+.endif # !target(proginstall-${_P}) # }
+
+lint: lint-${_P}
+lint-${_P}: ${LOBJS.${_P}}
+.if defined(LOBJS.${_P}) && !empty(LOBJS.${_P})
+ ${LINT} ${LINTFLAGS} ${_LDFLAGS.${_P}:C/-L[ ]*/-L/Wg:M-L*} ${LOBJS.${_P}} ${_LDADD.${_P}}
+.endif
+
+.endfor # _P in ${PROGS} ${PROGS_CXX} # }
.if !target(proginstall)
-proginstall::
+proginstall:: ${_PROG_INSTALL}
.endif
.PHONY: proginstall
+
+
+realall: ${SCRIPTS}
.if defined(SCRIPTS) && !target(scriptsinstall) # {
SCRIPTSDIR?=${BINDIR}
SCRIPTSOWN?=${BINOWN}
@@ -337,11 +405,6 @@ scriptsinstall::
.endif
.PHONY: scriptsinstall
-lint: ${LOBJS}
-.if defined(LOBJS) && !empty(LOBJS)
- ${LINT} ${LINTFLAGS} ${LDFLAGS:C/-L[ ]*/-L/Wg:M-L*} ${LOBJS} ${LDADD}
-.endif
-
##### Pull in related .mk logic
.include <bsd.man.mk>
.include <bsd.nls.mk>
--Apple-Mail-5--556735670
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
--
Julio M. Merino Vidal <jmmv84@gmail.com>
--Apple-Mail-5--556735670--