From a8e1820be7fac61fb0c7b501cb5beb7f7b1c5b3f Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Tue, 17 Apr 2018 21:49:56 +0900 Subject: [PATCH] Integrate auto-dep into build system through make file generation --- .gitignore | 1 + Makefile | 65 ++++--------------- apps/{nyancat => }/nyancat.c | 4 +- libc/access.c | 1 + util/auto-dep.py | 120 +++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 53 deletions(-) rename apps/{nyancat => }/nyancat.c (99%) create mode 100755 util/auto-dep.py diff --git a/.gitignore b/.gitignore index 002f4721..119c748d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.a *.o *.iso +.make/* base/bin/* cdrom/kernel cdrom/mod/* diff --git a/Makefile b/Makefile index d90eb65f..f30cf31a 100644 --- a/Makefile +++ b/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} diff --git a/apps/nyancat/nyancat.c b/apps/nyancat.c similarity index 99% rename from apps/nyancat/nyancat.c rename to apps/nyancat.c index 0aa96f4a..2224b8d7 100644 --- a/apps/nyancat/nyancat.c +++ b/apps/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 diff --git a/libc/access.c b/libc/access.c index 54d8aeef..71034526 100644 --- a/libc/access.c +++ b/libc/access.c @@ -1,5 +1,6 @@ #include #include +#include int access(const char *pathname, int mode) { int result = syscall_access((char *)pathname, mode); diff --git a/util/auto-dep.py b/util/auto-dep.py new file mode 100755 index 00000000..75551259 --- /dev/null +++ b/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 + '': (None, '-ltoaru_kbd', []), + '': (None, '-ltoaru_list', []), + '': (None, '-ltoaru_hashmap', ['']), + '': (None, '-ltoaru_tree', ['']), + '': (None, '-ltoaru_pthread', []), + '': (None, '-ltoaru_pex', []), + '': (None, '-ltoaru_graphics', []), + '': (None, '-ltoaru_drawstring', ['']), + '': (None, '-ltoaru_rline', ['']), + '': (None, '-ltoaru_confreader', ['']), + '': (None, '-ltoaru_dlfcn', []), + '': (None, '-ltoaru_yutani', ['', '', '', '', '']), + '': (None, '-ltoaru_decorations', ['', '','']), + '': (None, '-ltoaru_termemu', ['']), + } + + 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]))) +