aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-26 14:26:52 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-26 14:26:52 -0400
commit678a255ecc014c74e3def88ef18379bd13a7c61a (patch)
treeeb746508d0df16cbb99ebf4f17acbc6ec6f54489
parentffab48769be00a7f8b846df95c6598beb19a70f3 (diff)
Be even more aggressive about lazy compilation. No need to recompile the
main() wrapper file if the component object files haven't changed. Also, no need to rectranspile .h/.c files just because the C compiler or optimization flags changed.
-rw-r--r--src/tomo.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/tomo.c b/src/tomo.c
index 0d2fd3e3..93a08e6c 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -29,6 +29,8 @@
#define run_cmd(...) ({ const char *_cmd = String(__VA_ARGS__); if (verbose) print("\033[34;1m", _cmd, "\033[m"); popen(_cmd, "w"); })
#define list_text(list) Text$join(Text(" "), list)
+#define whisper(...) print("\033[2m", __VA_ARGS__, "\033[m")
+
#ifdef __linux__
// Only on Linux is /proc/self/exe available
static struct stat compiler_stat;
@@ -93,6 +95,7 @@ static void compile_files(env_t *env, List_t files, List_t *object_files, List_t
static bool is_stale(Path_t path, Path_t relative_to);
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);
typedef struct {
bool h:1, c:1, o:1;
@@ -569,6 +572,8 @@ void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *
if (entry->staleness.h || clean_build) {
transpile_header(env, entry->filename);
entry->staleness.o = true;
+ } else {
+ if (verbose) whisper("Unchanged: ", build_file(entry->filename, ".h"));
}
}
@@ -586,12 +591,18 @@ void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *
Path_t filename;
staleness_t staleness;
} *entry = (dependency_files.entries.data + i*dependency_files.entries.stride);
- if (!clean_build && !entry->staleness.c && !entry->staleness.h && !entry->staleness.o)
+ if (!clean_build && !entry->staleness.c && !entry->staleness.h && !entry->staleness.o
+ && !is_config_outdated(entry->filename)) {
+ if (verbose) whisper("Unchanged: ", build_file(entry->filename, ".c"));
+ if (verbose) whisper("Unchanged: ", build_file(entry->filename, ".o"));
continue;
+ }
pid_t pid = fork();
if (pid == 0) {
- transpile_code(env, entry->filename);
+ if (clean_build || entry->staleness.c)
+ transpile_code(env, entry->filename);
+ else if (verbose) whisper("Unchanged: ", build_file(entry->filename, ".c"));
if (!stop_at_transpile)
compile_object_file(entry->filename);
_exit(EXIT_SUCCESS);
@@ -617,7 +628,7 @@ void compile_files(env_t *env, List_t to_compile, List_t *object_files, List_t *
}
}
-static bool is_config_outdated(Path_t path)
+bool is_config_outdated(Path_t path)
{
OptionalText_t config = Path$read(build_file(path, ".config"));
if (config.length < 0) return true;
@@ -635,8 +646,7 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l
};
staleness.o = staleness.c || staleness.h
|| is_stale(build_file(path, ".o"), build_file(path, ".c"))
- || is_stale(build_file(path, ".o"), build_file(path, ".h"))
- || is_config_outdated(path);
+ || is_stale(build_file(path, ".o"), build_file(path, ".h"));
Table$set(to_compile, &path, &staleness, Table$info(&Path$info, &Byte$info));
assert(Text$equal_values(Path$extension(path, true), Text("tm")));
@@ -811,6 +821,21 @@ Path_t compile_executable(env_t *base_env, Path_t path, Path_t exe_path, List_t
if (!main_binding || main_binding->type->tag != FunctionType)
print_err("No main() function has been defined for ", path, ", so it can't be run!");
+ if (!clean_build && Path$is_file(exe_path, true) && !is_config_outdated(path)) {
+ bool any_newer = false;
+ for (int64_t i = 0; i < object_files.length; i++) {
+ Path_t obj = *(Path_t*)(object_files.data + i*object_files.stride);
+ if (is_stale(exe_path, obj)) {
+ any_newer = true;
+ break;
+ }
+ }
+ if (!any_newer) {
+ if (verbose) whisper("Unchanged: ", exe_path);
+ return exe_path;
+ }
+ }
+
FILE *runner = run_cmd(cc, " ", cflags, " -O", optimization, " ", ldflags, " ", ldlibs, " ", list_text(extra_ldlibs), " ",
paths_str(object_files), " -x c - -o ", exe_path);
CORD program = CORD_all(