Browse Source

Integrate auto-dep into build system through make file generation

K. Lange 2 years ago
parent
commit
a8e1820be7
5 changed files with 138 additions and 53 deletions
  1. 1 0
      .gitignore
  2. 14 51
      Makefile
  3. 2 2
      apps/nyancat/nyancat.c
  4. 1 0
      libc/access.c
  5. 120 0
      util/auto-dep.py

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@
 *.a
 *.o
 *.iso
+.make/*
 base/bin/*
 cdrom/kernel
 cdrom/mod/*

+ 14 - 51
Makefile

@@ -28,6 +28,7 @@ LIBC_OBJS=$(patsubst %.c,%.o,$(wildcard libc/*.c))
 LC=base/lib/libc.so
 
 APPS_X=$(foreach app,$(APPS),base/bin/$(app))
+APPS_Y=$(foreach app,$(filter-out init,$(APPS)),.make/$(app).mak)
 
 all: image.iso
 
@@ -91,7 +92,9 @@ base/lib:
 	mkdir -p base/lib
 cdrom/boot:
 	mkdir -p cdrom/boot
-dirs: base/dev base/tmp base/proc base/bin base/lib cdrom/boot
+.make:
+	mkdir -p .make
+dirs: base/dev base/tmp base/proc base/bin base/lib cdrom/boot .make
 
 # C Library
 
@@ -167,65 +170,24 @@ base/bin/init: apps/init.c base/lib/libc.a | dirs
 
 # Userspace
 
-base/bin/sh: apps/sh.c base/lib/libc.so base/lib/libtoaru_list.so base/lib/libtoaru_rline.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_rline -ltoaru_list -ltoaru_kbd $(LIBS)
+.PHONY: update
+update: ${APPS_Y}
 
-base/bin/migrate: apps/migrate.c base/lib/libc.so base/lib/libtoaru_list.so base/lib/libtoaru_hashmap.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_hashmap -ltoaru_list $(LIBS)
+base/bin/%: .make/%.mak
 
-base/bin/sysinfo: apps/sysinfo.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_termemu.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_graphics -ltoaru_termemu $(LIBS)
+.make/%.mak: apps/%.c util/auto-dep.py | dirs
+	util/auto-dep.py --make $< > $@
 
-base/bin/terminal: apps/terminal.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_decorations.so base/lib/libtoaru_dlfcn.so base/lib/libtoaru_list.so base/lib/libtoaru_kbd.so base/lib/libtoaru_termemu.so base/lib/libtoaru_pex.so base/lib/libtoaru_hashmap.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_termemu -ltoaru_decorations -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_hashmap -ltoaru_dlfcn -ltoaru_kbd -ltoaru_list $(LIBS)
+base/bin/%: | ${APPS_Y}
 
-base/bin/terminal-vga: apps/terminal-vga.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_kbd.so base/lib/libtoaru_termemu.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_termemu -ltoaru_graphics -ltoaru_kbd $(LIBS)
-
-base/bin/background: apps/background.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so base/lib/libtoaru_drawstring.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_drawstring -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/drawlines: apps/drawlines.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/plasma: apps/plasma.c base/lib/libc.so base/lib/libtoaru_decorations.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_decorations -ltoaru_dlfcn  -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/julia: apps/julia.c base/lib/libc.so base/lib/libtoaru_decorations.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_decorations -ltoaru_dlfcn  -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/panel: apps/panel.c base/lib/libc.so base/lib/libtoaru_decorations.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_decorations -ltoaru_drawstring  -ltoaru_dlfcn  -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/yutani-query: apps/yutani-query.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/yutani-test: apps/yutani-test.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_yutani.so base/lib/libtoaru_pthread.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_yutani -ltoaru_graphics -ltoaru_pex -ltoaru_pthread -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/compositor: apps/compositor.c base/lib/libc.so base/lib/libtoaru_graphics.so base/lib/libtoaru_list.so base/lib/libtoaru_kbd.so base/lib/libtoaru_pthread.so base/lib/libtoaru_pex.so base/lib/libtoaru_yutani.so base/lib/libtoaru_hashmap.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_yutani -ltoaru_pthread -ltoaru_pex -ltoaru_graphics -ltoaru_kbd -ltoaru_hashmap -ltoaru_list $(LIBS)
-
-base/bin/ls: apps/ls.c base/lib/libc.so base/lib/libtoaru_list.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_list $(LIBS)
-
-base/bin/nyancat: apps/nyancat/nyancat.c ${LC}
-	$(CC) $(CFLAGS) -o $@ $< $(LIBS)
-
-base/bin/ps: apps/ps.c base/lib/libc.so base/lib/libtoaru_list.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_list $(LIBS)
-
-base/bin/pstree: apps/pstree.c base/lib/libc.so base/lib/libtoaru_tree.so base/lib/libtoaru_list.so
-	$(CC) $(CFLAGS) -o $@ $< -ltoaru_tree -ltoaru_list $(LIBS)
-
-base/bin/%: apps/%.c base/lib/libc.so ${LC} | dirs
-	$(CC) $(CFLAGS) -o $@ $< $(LIBS)
+-include ${APPS_Y}
 
 # Ramdisk
 
-cdrom/ramdisk.img: ${APPS_X} base/lib/ld.so base/lib/libtoaru-decor-fancy.so Makefile | dirs
+cdrom/ramdisk.img: ${APPS_X} ${APPS_Y} base/lib/ld.so base/lib/libtoaru-decor-fancy.so Makefile | dirs
 	genext2fs -B 4096 -d base -U -b 4096 -N 2048 cdrom/ramdisk.img
 
+
 # CD image
 
 image.iso: cdrom/ramdisk.img cdrom/boot/boot.sys cdrom/kernel ${MODULES}
@@ -256,4 +218,5 @@ clean:
 	rm -f ${KERNEL_OBJS} ${KERNEL_ASMOBJS} kernel/symbols.o kernel/symbols.S
 	rm -f base/lib/crt*.o
 	rm -f ${MODULES}
+	rm -f ${APPS_Y}
 

+ 2 - 2
apps/nyancat/nyancat.c

@@ -77,13 +77,13 @@
  * (it surprises some people that telnet is, really,
  *  a protocol, and not just raw text transmission)
  */
-#include "telnet.h"
+#include "nyancat/telnet.h"
 
 /*
  * The animation frames are stored separately in
  * this header so they don't clutter the core source
  */
-#include "animation.h"
+#include "nyancat/animation.h"
 
 /*
  * Color palette to use for final output

+ 1 - 0
libc/access.c

@@ -1,5 +1,6 @@
 #include <unistd.h>
 #include <errno.h>
+#include <syscall.h>
 
 int access(const char *pathname, int mode) {
 	int result = syscall_access((char *)pathname, mode);

+ 120 - 0
util/auto-dep.py

@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+# coding: utf-8
+
+import os
+import sys
+
+try:
+    TOOLCHAIN_PATH = os.environ['TOOLCHAIN']
+except KeyError:
+    # This is not good, but we need to let it happen for the make file
+    TOOLCHAIN_PATH = ""
+
+force_static = []
+
+class Classifier(object):
+
+    dependency_hints = {
+        # Toaru Standard Library
+        '<toaru/kbd.h>':         (None, '-ltoaru_kbd',         []),
+        '<toaru/list.h>':        (None, '-ltoaru_list',        []),
+        '<toaru/hashmap.h>':     (None, '-ltoaru_hashmap',     ['<toaru/list.h>']),
+        '<toaru/tree.h>':        (None, '-ltoaru_tree',        ['<toaru/list.h>']),
+        '<toaru/pthread.h>':     (None, '-ltoaru_pthread',     []),
+        '<toaru/pex.h>':         (None, '-ltoaru_pex',         []),
+        '<toaru/graphics.h>':    (None, '-ltoaru_graphics',    []),
+        '<toaru/drawstring.h>':  (None, '-ltoaru_drawstring',  ['<toaru/graphics.h>']),
+        '<toaru/rline.h>':       (None, '-ltoaru_rline',       ['<toaru/kbd.h>']),
+        '<toaru/confreader.h>':  (None, '-ltoaru_confreader',  ['<toaru/hashmap.h>']),
+        '<toaru/dlfcn.h>':       (None, '-ltoaru_dlfcn',       []),
+        '<toaru/yutani.h>':      (None, '-ltoaru_yutani',      ['<toaru/kbd.h>', '<toaru/list.h>', '<toaru/pex.h>', '<toaru/graphics.h>', '<toaru/hashmap.h>']),
+        '<toaru/decorations.h>': (None, '-ltoaru_decorations', ['<toaru/graphics.h>', '<toaru/yutani.h>','<toaru/dlfcn.h>']),
+        '<toaru/termemu.h>':     (None, '-ltoaru_termemu',     ['<toaru/graphics.h>']),
+    }
+
+    def __init__(self, filename):
+        self.filename  = filename
+        self.includes, self.libs = self._depends()
+
+    def _calculate(self, depends, new):
+        """Calculate all dependencies for the given set of new elements."""
+        for k in new:
+            if not k in depends:
+                depends.append(k)
+                _, _, other = self.dependency_hints[k]
+                depends = self._calculate(depends, other)
+        return depends
+
+    def _sort(self, depends):
+        """Sort the list of dependencies so that elements appearing first depend on elements following."""
+        satisfied = []
+        a = depends[:]
+
+        while set(satisfied) != set(depends):
+            b = []
+            for k in a:
+                if all([x in satisfied for x in self.dependency_hints[k][2]]):
+                    satisfied.append(k)
+                else:
+                    b.append(k)
+            a = b[:]
+        return satisfied[::-1]
+
+    def _depends(self):
+        """Calculate include and library dependencies."""
+        lines = []
+        depends = []
+        with open(self.filename,'r') as f:
+            lines = f.readlines()
+        for l in lines:
+            if l.startswith('#include'):
+                depends.extend([k for k in list(self.dependency_hints.keys()) if l.startswith('#include ' + k)])
+        depends = self._calculate([], depends)
+        depends = self._sort(depends)
+        includes  = []
+        libraries = []
+        for k in depends:
+            dep = self.dependency_hints[k]
+            if dep[0]:
+                includes.append('-I' + TOOLCHAIN_PATH + '/include/' + dep[0])
+            if dep[1]:
+                libraries.append(dep[1])
+        return includes, libraries
+
+
+def todep(name):
+    """Convert a library name to an archive path or object file name."""
+    if name.startswith("-l"):
+        name = name.replace("-l","",1)
+        if name in force_static:
+            return (False, "%s/lib%s.a" % (TOOLCHAIN_PATH + '/lib', name))
+        else:
+            return (True, "%s/lib%s.so" % ('base/lib', name))
+    else:
+        return (False, name)
+
+if __name__ == "__main__":
+    if len(sys.argv) < 3:
+        print("usage: util/auto-dep.py command filename")
+        exit(1)
+    command  = sys.argv[1]
+    filename = sys.argv[2]
+
+    c = Classifier(filename)
+
+    if command == "--cflags":
+        print(" ".join([x for x in c.includes]))
+    elif command == "--libs":
+        print(" ".join([x for x in c.libs]))
+    elif command == "--deps":
+        results = [todep(x) for x in c.libs]
+        normal = [x[1] for x in results if not x[0]]
+        order_only = [x[1] for x in results if x[0]]
+        print(" ".join(normal) + " | " + " ".join(order_only))
+    elif command == "--make":
+        print("base/bin/{app}: {source} | {libraryfiles} base/lib/libc.so\n\t$(CC) $(CFLAGS) -o $@ $< {libraries} $(LIBS)".format(
+            app=os.path.basename(filename).replace(".c",""),
+            source=filename,
+            libraryfiles=" ".join([todep(x)[1] for x in c.libs]),
+            libraries=" ".join([x for x in c.libs])))
+