From e01383da05d5cf03d080854ac048df37df4d1b9a Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 15:11:52 -0400 Subject: Change module install directory to PREFIX/lib/tomo_vX.Y/* --- src/compile/headers.c | 4 ++-- src/compile/statements.c | 4 ++-- src/modules.c | 44 +++++++++++++++++++------------------------- src/stdlib/stacktrace.c | 2 +- src/tomo.c | 28 +++++++++++++--------------- src/typecheck.c | 4 ++-- 6 files changed, 39 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/compile/headers.c b/src/compile/headers.c index 8c0863ee..be564144 100644 --- a/src/compile/headers.c +++ b/src/compile/headers.c @@ -174,8 +174,8 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, - NULL, &tm_files) + if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + &tm_files) != 0) { if (!try_install_module(mod)) code_err(ast, "Could not find library"); } diff --git a/src/compile/statements.c b/src/compile/statements.c index e296795b..82a91a5e 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -204,8 +204,8 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, - NULL, &tm_files) + if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + &tm_files) != 0) { if (!try_install_module(mod)) code_err(ast, "Could not find library"); } diff --git a/src/modules.c b/src/modules.c index 40b3daf3..67b09fdb 100644 --- a/src/modules.c +++ b/src/modules.c @@ -50,34 +50,25 @@ module_info_t get_module_info(ast_t *use) { if (cached) return **cached; const char *name = Match(use, Use)->path; module_info_t *info = new (module_info_t, .name = name); - if (streq(name, "commands")) info->version = "v1.0"; - else if (streq(name, "random")) info->version = "v1.0"; - else if (streq(name, "base64")) info->version = "v1.0"; - else if (streq(name, "core")) info->version = "v1.0"; - else if (streq(name, "patterns")) info->version = "v1.1"; - else if (streq(name, "json")) info->version = "v1.0"; - else if (streq(name, "pthreads")) info->version = "v1.0"; - else if (streq(name, "shell")) info->version = "v1.0"; - else if (streq(name, "time")) info->version = "v1.0"; - else if (streq(name, "uuid")) info->version = "v1.0"; - else { - read_modules_ini(Path$sibling(Path$from_str(use->file->filename), Text("modules.ini")), info); - read_modules_ini(Path$with_extension(Path$from_str(use->file->filename), Text(":modules.ini"), false), info); - } + read_modules_ini(Path$sibling(Path$from_str(use->file->filename), Text("modules.ini")), info); + read_modules_ini(Path$with_extension(Path$from_str(use->file->filename), Text(":modules.ini"), false), info); Table$set(&cache, &use, &info, cache_type); return *info; } bool try_install_module(module_info_t mod) { if (mod.git) { - OptionalText_t answer = ask(Texts(Text("The module \""), Text$from_str(mod.name), - Text("\" is not installed.\nDo you want to install it from git URL "), - Text$from_str(mod.git), Text("? [Y/n] ")), + OptionalText_t answer = ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + " is not installed.\nDo you want to install it from git URL ", + Text$from_str(mod.git), "? [Y/n] "), true, true); if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) return false; print("Installing ", mod.name, " from git..."); Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX")); + tmpdir = Path$child(tmpdir, Text$from_str(mod.name)); + Path$create_directory(tmpdir, 0755); + if (mod.revision) xsystem("git clone --depth=1 --revision ", mod.revision, " ", mod.git, " ", tmpdir); else xsystem("git clone --depth=1 ", mod.git, " ", tmpdir); if (mod.path) xsystem("tomo -IL ", tmpdir, "/", mod.path); @@ -85,10 +76,10 @@ bool try_install_module(module_info_t mod) { Path$remove(tmpdir, true); return true; } else if (mod.url) { - OptionalText_t answer = ask(Texts(Text("The module "), Text$from_str(mod.name), - Text(" is not installed.\nDo you want to install it from URL "), - Text$from_str(mod.url), Text("? [Y/n] ")), - true, true); + OptionalText_t answer = + ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + " is not installed.\nDo you want to install it from URL ", Text$from_str(mod.url), "? [Y/n] "), + true, true); if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) return false; @@ -101,6 +92,9 @@ bool try_install_module(module_info_t mod) { if (!p) return false; const char *extension = p + 1; Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX")); + tmpdir = Path$child(tmpdir, Text$from_str(mod.name)); + Path$create_directory(tmpdir, 0755); + xsystem("curl ", mod.url, " -o ", tmpdir); if (streq(extension, ".zip")) xsystem("unzip ", tmpdir, "/", filename); else if (streq(extension, ".tar.gz") || streq(extension, ".tar")) xsystem("tar xf ", tmpdir, "/", filename); @@ -111,10 +105,10 @@ bool try_install_module(module_info_t mod) { Path$remove(tmpdir, true); return true; } else if (mod.path) { - OptionalText_t answer = ask(Texts(Text("The module "), Text$from_str(mod.name), - Text(" is not installed.\nDo you want to install it from path "), - Text$from_str(mod.path), Text("? [Y/n] ")), - true, true); + OptionalText_t answer = + ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + " is not installed.\nDo you want to install it from path ", Text$from_str(mod.path), "? [Y/n] "), + true, true); if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) return false; diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c index 266dc4ef..c7ec54d3 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 = TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/"; + const char *install_dir = TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/"; static void *stack[1024]; int64_t size = (int64_t)backtrace(stack, sizeof(stack) / sizeof(stack[0])); diff --git a/src/tomo.c b/src/tomo.c index da10df87..0e455ec6 100644 --- a/src/tomo.c +++ b/src/tomo.c @@ -87,8 +87,8 @@ static OptionalText_t show_codegen = NONE_TEXT, " -D_BSD_SOURCE" #endif " -DGC_THREADS" - " -I'" TOMO_PREFIX "/include' -I'" TOMO_PREFIX "/share/tomo_" TOMO_VERSION - "/installed' -I/usr/local/include"), + " -I'" TOMO_PREFIX "/include' -I'" TOMO_PREFIX "/lib/tomo_" TOMO_VERSION + "' -I/usr/local/include"), ldlibs = Text("-lgc -lm -lgmp -lunistring -ltomo_" TOMO_VERSION), ldflags = Text("-Wl,-rpath,'" TOMO_PREFIX "/lib',-rpath,/usr/local/lib" " -L/usr/local/lib"), @@ -163,8 +163,7 @@ int main(int argc, char *argv[]) { // Run a tool: if ((streq(argv[1], "-r") || streq(argv[1], "--run")) && argc >= 3) { if (strcspn(argv[2], "/;$") == strlen(argv[2])) { - const char *program = - String("'" TOMO_PREFIX "'/share/tomo_" TOMO_VERSION "/installed/", argv[2], "/", argv[2]); + const char *program = String("'" TOMO_PREFIX "'/lib/tomo_" TOMO_VERSION "/", argv[2], "/", argv[2]); execv(program, &argv[2]); } print_err("This is not an installed tomo program: ", argv[2]); @@ -183,7 +182,7 @@ int main(int argc, char *argv[]) { " --parse|-p: show parse tree\n" " --install|-I: install the executable or library\n" " --optimization|-O : set optimization level\n" - " --run|-r: run a program from " TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed\n"); + " --run|-r: run a program from " TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "\n"); Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage); tomo_parse_args( argc, argv, usage, help, TOMO_VERSION, {"files", true, List$info(&Path$info), &files}, @@ -248,7 +247,7 @@ int main(int argc, char *argv[]) { for (int64_t i = 0; i < uninstall.length; i++) { Text_t *u = (Text_t *)(uninstall.data + i * uninstall.stride); - xsystem(as_owner, "rm -rvf '" TOMO_PREFIX "'/share/tomo_" TOMO_VERSION "/installed/", *u); + xsystem(as_owner, "rm -rvf '" TOMO_PREFIX "'/lib/tomo_" TOMO_VERSION "/", *u); print("Uninstalled ", *u); } @@ -410,8 +409,7 @@ void build_library(Path_t lib_dir) { void install_library(Path_t lib_dir) { Text_t lib_dir_name = Path$base_name(lib_dir); Text_t version_suffix = get_version_suffix(lib_dir); - Path_t dest = Path$child(Path$from_str(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed"), - Texts(lib_dir_name, version_suffix)); + Path_t dest = Path$child(Path$from_str(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION), Texts(lib_dir_name, version_suffix)); if (!Path$equal_values(lib_dir, dest)) { if (verbose) whisper("Clearing out any pre-existing version of ", lib_dir_name); xsystem(as_owner, "rm -rf '", dest, "'"); @@ -430,8 +428,8 @@ void install_library(Path_t lib_dir) { "' " ">/dev/null 2>/dev/null")); (void)result; - print("Installed \033[1m", lib_dir_name, "\033[m to " TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/", - lib_dir_name, version_suffix); + print("Installed \033[1m", lib_dir_name, "\033[m to " TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", lib_dir_name, + version_suffix); } void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *extra_ldlibs) { @@ -592,13 +590,13 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l module_info_t mod = get_module_info(stmt_ast); const char *full_name = mod.version ? String(mod.name, "_", mod.version) : mod.name; Text_t lib = - Texts(Text("-Wl,-rpath,'"), Text(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/"), - Text$from_str(full_name), Text("' '" TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/"), - Text$from_str(full_name), Text("/lib"), Text$from_str(full_name), Text(SHARED_SUFFIX "'")); + Texts(Text("-Wl,-rpath,'"), Text(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/"), Text$from_str(full_name), + Text("' '" TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/"), Text$from_str(full_name), Text("/lib"), + Text$from_str(full_name), Text(SHARED_SUFFIX "'")); Table$set(to_link, &lib, NULL, Table$info(&Text$info, &Void$info)); - List_t children = Path$glob(Path$from_str( - String(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/", full_name, "/[!._0-9]*.tm"))); + List_t children = + Path$glob(Path$from_str(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", full_name, "/[!._0-9]*.tm"))); for (int64_t i = 0; i < children.length; i++) { Path_t *child = (Path_t *)(children.data + i * children.stride); Table_t discarded = {.fallback = to_compile}; diff --git a/src/typecheck.c b/src/typecheck.c index 07970bd9..adb267df 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -186,8 +186,8 @@ static env_t *load_module(env_t *env, ast_t *module_ast) { module_info_t mod = get_module_info(module_ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, - NULL, &tm_files) + if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + &tm_files) != 0) { if (!try_install_module(mod)) code_err(module_ast, "Couldn't find or install library: ", folder); } -- cgit v1.2.3 From 02a99d24a310c04622a875dcf4b0c6fd2de71332 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 15:32:19 -0400 Subject: Fix for versions getting double appended for libs --- src/modules.c | 28 +++++++++++++--------------- src/tomo.c | 26 +++++++++++++++----------- 2 files changed, 28 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/modules.c b/src/modules.c index 67b09fdb..5327f28b 100644 --- a/src/modules.c +++ b/src/modules.c @@ -5,6 +5,7 @@ #include #include +#include "config.h" #include "modules.h" #include "stdlib/memory.h" #include "stdlib/paths.h" @@ -57,6 +58,8 @@ module_info_t get_module_info(ast_t *use) { } bool try_install_module(module_info_t mod) { + Path_t dest = Path$from_text( + Texts(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", Text$from_str(mod.name), "_", Text$from_str(mod.version))); if (mod.git) { OptionalText_t answer = ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), " is not installed.\nDo you want to install it from git URL ", @@ -65,15 +68,9 @@ bool try_install_module(module_info_t mod) { if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) return false; print("Installing ", mod.name, " from git..."); - Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX")); - tmpdir = Path$child(tmpdir, Text$from_str(mod.name)); - Path$create_directory(tmpdir, 0755); - - if (mod.revision) xsystem("git clone --depth=1 --revision ", mod.revision, " ", mod.git, " ", tmpdir); - else xsystem("git clone --depth=1 ", mod.git, " ", tmpdir); - if (mod.path) xsystem("tomo -IL ", tmpdir, "/", mod.path); - else xsystem("tomo -IL ", tmpdir); - Path$remove(tmpdir, true); + if (mod.revision) xsystem("git clone --depth=1 --revision ", mod.revision, " ", mod.git, " ", dest); + else xsystem("git clone --depth=1 ", mod.git, " ", dest); + xsystem("tomo -L ", dest); return true; } else if (mod.url) { OptionalText_t answer = @@ -96,12 +93,12 @@ bool try_install_module(module_info_t mod) { Path$create_directory(tmpdir, 0755); xsystem("curl ", mod.url, " -o ", tmpdir); - if (streq(extension, ".zip")) xsystem("unzip ", tmpdir, "/", filename); - else if (streq(extension, ".tar.gz") || streq(extension, ".tar")) xsystem("tar xf ", tmpdir, "/", filename); + Path$create_directory(dest, 0755); + if (streq(extension, ".zip")) xsystem("unzip ", tmpdir, "/", filename, " -d ", dest); + else if (streq(extension, ".tar.gz") || streq(extension, ".tar")) + xsystem("tar xf ", tmpdir, "/", filename, " -C ", dest); else return false; - const char *basename = String(string_slice(filename, strcspn(filename, "."))); - if (mod.path) xsystem("tomo -IL ", tmpdir, "/", basename, "/", mod.path); - else xsystem("tomo -IL ", tmpdir, "/", basename); + xsystem("tomo -L ", dest); Path$remove(tmpdir, true); return true; } else if (mod.path) { @@ -113,7 +110,8 @@ bool try_install_module(module_info_t mod) { return false; print("Installing ", mod.name, " from path..."); - xsystem("tomo -IL ", mod.path); + xsystem("ln -s ", mod.path, " ", dest); + xsystem("tomo -L ", dest); return true; } diff --git a/src/tomo.c b/src/tomo.c index 0e455ec6..b6440f10 100644 --- a/src/tomo.c +++ b/src/tomo.c @@ -368,21 +368,25 @@ static const char *get_version(Path_t lib_dir) { return String(string_slice(version_line + 4, strcspn(version_line + 4, "\r\n"))); } -static Text_t get_version_suffix(Path_t lib_dir) { return Texts(Text("_"), Text$from_str(get_version(lib_dir))); } +static Path_t with_version_suffix(Path_t lib_dir) { + Text_t suffix = Texts(Text("_"), Text$from_str(get_version(lib_dir))); + return Text$ends_with(Path$base_name(lib_dir), suffix, NULL) + ? lib_dir + : Path$sibling(lib_dir, Texts(Path$base_name(lib_dir), suffix)); +} void build_library(Path_t lib_dir) { lib_dir = Path$resolved(lib_dir, Path$current_dir()); if (!Path$is_directory(lib_dir, true)) print_err("Not a valid directory: ", lib_dir); - Text_t lib_dir_name = Path$base_name(lib_dir); List_t tm_files = Path$glob(Path$child(lib_dir, Text("[!._0-9]*.tm"))); env_t *env = fresh_scope(global_env(source_mapping)); List_t object_files = {}, extra_ldlibs = {}; compile_files(env, tm_files, &object_files, &extra_ldlibs); - Text_t version_suffix = get_version_suffix(lib_dir); - Path_t shared_lib = Path$child(lib_dir, Texts(Text("lib"), lib_dir_name, version_suffix, Text(SHARED_SUFFIX))); + Text_t versioned_dir = Path$base_name(with_version_suffix(lib_dir)); + Path_t shared_lib = Path$child(lib_dir, Texts(Text("lib"), versioned_dir, Text(SHARED_SUFFIX))); if (!is_stale_for_any(shared_lib, object_files, false)) { if (verbose) whisper("Unchanged: ", shared_lib); return; @@ -390,10 +394,10 @@ void build_library(Path_t lib_dir) { FILE *prog = run_cmd(cc, " -O", optimization, " ", cflags, " ", ldflags, " ", ldlibs, " ", list_text(extra_ldlibs), #ifdef __APPLE__ - " -Wl,-install_name,@rpath/'lib", lib_dir_name, version_suffix, SHARED_SUFFIX, + " -Wl,-install_name,@rpath/'lib", Path$base_name(lib_dir), version_suffix, SHARED_SUFFIX, "'" #else - " -Wl,-soname,'lib", lib_dir_name, version_suffix, SHARED_SUFFIX, + " -Wl,-soname,'lib", versioned_dir, SHARED_SUFFIX, "'" #endif " -shared ", @@ -408,8 +412,9 @@ void build_library(Path_t lib_dir) { void install_library(Path_t lib_dir) { Text_t lib_dir_name = Path$base_name(lib_dir); - Text_t version_suffix = get_version_suffix(lib_dir); - Path_t dest = Path$child(Path$from_str(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION), Texts(lib_dir_name, version_suffix)); + Text_t versioned_dir = Path$base_name(with_version_suffix(lib_dir)); + Path_t dest = Path$child(Path$from_str(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION), versioned_dir); + print("Installing ", lib_dir, " into ", dest); if (!Path$equal_values(lib_dir, dest)) { if (verbose) whisper("Clearing out any pre-existing version of ", lib_dir_name); xsystem(as_owner, "rm -rf '", dest, "'"); @@ -424,12 +429,11 @@ void install_library(Path_t lib_dir) { int result = system(String(as_owner, "debugedit -b ", lib_dir, " -d '", dest, "'" " '", - dest, "/lib", lib_dir_name, version_suffix, SHARED_SUFFIX, + dest, "/lib", versioned_dir, SHARED_SUFFIX, "' " ">/dev/null 2>/dev/null")); (void)result; - print("Installed \033[1m", lib_dir_name, "\033[m to " TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", lib_dir_name, - version_suffix); + print("Installed \033[1m", lib_dir_name, "\033[m to " TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", versioned_dir); } void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *extra_ldlibs) { -- cgit v1.2.3 From ed50c5fefb8892ad2ba5262491669f268ddbd436 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 16:44:58 -0400 Subject: Overhaul code to stop keeping examples and libraries in the same repo, but instead spin each out into its own repo. --- src/compile/headers.c | 2 +- src/compile/statements.c | 2 +- src/modules.c | 67 +++++++++++++++++++++++++++++++++++++----------- src/modules.h | 3 ++- src/tomo.c | 11 ++++++-- src/typecheck.c | 2 +- 6 files changed, 66 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/compile/headers.c b/src/compile/headers.c index be564144..d1131bde 100644 --- a/src/compile/headers.c +++ b/src/compile/headers.c @@ -177,7 +177,7 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(ast, "Could not find library"); + if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); } Text_t includes = EMPTY_TEXT; diff --git a/src/compile/statements.c b/src/compile/statements.c index 82a91a5e..af6a5223 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -207,7 +207,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(ast, "Could not find library"); + if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); } Text_t initialization = EMPTY_TEXT; diff --git a/src/modules.c b/src/modules.c index 5327f28b..6658f8a5 100644 --- a/src/modules.c +++ b/src/modules.c @@ -15,6 +15,7 @@ #include "stdlib/tables.h" #include "stdlib/text.h" #include "stdlib/types.h" +#include "stdlib/util.h" #define xsystem(...) \ ({ \ @@ -23,6 +24,33 @@ errx(1, "Failed to run command: %s", String(__VA_ARGS__)); \ }) +bool install_from_modules_ini(Path_t ini_file, bool ask_confirmation) { + OptionalClosure_t by_line = Path$by_line(ini_file); + if (by_line.fn == NULL) return false; + OptionalText_t (*next_line)(void *) = by_line.fn; + module_info_t info = {}; + for (Text_t line; (line = next_line(by_line.userdata)).length >= 0;) { + char *line_str = Text$as_c_string(line); + const char *next_section = NULL; + if (!strparse(line_str, "[", &next_section, "]")) { + if (info.name) { + if (!try_install_module(info, ask_confirmation)) return false; + } + print("Checking module ", next_section, "..."); + info = (module_info_t){.name = next_section}; + continue; + } + if (!strparse(line_str, "version=", &info.version) || !strparse(line_str, "url=", &info.url) + || !strparse(line_str, "git=", &info.git) || !strparse(line_str, "path=", &info.path) + || !strparse(line_str, "revision=", &info.revision)) + continue; + } + if (info.name) { + if (!try_install_module(info, ask_confirmation)) return false; + } + return true; +} + static void read_modules_ini(Path_t ini_file, module_info_t *info) { OptionalClosure_t by_line = Path$by_line(ini_file); if (by_line.fn == NULL) return; @@ -57,28 +85,35 @@ module_info_t get_module_info(ast_t *use) { return *info; } -bool try_install_module(module_info_t mod) { +bool try_install_module(module_info_t mod, bool ask_confirmation) { Path_t dest = Path$from_text( Texts(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", Text$from_str(mod.name), "_", Text$from_str(mod.version))); + if (Path$exists(dest)) return true; + if (mod.git) { - OptionalText_t answer = ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), - " is not installed.\nDo you want to install it from git URL ", - Text$from_str(mod.git), "? [Y/n] "), - true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) - return false; + if (ask_confirmation) { + OptionalText_t answer = + ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + " is not installed.\nDo you want to install it from git URL ", Text$from_str(mod.git), + "? [Y/n] "), + true, true); + if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + return false; + } print("Installing ", mod.name, " from git..."); if (mod.revision) xsystem("git clone --depth=1 --revision ", mod.revision, " ", mod.git, " ", dest); else xsystem("git clone --depth=1 ", mod.git, " ", dest); xsystem("tomo -L ", dest); return true; } else if (mod.url) { - OptionalText_t answer = - ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + if (ask_confirmation) { + OptionalText_t answer = ask( + Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), " is not installed.\nDo you want to install it from URL ", Text$from_str(mod.url), "? [Y/n] "), true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) - return false; + if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + return false; + } print("Installing ", mod.name, " from URL..."); @@ -102,12 +137,14 @@ bool try_install_module(module_info_t mod) { Path$remove(tmpdir, true); return true; } else if (mod.path) { - OptionalText_t answer = - ask(Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), + if (ask_confirmation) { + OptionalText_t answer = ask( + Texts("The module \"", Text$from_str(mod.name), "\" ", Text$from_str(mod.version), " is not installed.\nDo you want to install it from path ", Text$from_str(mod.path), "? [Y/n] "), true, true); - if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) - return false; + if (!(answer.length == 0 || Text$equal_values(answer, Text("Y")) || Text$equal_values(answer, Text("y")))) + return false; + } print("Installing ", mod.name, " from path..."); xsystem("ln -s ", mod.path, " ", dest); diff --git a/src/modules.h b/src/modules.h index 1c3b2d8e..c36d96dd 100644 --- a/src/modules.h +++ b/src/modules.h @@ -11,4 +11,5 @@ typedef struct { } module_info_t; module_info_t get_module_info(ast_t *use); -bool try_install_module(module_info_t mod); +bool install_from_modules_ini(Path_t ini_file, bool ask_confirmation); +bool try_install_module(module_info_t mod, bool ask_confirmation); diff --git a/src/tomo.c b/src/tomo.c index b6440f10..a1f21dcf 100644 --- a/src/tomo.c +++ b/src/tomo.c @@ -260,8 +260,15 @@ int main(int argc, char *argv[]) { // This *could* be done in parallel, but there may be some dependency issues. pid_t child = fork(); if (child == 0) { - build_library(*lib); - if (should_install) install_library(*lib); + if (Text$equal_values(Path$extension(*lib, false), Text("ini"))) { + if (!install_from_modules_ini(*lib, false)) { + print("Failed to install modules from file: ", *lib); + _exit(1); + } + } else { + build_library(*lib); + if (should_install) install_library(*lib); + } _exit(0); } wait_for_child_success(child); diff --git a/src/typecheck.c b/src/typecheck.c index adb267df..80c270ef 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -189,7 +189,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) { if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { - if (!try_install_module(mod)) code_err(module_ast, "Couldn't find or install library: ", folder); + if (!try_install_module(mod, true)) code_err(module_ast, "Couldn't find or install library: ", folder); } env_t *module_env = fresh_scope(env); -- cgit v1.2.3 From 081a26de86eca95ba3ee0887992cdc3d96190cce Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 17:32:42 -0400 Subject: Fixes for local-tomo so that it *actually* uses local header files, which don't need to be installed anymore. --- src/compile/headers.c | 2 +- src/compile/statements.c | 2 +- src/config.h | 6 ++-- src/modules.c | 4 +-- src/stdlib/stacktrace.c | 2 +- src/stdlib/stdlib.c | 3 ++ src/tomo.c | 81 ++++++++++++++++++++++++++---------------------- src/typecheck.c | 3 +- 8 files changed, 57 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/compile/headers.c b/src/compile/headers.c index d1131bde..6dc69f03 100644 --- a/src/compile/headers.c +++ b/src/compile/headers.c @@ -174,7 +174,7 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast) module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + if (glob(String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); diff --git a/src/compile/statements.c b/src/compile/statements.c index af6a5223..a7c5214a 100644 --- a/src/compile/statements.c +++ b/src/compile/statements.c @@ -204,7 +204,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) { module_info_t mod = get_module_info(ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, + if (glob(String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { if (!try_install_module(mod, true)) code_err(ast, "Could not find library"); diff --git a/src/config.h b/src/config.h index 1afbb3e5..8ee44200 100644 --- a/src/config.h +++ b/src/config.h @@ -8,10 +8,12 @@ #define GIT_VERSION "???" #endif -#ifndef TOMO_PREFIX -#define TOMO_PREFIX "/usr/local" +#ifndef TOMO_INSTALL +#define TOMO_INSTALL "/usr/local" #endif +extern const char *TOMO_PATH; + #ifndef DEFAULT_C_COMPILER #define DEFAULT_C_COMPILER "cc" #endif diff --git a/src/modules.c b/src/modules.c index 6658f8a5..fafbbf86 100644 --- a/src/modules.c +++ b/src/modules.c @@ -86,8 +86,8 @@ module_info_t get_module_info(ast_t *use) { } bool try_install_module(module_info_t mod, bool ask_confirmation) { - Path_t dest = Path$from_text( - Texts(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", Text$from_str(mod.name), "_", Text$from_str(mod.version))); + Path_t dest = Path$from_text(Texts(Text$from_str(TOMO_PATH), "/lib/tomo_" TOMO_VERSION "/", Text$from_str(mod.name), + "_", Text$from_str(mod.version))); if (Path$exists(dest)) return true; if (mod.git) { diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c index c7ec54d3..0953e660 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 = TOMO_PREFIX "/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 bf36ca0d..5ea8cb79 100644 --- a/src/stdlib/stdlib.c +++ b/src/stdlib/stdlib.c @@ -41,6 +41,9 @@ bool USE_COLOR; public Text_t TOMO_VERSION_TEXT = Text(TOMO_VERSION); +public +const char *TOMO_PATH = TOMO_INSTALL; + static _Noreturn void signal_handler(int sig, siginfo_t *info, void *userdata) { (void)info, (void)userdata; assert(sig == SIGILL); diff --git a/src/tomo.c b/src/tomo.c index a1f21dcf..449bac37 100644 --- a/src/tomo.c +++ b/src/tomo.c @@ -34,6 +34,7 @@ #include "stdlib/siphash.h" #include "stdlib/tables.h" #include "stdlib/text.h" +#include "stdlib/util.h" #include "types.h" #define run_cmd(...) \ @@ -87,16 +88,13 @@ static OptionalText_t show_codegen = NONE_TEXT, " -D_BSD_SOURCE" #endif " -DGC_THREADS" - " -I'" TOMO_PREFIX "/include' -I'" TOMO_PREFIX "/lib/tomo_" TOMO_VERSION - "' -I/usr/local/include"), + " -I/usr/local/include"), ldlibs = Text("-lgc -lm -lgmp -lunistring -ltomo_" TOMO_VERSION), - ldflags = Text("-Wl,-rpath,'" TOMO_PREFIX "/lib',-rpath,/usr/local/lib" - " -L/usr/local/lib"), - optimization = Text("2"), cc = Text(DEFAULT_C_COMPILER); + ldflags = Text(" -L/usr/local/lib"), optimization = Text("2"), cc = Text(DEFAULT_C_COMPILER); static Text_t config_summary, // This will be either "" or "sudo -u " or "doas -u " - // to allow a command to put stuff into TOMO_PREFIX as the owner + // to allow a command to put stuff into TOMO_PATH as the owner // of that directory. as_owner = Text(""); @@ -149,40 +147,48 @@ int main(int argc, char *argv[]) { #error "Unsupported platform for secure random number generation" #endif + if (getenv("TOMO_PATH")) TOMO_PATH = getenv("TOMO_PATH"); + + cflags = Texts("-I'", TOMO_PATH, "/include' -I'", TOMO_PATH, "/lib/tomo_" TOMO_VERSION "' ", cflags); + // Set up environment variables: const char *PATH = getenv("PATH"); - setenv("PATH", PATH ? String(TOMO_PREFIX "/bin:", PATH) : TOMO_PREFIX "/bin", 1); + setenv("PATH", PATH ? String(TOMO_PATH, "/bin:", PATH) : String(TOMO_PATH, "/bin"), 1); const char *LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH"); - setenv("LD_LIBRARY_PATH", LD_LIBRARY_PATH ? String(TOMO_PREFIX "/lib:", LD_LIBRARY_PATH) : TOMO_PREFIX "/lib", 1); + setenv("LD_LIBRARY_PATH", LD_LIBRARY_PATH ? String(TOMO_PATH, "/lib:", LD_LIBRARY_PATH) : String(TOMO_PATH, "/lib"), + 1); const char *LIBRARY_PATH = getenv("LIBRARY_PATH"); - setenv("LIBRARY_PATH", LIBRARY_PATH ? String(TOMO_PREFIX "/lib:", LIBRARY_PATH) : TOMO_PREFIX "/lib", 1); + setenv("LIBRARY_PATH", LIBRARY_PATH ? String(TOMO_PATH, "/lib:", LIBRARY_PATH) : String(TOMO_PATH, "/lib"), 1); const char *C_INCLUDE_PATH = getenv("C_INCLUDE_PATH"); - setenv("C_INCLUDE_PATH", C_INCLUDE_PATH ? String(TOMO_PREFIX "/include:", C_INCLUDE_PATH) : TOMO_PREFIX "/include", - 1); + setenv("C_INCLUDE_PATH", + C_INCLUDE_PATH ? String(TOMO_PATH, "/include:", C_INCLUDE_PATH) : String(TOMO_PATH, "/include"), 1); + const char *CPATH = getenv("CPATH"); + setenv("CPATH", CPATH ? String(TOMO_PATH, "/include:", CPATH) : String(TOMO_PATH, "/include"), 1); // Run a tool: if ((streq(argv[1], "-r") || streq(argv[1], "--run")) && argc >= 3) { if (strcspn(argv[2], "/;$") == strlen(argv[2])) { - const char *program = String("'" TOMO_PREFIX "'/lib/tomo_" TOMO_VERSION "/", argv[2], "/", argv[2]); + const char *program = String("'", TOMO_PATH, "'/lib/tomo_" TOMO_VERSION "/", argv[2], "/", argv[2]); execv(program, &argv[2]); } print_err("This is not an installed tomo program: ", argv[2]); } - Text_t usage = Text("\x1b[33;4;1mUsage:\x1b[m\n" - "\x1b[1mRun a program:\x1b[m tomo file.tm [-- args...]\n" - "\x1b[1mTranspile files:\x1b[m tomo -t file.tm...\n" - "\x1b[1mCompile object files:\x1b[m tomo -c file.tm...\n" - "\x1b[1mCompile executables:\x1b[m tomo -e file.tm...\n" - "\x1b[1mBuild libraries:\x1b[m tomo -L lib...\n" - "\x1b[1mUninstall libraries:\x1b[m tomo -u lib...\n" - "\x1b[1mOther flags:\x1b[m\n" - " --verbose|-v: verbose output\n" - " --quiet|-q: quiet output\n" - " --parse|-p: show parse tree\n" - " --install|-I: install the executable or library\n" - " --optimization|-O : set optimization level\n" - " --run|-r: run a program from " TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "\n"); + Text_t usage = Texts("\x1b[33;4;1mUsage:\x1b[m\n" + "\x1b[1mRun a program:\x1b[m tomo file.tm [-- args...]\n" + "\x1b[1mTranspile files:\x1b[m tomo -t file.tm...\n" + "\x1b[1mCompile object files:\x1b[m tomo -c file.tm...\n" + "\x1b[1mCompile executables:\x1b[m tomo -e file.tm...\n" + "\x1b[1mBuild libraries:\x1b[m tomo -L lib...\n" + "\x1b[1mUninstall libraries:\x1b[m tomo -u lib...\n" + "\x1b[1mOther flags:\x1b[m\n" + " --verbose|-v: verbose output\n" + " --quiet|-q: quiet output\n" + " --parse|-p: show parse tree\n" + " --install|-I: install the executable or library\n" + " --optimization|-O : set optimization level\n" + " --run|-r: run a program from ", + TOMO_PATH, "/lib/tomo_" TOMO_VERSION "\n"); Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage); tomo_parse_args( argc, argv, usage, help, TOMO_VERSION, {"files", true, List$info(&Path$info), &files}, @@ -203,7 +209,7 @@ int main(int argc, char *argv[]) { {"m", false, &Bool$info, &source_mapping}, {"changelog", false, &Bool$info, &show_changelog}, ); if (show_prefix) { - print(TOMO_PREFIX); + print(TOMO_PATH); return 0; } @@ -229,6 +235,8 @@ int main(int argc, char *argv[]) { cflags = Texts(cflags, Text(" -Wno-parentheses-equality")); } + ldflags = Texts("-Wl,-rpath,'", TOMO_PATH, "/lib',-rpath,/usr/local/lib ", ldflags); + #ifdef __APPLE__ cflags = Texts(cflags, Text(" -I/opt/homebrew/include")); ldflags = Texts(ldflags, Text(" -L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib")); @@ -239,7 +247,7 @@ int main(int argc, char *argv[]) { config_summary = Text$from_str(String(cc, " ", cflags, " -O", optimization)); - Text_t owner = Path$owner(Path$from_str(TOMO_PREFIX), true); + Text_t owner = Path$owner(Path$from_str(TOMO_PATH), true); Text_t user = Text$from_str(getenv("USER")); if (!Text$equal_values(user, owner)) { as_owner = Texts(Text(SUDO " -u "), owner, Text(" ")); @@ -247,7 +255,7 @@ int main(int argc, char *argv[]) { for (int64_t i = 0; i < uninstall.length; i++) { Text_t *u = (Text_t *)(uninstall.data + i * uninstall.stride); - xsystem(as_owner, "rm -rvf '" TOMO_PREFIX "'/lib/tomo_" TOMO_VERSION "/", *u); + xsystem(as_owner, "rm -rvf '", TOMO_PATH, "'/lib/tomo_" TOMO_VERSION "/", *u); print("Uninstalled ", *u); } @@ -333,7 +341,7 @@ int main(int argc, char *argv[]) { for (int64_t i = 0; i < files.length; i++) { Path_t path = *(Path_t *)(files.data + i * files.stride); Path_t exe = Path$with_extension(path, Text(""), true); - xsystem(as_owner, "cp -v '", exe, "' '" TOMO_PREFIX "'/bin/"); + xsystem(as_owner, "cp -v '", exe, "' '", TOMO_PATH, "'/bin/"); } } return 0; @@ -420,7 +428,7 @@ void build_library(Path_t lib_dir) { void install_library(Path_t lib_dir) { Text_t lib_dir_name = Path$base_name(lib_dir); Text_t versioned_dir = Path$base_name(with_version_suffix(lib_dir)); - Path_t dest = Path$child(Path$from_str(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION), versioned_dir); + Path_t dest = Path$child(Path$from_str(String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION)), versioned_dir); print("Installing ", lib_dir, " into ", dest); if (!Path$equal_values(lib_dir, dest)) { if (verbose) whisper("Clearing out any pre-existing version of ", lib_dir_name); @@ -440,7 +448,7 @@ void install_library(Path_t lib_dir) { "' " ">/dev/null 2>/dev/null")); (void)result; - print("Installed \033[1m", lib_dir_name, "\033[m to " TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", versioned_dir); + print("Installed \033[1m", lib_dir_name, "\033[m to ", TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", versioned_dir); } void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *extra_ldlibs) { @@ -600,14 +608,13 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l case USE_MODULE: { module_info_t mod = get_module_info(stmt_ast); const char *full_name = mod.version ? String(mod.name, "_", mod.version) : mod.name; - Text_t lib = - Texts(Text("-Wl,-rpath,'"), Text(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/"), Text$from_str(full_name), - Text("' '" TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/"), Text$from_str(full_name), Text("/lib"), - Text$from_str(full_name), Text(SHARED_SUFFIX "'")); + Text_t lib = Texts("-Wl,-rpath,'", TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", Text$from_str(full_name), + "' '", TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", Text$from_str(full_name), "/lib", + Text$from_str(full_name), SHARED_SUFFIX "'"); Table$set(to_link, &lib, NULL, Table$info(&Text$info, &Void$info)); List_t children = - Path$glob(Path$from_str(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", full_name, "/[!._0-9]*.tm"))); + Path$glob(Path$from_str(String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", full_name, "/[!._0-9]*.tm"))); for (int64_t i = 0; i < children.length; i++) { Path_t *child = (Path_t *)(children.data + i * children.stride); Table_t discarded = {.fallback = to_compile}; diff --git a/src/typecheck.c b/src/typecheck.c index 80c270ef..5ce0baec 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -186,8 +186,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) { module_info_t mod = get_module_info(module_ast); glob_t tm_files; const char *folder = mod.version ? String(mod.name, "_", mod.version) : mod.name; - if (glob(String(TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, - &tm_files) + if (glob(String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/", folder, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0) { if (!try_install_module(mod, true)) code_err(module_ast, "Couldn't find or install library: ", folder); } -- cgit v1.2.3