From dee972a6370d78644ee147463bf54452dfcc3468 Mon Sep 17 00:00:00 2001 From: servostar Date: Sun, 22 Sep 2024 23:12:29 +0200 Subject: [PATCH] feat: add triple customization in target configuration --- src/cfg/opt.c | 29 +++++++++++++++++++++++++++++ src/cfg/opt.h | 2 ++ src/link/lldc/lldc.c | 24 +++++++++++++++++++++--- src/llvm/backend.c | 27 ++++++++++++++++++++++++++- src/llvm/backend.h | 2 +- tests/box/build.toml | 2 ++ 6 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/cfg/opt.c b/src/cfg/opt.c index dd624c9..7c83bfe 100644 --- a/src/cfg/opt.c +++ b/src/cfg/opt.c @@ -43,6 +43,33 @@ const char* ENV_ANDROID = "android"; const char* ENV_MACHO = "macho"; const char* ENV_ELF = "elf"; +bool target_has_shared_dependency(TargetLinkConfig* config) +{ + bool has_shared = false; + + const char* shared_files[] = { + ".so", + ".dll" + }; + + for (guint i = 0; i < config->object_file_names->len; i++) + { + char* object_file = g_array_index(config->object_file_names, char*, i); + + for (int k = 0; k < sizeof(shared_files)/sizeof(char*); k++) + { + has_shared = g_str_has_suffix(object_file, shared_files[k]); + if (has_shared) + break; + } + + if (has_shared) + break; + } + + return has_shared; +} + const char* find_string(const char* haystack, const char** options, size_t size) { const static char* found = NULL; @@ -571,6 +598,8 @@ static int parse_target(const ProjectConfig* config, get_int(&target_config->optimization_level, target_table, "opt"); + get_str(&target_config->triple, target_table, "triple"); + char* mode = NULL; get_str(&mode, target_table, "mode"); int err = get_mode_from_str(&target_config->mode, mode); diff --git a/src/cfg/opt.h b/src/cfg/opt.h index cb2cb3f..281ffb9 100644 --- a/src/cfg/opt.h +++ b/src/cfg/opt.h @@ -168,6 +168,8 @@ const char* extract_sys_from_triple(const char* triple); const char* extract_env_from_triple(const char* triple); +bool target_has_shared_dependency(TargetLinkConfig*); + /** * @brief Create the default configuration for targets. * @return A pointer to a new target configuration. diff --git a/src/link/lldc/lldc.c b/src/link/lldc/lldc.c index 58a837d..4879f23 100644 --- a/src/link/lldc/lldc.c +++ b/src/link/lldc/lldc.c @@ -11,9 +11,7 @@ extern int lld_main(int Argc, const char **Argv, const char **outstr); const char* FLAGS[] = { - "--fatal-warnings", - "--Bdynamic", - "--dynamic-linker=/usr/bin/ld.so" + "--fatal-warnings" }; const char* get_optimization_level_string(TargetConfig* config) @@ -35,6 +33,26 @@ bool lldc_link(TargetConfig* target_config, TargetLinkConfig* link_config) { const char* optimization_level = get_optimization_level_string(target_config); g_array_append_val(arguments, optimization_level); + // enable dynamic linker on linux + if (extract_sys_from_triple(target_config->triple) == SYS_LINUX) + { + if (target_has_shared_dependency(link_config)) + { + // add dynamic linker + print_message(Info, "Enabling dynamic linker for build"); + + const char* enable_dynamic_linker = "--Bdynamic"; + g_array_append_val(arguments, enable_dynamic_linker); + + const char* default_dynamic_linker_path = "/usr/bin/ld.so"; + const char* dynamic_linker_option = "--dynamic-linker="; + + char* buffer = mem_alloc(MemoryNamespaceLld, strlen(dynamic_linker_option) + strlen(default_dynamic_linker_path) + 1); + sprintf(buffer, "%s%s", dynamic_linker_option, default_dynamic_linker_path); + g_array_append_val(arguments, buffer); + } + } + for (int i = 0; i < sizeof(FLAGS)/sizeof(char*); i++) { char* flag = (char*) FLAGS[i]; diff --git a/src/llvm/backend.c b/src/llvm/backend.c index 575d338..cb2ef3e 100644 --- a/src/llvm/backend.c +++ b/src/llvm/backend.c @@ -62,10 +62,35 @@ static char* create_target_output_name(const TargetConfig* config) { return cached_name; } -Target create_target_from_config(const TargetConfig* config) { +Target create_target_from_triple(char* triple) +{ + Target target; + + target.triple.str = mem_strdup(MemoryNamespaceLld, triple); + target.triple.allocation = NONE; + + // select default + target.cpu.str = ""; + target.cpu.allocation = NONE; + + // select default + target.features.str = ""; + target.features.allocation = NONE; + + return target; +} + +Target create_target_from_config(TargetConfig* config) { DEBUG("Building target from configuration"); Target target = create_native_target(); + if (config->triple != NULL) + { + target = create_target_from_triple(config->triple); + } else + { + config->triple = target.triple.str; + } target.name.str = create_target_output_name(config); target.name.allocation = NONE; // freed later by compiler diff --git a/src/llvm/backend.h b/src/llvm/backend.h index c553de8..ea789ab 100644 --- a/src/llvm/backend.h +++ b/src/llvm/backend.h @@ -23,7 +23,7 @@ typedef struct Target_t { Target create_native_target(); -Target create_target_from_config(const TargetConfig* config); +Target create_target_from_config(TargetConfig* config); void delete_target(Target target); diff --git a/tests/box/build.toml b/tests/box/build.toml index 102bb25..20c8dc1 100644 --- a/tests/box/build.toml +++ b/tests/box/build.toml @@ -17,6 +17,8 @@ driver = "ld.lld" print_asm = true print_ir = true print_ast = true +opt = 3 +triple = "x86_64-unknown-linux" [targets.dependencies] std = { build-path = "../../lib/src", target = "gsc-libc" }