aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-03-30 14:44:42 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-03-30 14:44:42 -0400
commit67f088689019bfc3c731f8157e50c560fabddb04 (patch)
treee1fa1ce523545eab7ede7f6d3924ba3d2ccd71bf
parentcdbf36b63c9250c132b1fafb46b7881b4a263217 (diff)
Fix some relative import issues with compiled modules
-rw-r--r--src/compile.c38
-rw-r--r--src/compile.h7
-rw-r--r--src/tomo.c25
3 files changed, 42 insertions, 28 deletions
diff --git a/src/compile.c b/src/compile.c
index aa4ddac9..abccc599 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -4391,27 +4391,36 @@ CORD compile_file(env_t *env, ast_t *ast)
"}\n");
}
-CORD compile_statement_type_header(env_t *env, ast_t *ast)
+CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast)
{
switch (ast->tag) {
case Use: {
auto use = Match(ast, Use);
+ Path_t source_path = Path$from_str(ast->file->filename);
+ Path_t source_dir = Path$parent(source_path);
+ char cwd[PATH_MAX];
+ getcwd(cwd, sizeof(cwd));
+ Path_t build_dir = Path$resolved(Path$parent(header_path), Path(cwd));
switch (use->what) {
case USE_MODULE: {
return CORD_all("#include <", use->path, "/", use->path, ".h>\n");
}
case USE_LOCAL: {
- Path_t path = Path$relative_to(Path$from_str(use->path), Path(".build"));
- Path_t build_dir = Path$with_component(Path$parent(path), Text(".build"));
- path = Path$with_component(build_dir, Texts(Path$base_name(path), Text(".h")));
- return CORD_all("#include \"", Path$as_c_string(path), "\"\n");
+ Path_t used_path = Path$from_str(use->path);
+ if (used_path.type.$tag == PATH_RELATIVE)
+ used_path = Path$concat(source_dir, used_path);
+ Path_t used_build_dir = Path$with_component(Path$parent(used_path), Text(".build"));
+ Path_t used_header_path = Path$with_component(used_build_dir, Texts(Path$base_name(used_path), Text(".h")));
+ return CORD_all("#include \"", Path$as_c_string(Path$relative_to(used_header_path, build_dir)), "\"\n");
}
case USE_HEADER:
if (use->path[0] == '<') {
return CORD_all("#include ", use->path, "\n");
} else {
- Path_t path = Path$relative_to(Path$from_str(use->path), Path(".build"));
- return CORD_all("#include \"", Path$as_c_string(path), "\"\n");
+ Path_t used_path = Path$from_str(use->path);
+ if (used_path.type.$tag == PATH_RELATIVE)
+ used_path = Path$concat(source_dir, used_path);
+ return CORD_all("#include \"", Path$as_c_string(Path$relative_to(used_path, build_dir)), "\"\n");
}
default:
return CORD_EMPTY;
@@ -4440,7 +4449,7 @@ CORD compile_statement_type_header(env_t *env, ast_t *ast)
}
}
-CORD compile_statement_namespace_header(env_t *env, ast_t *ast)
+CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *ast)
{
const char *ns_name = NULL;
ast_t *block = NULL;
@@ -4496,7 +4505,7 @@ CORD compile_statement_namespace_header(env_t *env, ast_t *ast)
code_err(ast, "You can't declare a variable with a ", type_to_str(t), " value");
return CORD_all(
- compile_statement_type_header(env, decl->value),
+ compile_statement_type_header(env, header_path, decl->value),
"extern ", compile_declaration(t, CORD_cat(namespace_prefix(env, env->namespace), decl_name)), ";\n");
}
case FunctionDef: {
@@ -4546,7 +4555,7 @@ CORD compile_statement_namespace_header(env_t *env, ast_t *ast)
env_t *ns_env = namespace_env(env, ns_name);
CORD header = CORD_EMPTY;
for (ast_list_t *stmt = block ? Match(block, Block)->statements : NULL; stmt; stmt = stmt->next) {
- header = CORD_all(header, compile_statement_namespace_header(ns_env, stmt->ast));
+ header = CORD_all(header, compile_statement_namespace_header(ns_env, header_path, stmt->ast));
}
return header;
}
@@ -4554,6 +4563,7 @@ CORD compile_statement_namespace_header(env_t *env, ast_t *ast)
typedef struct {
env_t *env;
CORD *header;
+ Path_t header_path;
} compile_typedef_info_t;
static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast)
@@ -4581,18 +4591,18 @@ static void _make_typedefs(compile_typedef_info_t *info, ast_t *ast)
static void _define_types_and_funcs(compile_typedef_info_t *info, ast_t *ast)
{
*info->header = CORD_all(*info->header,
- compile_statement_type_header(info->env, ast),
- compile_statement_namespace_header(info->env, ast));
+ compile_statement_type_header(info->env, info->header_path, ast),
+ compile_statement_namespace_header(info->env, info->header_path, ast));
}
-CORD compile_file_header(env_t *env, ast_t *ast)
+CORD compile_file_header(env_t *env, Path_t header_path, ast_t *ast)
{
CORD header = CORD_all(
"#pragma once\n"
"#line 1 ", CORD_quoted(ast->file->filename), "\n",
"#include <tomo/tomo.h>\n");
- compile_typedef_info_t info = {.env=env, .header=&header};
+ 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});
visit_topologically(Match(ast, Block)->statements, (Closure_t){.fn=(void*)_define_types_and_funcs, &info});
diff --git a/src/compile.h b/src/compile.h
index 4256ab5d..ae9e510b 100644
--- a/src/compile.h
+++ b/src/compile.h
@@ -7,17 +7,18 @@
#include <stdio.h>
#include "environment.h"
+#include "stdlib/datatypes.h"
CORD expr_as_text(CORD expr, type_t *t, CORD color);
CORD compile_file(env_t *env, ast_t *ast);
-CORD compile_file_header(env_t *env, ast_t *ast);
+CORD compile_file_header(env_t *env, Path_t header_path, ast_t *ast);
CORD compile_declaration(type_t *t, const char *name);
CORD compile_type(type_t *t);
CORD compile(env_t *env, ast_t *ast);
CORD compile_namespace_header(env_t *env, const char *ns_name, ast_t *block);
CORD compile_statement(env_t *env, ast_t *ast);
-CORD compile_statement_type_header(env_t *env, ast_t *ast);
-CORD compile_statement_namespace_header(env_t *env, ast_t *ast);
+CORD compile_statement_type_header(env_t *env, Path_t header_path, ast_t *ast);
+CORD compile_statement_namespace_header(env_t *env, Path_t header_path, ast_t *ast);
CORD compile_type_info(type_t *t);
CORD compile_cli_arg_call(env_t *env, CORD fn_name, type_t *fn_type);
diff --git a/src/tomo.c b/src/tomo.c
index 255332f8..3a73707e 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -297,6 +297,7 @@ typedef struct {
env_t *env;
Table_t *used_imports;
FILE *output;
+ Path_t header_path;
} libheader_info_t;
static void _compile_statement_header_for_library(libheader_info_t *info, ast_t *ast)
@@ -312,12 +313,12 @@ static void _compile_statement_header_for_library(libheader_info_t *info, ast_t
Path_t path = Path$from_str(use->path);
if (!Table$get(*info->used_imports, &path, Table$info(&Path$info, &Path$info))) {
Table$set(info->used_imports, &path, ((Bool_t[1]){1}), Table$info(&Text$info, &Bool$info));
- CORD_put(compile_statement_type_header(info->env, ast), info->output);
- CORD_put(compile_statement_namespace_header(info->env, ast), info->output);
+ CORD_put(compile_statement_type_header(info->env, info->header_path, ast), info->output);
+ CORD_put(compile_statement_namespace_header(info->env, info->header_path, ast), info->output);
}
} else {
- CORD_put(compile_statement_type_header(info->env, ast), info->output);
- CORD_put(compile_statement_namespace_header(info->env, ast), info->output);
+ CORD_put(compile_statement_type_header(info->env, info->header_path, ast), info->output);
+ CORD_put(compile_statement_namespace_header(info->env, info->header_path, ast), info->output);
}
}
@@ -342,7 +343,7 @@ static void _make_typedefs_for_library(libheader_info_t *info, ast_t *ast)
}
}
-static void _compile_file_header_for_library(env_t *env, Path_t path, Table_t *visited_files, Table_t *used_imports, FILE *output)
+static void _compile_file_header_for_library(env_t *env, Path_t header_path, Path_t path, Table_t *visited_files, Table_t *used_imports, FILE *output)
{
if (Table$get(*visited_files, &path, Table$info(&Path$info, &Bool$info)))
return;
@@ -357,6 +358,7 @@ static void _compile_file_header_for_library(env_t *env, Path_t path, Table_t *v
.env=module_env,
.used_imports=used_imports,
.output=output,
+ .header_path=header_path,
};
// Visit files in topological order:
@@ -369,7 +371,7 @@ static void _compile_file_header_for_library(env_t *env, Path_t path, Table_t *v
auto use = Match(ast, Use);
if (use->what == USE_LOCAL) {
Path_t resolved = Path$resolved(Path$from_str(use->path), Path("./"));
- _compile_file_header_for_library(env, resolved, visited_files, used_imports, output);
+ _compile_file_header_for_library(env, header_path, resolved, visited_files, used_imports, output);
}
}
@@ -394,6 +396,7 @@ void build_library(Text_t lib_dir_name)
env->libname = Text$as_c_string(escape_lib_name(lib_dir_name));
// Build a "whatever.h" header that loads all the headers:
+ Path_t header_path = Path$resolved(Path$from_str(String(lib_dir_name, ".h")), Path$from_str("."));
FILE *header = fopen(String(lib_dir_name, ".h"), "w");
fputs("#pragma once\n", header);
fputs("#include <tomo/tomo.h>\n", header);
@@ -402,7 +405,7 @@ void build_library(Text_t lib_dir_name)
for (int64_t i = 0; i < tm_files.length; i++) {
Path_t f = *(Path_t*)(tm_files.data + i*tm_files.stride);
Path_t resolved = Path$resolved(f, Path("."));
- _compile_file_header_for_library(env, resolved, &visited_files, &used_imports, header);
+ _compile_file_header_for_library(env, header_path, resolved, &visited_files, &used_imports, header);
}
if (fclose(header) == -1)
print_err("Failed to write header file: ", lib_dir_name, ".h");
@@ -445,8 +448,6 @@ void build_library(Text_t lib_dir_name)
if (verbose)
CORD_printf("Successfully renamed symbols with library prefix!\n");
- // unlink(".build/symbol_renames.txt");
-
if (should_install) {
char library_directory[PATH_MAX];
getcwd(library_directory, sizeof(library_directory));
@@ -601,7 +602,9 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l
break;
}
case USE_ASM: {
- Text_t linker_text = Text$from_str(use->path);
+ Path_t asm_path = Path$from_str(use->path);
+ asm_path = Path$concat(Path$parent(path), asm_path);
+ Text_t linker_text = Path$as_text(&asm_path, NULL, &Path$info);
Table$set(to_link, &linker_text, ((Bool_t[1]){1}), Table$info(&Text$info, &Bool$info));
break;
}
@@ -637,7 +640,7 @@ void transpile_header(env_t *base_env, Path_t path)
env_t *module_env = load_module_env(base_env, ast);
- CORD h_code = compile_file_header(module_env, ast);
+ CORD h_code = compile_file_header(module_env, Path$resolved(h_filename, Path$from_str(".")), ast);
FILE *header = fopen(Path$as_c_string(h_filename), "w");
if (!header)