diff --git a/tomo.c b/tomo.c index 5937836..0fcf0b7 100644 --- a/tomo.c +++ b/tomo.c @@ -18,14 +18,14 @@ #include "typecheck.h" #include "types.h" -typedef enum { MODE_TRANSPILE = 0, MODE_COMPILE_OBJ = 1, MODE_COMPILE_EXE = 2, MODE_RUN = 3 } mode_e; +typedef enum { MODE_TRANSPILE = 0, MODE_COMPILE_OBJ = 1, MODE_COMPILE_SHARED_OBJ = 2, MODE_COMPILE_EXE = 3, MODE_RUN = 4 } mode_e; static bool verbose = false; static const char *autofmt, *cconfig, *cflags, *objfiles, *ldlibs, *ldflags, *cc; static array_t get_file_dependencies(const char *filename); static int transpile(const char *filename, bool force_retranspile, module_code_t *module_code); -static int compile_object_file(const char *filename, bool force_recompile); +static int compile_object_file(const char *filename, bool force_recompile, bool shared); static int compile_executable(const char *filename, const char *object_files, module_code_t *module_code); int main(int argc, char *argv[]) @@ -38,6 +38,8 @@ int main(int argc, char *argv[]) mode = MODE_TRANSPILE; } else if (streq(argv[i], "-c")) { mode = MODE_COMPILE_OBJ; + } else if (streq(argv[i], "-s")) { + mode = MODE_COMPILE_SHARED_OBJ; } else if (streq(argv[i], "-r")) { mode = MODE_RUN; } else if (streq(argv[i], "-e")) { @@ -115,12 +117,12 @@ int main(int argc, char *argv[]) CORD object_files_cord = CORD_EMPTY; for (int64_t i = 0; i < file_deps.length; i++) { const char *dep = *(char**)(file_deps.data + i*file_deps.stride); - int compile_status = compile_object_file(dep, false); + int compile_status = compile_object_file(dep, false, mode == MODE_COMPILE_SHARED_OBJ && streq(dep, resolve_path(filename, ".", "."))); if (compile_status != 0) return compile_status; object_files_cord = object_files_cord ? CORD_all(object_files_cord, " ", dep, ".o") : CORD_cat(dep, ".o"); } - if (mode == MODE_COMPILE_OBJ) + if (mode == MODE_COMPILE_OBJ || mode == MODE_COMPILE_SHARED_OBJ) return 0; const char *object_files = CORD_to_const_char_star(object_files_cord); @@ -296,21 +298,26 @@ int transpile(const char *filename, bool force_retranspile, module_code_t *modul return 0; } -int compile_object_file(const char *filename, bool force_recompile) +int compile_object_file(const char *filename, bool force_recompile, bool shared) { const char *obj_file = heap_strf("%s.o", filename); if (!force_recompile && !stale(obj_file, filename) && !stale(obj_file, heap_strf("%s.c", filename)) && !stale(obj_file, heap_strf("%s.h", filename))) { return 0; } - const char *cmd = heap_strf("%s %s -c %s.c -o %s.o", cc, cflags, filename, filename); + const char *base = strrchr(filename, '/')+1; + base = heap_strn(base, strlen(base) - strlen(".tm")); + const char *outfile = shared ? heap_strf("lib%s.so", base) : heap_strf("%s.o", filename); + const char *cmd = shared ? + heap_strf("%s %s %s %s %s -Wl,-soname,lib%s.so -shared %s.c -o %s", cc, cflags, ldflags, ldlibs, objfiles, base, filename, outfile) + : heap_strf("%s %s -c %s.c -o %s", cc, cflags, filename, outfile); if (verbose) printf("Running: %s\n", cmd); FILE *prog = popen(cmd, "w"); int status = pclose(prog); if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { if (verbose) - printf("Compiled to %s.o\n", filename); + printf("Compiled to %s\n", outfile); } return WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE; }