added binary driver clang

This commit is contained in:
Sven Vogel 2024-07-18 22:41:11 +02:00
parent fcf5e08ef0
commit 11594bf44c
8 changed files with 145 additions and 27 deletions

View File

@ -24,6 +24,7 @@ typedef struct TargetLinkConfig_t {
// colorize linker output
bool colorize;
char* output_file;
char* driver;
} TargetLinkConfig;
typedef enum TargetCompilationMode_t {

View File

@ -15,6 +15,7 @@
#include <llvm/backend.h>
#include <mem/cache.h>
#include <set/set.h>
#include <link/lib.h>
#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")) {

42
src/link/clang/driver.c Normal file
View File

@ -0,0 +1,42 @@
//
// Created by servostar on 18.07.24.
//
#include <link/clang/driver.h>
#include <io/files.h>
#include <mem/cache.h>
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;
}

14
src/link/clang/driver.h Normal file
View File

@ -0,0 +1,14 @@
//
// Created by servostar on 18.07.24.
//
#ifndef GEMSTONE_CLANG_DRIVER_H
#define GEMSTONE_CLANG_DRIVER_H
#include <link/driver.h>
bool clang_link(TargetLinkConfig* config);
BinaryDriver* clang_get_driver();
#endif // GEMSTONE_CLANG_DRIVER_H

18
src/link/driver.h Normal file
View File

@ -0,0 +1,18 @@
//
// Created by servostar on 18.07.24.
//
#ifndef GEMSTONE_DRIVER_H
#define GEMSTONE_DRIVER_H
#include <cfg/opt.h>
//! @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

47
src/link/lib.c Normal file
View File

@ -0,0 +1,47 @@
//
// Created by servostar on 18.07.24.
//
#include <link/lib.h>
#include <mem/cache.h>
#include <sys/log.h>
#include <io/files.h>
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;
}
}

16
src/link/lib.h Normal file
View File

@ -0,0 +1,16 @@
//
// Created by servostar on 18.07.24.
//
#ifndef GEMSTONE_LIB_H
#define GEMSTONE_LIB_H
#include <link/clang/driver.h>
typedef BinaryDriver* (*driver_init)();
void link_init();
bool link_run(TargetLinkConfig*);
#endif //GEMSTONE_LIB_H

View File

@ -6,6 +6,7 @@
#include <sys/log.h>
#include <mem/cache.h>
#include <sys/col.h>
#include <link/lib.h>
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;
}