aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-11-27 12:53:24 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-11-27 12:53:24 -0500
commit7e85117099cc77a8c083a3479246d5e130b8afe1 (patch)
treed41c4495b86fa1ed31da77c2c28176ba2b352500 /src
parent8b897851facaa177e2346e0d97fcba7411dfc0aa (diff)
Support EXECUTABLE metadata
Diffstat (limited to 'src')
-rw-r--r--src/tomo.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/tomo.c b/src/tomo.c
index 66ac0ddf..1aa62a0e 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -116,6 +116,7 @@ static bool is_stale_for_any(Path_t path, List_t relative_to, bool ignore_missin
static Path_t build_file(Path_t path, const char *extension);
static void wait_for_child_success(pid_t child);
static bool is_config_outdated(Path_t path);
+static Path_t get_exe_path(Path_t path);
typedef struct {
bool h : 1, c : 1, o : 1;
@@ -368,7 +369,9 @@ int main(int argc, char *argv[]) {
for (int64_t i = 0; i < (int64_t)compile_executables.length; i++) {
Path_t path = *(Path_t *)(compile_executables.data + i * compile_executables.stride);
- Path_t exe_path = Path$with_extension(path, Text(""), true);
+ Path_t exe_path = get_exe_path(path);
+ // Put executable as a sibling to the .tm file instead of in the .build directory
+ exe_path = Path$sibling(path, Path$base_name(exe_path));
pid_t child = fork();
if (child == 0) {
env_t *env = global_env(source_mapping);
@@ -399,7 +402,7 @@ int main(int argc, char *argv[]) {
// Compile runnable files in parallel, then execute in serial:
for (int64_t i = 0; i < (int64_t)run_files.length; i++) {
Path_t path = *(Path_t *)(run_files.data + i * run_files.stride);
- Path_t exe_path = build_file(Path$with_extension(path, Text(""), true), "");
+ Path_t exe_path = get_exe_path(path);
pid_t child = fork();
if (child == 0) {
env_t *env = global_env(source_mapping);
@@ -418,7 +421,7 @@ int main(int argc, char *argv[]) {
// After parallel compilation, do serial execution:
for (int64_t i = 0; i < (int64_t)run_files.length; i++) {
Path_t path = *(Path_t *)(run_files.data + i * run_files.stride);
- Path_t exe_path = build_file(Path$with_extension(path, Text(""), true), "");
+ Path_t exe_path = get_exe_path(path);
// Don't fork for the last program
pid_t child = i == (int64_t)run_files.length - 1 ? 0 : fork();
if (child == 0) {
@@ -449,6 +452,18 @@ void wait_for_child_success(pid_t child) {
}
}
+Path_t get_exe_path(Path_t path) {
+ ast_t *ast = parse_file(Path$as_c_string(path), NULL);
+ OptionalText_t exe_name = ast_metadata(ast, "EXECUTABLE");
+ if (exe_name.tag == TEXT_NONE) exe_name = Path$base_name(Path$with_extension(path, Text(""), true));
+
+ Path_t build_dir = Path$sibling(path, Text(".build"));
+ if (mkdir(Path$as_c_string(build_dir), 0755) != 0) {
+ if (!Path$is_directory(build_dir, true)) err(1, "Could not make .build directory");
+ }
+ return Path$child(build_dir, exe_name);
+}
+
Path_t build_file(Path_t path, const char *extension) {
Path_t build_dir = Path$sibling(path, Text(".build"));
if (mkdir(Path$as_c_string(build_dir), 0755) != 0) {