aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compile/headers.c6
-rw-r--r--src/compile/statements.c6
-rw-r--r--src/config.h6
-rw-r--r--src/modules.c119
-rw-r--r--src/modules.h3
-rw-r--r--src/stdlib/stacktrace.c2
-rw-r--r--src/stdlib/stdlib.c3
-rw-r--r--src/tomo.c118
-rw-r--r--src/typecheck.c5
9 files changed, 159 insertions, 109 deletions
diff --git a/src/compile/headers.c b/src/compile/headers.c
index 8c0863ee..6dc69f03 100644
--- a/src/compile/headers.c
+++ b/src/compile/headers.c
@@ -174,10 +174,10 @@ 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_PATH, "/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 e296795b..a7c5214a 100644
--- a/src/compile/statements.c
+++ b/src/compile/statements.c
@@ -204,10 +204,10 @@ 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_PATH, "/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/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 ff112c02..fafbbf86 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -5,6 +5,7 @@
#include <string.h>
#include <sys/wait.h>
+#include "config.h"
#include "modules.h"
#include "stdlib/memory.h"
#include "stdlib/paths.h"
@@ -14,6 +15,7 @@
#include "stdlib/tables.h"
#include "stdlib/text.h"
#include "stdlib/types.h"
+#include "stdlib/util.h"
#define xsystem(...) \
({ \
@@ -22,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;
@@ -50,47 +79,41 @@ 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.1";
- 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.1";
- 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.1";
- 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) {
+bool try_install_module(module_info_t mod, bool ask_confirmation) {
+ 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) {
- 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] ")),
- 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...");
- Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX"));
- 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 = 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);
- 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 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;
+ }
print("Installing ", mod.name, " from URL...");
@@ -101,25 +124,31 @@ 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);
+ 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) {
- 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);
- 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 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;
+ }
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/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/stdlib/stacktrace.c b/src/stdlib/stacktrace.c
index 266dc4ef..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 "/share/tomo_" TOMO_VERSION "/installed/";
+ 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 da10df87..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 "/share/tomo_" TOMO_VERSION
- "/installed' -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 <user>" or "doas -u <user>"
- // 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,41 +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 "'/share/tomo_" TOMO_VERSION "/installed/", 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 <level>: set optimization level\n"
- " --run|-r: run a program from " TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed\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 <level>: 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},
@@ -204,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;
}
@@ -230,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"));
@@ -240,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(" "));
@@ -248,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 "'/share/tomo_" TOMO_VERSION "/installed/", *u);
+ xsystem(as_owner, "rm -rvf '", TOMO_PATH, "'/lib/tomo_" TOMO_VERSION "/", *u);
print("Uninstalled ", *u);
}
@@ -261,8 +268,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);
@@ -327,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;
@@ -369,21 +383,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;
@@ -391,10 +409,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 ",
@@ -409,9 +427,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 "/share/tomo_" TOMO_VERSION "/installed"),
- 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(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);
xsystem(as_owner, "rm -rf '", dest, "'");
@@ -426,12 +444,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 "/share/tomo_" TOMO_VERSION "/installed/",
- lib_dir_name, version_suffix);
+ 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) {
@@ -591,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 "/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 "'"));
+ 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 "/share/tomo_" TOMO_VERSION "/installed/", full_name, "/[!._0-9]*.tm")));
+ List_t children =
+ 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 49d0ba02..695f7cbc 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -186,10 +186,9 @@ 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_PATH, "/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);