diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-12-21 15:54:55 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-12-21 15:54:55 -0500 |
| commit | 434ffd71c9a7eebd46ec0cba1d97b0827b874901 (patch) | |
| tree | eb5b02823b7cba714136a0c6b777aca36d147c3a /src/stdlib | |
| parent | 63e6d52f1e1ad9ba3e5dd453115abfc2f8418fc6 (diff) | |
Don't embed tomo version/path information at compile time, instead infer
it at runtime
Diffstat (limited to 'src/stdlib')
| -rw-r--r-- | src/stdlib/stacktrace.c | 2 | ||||
| -rw-r--r-- | src/stdlib/stdlib.c | 61 | ||||
| -rw-r--r-- | src/stdlib/stdlib.h | 1 |
3 files changed, 61 insertions, 3 deletions
diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c index ea939f62..1eba8188 100644 --- a/src/stdlib/stacktrace.c +++ b/src/stdlib/stacktrace.c @@ -98,7 +98,7 @@ void print_stacktrace(FILE *out, int offset) { cwd[cwd_len++] = '/'; cwd[cwd_len] = '\0'; - const char *install_dir = String(TOMO_PATH, "/lib/tomo@" TOMO_VERSION "/"); + const char *install_dir = String(TOMO_PATH, "/lib/tomo@", TOMO_VERSION, "/"); static void *stack[1024]; int64_t size = (int64_t)backtrace(stack, sizeof(stack) / sizeof(stack[0])); diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c index f4e6d678..688f2eb4 100644 --- a/src/stdlib/stdlib.c +++ b/src/stdlib/stdlib.c @@ -17,6 +17,7 @@ #include "files.h" #include "metamethods.h" #include "optionals.h" +#include "paths.h" #include "print.h" #include "siphash.h" #include "stacktrace.h" @@ -39,11 +40,66 @@ static ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) { public bool USE_COLOR; + +public +const char *TOMO_PATH = "/usr/local"; + public -Text_t TOMO_VERSION_TEXT = Text(TOMO_VERSION); +const char *TOMO_VERSION = "v0"; + +public +Text_t TOMO_VERSION_TEXT = Text("v0"); + +#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD) +#include <dlfcn.h> + +static inline const char *get_library_path(void *func) { + static Dl_info info; + if (dladdr(func, &info)) { + return info.dli_fname; // full path of the library + } + return NULL; +} + +#elif defined(_WIN32) +#include <windows.h> + +static inline const char *get_library_path(void *func) { + static char path[MAX_PATH]; + HMODULE hm = NULL; + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCSTR)func, &hm)) { + if (GetModuleFileName(hm, path, MAX_PATH)) { + return path; + } + } + return NULL; +} + +#else +#error "Unsupported platform" +#endif + +const char *resolve_symlinks(const char *path) { + static char resolved[PATH_MAX]; + if (realpath(path, resolved) != NULL) { + return resolved; + } else { + perror("realpath"); + return NULL; + } +} public -const char *TOMO_PATH = TOMO_INSTALL; +void tomo_configure(void) { + const char *lib_path = resolve_symlinks(get_library_path(get_library_path)); + Path_t path = Path$from_str(lib_path); + TOMO_PATH = Path$as_c_string(Path$parent(Path$parent(path))); + Text_t base_name = Path$base_name(path); + TOMO_VERSION_TEXT = Text$without_suffix( + Text$without_prefix(Text$without_prefix(base_name, Text("lib")), Text("tomo@")), Text(".so")); + TOMO_VERSION = Text$as_c_string(TOMO_VERSION_TEXT); +} static _Noreturn void signal_handler(int sig, siginfo_t *info, void *userdata) { (void)info, (void)userdata; @@ -60,6 +116,7 @@ static _Noreturn void signal_handler(int sig, siginfo_t *info, void *userdata) { public void tomo_init(void) { GC_INIT(); + tomo_configure(); const char *color_env = getenv("COLOR"); USE_COLOR = color_env ? strcmp(color_env, "1") == 0 : isatty(STDOUT_FILENO); const char *no_color_env = getenv("NO_COLOR"); diff --git a/src/stdlib/stdlib.h b/src/stdlib/stdlib.h index 3afe3529..234048e9 100644 --- a/src/stdlib/stdlib.h +++ b/src/stdlib/stdlib.h @@ -15,6 +15,7 @@ extern bool USE_COLOR; extern Text_t TOMO_VERSION_TEXT; +void tomo_configure(void); void tomo_init(void); void tomo_at_cleanup(Closure_t fn); void tomo_cleanup(void); |
