Subject: crunchgen simplifications
To: None <tech-toolchain@netbsd.org>
From: David Laight <david@l8s.co.uk>
List: tech-toolchain
Date: 08/06/2003 16:14:34
If we add:

${PROG}.ro: ${OBJS} ${DPADD}
	${LD} -r -dc -o ${.TARGET} ${OBJS}

to bsd.prog.mk, then crunchgen no longer needs to find out all the
${OBJ} files for a program.
The <crunchprog>.mk file can then have fragments like:

# -------- cat  

cat_SRCDIR=/bsd/src/bin/cat
cat_make:
        if [ \! -d cat ]; then mkdir cat; fi; cd cat; \
        printf ".PATH: ${cat_SRCDIR}\n.CURDIR:= ${cat_SRCDIR}\n.include \"\$${.CURDIR}/Makefile\"\n" \
        | ${MAKE} CRUNCHEDPROG=1 DBG="${DBG}" -f- depend cat.ro

cat.cro: cat/cat.ro
        ${NM} -ng cat/cat.ro | awk '/^ *U / { next }; \
		/ main$$/ { print "main _crunched_cat_stub"; next }; \
		{ print $$3 " _$$$$hide$$$$cat.cro$$$$" $$3 }' > cat.cro.syms
	${OBJCOPY} --redefine-syms cat.cro.syms cat/cat.ro cat.cro

As well as not requiring crunchgen to know all the .o files, it renames
'main' (instead of having a stub file) and uses awk to remove the unwanted
symbols (instead of multiple greps).

This also means that you only get one 'xxx is up to date' line per program
(not one per source file) when re-running the crunched make.

I think this makes the comments in some Makefiles (eg sysinst) saying that
all the files must be listed in the top level Makefile redundant.

There are a couple of drawbacks:
1) it only works if NEW_TOOLCHAIN is defined
   (you need the stub file without NEW_TOOLCHAIN)
2) It is easier to depracate the '-o' (use existing objects) than to make
   them work.  The 'reachover' makefile version is probably better anyway.

Does it matter if crunchgen rquires NEW_TOOLCHAIN (do allports use it?)
and doesn't support explicit lists of object files?

Patch is below (with broken support for useobjs).

	David

Index: crunchgen.c
===================================================================
RCS file: /cvsroot/src/usr.bin/crunch/crunchgen/crunchgen.c,v
retrieving revision 1.49
diff -u -p -r1.49 crunchgen.c
--- crunchgen.c	2003/07/09 19:51:07	1.49
+++ crunchgen.c	2003/08/06 15:08:12
@@ -77,7 +77,6 @@ typedef struct prog {
     struct prog *next;
     char *name, *ident;
     char *srcdir, *objdir;
-    strlst_t *objs, *objpaths;
     strlst_t *links, *keepsymbols;
     int goterror;
 } prog_t;
@@ -372,7 +371,7 @@ void add_prog(char *progname)
     else p1->next = p2;
 
     p2->ident = p2->srcdir = p2->objdir = NULL;
-    p2->objs = p2->objpaths = p2->links = p2->keepsymbols = NULL;
+    p2->links = p2->keepsymbols = NULL;
     p2->goterror = 0;
 }
 
@@ -441,16 +440,6 @@ void add_special(int argc, char **argv)
 	if((p->objdir = strdup(argv[3])) == NULL)
 	    out_of_memory();
     }
-    else if(!strcmp(argv[2], "objs")) {
-	p->objs = NULL;
-	for(i=3;i<argc;i++)
-	    add_string(&p->objs, argv[i]);
-    }
-    else if(!strcmp(argv[2], "objpaths")) {
-	p->objpaths = NULL;
-	for(i=3;i<argc;i++)
-	    add_string(&p->objpaths, argv[i]);
-    }
     else if(!strcmp(argv[2], "keepsymbols")) {
 	p->keepsymbols = NULL;
 	for (i=3;i<argc;i++)
@@ -497,7 +486,6 @@ void gen_specials_cache(void);
 void gen_output_makefile(void);
 void gen_output_cfile(void);
 
-void fillin_program_objs(prog_t *p, char *path);
 void top_makefile_rules(FILE *outmk);
 void bottom_makefile_rules(FILE *outmk);
 void prog_makefile_rules(FILE *outmk, prog_t *p);
@@ -528,7 +516,6 @@ void fillin_program(prog_t *p)
 {
     char path[MAXPATHLEN];
     char *srcparent;
-    strlst_t *s;
 
     (void)snprintf(line, sizeof(line), "filling in parms for %s", p->name);
     status(line);
@@ -566,101 +553,10 @@ void fillin_program(prog_t *p)
 
     if(p->srcdir)
 	(void)snprintf(path, sizeof(path), "%s/Makefile", p->srcdir);
-    if(!p->objs && p->srcdir && is_nonempty_file(path))
-	fillin_program_objs(p, p->srcdir);
-
-    if(!p->objpaths && p->objs) {
-	if (p->objdir && useobjs) {
-	    for(s = p->objs; s != NULL; s = s->next) {
-		(void)snprintf(line, sizeof(line), "%s/%s", p->objdir, s->str);
-		add_string(&p->objpaths, line);
-	    }
-	} else {
-	    for(s = p->objs; s != NULL; s = s->next) {
-		(void)snprintf(line, sizeof(line), "%s/%s", p->ident, s->str);
-		add_string(&p->objpaths, line);
-	    }
-	}
-    }
 	    
     if(!p->srcdir && verbose)
 	fprintf(stderr, "%s: %s: warning: could not find source directory.\n",
 		infilename, p->name);
-    if(!p->objs && verbose)
-	fprintf(stderr, "%s: %s: warning: could not find any .o files.\n", 
-		infilename, p->name);
-
-    if(!p->objpaths) {
-	fprintf(stderr, 
-		"%s: %s: error: no objpaths specified or calculated.\n",
-		infilename, p->name);
-	p->goterror = goterror = 1;
-    }
-}
-
-void fillin_program_objs(prog_t *p, char *dirpath)
-{
-    char *obj, *cp;
-    int rc;
-    int fd;
-    FILE *f;
-    char tempfname[MAXPATHLEN];
-
-    /* discover the objs from the srcdir Makefile */
-
-    (void)snprintf(tempfname, sizeof(tempfname), "/tmp/%sXXXXXX", confname);
-    if((fd = mkstemp(tempfname)) < 0) {
-	perror(tempfname);
-	exit(1);
-    }
-
-    if((f = fdopen(fd, "w")) == NULL) {
-	perror(tempfname);
-	goterror = 1;
-	return;
-    }
-	
-    fprintf(f, ".include \"${.CURDIR}/Makefile\"\n");
-    fprintf(f, ".if defined(PROG)\n");
-    fprintf(f, "OBJS?= ${PROG}.o\n");
-    fprintf(f, ".endif\n");
-    fprintf(f, "crunchgen_objs:\n\t@echo 'OBJS= '${OBJS}\n");
-    fclose(f);
-
-    (void)snprintf(line, sizeof(line),
-	"cd %s && %s -B CRUNCHEDPROG=1 -f %s %s crunchgen_objs 2>&1", dirpath,
-	makebin, tempfname, makeflags);
-    if((f = popen(line, "r")) == NULL) {
-	perror("submake pipe");
-	goterror = 1;
-	unlink(tempfname);
-	return;
-    }
-
-    while(fgets(line, MAXLINELEN, f)) {
-	if(strncmp(line, "OBJS= ", 6)) {
-	    if (strcmp(line,
-	   	"sh: warning: running as root with dot in PATH\n") == 0)
-		    continue;
-	    fprintf(stderr, "make error: %s", line);
-	    goterror = 1;	
-	    continue;
-	}
-	cp = line + 6;
-	while(isspace(*cp)) cp++;
-	while(*cp) {
-	    obj = cp;
-	    while(*cp && !isspace(*cp)) cp++;
-	    if(*cp) *cp++ = '\0';
-	    add_string(&p->objs, obj);
-	    while(isspace(*cp)) cp++;
-	}
-    }
-    if((rc=pclose(f)) != 0) {
-	fprintf(stderr, "make error: make returned %d\n", rc);
-	goterror = 1;
-    }
-    unlink(tempfname);
 }
 
 void remove_error_progs(void)
@@ -705,12 +601,6 @@ void gen_specials_cache(void)
 	    fprintf(cachef, "special %s srcdir %s\n", p->name, p->srcdir);
 	if(p->objdir && useobjs)
 	    fprintf(cachef, "special %s objdir %s\n", p->name, p->objdir);
-	if(p->objs) {
-	    fprintf(cachef, "special %s objs", p->name);
-	    output_strlst(cachef, p->objs);
-	}
-	fprintf(cachef, "special %s objpaths", p->name);
-	output_strlst(cachef, p->objpaths);
     }
     fclose(cachef);
 }
@@ -885,61 +775,43 @@ void prog_makefile_rules(FILE *outmk, pr
 
     fprintf(outmk, "\n# -------- %s\n\n", p->name);
 
-    fprintf(outmk,   "%s_OBJPATHS=", p->ident);
-    output_strlst(outmk, p->objpaths);
 
-    if(p->srcdir && p->objs && !useobjs) {
+    if(p->srcdir && !useobjs) {
 	fprintf(outmk, "%s_SRCDIR=%s\n", p->ident, p->srcdir);
-	fprintf(outmk, "%s_OBJS=", p->ident);
-	output_strlst(outmk, p->objs);
 	fprintf(outmk, "%s_make:\n", p->ident);
 	fprintf(outmk, "\tif [ \\! -d %s ]; then mkdir %s; fi; cd %s; \\\n",
 	    p->ident, p->ident, p->ident);
 	fprintf(outmk, "\tprintf \".PATH: ${%s_SRCDIR}\\n.CURDIR:= ${%s_SRCDIR}\\n"
 	    ".include \\\"\\$${.CURDIR}/Makefile\\\"\\n\" \\\n", p->ident, p->ident);
-	fprintf(outmk, "\t| ${MAKE} CRUNCHEDPROG=1 DBG=\"${DBG}\" -f- depend ${%s_OBJS}\n\n",
-	    p->ident);
+	fprintf(outmk, "\t| ${MAKE} CRUNCHEDPROG=1 DBG=\"${DBG}\" -f- depend %s.ro\n\n",
+	    p->name);
     }
     else
         fprintf(outmk, "%s_make:\n\t@echo \"** Using existing objs for %s\"\n\n", 
 		p->ident, p->name);
 
 
-    fprintf(outmk, "%s_stub.c:\n", p->name);
-    fprintf(outmk, "\techo \""
-	           "int _crunched_%s_stub(int argc, char **argv, char **envp)"
-	           "{return main(argc,argv,envp);}\" >%s_stub.c\n",
-	    p->ident, p->name);
     if (useobjs)
 	    fprintf(outmk, "%s.cro: %s_stub.o\n",
 		p->name, p->name);
     else
-	    fprintf(outmk, "%s.cro: %s_stub.o ${%s_OBJPATHS}\n",
-		p->name, p->name, p->ident);
-    fprintf(outmk, "\t${LD} -dc -r -o %s.cro %s_stub.o $(%s_OBJPATHS)\n", 
-	    p->name, p->name, p->ident);
+	    fprintf(outmk, "%s.cro: %s/%s.ro\n",
+		p->name, p->name, p->name);
 #ifdef NEW_TOOLCHAIN
-#ifdef RENAME_SYMS
-    fprintf(outmk, "\t${NM} -ng %s.cro | grep -wv U | ", p->name);
-    fprintf(outmk, "egrep -vw _crunched_%s_stub | ", p->ident);
+    fprintf(outmk, "\t${NM} -ng %s/%s.ro | awk '/^ *U / { next };", p->name, p->name);
     for (lst = p->keepsymbols; lst != NULL; lst = lst->next)
-	fprintf(outmk, "egrep -vw %s | ", lst->str);
-    fprintf(outmk, "env CRO=%s.cro awk "
-	"'{ print $$3 \" _$$$$hide$$$$\" ENVIRON[\"CRO\"] \"$$$$\" $$3 }' "
+	fprintf(outmk, " / %s$$/ { next };", lst->str);
+    fprintf(outmk, " / main$$/ { print \"main _crunched_%s_stub\"; next };", p->ident);
+    fprintf(outmk, " { print $$3 \" _$$$$hide$$$$%s.cro$$$$\" $$3 }' "
 	"> %s.cro.syms\n", p->name, p->name);
     fprintf(outmk, "\t${OBJCOPY} --redefine-syms %s.cro.syms ", p->name);
+    fprintf(outmk, "%s/%s.ro %s.cro\n", p->name, p->name, p->name);
 #else
-    fprintf(outmk, "\t${OBJCOPY} --keep-global-symbol _crunched_%s_stub ",
-  	    p->ident);
-    for (lst = p->keepsymbols; lst != NULL; lst = lst->next)
-	fprintf(outmk, "--keep-global-symbol %s ", lst->str);
-#endif
-#else
     fprintf(outmk, "\t${CRUNCHIDE} -k _crunched_%s_stub ", p->ident);
     for (lst = p->keepsymbols; lst != NULL; lst = lst->next)
 	fprintf(outmk, "-k %s ", lst->str);
-#endif
     fprintf(outmk, "%s.cro\n", p->name);
+#endif
 }
 
 void output_strlst(FILE *outf, strlst_t *lst)

-- 
David Laight: david@l8s.co.uk