[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH v2] build hinzugefuegt



+ build: Erster Commit des Buildtools fuer tyndur
---
 src/modules/c/build/Makefile.all    |    7 +
 src/modules/c/build/build.c         |  273 +++++++++++++++++++++++++++++++++++
 src/modules/c/build/dir.c           |  201 ++++++++++++++++++++++++++
 src/modules/c/build/include/build.h |   76 ++++++++++
 src/modules/c/build/main.c          |  115 +++++++++++++++
 5 files changed, 672 insertions(+), 0 deletions(-)
 create mode 100644 src/modules/c/build/Makefile.all
 create mode 100644 src/modules/c/build/build.c
 create mode 100644 src/modules/c/build/dir.c
 create mode 100644 src/modules/c/build/include/build.h
 create mode 100644 src/modules/c/build/main.c

diff --git a/src/modules/c/build/Makefile.all b/src/modules/c/build/Makefile.all
new file mode 100644
index 0000000..8c9b17a
--- /dev/null
+++ b/src/modules/c/build/Makefile.all
@@ -0,0 +1,7 @@
+shopt -s extglob
+source $LOST_BUILDMK_ROOT/config.sh
+
+echo "LD   $1/apps/build"
+
+$LOST_TOOLS_LD -obuild -Ttext=0x40000000 *.o --start-group $2 --end-group
+$LOST_TOOLS_STRIP -s build -o $1/apps/build
diff --git a/src/modules/c/build/build.c b/src/modules/c/build/build.c
new file mode 100644
index 0000000..e043efe
--- /dev/null
+++ b/src/modules/c/build/build.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the tyndur Project
+ *     and its contributors.
+ * 4. Neither the name of the tyndur Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "build.h"
+
+#ifdef __LINUX__
+static const char* cflags = "-m32 -g -O0 -Wall -fno-stack-protector -nostdinc"
+    " -fno-leading-underscore -fno-omit-frame-pointer -fno-strict-aliasing"
+    " -fno-builtin -c";
+#else
+//static const char* cflags = "-c -combine";
+static const char* cflags = "-c";
+#endif
+
+static const char* fpcflags = "-n -Cn -CX -Tlost";
+static const char* nasmflags = "-felf -O99";
+static const char* gasflags = "-32";
+
+static int dry_run = 0;
+static char* root_path;
+
+extern int verbose;
+
+
+/**
+ * Fuehrt einen Shellbefehl in einem gegebenen Arbeitsverzeichnis aus
+ */
+static void do_command(const char* path, const char* binary,
+    const char* args_fmt, ...)
+{
+    char* buf;
+    char* buf2;
+    char* dirname;
+    va_list ap;
+
+    asprintf(&dirname, "%s/%s", root_path, path);
+    if (verbose) {
+        printf(">>> cd %s\n", dirname);
+    }
+    chdir(dirname);
+
+    va_start(ap, args_fmt);
+    vasprintf(&buf, args_fmt, ap);
+    va_end(ap);
+
+    asprintf(&buf2, "%s %s", binary, buf);
+
+    if (verbose) {
+        printf(">>> %s\n", buf2);
+    }
+    if (!dry_run) {
+        system(buf2);
+    }
+
+    free(buf);
+    free(buf2);
+    chdir(root_path);
+}
+
+/**
+ * Sammelt alle Objektdateien in einem gegebenen Pfad ein und gibt sie durch
+ * Leerzeichen getrennt zurueck.
+ *
+ * FIXME Mit Leerzeichen im Dateinamen ist das offensichtlich kaputt
+ */
+static char* get_obj_files(const char* path)
+{
+    struct build_dir* dir;
+    struct build_dir* subdir;
+    struct build_file* file;
+    char* tmp = NULL;
+    char* subdir_files;
+    char* file_list = strdup("");
+    int i;
+
+    dir = scan_directory(NULL, path);
+    for (i = 0; (file = list_get_element_at(dir->obj_files, i)); i++) {
+        tmp = file_list;
+        asprintf(&file_list, "%s %s/%s", tmp, dir->path, file->name);
+        free(tmp);
+    }
+
+    for (i = 0; (subdir = list_get_element_at(dir->subdirs, i)); i++) {
+        tmp = file_list;
+        subdir_files = get_obj_files(subdir->path);
+        asprintf(&file_list, "%s %s", tmp, subdir_files);
+        free(subdir_files);
+        free(tmp);
+    }
+
+    return file_list;
+}
+
+/**
+ * Kompiliert eine Anzahl von Dateien
+ *
+ * @param path Arbeitsverzeichnis
+ * @param files Liste von zu kompilierenden Dateinamen
+ * @param compiler Dateiname des Compilers
+ * @param flags Flags, die in den Aufruf eingebunden werden sollen
+ * @param include Zusaezlicher String, der in den Aufruf eingebunden werden
+ * soll; primaer fuer die Angabe von Includeverzeichnissen.
+ */
+static void compile(const char* path, list_t* files, const char* compiler,
+    const char* flags, const char* include)
+{
+    struct build_file* file;
+    char* file_list = strdup("");
+    char* tmp;
+    int i;
+
+    for (i = 0; (file = list_get_element_at(files, i)); i++) {
+        tmp = file_list;
+        asprintf(&file_list, "%s %s", tmp, file->name);
+        free(tmp);
+    }
+
+    if (*file_list) {
+        do_command(path, compiler, "%s -I %s/%s %s %s",
+            flags, root_path, path, include, file_list);
+    }
+}
+
+/**
+ * Baut ein Projektverzeichnis
+ *
+ * @param dir Verzeichnis, das gebaut werden soll
+ * @param parent_include Includeverzeichnisse des Vaterverzeichnisses, die fuer
+ * Quellcodedateien in diesem Verzeichnis zur Verfuegung stehen sollen
+ * @param parent_lib lib-Verzeichnisse der Vaterverzeichnisse, deren
+ * Bibliotheken in diesem Verzeichnis zur Verfuegung stehen sollen
+ * @param depth Verschachtelungstiefe ausgehend vom Wurzelverzeichnis, in dem
+ * gebaut wird (fuer Baumdarstellung)
+ */
+static void do_build(struct build_dir* dir, const char* parent_include,
+    const char* parent_lib, int depth)
+{
+    char* include;
+    char* lib;
+    char* tmp = NULL;
+
+    char* objs;
+    struct build_dir* subdir;
+    struct build_file* file;
+    int i;
+
+    for (i = 0; i < depth; i++) {
+        printf("| ");
+    }
+    printf("+ %s\n", dir->path);
+
+    // Ggf. include-Verzeichnis anhaengen
+    if (dir->has_include) {
+        asprintf(&include, "%s -I %s/%s/include",
+            parent_include, root_path, dir->path);
+    } else {
+        include = strdup(parent_include);
+    }
+
+    if (dir->has_arch_include) {
+        tmp = include;
+        asprintf(&include, "%s -I %s/%s/include/arch/%s",
+            tmp, root_path, dir->path, arch);
+        free(tmp);
+    }
+
+    // Ggf. Lib-Verzeichnis anhaengen
+    if (dir->lib != NULL) {
+        asprintf(&lib, "%s %s/%s/lib/library.a",
+            parent_lib, root_path, dir->path);
+    } else {
+        lib = strdup(parent_lib);
+    }
+
+    // lib-Verzeichnis wird als erstes kompiliert
+    if (dir->lib) {
+        do_build(dir->lib, include, lib, depth + 1);
+        objs = get_obj_files(dir->lib->path);
+        do_command(".", "ar", "rs %s/library.a %s",
+            dir->lib->path, objs);
+        free(objs);
+    }
+
+    // Dann alle anderen Unterverzeichnisse
+    for (i = 0; (subdir = list_get_element_at(dir->subdirs, i)); i++) {
+        do_build(subdir, include, lib, depth + 1);
+    }
+
+    // Und schliesslich noch die einzelnen Dateien
+    // TODO Pruefen, ob sich Abhaengigkeiten veraendert haben
+    printf("%s: Kompilieren (C)...", dir->path);
+    fflush(stdout);
+    compile(dir->path, dir->src_files[LANG_C], "gcc", cflags, include);
+
+    printf("\r%s: Kompilieren (Pascal)...\033[K", dir->path);
+    fflush(stdout);
+    compile(dir->path, dir->src_files[LANG_PAS], "fpc", fpcflags, include);
+
+    printf("\r%s: Assemblieren (gas)...\033[K", dir->path);
+    fflush(stdout);
+    compile(dir->path, dir->src_files[LANG_ASM_GAS], "as", gasflags, include);
+
+    for (i = 0; (file = list_get_element_at(dir->src_files[LANG_ASM_NASM], i)); i++) {
+        do_command(dir->path, "nasm", "%s %s", nasmflags, file->name);
+    }
+
+    // Im Wurzelverzeichnis wird gelinkt (TODO einstellbar machen)
+    if (dir->parent == NULL) {
+        printf("\r%s: Linken...\033[K", dir->path);
+        fflush(stdout);
+
+        objs = get_obj_files(dir->path);
+        do_command(".", "gcc", "-o %s/run %s %s", dir->path, lib, objs);
+        free(objs);
+    }
+
+    printf("\r\033[K");
+    fflush(stdout);
+
+    free(include);
+    free(lib);
+}
+
+/**
+ * Bauen!
+ *
+ * @param root Wurzelverzeichnis des Projekts
+ */
+void build(struct build_dir* root)
+{
+    root_path = getcwd(NULL, 0);
+    do_build(root, "", "", 0);
+    printf("Fertig gebaut.\n");
+    free(root_path);
+}
diff --git a/src/modules/c/build/dir.c b/src/modules/c/build/dir.c
new file mode 100644
index 0000000..83d72e8
--- /dev/null
+++ b/src/modules/c/build/dir.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the tyndur Project
+ *     and its contributors.
+ * 4. Neither the name of the tyndur Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "build.h"
+
+/**
+ * Durchsucht ein Verzeichnis und speichert alle fuer das Bauen noetige
+ * Informationen in einer per malloc angelegten struct build_dir, die
+ * zurueckgegeben wird und vom Aufrufer freigegeben werden muss.
+ *
+ * Das bedeutet:
+ * - Alle Quellcodedateien sammeln (*.c, *.pas, ...)
+ * - Includeverzeichnisse speichern
+ * - lib-Verzeichnisse erfassen
+ * - Bei arch/-Verzeichnissen nur die richtige Architektur beruecksichtigen
+ * - .nobuild und .ignorenobuild beachten
+ */
+struct build_dir* scan_directory(struct build_dir* parent, const char* path)
+{
+    DIR* dir = opendir(path);
+    struct dirent* ent;
+    char* suffix;
+    struct build_file* file;
+    enum filetype filetype;
+    struct stat stat_buf;
+    struct build_dir* build_dir;
+    struct build_dir* subdir;
+    char* file_path;
+    int i;
+
+    int nobuild = 0;
+    int ignorenobuild = 0;
+
+    if (dir == NULL) {
+        fprintf(stderr, "Verzeichnis %s kann nicht geoeffnet werden.\n",
+            path);
+        return NULL;
+    }
+
+    // Speicher fuer Verzeichnis-struct anlegen und initialiseren
+    build_dir = calloc(1, sizeof(*build_dir));
+    build_dir->path = strdup(path);
+    build_dir->parent = parent;
+    build_dir->subdirs = list_create();
+    build_dir->obj_files = list_create();
+    for (i = 0; i < MAX_LANG; i++) {
+        build_dir->src_files[i] = list_create();
+    }
+
+    // Dateien und Unterverzeichnisse einlesen
+    while ((ent = readdir(dir))) {
+
+        filetype = OTHER_FILE;
+        suffix = strrchr(ent->d_name, '.');
+
+        asprintf(&file_path, "%s/%s", path, ent->d_name);
+        stat(file_path, &stat_buf);
+
+        // Dateityp erkennen
+        if (!strcmp(ent->d_name, ".nobuild")) {
+            nobuild = 1;
+            goto next;
+        } else if (!strcmp(ent->d_name, ".ignorenobuild")) {
+            ignorenobuild = 1;
+            goto next;
+        } else if (*ent->d_name == '.') {
+            goto next;
+        } else if (S_ISDIR(stat_buf.st_mode)) {
+            filetype = SUBDIR;
+        } else if (suffix == NULL) {
+            filetype = OTHER_FILE;
+        } else if (!strcmp(suffix, ".o")) {
+            filetype = OBJ;
+        } else if (!strcmp(suffix, ".c")) {
+            filetype = LANG_C;
+        } else if (!strcmp(suffix, ".pas")) {
+            filetype = LANG_PAS;
+        } else if (!strcmp(suffix, ".asm")) {
+            filetype = LANG_ASM_NASM;
+        } else if (!strcmp(suffix, ".S")) {
+            filetype = LANG_ASM_GAS;
+        }
+
+        // Wenn bis hierher nichts verwertbares gefunden wurde, wird die Datei
+        // einfach ignoriert.
+        if (filetype == OTHER_FILE) {
+            goto next;
+        }
+
+        // Datei je nach Typ verarbeiten
+        file = calloc(1, sizeof(*file));
+        file->type = LANG_ASM_GAS;
+        file->name = strdup(ent->d_name);
+
+        switch (filetype) {
+            case SUBDIR:
+                // Unterverzeichnisse werden je nach Namen unterschiedlich
+                // erfasst:
+                //
+                // - include/ wird zu den Includepfaden hinzugefuegt, das
+                //   Verzeicnis wird nicht weiter durchsucht
+                // - In include/arch/ und arch/ wird nur das richtige
+                //   Unterverzeichnis weiterverfolgt
+                // - lib/ wird gesondert gespeichert, damit es vor allen
+                //   anderen Verzeichnissen gebaut werden kann
+                // - Alles andere wird einfach als Unterverzeichnis gemerkt
+                if (!strcmp(file->name, "include")) {
+                    DIR* arch_dir;
+                    char* tmp;
+
+                    build_dir->has_include = 1;
+
+                    asprintf(&tmp, "include/arch/%s", arch);
+                    arch_dir = opendir(tmp);
+                    free(tmp);
+
+                    if (arch_dir != NULL) {
+                        closedir(arch_dir);
+                        build_dir->has_arch_include = 1;
+                    }
+
+                } else if (!strcmp(file->name, "lib")) {
+                    build_dir->lib = scan_directory(build_dir, file_path);
+                } else if (!strcmp(file->name, "arch")) {
+                    char* tmp;
+                    asprintf(&tmp, "%s/%s", file_path, arch);
+                    subdir = scan_directory(build_dir, tmp);
+                    free(tmp);
+                    if (subdir != NULL) {
+                        list_push(build_dir->subdirs, subdir);
+                    }
+                } else {
+                    subdir = scan_directory(build_dir, file_path);
+                    if (subdir != NULL) {
+                        list_push(build_dir->subdirs, subdir);
+                    }
+                }
+                break;
+            case OBJ:
+                // Objektdateien haben ihre eigene Liste
+                list_push(build_dir->obj_files, file);
+                break;
+            default:
+                // Quellcodedateien werden nach Sprache getrennt gespeichert
+                list_push(build_dir->src_files[filetype], file);
+                break;
+        }
+
+    next:
+        free(file_path);
+    }
+
+    closedir(dir);
+
+    // Wenn das Verzeichnis gar nicht gebaut werden soll, besser nichts
+    // zurueckgeben
+    if (nobuild && !ignorenobuild) {
+        // TODO Freigeben
+        return NULL;
+    }
+
+    return build_dir;
+}
diff --git a/src/modules/c/build/include/build.h b/src/modules/c/build/include/build.h
new file mode 100644
index 0000000..f4b8614
--- /dev/null
+++ b/src/modules/c/build/include/build.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the tyndur Project
+ *     and its contributors.
+ * 4. Neither the name of the tyndur Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _BUILD_H_
+#define _BUILD_H_
+
+#include "collections.h"
+
+enum filetype {
+    LANG_C,
+    LANG_PAS,
+    LANG_ASM_GAS,
+    LANG_ASM_NASM,
+
+#define MAX_LANG OTHER_FILE
+    OTHER_FILE,
+    SUBDIR,
+    OBJ,
+};
+
+
+extern char* filetype_str[];
+extern char* arch;
+
+struct build_dir {
+    int                 has_include;
+    int                 has_arch_include;
+    char*               path;
+    struct build_dir*   parent;
+    struct build_dir*   lib;
+    list_t*             src_files[MAX_LANG];
+    list_t*             obj_files;
+    list_t*             subdirs;
+};
+
+struct build_file {
+    enum filetype   type;
+    char*           name;
+};
+
+struct build_dir* scan_directory(struct build_dir* parent, const char* path);
+void build(struct build_dir* root);
+
+#endif
diff --git a/src/modules/c/build/main.c b/src/modules/c/build/main.c
new file mode 100644
index 0000000..74a6292
--- /dev/null
+++ b/src/modules/c/build/main.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2009 The tyndur Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the tyndur Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the tyndur Project
+ *     and its contributors.
+ * 4. Neither the name of the tyndur Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "build.h"
+
+/**
+ * Legt Kuerzel fuer Dateitypen fest, die fuer die Anzeige benutzt werden
+ * koennen, waehrend die Datei verarbeitet wird
+ */
+char* filetype_str[] = {
+    [OTHER_FILE]    = " ? ",
+    [SUBDIR]        = "DIR",
+    [OBJ]           = "OBJ",
+    [LANG_C]        = " C ",
+    [LANG_PAS]      = "PAS",
+    [LANG_ASM_GAS]  = "ASM",
+    [LANG_ASM_NASM] = "ASM",
+};
+
+/**
+ * Legt die aktuelle Architektur fest.
+ *
+ * Wird benutzt, falls arch/-Verzeichnisse im Projekt existieren
+ */
+char* arch = "i386";
+
+/**
+ * Mit verbose != 0 wird die Kommandozeile aller aufgerufenen Tools angezeigt.
+ * Sonst wird nur eine kurze Statusmeldung ausgegeben.
+ */
+int verbose = 0;
+
+
+static void usage(char* binary)
+{
+    fprintf(stderr, "Aufruf: %s [-v] [<Wurzelverzeichnis>]\n", binary);
+    exit(1);
+}
+
+int main(int argc, char** argv)
+{
+    struct build_dir* rootdir;
+    int i;
+    char* rootdir_path = NULL;
+
+    // Verarbeitung der Kommandozeilenparameter
+    for (i = 1; i < argc; i++) {
+        if (!strcmp(argv[i], "-v")) {
+            verbose = 1;
+        } else if (argv[i][0] == '-') {
+            usage(argv[0]);
+        } else if (rootdir_path) {
+            usage(argv[0]);
+        } else {
+            rootdir_path = argv[i];
+        }
+    }
+
+    // Ins Wurzelverzeichnis des Projekts wechseln
+    if (rootdir_path) {
+        if (chdir(argv[i])) {
+            fprintf(stderr, "Verzeichnis nicht gefunden\n");
+            return 1;
+        }
+    }
+
+    // Alle zu kompilierenden Dateien, Includeverzeichnisse usw. erfassen
+    rootdir = scan_directory(NULL, ".");
+    if (rootdir == NULL) {
+        fprintf(stderr, "Verzeichnis nicht gefunden\n");
+        return 1;
+    }
+
+    // Bauen!
+    build(rootdir);
+
+    return 0;
+}
-- 
1.5.6.5