aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-12-21 15:57:21 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-12-21 15:57:21 -0500
commit13c430fde1388703aa002fdb203548801082d4e3 (patch)
tree236718203fa84bcf78b755bf8ec3b69a1da716ad
parent86a08a38a8a60b6a0de0da62a5d3fa843f6db71f (diff)
parent434ffd71c9a7eebd46ec0cba1d97b0827b874901 (diff)
Merge branch 'dev'
-rw-r--r--Makefile106
l---------build/include/tomo1
-rw-r--r--link_versions.sh5
-rwxr-xr-xlocal-tomo11
-rw-r--r--src/compile/files.c4
-rw-r--r--src/compile/headers.c4
-rw-r--r--src/compile/statements.c2
-rw-r--r--src/config.h9
-rw-r--r--src/modules.c6
-rw-r--r--src/stdlib/stacktrace.c2
-rw-r--r--src/stdlib/stdlib.c61
-rw-r--r--src/stdlib/stdlib.h1
-rw-r--r--src/tomo.c28
-rw-r--r--src/typecheck.c3
14 files changed, 155 insertions, 88 deletions
diff --git a/Makefile b/Makefile
index 32192554..11b3282f 100644
--- a/Makefile
+++ b/Makefile
@@ -84,8 +84,8 @@ O=-O3
TOMO_VERSION=$(shell awk 'BEGIN{hashes=sprintf("%c%c",35,35)} $$1==hashes {print $$2; exit}' CHANGES.md)
GIT_VERSION=$(shell git log -1 --pretty=format:"%as_%h")
CFLAGS=$(CCONFIG) $(INCLUDE_DIRS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) $(LTO) \
- -DTOMO_INSTALL='"$(PREFIX)"' -DSUDO='"$(SUDO)"' -DDEFAULT_C_COMPILER='"$(DEFAULT_C_COMPILER)"' \
- -DTOMO_VERSION='"$(TOMO_VERSION)"' -DGIT_VERSION='"$(GIT_VERSION)"'
+ -DSUDO='"$(SUDO)"' -DDEFAULT_C_COMPILER='"$(DEFAULT_C_COMPILER)"' \
+ -DGIT_VERSION='"$(GIT_VERSION)"'
CFLAGS_PLACEHOLDER="$$(printf '\033[2m<flags...>\033[m\n')"
LDLIBS=-lgc -lm -lunistring -lgmp
LIBTOMO_FLAGS=-shared
@@ -107,49 +107,82 @@ else
LIBTOMO_FLAGS += -Wl,-soname,libtomo@$(TOMO_VERSION).so
endif
EXE_FILE=tomo@$(TOMO_VERSION)
-MODULES_FILE=build/lib/tomo@$(TOMO_VERSION)/modules.ini
COMPILER_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/compile/*.c src/parse/*.c src/formatter/*.c))
STDLIB_OBJS=$(patsubst %.c,%.o,$(wildcard src/stdlib/*.c))
TESTS=$(patsubst test/%.tm,test/results/%.tm.testresult,$(wildcard test/[!_]*.tm))
API_YAML=$(wildcard api/*.yaml)
API_MD=$(patsubst %.yaml,%.md,$(API_YAML))
-INCLUDE_SYMLINK=build/include/tomo@$(TOMO_VERSION)
-all: config.mk check-c-compiler check-libs $(INCLUDE_SYMLINK) build/lib/$(LIB_FILE) build/lib/$(AR_FILE) $(MODULES_FILE) build/bin/$(EXE_FILE)
+all: config.mk check-c-compiler check-libs build
@$(ECHO) "All done!"
-$(INCLUDE_SYMLINK):
- ln -s ../../src/stdlib $@
+BUILD_DIR=build/$(TOMO_VERSION)
+headers := $(wildcard src/stdlib/*.h)
+build_headers := $(patsubst src/stdlib/%.h, $(BUILD_DIR)/include/tomo@$(TOMO_VERSION)/%.h, $(headers))
-version:
- @echo $(TOMO_VERSION)
+# find all man pages
+manpages := $(wildcard man/*/*)
-check-c-compiler:
- @$(DEFAULT_C_COMPILER) -v 2>/dev/null >/dev/null \
- || { printf '\033[31;1m%s\033[m\n' "You have set your DEFAULT_C_COMPILER to $(DEFAULT_C_COMPILER) in your config.mk, but I can't run it!"; exit 1; }
+# generate corresponding build paths with .gz
+build_manpages := $(foreach f,$(manpages),$(BUILD_DIR)/$(f).gz)
-check-libs: check-c-compiler
- @echo 'int main() { return 0; }' | $(DEFAULT_C_COMPILER) $(LDFLAGS) $(LDLIBS) -x c - -o /dev/null 2>/dev/null >/dev/null \
- || { printf '\033[31;1m%s\033[m\n' "I expected to find the following libraries on your system, but I can't find them: $(LDLIBS)"; exit 1; }
+# Ensure directories exist
+dirs := $(BUILD_DIR)/include/tomo@$(TOMO_VERSION) \
+ $(BUILD_DIR)/lib \
+ $(BUILD_DIR)/lib/tomo@$(TOMO_VERSION) \
+ $(BUILD_DIR)/bin \
+ $(BUILD_DIR)/man/man1 \
+ $(BUILD_DIR)/man/man3 \
+ $(BUILD_DIR)/share/licenses/tomo@$(TOMO_VERSION)
+
+$(dirs):
+ mkdir -p $@
+
+# Rule for copying headers
+$(BUILD_DIR)/include/tomo@$(TOMO_VERSION)%.h: src/stdlib/%.h | $(BUILD_DIR)/include/tomo@$(TOMO_VERSION)
+ cp $< $@
+
+# Rule for gzipping man pages
+$(BUILD_DIR)/man/man1/%.gz: man/man1/% | $(BUILD_DIR)/man/man1
+ gzip -c $< > $@
+$(BUILD_DIR)/man/man3/%.gz: man/man3/% | $(BUILD_DIR)/man/man3
+ gzip -c $< > $@
-build/bin/$(EXE_FILE): $(STDLIB_OBJS) $(COMPILER_OBJS)
- @mkdir -p build/bin
+$(BUILD_DIR)/bin/tomo: $(BUILD_DIR)/bin/tomo@$(TOMO_VERSION) | $(BUILD_DIR)/bin
+ ln -sf tomo@$(TOMO_VERSION) $@
+
+$(BUILD_DIR)/bin/$(EXE_FILE): $(STDLIB_OBJS) $(COMPILER_OBJS) | $(BUILD_DIR)/bin
@$(ECHO) $(CC) $(CFLAGS_PLACEHOLDER) $(LDFLAGS) $^ $(LDLIBS) -o $@
@$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
-build/lib/$(LIB_FILE): $(STDLIB_OBJS)
- @mkdir -p build/lib
+$(BUILD_DIR)/lib/$(LIB_FILE): $(STDLIB_OBJS) | $(BUILD_DIR)/lib
@$(ECHO) $(CC) $^ $(CFLAGS_PLACEHOLDER) $(OSFLAGS) $(LDFLAGS) $(LDLIBS) $(LIBTOMO_FLAGS) -o $@
@$(CC) $^ $(CFLAGS) $(OSFLAGS) $(LDFLAGS) $(LDLIBS) $(LIBTOMO_FLAGS) -o $@
-$(MODULES_FILE): modules/core.ini modules/examples.ini
- @mkdir -p build/lib/tomo@$(TOMO_VERSION)
+$(BUILD_DIR)/lib/$(AR_FILE): $(STDLIB_OBJS) | $(BUILD_DIR)/lib
+ ar -rcs $@ $^
+
+$(BUILD_DIR)/lib/tomo@$(TOMO_VERSION)/modules.ini: modules/core.ini modules/examples.ini | $(BUILD_DIR)/lib/tomo@$(TOMO_VERSION)
@cat $^ > $@
-build/lib/$(AR_FILE): $(STDLIB_OBJS)
- @mkdir -p build/lib
- ar -rcs $@ $^
+$(BUILD_DIR)/share/licenses/tomo@$(TOMO_VERSION)/LICENSE.md: LICENSE.md | $(BUILD_DIR)/share/licenses/tomo@$(TOMO_VERSION)
+ cp $< $@
+
+build: $(BUILD_DIR)/bin/tomo $(BUILD_DIR)/bin/tomo@$(TOMO_VERSION) $(BUILD_DIR)/lib/$(LIB_FILE) \
+ $(BUILD_DIR)/lib/$(AR_FILE) $(BUILD_DIR)/lib/tomo@$(TOMO_VERSION)/modules.ini \
+ $(BUILD_DIR)/share/licenses/tomo@$(TOMO_VERSION)/LICENSE.md $(build_headers) $(build_manpages)
+
+version:
+ @echo $(TOMO_VERSION)
+
+check-c-compiler:
+ @$(DEFAULT_C_COMPILER) -v 2>/dev/null >/dev/null \
+ || { printf '\033[31;1m%s\033[m\n' "You have set your DEFAULT_C_COMPILER to $(DEFAULT_C_COMPILER) in your config.mk, but I can't run it!"; exit 1; }
+
+check-libs: check-c-compiler
+ @echo 'int main() { return 0; }' | $(DEFAULT_C_COMPILER) $(LDFLAGS) $(LDLIBS) -x c - -o /dev/null 2>/dev/null >/dev/null \
+ || { printf '\033[31;1m%s\033[m\n' "I expected to find the following libraries on your system, but I can't find them: $(LDLIBS)"; exit 1; }
tags:
ctags src/*.{c,h} src/stdlib/*.{c,h} src/compile/*.{c,h} src/parse/*.{c,h} src/formatter/*.{c,h}
@@ -181,7 +214,7 @@ src/tomo.o: src/changes.md.h
%: %.tm
./local-tomo -e $<
-test/results/%.tm.testresult: test/%.tm build/bin/$(EXE_FILE)
+test/results/%.tm.testresult: test/%.tm build
@mkdir -p test/results
@printf '\033[33;1;4m%s\033[m\n' $<
@if ! COLOR=1 LC_ALL=C ./local-tomo -O 1 $< 2>&1 | tee $@; then \
@@ -193,7 +226,7 @@ test: $(TESTS)
@printf '\033[32;7m ALL TESTS PASSED! \033[m\n'
clean:
- rm -rf build/{lib,bin}/* $(COMPILER_OBJS) $(STDLIB_OBJS) test/*.tm.testresult test/.build lib/*/.build examples/.build examples/*/.build
+ rm -rf build/* $(COMPILER_OBJS) $(STDLIB_OBJS) test/*.tm.testresult test/.build lib/*/.build examples/.build examples/*/.build
%: %.md
pandoc --lua-filter=docs/.pandoc/bold-code.lua -s $< -t man -o $@
@@ -228,7 +261,7 @@ check-utilities: check-c-compiler
@which debugedit 2>/dev/null >/dev/null \
|| printf '\033[33;1m%s\033[m\n' "I couldn't find 'debugedit' on your system! Try installing the package 'debugedit' with your package manager. (It's not required though)"
-install-files: $(INCLUDE_SYMLINK) build/bin/$(EXE_FILE) build/lib/$(LIB_FILE) build/lib/$(AR_FILE) $(MODULES_FILE) check-utilities
+install-files: build check-utilities
@if ! echo "$$PATH" | tr ':' '\n' | grep -qx "$(PREFIX)/bin"; then \
echo $$PATH; \
printf "\033[31;1mError: '$(PREFIX)/bin' is not in your \$$PATH variable!\033[m\n" >&2; \
@@ -241,17 +274,7 @@ install-files: $(INCLUDE_SYMLINK) build/bin/$(EXE_FILE) build/lib/$(LIB_FILE) bu
$(SUDO) -u $(OWNER) $(MAKE) install-files; \
exit 0; \
fi; \
- mkdir -p -m 755 "$(PREFIX)/man/man1" "$(PREFIX)/man/man3" "$(PREFIX)/bin" \
- "$(PREFIX)/include/tomo@$(TOMO_VERSION)" "$(PREFIX)/lib" "$(PREFIX)/lib/tomo@$(TOMO_VERSION)" "$(PREFIX)/share/licenses/tomo@$(TOMO_VERSION)"; \
- cp src/stdlib/*.h "$(PREFIX)/include/tomo@$(TOMO_VERSION)/"; \
- cp build/lib/$(LIB_FILE) build/lib/$(AR_FILE) "$(PREFIX)/lib/"; \
- cp $(MODULES_FILE) "$(PREFIX)/lib/tomo@$(TOMO_VERSION)"; \
- cp LICENSE.md "$(PREFIX)/share/licenses/tomo@$(TOMO_VERSION)"; \
- rm -f "$(PREFIX)/bin/$(EXE_FILE)"; \
- cp build/bin/$(EXE_FILE) "$(PREFIX)/bin/"; \
- cp man/man1/* "$(PREFIX)/man/man1/"; \
- cp man/man3/* "$(PREFIX)/man/man3/"; \
- sh link_versions.sh
+ cp -r $(BUILD_DIR)/* $(PREFIX)/
install: install-files
@@ -260,11 +283,10 @@ uninstall:
$(SUDO) -u $(OWNER) $(MAKE) uninstall; \
exit 0; \
fi; \
- rm -rvf "$(PREFIX)/bin/tomo" "$(PREFIX)/bin/tomo"[0-9]* "$(PREFIX)/bin/tomo_v"* "$(PREFIX)/include/tomo_v"* \
- "$(PREFIX)/lib/libtomo_v*" "$(PREFIX)/lib/tomo@$(TOMO_VERSION)" "$(PREFIX)/share/licenses/tomo@$(TOMO_VERSION)"; \
- sh link_versions.sh
+ rm -rvf "$(PREFIX)/bin/tomo" "$(PREFIX)/bin/tomo"* "$(PREFIX)/include/tomo"* \
+ "$(PREFIX)/lib/libtomo@"* "$(PREFIX)/lib/tomo@"* "$(PREFIX)/share/licenses/tomo@"*; \
endif
.SUFFIXES:
-.PHONY: all clean install install-files uninstall test tags core-libs examples deps check-utilities check-c-compiler check-libs version
+.PHONY: all build clean install install-files uninstall test tags core-libs examples deps check-utilities check-c-compiler check-libs version
diff --git a/build/include/tomo b/build/include/tomo
deleted file mode 120000
index 82be04c8..00000000
--- a/build/include/tomo
+++ /dev/null
@@ -1 +0,0 @@
-../../src/stdlib \ No newline at end of file
diff --git a/link_versions.sh b/link_versions.sh
deleted file mode 100644
index 8dadbb52..00000000
--- a/link_versions.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-TOMO_PREFIX="$(awk -F= '/PREFIX/{print $2}' config.mk)"
-cd "$TOMO_PREFIX/bin"
-top_version="$(printf '%s\n' 'tomo@'* | sort -r | head -1)"
-ln -fs "$top_version" tomo
diff --git a/local-tomo b/local-tomo
index 76864837..d16e090e 100755
--- a/local-tomo
+++ b/local-tomo
@@ -1,11 +1,6 @@
#!/bin/sh
version=$(awk '/^## / {print $2; exit}' CHANGES.md)
-here="$(realpath "$(dirname "$0")")"
-if [ ! -e "$here/build/bin/tomo@$version" ]; then
- echo "Tomo hasn't been compiled yet! Run \`make\` to compile it!"
- exit 1;
+if ! [ -e ./build/$version/bin/tomo ]; then
+ make -j
fi
-
-PATH="$here/build/bin${PATH:+:$PATH}" \
-TOMO_PATH="$here/build" \
-tomo@"$version" "$@"
+exec ./build/$version/bin/tomo "$@"
diff --git a/src/compile/files.c b/src/compile/files.c
index 27c2e041..555f848c 100644
--- a/src/compile/files.c
+++ b/src/compile/files.c
@@ -194,8 +194,8 @@ Text_t compile_file(env_t *env, ast_t *ast) {
const char *name = file_base_name(ast->file->filename);
return Texts(env->do_source_mapping ? Texts("#line 1 ", quoted_str(ast->file->filename), "\n") : EMPTY_TEXT,
- "#define __SOURCE_FILE__ ", quoted_str(ast->file->filename), "\n",
- "#include <tomo@" TOMO_VERSION "/tomo.h>\n"
+ "#define __SOURCE_FILE__ ", quoted_str(ast->file->filename), "\n", "#include <tomo@", TOMO_VERSION,
+ "/tomo.h>\n"
"#include \"",
name, ".tm.h\"\n\n", includes, env->code->local_typedefs, "\n", env->code->lambdas, "\n",
env->code->staticdefs, "\n", top_level_code, "public void ",
diff --git a/src/compile/headers.c b/src/compile/headers.c
index e90556a1..df7142d1 100644
--- a/src/compile/headers.c
+++ b/src/compile/headers.c
@@ -135,7 +135,7 @@ Text_t compile_file_header(env_t *env, Path_t header_path, ast_t *ast) {
Text_t header =
Texts("#pragma once\n",
env->do_source_mapping ? Texts("#line 1 ", quoted_str(ast->file->filename), "\n") : EMPTY_TEXT,
- "#include <tomo@" TOMO_VERSION "/tomo.h>\n");
+ "#include <tomo@", TOMO_VERSION, "/tomo.h>\n");
compile_typedef_info_t info = {.env = env, .header = &header, .header_path = header_path};
visit_topologically(Match(ast, Block)->statements, (Closure_t){.fn = (void *)_make_typedefs, &info});
@@ -161,7 +161,7 @@ Text_t compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast)
module_info_t mod = get_used_module_info(ast);
glob_t tm_files;
const char *folder = mod.version ? String(mod.name, "@", mod.version) : mod.name;
- if (glob(String(TOMO_PATH, "/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 01fb1a0b..13dcc064 100644
--- a/src/compile/statements.c
+++ b/src/compile/statements.c
@@ -197,7 +197,7 @@ static Text_t _compile_statement(env_t *env, ast_t *ast) {
module_info_t mod = get_used_module_info(ast);
glob_t tm_files;
const char *folder = mod.version ? String(mod.name, "@", mod.version) : mod.name;
- if (glob(String(TOMO_PATH, "/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 8ee44200..e703f95d 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,18 +1,11 @@
// Configuration of values that will be baked into the executable:
-#ifndef TOMO_VERSION
-#define TOMO_VERSION "v???"
-#endif
-
#ifndef GIT_VERSION
#define GIT_VERSION "???"
#endif
-#ifndef TOMO_INSTALL
-#define TOMO_INSTALL "/usr/local"
-#endif
-
extern const char *TOMO_PATH;
+extern const char *TOMO_VERSION;
#ifndef DEFAULT_C_COMPILER
#define DEFAULT_C_COMPILER "cc"
diff --git a/src/modules.c b/src/modules.c
index 36952ec8..056cd5cc 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -102,7 +102,7 @@ module_info_t get_used_module_info(ast_t *use) {
const char *name = Match(use, Use)->path;
module_info_t *info = new (module_info_t, .name = name);
Path_t tomo_default_modules =
- Path$from_text(Texts(Text$from_str(TOMO_PATH), "/lib/tomo@" TOMO_VERSION "/modules.ini"));
+ Path$from_text(Texts(Text$from_str(TOMO_PATH), "/lib/tomo@", TOMO_VERSION, "/modules.ini"));
read_modules_ini(tomo_default_modules, 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);
@@ -111,8 +111,8 @@ module_info_t get_used_module_info(ast_t *use) {
}
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)));
+ 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;
print("No such path: ", dest);
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);
diff --git a/src/tomo.c b/src/tomo.c
index 04f0289a..f829951c 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -92,8 +92,8 @@ static OptionalText_t show_codegen = NONE_TEXT,
" -D_BSD_SOURCE"
#endif
" -DGC_THREADS"),
- ldlibs = Text("-lgc -lm -lgmp -lunistring -ltomo@" TOMO_VERSION), ldflags = Text(""),
- optimization = Text("2"), cc = Text(DEFAULT_C_COMPILER);
+ ldlibs = Text("-lgc -lm -lgmp -lunistring"), ldflags = Text(""), 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>"
@@ -139,6 +139,9 @@ static List_t normalize_tm_paths(List_t paths) {
}
int main(int argc, char *argv[]) {
+ GC_INIT();
+ tomo_configure();
+
#ifdef __linux__
// Get the file modification time of the compiler, so we
// can recompile files after changing the compiler:
@@ -149,6 +152,7 @@ int main(int argc, char *argv[]) {
if (stat(compiler_path, &compiler_stat) != 0) err(1, "Could not find age of compiler");
#endif
+ ldlibs = Texts(ldlibs, " -ltomo@", TOMO_VERSION);
#ifdef __OpenBSD__
ldlibs = Texts(ldlibs, Text(" -lexecinfo"));
#endif
@@ -168,7 +172,7 @@ int main(int argc, char *argv[]) {
if (getenv("TOMO_PATH")) TOMO_PATH = getenv("TOMO_PATH");
- cflags = Texts("-I'", TOMO_PATH, "/include' -I'", TOMO_PATH, "/lib/tomo@" TOMO_VERSION "' ", cflags);
+ cflags = Texts("-I'", TOMO_PATH, "/include' -I'", TOMO_PATH, "/lib/tomo@", TOMO_VERSION, "' ", cflags);
// Set up environment variables:
const char *PATH = getenv("PATH");
@@ -187,7 +191,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_PATH, "'/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]);
@@ -219,7 +223,7 @@ int main(int argc, char *argv[]) {
" --source-mapping|-m <yes|no>: toggle source mapping in generated code\n"
" --changelog: show the Tomo changelog\n"
" --run|-r: run a program from ",
- TOMO_PATH, "/share/tomo@" TOMO_VERSION "/installed\n");
+ TOMO_PATH, "/share/tomo@", TOMO_VERSION, "/installed\n");
Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage);
cli_arg_t tomo_args[] = {
{"run", &run_files, List$info(&Path$info), .short_flag = 'r'}, //
@@ -293,7 +297,7 @@ int main(int argc, char *argv[]) {
// Uninstall libraries:
for (int64_t i = 0; i < (int64_t)uninstall_libraries.length; i++) {
Text_t *u = (Text_t *)(uninstall_libraries.data + i * uninstall_libraries.stride);
- xsystem(as_owner, "rm -rvf '", TOMO_PATH, "'/lib/tomo@" TOMO_VERSION "/", *u, " '", TOMO_PATH, "'/bin/", *u,
+ xsystem(as_owner, "rm -rvf '", TOMO_PATH, "'/lib/tomo@", TOMO_VERSION, "/", *u, " '", TOMO_PATH, "'/bin/", *u,
" '", TOMO_PATH, "'/man/man1/", *u, ".1");
print("Uninstalled ", *u);
}
@@ -510,7 +514,7 @@ void build_library(Path_t lib_dir) {
void install_library(Path_t lib_dir) {
Text_t lib_name = get_library_name(lib_dir);
- Path_t dest = Path$child(Path$from_str(String(TOMO_PATH, "/lib/tomo@" TOMO_VERSION)), lib_name);
+ Path_t dest = Path$child(Path$from_str(String(TOMO_PATH, "/lib/tomo@", TOMO_VERSION)), lib_name);
print("Installing ", lib_dir, " into ", dest);
if (!Enum$equal(&lib_dir, &dest, &Path$info)) {
if (verbose) whisper("Clearing out any pre-existing version of ", lib_name);
@@ -530,7 +534,7 @@ void install_library(Path_t lib_dir) {
"' "
">/dev/null 2>/dev/null"));
(void)result;
- print("Installed \033[1m", lib_dir, "\033[m to ", TOMO_PATH, "/lib/tomo@" TOMO_VERSION "/", lib_name);
+ print("Installed \033[1m", lib_dir, "\033[m to ", TOMO_PATH, "/lib/tomo@", TOMO_VERSION, "/", lib_name);
}
void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *extra_ldlibs, compile_mode_t mode) {
@@ -692,13 +696,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_used_module_info(stmt_ast);
const char *full_name = mod.version ? String(mod.name, "@", mod.version) : mod.name;
- 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_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_PATH, "/lib/tomo@" TOMO_VERSION "/", 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 < (int64_t)children.length; i++) {
Path_t *child = (Path_t *)(children.data + i * children.stride);
Table_t discarded = {.entries = EMPTY_LIST, .fallback = to_compile};
diff --git a/src/typecheck.c b/src/typecheck.c
index 139f0655..1ac3943c 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -225,7 +225,8 @@ static env_t *load_module(env_t *env, ast_t *use_ast) {
module_info_t mod = get_used_module_info(use_ast);
glob_t tm_files;
const char *folder = mod.version ? String(mod.name, "@", mod.version) : mod.name;
- if (glob(String(TOMO_PATH, "/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(use_ast, "Couldn't find or install library: ", folder);
}