From aca9e0a5c445e890004a60c070ea4650eba865a6 Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 10 Jan 2025 20:53:40 +0200 Subject: [PATCH 1/3] Delete compiler/output.jou and move its contents to other files --- compiler/main.jou | 29 +++++++++++++- compiler/output.jou | 95 --------------------------------------------- compiler/run.jou | 61 +++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 96 deletions(-) delete mode 100644 compiler/output.jou diff --git a/compiler/main.jou b/compiler/main.jou index f96f42da..60c246b1 100644 --- a/compiler/main.jou +++ b/compiler/main.jou @@ -10,7 +10,6 @@ import "./evaluate.jou" import "./run.jou" import "./codegen.jou" import "./llvm.jou" -import "./output.jou" import "./typecheck/common.jou" import "./typecheck/step1_create_types.jou" import "./typecheck/step2_populate_types.jou" @@ -452,6 +451,34 @@ def optimize(module: LLVMModule*, level: int) -> None: LLVMDisposePassManager(pm) +def compile_to_object_file(module: LLVMModule*) -> byte*: + len = 0L + objname = get_filename_without_jou_suffix(LLVMGetSourceFileName(module, &len)) + + objname = realloc(objname, strlen(objname) + 10) + if WINDOWS: + strcat(objname, ".obj") + else: + strcat(objname, ".o") + + path = get_path_to_file_in_jou_compiled(objname) + free(objname) + + if command_line_args.verbosity >= 1: + printf("Emitting object file: %s\n", path) + + tmppath = strdup(path) + error: byte* = NULL + if LLVMTargetMachineEmitToFile(target.target_machine, module, tmppath, LLVMCodeGenFileType::ObjectFile, &error) != 0: + assert error != NULL + fprintf(stderr, "failed to emit object file \"%s\": %s\n", path, error) + exit(1) + free(tmppath) + + assert error == NULL + return path + + def tokenize_only(path: byte*) -> None: tokens = tokenize(command_line_args.infile, NULL) print_tokens(tokens) diff --git a/compiler/output.jou b/compiler/output.jou deleted file mode 100644 index 53045365..00000000 --- a/compiler/output.jou +++ /dev/null @@ -1,95 +0,0 @@ -import "stdlib/str.jou" -import "stdlib/io.jou" -import "stdlib/process.jou" -import "stdlib/mem.jou" - -import "../config.jou" -import "./llvm.jou" -import "./target.jou" -import "./structs.jou" -import "./paths.jou" - - -def run_linker(objpaths: byte**, exepath: byte*) -> None: - jou_exe = find_current_executable() - instdir = dirname(jou_exe) - - if command_line_args.linker_flags != NULL: - linker_flags = malloc(strlen(command_line_args.linker_flags) + 50) - assert linker_flags != NULL - strcpy(linker_flags, "-lm ") - strcat(linker_flags, command_line_args.linker_flags) - else: - linker_flags = strdup("-lm") - assert linker_flags != NULL - - size = 10L - for i = 0; objpaths[i] != NULL; i++: - size += strlen(objpaths[i]) + 10 - - quoted_object_files: byte* = malloc(size) - assert quoted_object_files != NULL - quoted_object_files[0] = '\0' - - for i = 0; objpaths[i] != NULL; i++: - if i != 0: - strcat(quoted_object_files, " ") - strcat(quoted_object_files, "\"") - strcat(quoted_object_files, objpaths[i]) # TODO: escape properly? - strcat(quoted_object_files, "\"") - - size = strlen(instdir) + strlen(quoted_object_files) + strlen(exepath) + strlen(linker_flags) + 100 - if get_jou_clang_path() != NULL: - size += strlen(get_jou_clang_path()) - command: byte* = malloc(size) - - if WINDOWS: - # Assume mingw with clang has been downloaded with windows_setup.sh. - # Could also use clang, but gcc has less dependencies so we can make the Windows zips smaller. - # Windows quoting is weird. The outermost quotes get stripped here. - snprintf(command, size, "\"\"%s\\mingw64\\bin\\gcc.exe\" %s -o \"%s\" %s\"", instdir, quoted_object_files, exepath, linker_flags) - else: - # Assume clang is installed and use it to link. Could use lld, but clang is needed anyway. - # instdir is not used in this case. - snprintf(command, size, "'%s' %s -o '%s' %s", get_jou_clang_path(), quoted_object_files, exepath, linker_flags) - - free(quoted_object_files) - free(jou_exe) - free(linker_flags) - - if command_line_args.verbosity >= 2: - printf("Running linker: %s\n", command) - elif command_line_args.verbosity >= 1: - printf("Running linker\n") - - if system(command) != 0: - exit(1) - free(command) - - -def compile_to_object_file(module: LLVMModule*) -> byte*: - len = 0L - objname = get_filename_without_jou_suffix(LLVMGetSourceFileName(module, &len)) - - objname = realloc(objname, strlen(objname) + 10) - if WINDOWS: - strcat(objname, ".obj") - else: - strcat(objname, ".o") - - path = get_path_to_file_in_jou_compiled(objname) - free(objname) - - if command_line_args.verbosity >= 1: - printf("Emitting object file: %s\n", path) - - tmppath = strdup(path) - error: byte* = NULL - if LLVMTargetMachineEmitToFile(target.target_machine, module, tmppath, LLVMCodeGenFileType::ObjectFile, &error) != 0: - assert error != NULL - fprintf(stderr, "failed to emit object file \"%s\": %s\n", path, error) - exit(1) - free(tmppath) - - assert error == NULL - return path diff --git a/compiler/run.jou b/compiler/run.jou index 4646992b..007b9419 100644 --- a/compiler/run.jou +++ b/compiler/run.jou @@ -3,6 +3,10 @@ import "stdlib/mem.jou" import "stdlib/io.jou" import "stdlib/process.jou" +import "../config.jou" +import "./structs.jou" +import "./paths.jou" + def run_exe(exepath: byte*, valgrind: bool) -> int: command = malloc(strlen(exepath) + 1000) @@ -27,3 +31,60 @@ def run_exe(exepath: byte*, valgrind: bool) -> int: return 0 # success else: return 1 # TODO: extract actual error code / return value + + +def run_linker(objpaths: byte**, exepath: byte*) -> None: + jou_exe = find_current_executable() + instdir = dirname(jou_exe) + + if command_line_args.linker_flags != NULL: + linker_flags = malloc(strlen(command_line_args.linker_flags) + 50) + assert linker_flags != NULL + strcpy(linker_flags, "-lm ") + strcat(linker_flags, command_line_args.linker_flags) + else: + linker_flags = strdup("-lm") + assert linker_flags != NULL + + size = 10L + for i = 0; objpaths[i] != NULL; i++: + size += strlen(objpaths[i]) + 10 + + quoted_object_files: byte* = malloc(size) + assert quoted_object_files != NULL + quoted_object_files[0] = '\0' + + for i = 0; objpaths[i] != NULL; i++: + if i != 0: + strcat(quoted_object_files, " ") + strcat(quoted_object_files, "\"") + strcat(quoted_object_files, objpaths[i]) # TODO: escape properly? + strcat(quoted_object_files, "\"") + + size = strlen(instdir) + strlen(quoted_object_files) + strlen(exepath) + strlen(linker_flags) + 100 + if get_jou_clang_path() != NULL: + size += strlen(get_jou_clang_path()) + command: byte* = malloc(size) + + if WINDOWS: + # Assume mingw with clang has been downloaded with windows_setup.sh. + # Could also use clang, but gcc has less dependencies so we can make the Windows zips smaller. + # Windows quoting is weird. The outermost quotes get stripped here. + snprintf(command, size, "\"\"%s\\mingw64\\bin\\gcc.exe\" %s -o \"%s\" %s\"", instdir, quoted_object_files, exepath, linker_flags) + else: + # Assume clang is installed and use it to link. Could use lld, but clang is needed anyway. + # instdir is not used in this case. + snprintf(command, size, "'%s' %s -o '%s' %s", get_jou_clang_path(), quoted_object_files, exepath, linker_flags) + + free(quoted_object_files) + free(jou_exe) + free(linker_flags) + + if command_line_args.verbosity >= 2: + printf("Running linker: %s\n", command) + elif command_line_args.verbosity >= 1: + printf("Running linker\n") + + if system(command) != 0: + exit(1) + free(command) From a4410bbdd2c4c132233b3d310504823b0594ff4f Mon Sep 17 00:00:00 2001 From: Akuli Date: Fri, 10 Jan 2025 20:55:28 +0200 Subject: [PATCH 2/3] fix order --- compiler/run.jou | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/compiler/run.jou b/compiler/run.jou index 007b9419..ef94e18b 100644 --- a/compiler/run.jou +++ b/compiler/run.jou @@ -8,31 +8,6 @@ import "./structs.jou" import "./paths.jou" -def run_exe(exepath: byte*, valgrind: bool) -> int: - command = malloc(strlen(exepath) + 1000) - if WINDOWS: - sprintf(command, "\"%s\"", exepath) - while strstr(command, "/") != NULL: - *strstr(command, "/") = '\\' - else: - if valgrind: - sprintf(command, "valgrind -q --leak-check=full --show-leak-kinds=all --error-exitcode=1 '%s'", exepath) - else: - sprintf(command, "'%s'", exepath) - - # Make sure that everything else shows up before the user's prints. - fflush(stdout) - fflush(stderr) - - ret = system(command) - free(command) - - if ret == 0: - return 0 # success - else: - return 1 # TODO: extract actual error code / return value - - def run_linker(objpaths: byte**, exepath: byte*) -> None: jou_exe = find_current_executable() instdir = dirname(jou_exe) @@ -88,3 +63,28 @@ def run_linker(objpaths: byte**, exepath: byte*) -> None: if system(command) != 0: exit(1) free(command) + + +def run_exe(exepath: byte*, valgrind: bool) -> int: + command = malloc(strlen(exepath) + 1000) + if WINDOWS: + sprintf(command, "\"%s\"", exepath) + while strstr(command, "/") != NULL: + *strstr(command, "/") = '\\' + else: + if valgrind: + sprintf(command, "valgrind -q --leak-check=full --show-leak-kinds=all --error-exitcode=1 '%s'", exepath) + else: + sprintf(command, "'%s'", exepath) + + # Make sure that everything else shows up before the user's prints. + fflush(stdout) + fflush(stderr) + + ret = system(command) + free(command) + + if ret == 0: + return 0 # success + else: + return 1 # TODO: extract actual error code / return value From 9c596ebce59d2e9860da1ecf30ed1948e9fb4b49 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sat, 11 Jan 2025 00:17:13 +0200 Subject: [PATCH 3/3] rename fn --- compiler/main.jou | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/main.jou b/compiler/main.jou index 9267b201..c6d733da 100644 --- a/compiler/main.jou +++ b/compiler/main.jou @@ -350,7 +350,7 @@ def optimize(module: LLVMModule*, level: int) -> None: LLVMDisposePassManager(pm) -def compile_to_object_file(module: LLVMModule*) -> byte*: +def compile_llvm_ir_to_object_file(module: LLVMModule*) -> byte*: len = 0L objname = get_filename_without_jou_suffix(LLVMGetSourceFileName(module, &len)) @@ -428,7 +428,7 @@ def main(argc: int, argv: byte**) -> int: llvm_ir = compst.files[i].build_llvm_ir(&cf_graphs) cf_graphs.free() - objpaths[i] = compile_to_object_file(llvm_ir) + objpaths[i] = compile_llvm_ir_to_object_file(llvm_ir) LLVMDisposeModule(llvm_ir) # Check for missing main() as late as possible, so that other errors come first.