Re: Perl make depend made faster

Linus Torvalds (torvalds@cs.helsinki.fi)
Sun, 15 Sep 1996 13:28:08 +0300 (EET DST)


If you want to make "make depend" faster, I don't see why perl would be
the answer. Perl has the problem that it easily uses lots of memory, and
also that it isn't always there. If people really care, how about
optimizing this patch instead?

(This just does the thing in C - you end compiling "mkdep", but it does
have the advantage that we know that a C compiler is always installed,
because we couldn't compile the kernel without one anyway).

Linus

-----
diff -u --recursive --new-file v2.0.20/linux/Makefile linux/Makefile
--- v2.0.20/linux/Makefile Sun Sep 15 10:19:09 1996
+++ linux/Makefile Sun Sep 15 12:59:23 1996
@@ -327,7 +327,7 @@
rm -f .menuconfig .menuconfig.log
rm -f include/asm
rm -f .depend `find . -name .depend -print`
- rm -f .hdepend
+ rm -f .hdepend scripts/mkdep
rm -f $(TOPDIR)/include/linux/modversions.h
rm -f $(TOPDIR)/include/linux/modules/*

@@ -344,8 +344,8 @@
sums:
find . -type f -print | sort | xargs sum > .SUMS

-dep-files: archdep .hdepend include/linux/version.h
- $(AWK) -f scripts/depend.awk init/*.c > .tmpdepend
+dep-files: scripts/mkdep archdep .hdepend include/linux/version.h
+ scripts/mkdep init/*.c > .tmpdepend
set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done
mv .tmpdepend .depend

@@ -383,7 +383,10 @@
# This generates dependencies for the .h files.
#

-.hdepend: dummy
+scripts/mkdep: scripts/mkdep.c
+ $(HOSTCC) -O -o scripts/mkdep scripts/mkdep.c
+
+.hdepend: scripts/mkdep
rm -f $@
- $(AWK) -f scripts/depend.awk `find $(HPATH) -name \*.h ! -name modversions.h -print` > .$@
+ scripts/mkdep `find $(HPATH) -name \*.h ! -name modversions.h -print` > .$@
mv .$@ $@
diff -u --recursive --new-file v2.0.20/linux/Rules.make linux/Rules.make
--- v2.0.20/linux/Rules.make Sat Jun 29 14:59:38 1996
+++ linux/Rules.make Sun Sep 15 12:58:24 1996
@@ -83,7 +83,7 @@
#
fastdep: dummy
if [ -n "$(wildcard *.[chS])" ]; then \
- $(AWK) -f $(TOPDIR)/scripts/depend.awk *.[chS] > .depend; fi
+ $(TOPDIR)/scripts/mkdep *.[chS] > .depend; fi
ifdef ALL_SUB_DIRS
set -e; for i in $(ALL_SUB_DIRS); do $(MAKE) -C $$i fastdep; done
endif
diff -u --recursive --new-file v2.0.20/linux/drivers/block/ide_modes.h linux/drivers/block/ide_modes.h
--- v2.0.20/linux/drivers/block/ide_modes.h Fri Aug 9 19:26:50 1996
+++ linux/drivers/block/ide_modes.h Sun Sep 15 13:00:06 1996
@@ -6,6 +6,8 @@
* Copyright (C) 1996 Linus Torvalds, Igor Abramov, and Mark Lord
*/

+#include <linux/config.h>
+
/*
* Shared data/functions for determining best PIO mode for an IDE drive.
* Most of this stuff originally lived in cmd640.c, and changes to the
diff -u --recursive --new-file v2.0.20/linux/drivers/scsi/g_NCR5380.h linux/drivers/scsi/g_NCR5380.h
--- v2.0.20/linux/drivers/scsi/g_NCR5380.h Sun May 19 18:23:20 1996
+++ linux/drivers/scsi/g_NCR5380.h Sun Sep 15 13:13:04 1996
@@ -32,6 +32,8 @@
#ifndef GENERIC_NCR5380_H
#define GENERIC_NCR5380_H

+#include <linux/config.h>
+
#define GENERIC_NCR5380_PUBLIC_RELEASE 1

#ifdef NCR53C400
diff -u --recursive --new-file v2.0.20/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v2.0.20/linux/drivers/sound/dev_table.h Thu Jul 11 19:14:10 1996
+++ linux/drivers/sound/dev_table.h Sun Sep 15 13:00:54 1996
@@ -15,6 +15,7 @@
#ifndef _DEV_TABLE_H_
#define _DEV_TABLE_H_

+#include <linux/config.h>

/*
* Sound card numbers 27 to 999. (1 to 26 are defined in soundcard.h)
diff -u --recursive --new-file v2.0.20/linux/scripts/mkdep.c linux/scripts/mkdep.c
--- v2.0.20/linux/scripts/mkdep.c Thu Jan 1 02:00:00 1970
+++ linux/scripts/mkdep.c Sun Sep 15 13:11:19 1996
@@ -0,0 +1,236 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+
+char *filename, *command, __depname[256] = "\n\t@touch ";
+int needsconfig, hasconfig, hasdep;
+
+#define depname (__depname+9)
+
+struct path_struct {
+ int len;
+ char buffer[256-sizeof(int)];
+} path_array[2] = {
+ { 23, "/usr/src/linux/include/" },
+ { 0, "" }
+};
+
+static void handle_include(int type, char *name, int len)
+{
+ int plen;
+ char namebuffer[128];
+ struct path_struct *path = path_array;
+
+ if (type == '"')
+ path++;
+
+ if (len == 14 && !memcmp(name, "linux/config.h", len))
+ hasconfig = 1;
+
+ plen = path->len;
+ memcpy(path->buffer+plen, name, len);
+ len += plen;
+ path->buffer[len] = '\0';
+ if (access(path->buffer, F_OK))
+ return;
+
+ if (!hasdep) {
+ hasdep = 1;
+ printf("%s:", depname);
+ }
+ printf(" \\\n %s", path->buffer);
+}
+
+static void handle_config(void)
+{
+ hasconfig = 1;
+ if (!hasdep)
+ fprintf(stderr,
+ "%s needs config but has not included config file\n",
+ filename);
+}
+
+#define GETNEXT { if (!left) break; current = *next; left--; next++; }
+#define CASE(c,label) if (current == c) goto label
+#define NOTCASE(c,label) if (current != c) goto label
+
+static void do_depend(void)
+{
+ char *map;
+ char *next;
+ int mapsize;
+ int left = 0;
+ int fd = open(filename, O_RDONLY);
+ struct stat st;
+
+ if (fd < 0)
+ return;
+ fstat(fd, &st);
+ left = st.st_size;
+ map = mmap(NULL, left, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (-1 == (long)map) {
+ close(fd);
+ return;
+ }
+ next = map;
+ for(;;) {
+ char current;
+
+normal:
+ GETNEXT
+__normal:
+ CASE('/',slash);
+ CASE('"',string);
+ CASE('\'',char_const);
+ CASE('#',preproc);
+ goto normal;
+
+slash:
+ GETNEXT
+ CASE('*',comment);
+ goto __normal;
+
+string:
+ GETNEXT
+ CASE('"',normal);
+ NOTCASE('\\',string);
+ GETNEXT
+ goto string;
+
+char_const:
+ GETNEXT
+ CASE('\'',normal);
+ NOTCASE('\\',char_const);
+ GETNEXT
+ goto char_const;
+
+comment:
+ GETNEXT
+__comment:
+ NOTCASE('*',comment);
+ GETNEXT
+ CASE('/',normal);
+ goto __comment;
+
+preproc:
+ GETNEXT
+ CASE('\n',normal);
+ CASE(' ',preproc);
+ CASE('\t',preproc);
+ CASE('i',i_preproc);
+ GETNEXT
+
+skippreproc:
+ CASE('\n',normal);
+ GETNEXT
+ goto skippreproc;
+
+i_preproc:
+ GETNEXT
+ CASE('f',if_line);
+ NOTCASE('n',skippreproc);
+ GETNEXT
+ NOTCASE('c',skippreproc);
+ GETNEXT
+ NOTCASE('l',skippreproc);
+ GETNEXT
+ NOTCASE('u',skippreproc);
+ GETNEXT
+ NOTCASE('d',skippreproc);
+ GETNEXT
+ NOTCASE('e',skippreproc);
+
+include_line:
+{
+ char type;
+ GETNEXT
+ CASE('\n',normal);
+ type = '>';
+ CASE('<', include_file);
+ type = '"';
+ NOTCASE('"', include_line);
+include_file:
+{
+ char *incname = next;
+include_name:
+ GETNEXT
+ CASE('\n',normal);
+ NOTCASE(type, include_name);
+ handle_include(type, incname, next-incname-1);
+ goto skippreproc;
+}}
+
+if_line:
+ if (hasconfig)
+ goto skippreproc;
+if_start:
+ if (!memcmp("CONFIG_", next, 7)) {
+ handle_config();
+ goto skippreproc;
+ }
+ GETNEXT
+ CASE('\n', normal);
+ CASE('_', if_middle);
+ if (current >= 'a' && current <= 'z')
+ goto if_middle;
+ if (current < 'A' || current > 'Z')
+ goto if_start;
+if_middle:
+ GETNEXT
+ CASE('\n', normal);
+ CASE('_', if_middle);
+ if (current >= 'a' && current <= 'z')
+ goto if_middle;
+ if (current < 'A' || current > 'Z')
+ goto if_start;
+ goto if_middle;
+ }
+ munmap(map, st.st_size);
+ if (hasdep)
+ puts(command);
+}
+
+int main(int argc, char **argv)
+{
+ int len;
+ char * hpath;
+
+ hpath = getenv("HPATH");
+ if (!hpath)
+ hpath = "/usr/src/linux/include";
+ len = strlen(hpath);
+ memcpy(path_array[0].buffer, hpath, len);
+ if (len && hpath[len-1] != '/') {
+ path_array[0].buffer[len] = '/';
+ len++;
+ }
+ path_array[0].buffer[len] = '\0';
+ path_array[0].len = len;
+
+ while (--argc > 0) {
+ int len;
+ char *name = *++argv;
+
+ filename = name;
+ len = strlen(name);
+ memcpy(depname, name, len+1);
+ command = __depname;
+ if (len > 2 && name[len-2] == '.') {
+ switch (name[len-1]) {
+ case 'c':
+ case 'S':
+ depname[len-1] = 'o';
+ command = "";
+ }
+ }
+ needsconfig = hasconfig = hasdep = 0;
+ do_depend();
+ }
+ return 0;
+}
-----