From 11594bf44cad4acde3bf691026f347ef26ecc107 Mon Sep 17 00:00:00 2001 From: servostar Date: Thu, 18 Jul 2024 22:41:11 +0200 Subject: [PATCH] added binary driver clang --- src/cfg/opt.h | 1 + src/compiler.c | 3 +++ src/link/clang/driver.c | 42 ++++++++++++++++++++++++++++++++++++ src/link/clang/driver.h | 14 ++++++++++++ src/link/driver.h | 18 ++++++++++++++++ src/link/lib.c | 47 +++++++++++++++++++++++++++++++++++++++++ src/link/lib.h | 16 ++++++++++++++ src/llvm/link/lld.c | 31 ++++----------------------- 8 files changed, 145 insertions(+), 27 deletions(-) create mode 100644 src/link/clang/driver.c create mode 100644 src/link/clang/driver.h create mode 100644 src/link/driver.h create mode 100644 src/link/lib.c create mode 100644 src/link/lib.h diff --git a/src/cfg/opt.h b/src/cfg/opt.h index 9b61def..e80f91f 100644 --- a/src/cfg/opt.h +++ b/src/cfg/opt.h @@ -24,6 +24,7 @@ typedef struct TargetLinkConfig_t { // colorize linker output bool colorize; char* output_file; + char* driver; } TargetLinkConfig; typedef enum TargetCompilationMode_t { diff --git a/src/compiler.c b/src/compiler.c index 7e85543..0ca4c9d 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -15,6 +15,7 @@ #include #include #include +#include #define GRAPHVIZ_FILE_EXTENSION "gv" @@ -355,6 +356,8 @@ static void build_project(ModuleFileStack *unit) { void run_compiler() { ModuleFileStack files = new_file_stack(); + link_init(); + if (is_option_set("build")) { build_project(&files); } else if (is_option_set("compile")) { diff --git a/src/link/clang/driver.c b/src/link/clang/driver.c new file mode 100644 index 0000000..6d4e0cf --- /dev/null +++ b/src/link/clang/driver.c @@ -0,0 +1,42 @@ +// +// Created by servostar on 18.07.24. +// + +#include +#include +#include + +bool clang_link(TargetLinkConfig* config) { + + GString* commandString = g_string_new(""); + + g_string_append(commandString, "clang"); + + for (guint i = 0; i < config->object_file_names->len; i++) { + g_string_append(commandString, " "); + g_string_append(commandString, g_array_index(config->object_file_names, char*, i)); + } + + g_string_append(commandString, " -o "); + g_string_append(commandString, config->output_file); + + print_message(Info, "invoking binary link with: %s", commandString->str); + + if (system(commandString->str)) { + return false; + } + + g_string_free(commandString, true); + + return true; +} + +BinaryDriver* clang_get_driver() { + + BinaryDriver* driver = mem_alloc(MemoryNamespaceLld, sizeof (BinaryDriver)); + + driver->name = "clang"; + driver->link_func = &clang_link; + + return driver; +} diff --git a/src/link/clang/driver.h b/src/link/clang/driver.h new file mode 100644 index 0000000..e8f15da --- /dev/null +++ b/src/link/clang/driver.h @@ -0,0 +1,14 @@ +// +// Created by servostar on 18.07.24. +// + +#ifndef GEMSTONE_CLANG_DRIVER_H +#define GEMSTONE_CLANG_DRIVER_H + +#include + +bool clang_link(TargetLinkConfig* config); + +BinaryDriver* clang_get_driver(); + +#endif // GEMSTONE_CLANG_DRIVER_H diff --git a/src/link/driver.h b/src/link/driver.h new file mode 100644 index 0000000..f797778 --- /dev/null +++ b/src/link/driver.h @@ -0,0 +1,18 @@ +// +// Created by servostar on 18.07.24. +// + +#ifndef GEMSTONE_DRIVER_H +#define GEMSTONE_DRIVER_H + +#include + +//! @brief Function a binary driver used to link files +typedef bool (*driver_link)(TargetLinkConfig*); + +typedef struct BinaryDriver_t { + const char* name; + driver_link link_func; +} BinaryDriver; + +#endif //GEMSTONE_DRIVER_H diff --git a/src/link/lib.c b/src/link/lib.c new file mode 100644 index 0000000..81ccdb8 --- /dev/null +++ b/src/link/lib.c @@ -0,0 +1,47 @@ +// +// Created by servostar on 18.07.24. +// + +#include +#include +#include +#include + +static driver_init AVAILABLE_DRIVER[] = { + clang_get_driver +}; + +static GHashTable* binary_driver = NULL; + +void link_init() { + INFO("initializing binary driver..."); + + if (binary_driver == NULL) { + binary_driver = mem_new_g_hash_table(MemoryNamespaceLld, g_str_hash, g_str_equal); + + for (unsigned long int i = 0; i < sizeof(AVAILABLE_DRIVER)/sizeof(driver_init); i++) { + BinaryDriver* driver = AVAILABLE_DRIVER[i](); + g_hash_table_insert(binary_driver, (gpointer) driver->name, driver); + INFO("initialized `%s` driver", driver->name); + } + } +} + +bool link_run(TargetLinkConfig* config) { + + if (g_hash_table_contains(binary_driver, config->driver)) { + print_message(Info, "Invoking binary driver: %s", config->driver); + + BinaryDriver* driver = g_hash_table_lookup(binary_driver, config->driver); + + if (!driver->link_func(config)) { + print_message(Error, "Driver %s failed", config->driver); + return false; + } + return true; + + } else { + print_message(Error, "Binary driver not available: `%s`", config->driver); + return false; + } +} diff --git a/src/link/lib.h b/src/link/lib.h new file mode 100644 index 0000000..44dcbde --- /dev/null +++ b/src/link/lib.h @@ -0,0 +1,16 @@ +// +// Created by servostar on 18.07.24. +// + +#ifndef GEMSTONE_LIB_H +#define GEMSTONE_LIB_H + +#include + +typedef BinaryDriver* (*driver_init)(); + +void link_init(); + +bool link_run(TargetLinkConfig*); + +#endif //GEMSTONE_LIB_H diff --git a/src/llvm/link/lld.c b/src/llvm/link/lld.c index 781944b..012c924 100644 --- a/src/llvm/link/lld.c +++ b/src/llvm/link/lld.c @@ -6,6 +6,7 @@ #include #include #include +#include const char* get_absolute_link_path(const TargetConfig* config, const char* link_target_name) { INFO("resolving absolute path for link target: %s", link_target_name); @@ -45,6 +46,7 @@ TargetLinkConfig* lld_create_link_config(__attribute__((unused)) const Target* t config->fatal_warnings = target_config->lld_fatal_warnings; config->object_file_names = g_array_new(FALSE, FALSE, sizeof(char*)); config->colorize = stdout_supports_ansi_esc(); + config->driver = mem_strdup(MemoryNamespaceLld, "clang"); // append build object file char* basename = g_strjoin(".", target_config->name, "o", NULL); @@ -90,37 +92,12 @@ TargetLinkConfig* lld_create_link_config(__attribute__((unused)) const Target* t return config; } -gboolean lld_generate_link_command(TargetLinkConfig* config, char** command) { - GString* commandString = g_string_new(""); - - g_string_append(commandString, "clang"); - - for (guint i = 0; i < config->object_file_names->len; i++) { - g_string_append(commandString, " "); - g_string_append(commandString, g_array_index(config->object_file_names, char*, i)); - } - - g_string_append(commandString, " -o "); - g_string_append(commandString, config->output_file); - - *command = commandString->str; - - return true; -} - BackendError lld_link_target(TargetLinkConfig* config) { - char* command = NULL; - lld_generate_link_command(config, &command); - - print_message(Info, "invoking binary driver with: %s", command); - - if (system(command)) { - print_message(Error, "failed generating binary..."); + if (link_run(config)) { + return new_backend_impl_error(Implementation, NULL, "linking failed"); } - g_free(command); - return SUCCESS; }