From 3cba603e7c9ee4b137f71635a4e66868d88691c0 Mon Sep 17 00:00:00 2001 From: 0x221E Date: Sun, 18 Jan 2026 18:24:00 +0100 Subject: [PATCH] Fix: Build phase for C. --- src/build.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/build.h | 36 ++++++++++++++++++++++ src/common.h | 12 ++++++++ 3 files changed, 135 insertions(+) create mode 100644 src/build.c create mode 100644 src/build.h create mode 100644 src/common.h diff --git a/src/build.c b/src/build.c new file mode 100644 index 0000000..0e495e9 --- /dev/null +++ b/src/build.c @@ -0,0 +1,87 @@ +#include "build.h" + +#include +#include + +#include "memory.h" +#include "string.h" +#include "discovery.h" +#include "command.h" +#include "io.h" +#include "utils.h" + +// Only supports C and multiple files + +void build(BuildContext* bc) +{ + assert(bc != NULL); + assert(bc->sp != NULL); + + int sc = build_c_to_o(bc); + if(sc != 0) DIE("Compilation failed!"); + link(bc); +} + +void link(BuildContext* bc) +{ + assert(bc != NULL); + + if(bc->obj_files == NULL) DIE("Linking process was triggered, however there are no object files."); + + Command cmd; + cmd.a = bc->a; + cmd.app = bc->d->cc; + + size_t len = bc->d->c_count + 2; + + const char** args = (const char**)arena_alloc(bc->a, sizeof(const char*) * len); + + args[0] = bc->d->cc.buf; + + for(size_t i = 0; i < bc->d->c_count; i++) + { + args[i + 1] = bc->obj_files[i]->buf; + } + + args[len - 1] = NULL; + cmd.args = args; + + int status = command_run(&cmd); + if(status != 0) + DIE("Linking failed with status code: %d"); + + LOG_DEBUG("Linking completed!"); +} + +int build_c_to_o(BuildContext* bc) +{ + assert(bc != NULL); + if(bc->d->c_count == 0) + return 1; + + CommandOptions co; + co.a = bc->a; + co.sp = bc->sp; + co.bp = bc->build_profile; + co.c = bc->c; + co.app = bc->d->cc; + + StringView* arr = (StringView*)arena_alloc(bc->a, sizeof(StringView) * 1); + co.files = arr; + + StringView** obj_files = (StringView**)arena_alloc(bc->a, sizeof(StringView*) * bc->d->c_count); + bc->obj_files = obj_files; + + for(size_t i = 0; i < bc->d->c_count; i++) + { + co.files[0] = bc->d->c_files[i]->path; + Command cmd = command_create_f_to_o(&co); + int status = command_run(&cmd); + if(status != 0) + DIE("Failed to compile %s, compiler exited with status code: %d", bc->d->c_files[i]->path.buf, status); + bc->obj_files[i] = &bc->d->c_files[i]->path; + LOG_DEBUG("Compiling %s", bc->d->c_files[i]->path.buf); + + } + return 0; +} diff --git a/src/build.h b/src/build.h new file mode 100644 index 0000000..360de4f --- /dev/null +++ b/src/build.h @@ -0,0 +1,36 @@ +#ifndef BUILD_H +#define BUILD_H + +#include "common.h" + +typedef struct Configuration Configuration; +typedef struct Discovery Discovery; +typedef struct Arena Arena; +typedef struct StringPool StringPool; +typedef struct StringView StringView; +typedef struct Command Command; + +struct BuildContext +{ + // Memory + Arena* a; + StringPool* sp; + + // Build Params + enum BuildProfile build_profile; + Configuration* c; + Discovery* d; + + StringView** obj_files; +}; + +typedef enum BuildProfile BuildProfile; +typedef struct BuildContext BuildContext; + +void build(BuildContext* bc); + +void link(BuildContext* bc); + +int build_c_to_o(BuildContext* bc); + +#endif diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..4b060e1 --- /dev/null +++ b/src/common.h @@ -0,0 +1,12 @@ +#ifndef COMMON_H +#define COMMON_H + +enum BuildProfile +{ + B_DEBUG, + B_PROD +}; + +typedef enum BuildProfile BuildProfile; + +#endif