The attached patch tags each .c file in the kernel with the options
that might have brought it in.  For example, the line

   file dev/widget/doohickey.c (widgetbus | frobnitz) & !gadgetry

in files.widget will cause

   OPT.doohickey.c+= widgetbus frobnitz

to appear in the kernel makefile.  (`gadgetry' is not included because
it is specifically the _absence_ of `gadgetry' that causes doohickey.c
to be put in the kernel.)

I want to use this to maintain subsystem-specific lists of compiler
warnings, like the completely absurd list in files.nouveau which is
currently done file-by-file.  If we added the fragment

   .for v in CFLAGS CPPFLAGS CWARNFLAGS
   .for c in ${CSRCS}
   .for o in OPT.${c}
   ${v}.${c}+=${v}.${o}
   .endfor
   .endfor
   .endfor

to Makefile.kern.inc, then the disaster in files.nouveau would become
simply:

makeoptions nouveau "CWARNFLAGS.nouveau+=-Wno-missing-field-initializers"

Thoughts?  I'm not wedded to this particular mechanism -- I just want
to make things like files.nouveau maintainable and I would like to get
progress before I run out of steam.


(I will consider different colours for the bikeshed OPT.foo.c, such as
CONFIGOPTS.foo.c or OPTS.foo.c, in the first two replies to this
patch; otherwise I will reject your paint colours with prejudice!)
>From 5e0ee893cdb9e42d7454624fd46fd6979688ba90 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastr...@netbsd.org>
Date: Mon, 30 Jul 2018 21:30:31 +0000
Subject: [PATCH] Tag each .c file with the options that might have brought it
 in.

---
 usr.bin/config/mkmakefile.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/usr.bin/config/mkmakefile.c b/usr.bin/config/mkmakefile.c
index eebc5086b4b5..63e773363b4b 100644
--- a/usr.bin/config/mkmakefile.c
+++ b/usr.bin/config/mkmakefile.c
@@ -584,6 +584,36 @@ emitincludes(FILE *fp)
 }
 
 /*
+ * Emit all options included in a conditional expression
+ */
+static void
+emitopts(FILE *fp, struct condexpr *cond, int include)
+{
+
+again: switch (cond->cx_type) {
+       case CX_ATOM:
+               if (include) {
+                       fprintf(fp, " %s", cond->cx_u.atom);
+               }
+               break;
+       case CX_NOT:
+               cond = cond->cx_u.not;
+               include = !include;
+               goto again;
+       case CX_AND:
+               emitopts(fp, cond->cx_u.and.left, include);
+               cond = cond->cx_u.and.right;
+               goto again;
+       case CX_OR:
+               emitopts(fp, cond->cx_u.and.left, include);
+               cond = cond->cx_u.and.right;
+               goto again;
+       default:
+               cfgerror("bug");
+       }
+}
+
+/*
  * Emit appending makeoptions.
  */
 static void
@@ -591,6 +621,17 @@ emitappmkoptions(FILE *fp)
 {
        struct nvlist *nv;
        struct condexpr *cond;
+       size_t i;
+
+       for (i = 0; i < nselfiles; i++) {
+               struct files *const fi = selfiles[i];
+
+               if (fi->fi_optx) {
+                       fprintf(fp, "OPT.%s.c+=", fi->fi_base);
+                       emitopts(fp, fi->fi_optx, 1);
+                       fprintf(fp, "\n");
+               }
+       }
 
        for (nv = appmkoptions; nv != NULL; nv = nv->nv_next)
                fprintf(fp, "%s+=%s\n", nv->nv_name, nv->nv_str);
-- 
2.11.0

Reply via email to