diff --git a/releasenotes.md b/releasenotes.md index 6c2475e26..9cb6d661c 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -67,6 +67,7 @@ - @tag didn't work with members #2236. - Assert comparing untyped lists #2240. - Fix bugs relating to optional interface addr-of #2244. +- Compiler null pointer when building a static-lib with -o somedir/... #2246 ### Stdlib changes - Deprecate `String.is_zstr` and `String.quick_zstr` #2188. diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index ab0399bd2..077bcc15b 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -676,17 +676,7 @@ void compiler_compile(void) create_output_dir(compiler.build.output_dir); output_exe = file_append_path(compiler.build.output_dir, output_exe); } - char *dir_path = file_get_dir(output_exe); - if (dir_path && strlen(dir_path) && !file_is_dir(dir_path)) - { - error_exit("Can't create '%s', the directory '%s' could not be found.", output_exe, dir_path); - } - - if (file_is_dir(output_exe)) - { - error_exit("Cannot create exe with the name '%s' - there is already a directory with that name.", output_exe); - } - + file_create_folders(output_exe); bool system_linker_available = link_libc() && compiler.platform.os != OS_TYPE_WIN32; bool use_system_linker = system_linker_available && compiler.build.arch_os_target == default_target; switch (compiler.build.linker_type) @@ -786,15 +776,7 @@ void compiler_compile(void) create_output_dir(compiler.build.output_dir); output_static = file_append_path(compiler.build.output_dir, output_static); } - char *dir_path = file_get_dir(output_static); - if (dir_path && strlen(dir_path) && !file_is_dir(dir_path)) - { - error_exit("Can't create '%s', the directory '%s' could not be found.", output_static, dir_path); - } - if (file_is_dir(output_static)) - { - error_exit("Cannot create a static library with the name '%s' - there is already a directory with that name.", output_exe); - } + file_create_folders(output_static); if (!static_lib_linker(output_static, obj_files, output_file_count)) { error_exit("Failed to produce static library '%s'.", output_static); @@ -811,15 +793,7 @@ void compiler_compile(void) create_output_dir(compiler.build.output_dir); output_dynamic = file_append_path(compiler.build.output_dir, output_dynamic); } - char *dir_path = file_get_dir(output_dynamic); - if (dir_path && strlen(dir_path) && !file_is_dir(dir_path)) - { - error_exit("Can't create '%s', the directory '%s' could not be found.", output_dynamic, dir_path); - } - if (file_is_dir(output_dynamic)) - { - error_exit("Cannot create a dynamic library with the name '%s' - there is already a directory with that name.", output_exe); - } + file_create_folders(output_dynamic); if (!dynamic_lib_linker(output_dynamic, obj_files, output_file_count)) { error_exit("Failed to produce dynamic library '%s'.", output_dynamic); diff --git a/src/compiler/headers.c b/src/compiler/headers.c index 15fe2bea3..d32009974 100644 --- a/src/compiler/headers.c +++ b/src/compiler/headers.c @@ -774,7 +774,12 @@ void header_gen(Module **modules, unsigned module_count) { filename = str_printf("%s.h", name); } + file_create_folders(filename); FILE *file = fopen(filename, "w"); + if (!file) + { + error_exit("Failed to open header file %s", filename); + } HeaderContext context = { .file = file, .gen_def = &table1, .gen_decl = &table2 }; HeaderContext *c = &context; PRINTF("#include \n"); diff --git a/src/utils/errors.c b/src/utils/errors.c index abaf3f430..f2eef54f2 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -24,7 +24,7 @@ NORETURN void error_exit(const char *format, ...) va_list arglist; va_start(arglist, format); vfprintf(stderr, format, arglist); - fprintf(stderr, "\n"); + fprintf(stderr, "\n"); // NOLINT va_end(arglist); exit_compiler(EXIT_FAILURE); } diff --git a/src/utils/file_utils.c b/src/utils/file_utils.c index d742c024e..fd3be897c 100644 --- a/src/utils/file_utils.c +++ b/src/utils/file_utils.c @@ -440,6 +440,28 @@ DONE:; return lib_path; } +void file_create_folders(const char *name) +{ + scratch_buffer_clear(); + scratch_buffer_append(name); + char *path = scratch_buffer_to_string(); + char *dir; + if (!file_namesplit(path, NULL, &dir)) + { + error_exit("Failed to split %s", filename); + } + if (str_eq(dir, ".") || dir[0] == '\0') return; + if (!file_exists(dir)) dir_make_recursive(dir); + if (!file_exists(dir)) + { + error_exit("Failed to create directory %s", dir); + } + if (!file_is_dir(dir)) + { + error_exit("File %s is not a directory", dir); + } +} + char *file_get_dir(const char *full_path) { char *dir = NULL; diff --git a/src/utils/lib.h b/src/utils/lib.h index 117ba34f3..4925c5e82 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -86,6 +86,7 @@ char *file_read_all(const char *path, size_t *return_size); bool file_write_all(const char *path, const char *data, size_t len); size_t file_clean_buffer(char *buffer, const char *path, size_t file_size); char *file_get_dir(const char *full_path); +void file_create_folders(const char *name); void file_get_dir_and_filename_from_full(const char *full_path, char **filename, char **dir_path); void file_find_top_dir(); bool file_has_suffix_in_list(const char *file_name, int name_len, const char **suffix_list, int suffix_count);