From 49033320e24d2e8dffc89ba9c56cb5a9949d6060 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 20 Mar 2025 20:51:36 +0100 Subject: [PATCH] Stable path for unpacked libraries. --- src/build/libraries.c | 28 +++++++++++++++++++++------- src/utils/file_utils.c | 32 +++++++++++++++++++++++++++++++- src/utils/lib.h | 2 ++ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/build/libraries.c b/src/build/libraries.c index 4fc16fbcf..4f1c22f20 100644 --- a/src/build/libraries.c +++ b/src/build/libraries.c @@ -204,12 +204,22 @@ static inline JSONObject *resolve_zip_library(BuildTarget *build_target, const c // Create the directory for the temporary files. const char *lib_name = filename(lib); scratch_buffer_clear(); - scratch_buffer_append(build_target->build_dir ? build_target->build_dir : "_temp_build"); - scratch_buffer_printf("/_c3l/%s_%x/", lib_name, file.file_crc32); - const char *lib_dir = scratch_buffer_copy(); - dir_make_recursive(scratch_buffer_to_string()); - scratch_buffer_append_char('/'); - char *dir = scratch_buffer_to_string(); + assert(build_target->build_dir); + scratch_buffer_append(build_target->build_dir); + scratch_buffer_printf("/_c3l/%s/", lib_name); + char *lib_dir = scratch_buffer_copy(); + char *lib_dir_copy = scratch_buffer_copy(); + scratch_buffer_append("checksum.txt"); + const char *checksum_file = scratch_buffer_to_string(); + uint32_t crc = file.file_crc32; + if (file_is_dir(lib_dir)) + { + size_t len; + char *data = file_exists(checksum_file) ? file_read_all(checksum_file, &len) : NULL; + if (data && crc == strtoll(data, &data, 16)) goto DONE; + file_delete_dir(lib_dir); + } + dir_make_recursive(lib_dir_copy); // Iterate through all files. zip_check_err(lib, zip_dir_iterator(f, &iterator)); @@ -218,9 +228,13 @@ static inline JSONObject *resolve_zip_library(BuildTarget *build_target, const c zip_check_err(lib, zip_dir_iterator_next(&iterator, &file)); if (file.uncompressed_size == 0 || file.name[0] == '.') continue; // Copy file. - zip_file_write(f, &file, dir, false); + zip_file_write(f, &file, lib_dir, false); } +DONE: fclose(f); + char buf[64]; + size_t len = snprintf(buf, 64, "%x", crc); + file_write_all(checksum_file, buf, len); *resulting_library = lib_dir; return json; diff --git a/src/utils/file_utils.c b/src/utils/file_utils.c index 7aef7e12e..d742c024e 100644 --- a/src/utils/file_utils.c +++ b/src/utils/file_utils.c @@ -204,6 +204,15 @@ FILE *file_open_read(const char *path) #endif } +FILE *file_open_write(const char *path) +{ +#if (_MSC_VER) + return _wfopen(win_utf8to16(path), L"wb"); +#else + return fopen(path, "wb"); +#endif +} + bool file_touch(const char *path) { #if (_MSC_VER) @@ -249,6 +258,15 @@ size_t file_clean_buffer(char *buffer, const char *path, size_t file_size) return file_size; } +bool file_write_all(const char *path, const char *data, size_t len) +{ + FILE *file = file_open_write(path); + if (file == NULL) return false; + bool success = len == fwrite(data, 1, len, file); + fclose(file); + return success; +} + char *file_read_all(const char *path, size_t *return_size) { FILE *file = file_open_read(path); @@ -571,13 +589,25 @@ bool file_delete_file(const char *path) #endif } +void file_delete_dir(const char *path) +{ +#if (_WIN32) + // Windows command to remove a directory recursively + const char *cmd = "rmdir /S /Q \"%s\" >nul 2>&1"; +#else + // UNIX-like command to remove a directory recursively + const char *cmd = "rm -rf \"%s\""; +#endif + execute_cmd(str_printf(cmd, path), true, NULL, 2048); +} + void file_delete_all_files_in_dir_with_suffix(const char *path, const char *suffix) { ASSERT(path); #if (_WIN32) const char *cmd = "del /q \"%s\\*%s\" >nul 2>&1"; #else - const char *cmd = "rm -f %s/*%s"; + const char *cmd = "rm -f \"%s/*%s\""; #endif execute_cmd(str_printf(cmd, path, suffix), true, NULL, 2048); } diff --git a/src/utils/lib.h b/src/utils/lib.h index 1a183aecd..d1ea4f121 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -76,12 +76,14 @@ const char *find_rel_exe_dir(const char *dir); void file_copy_file(const char *src_path, const char *dst_path, bool overwrite); void file_delete_all_files_in_dir_with_suffix(const char *dir, const char *suffix); bool file_delete_file(const char *path); +void file_delete_dir(const char *path); bool file_is_dir(const char *file); bool file_exists(const char *path); FILE *file_open_read(const char *path); bool file_touch(const char *path); char *file_read_binary(const char *path, size_t *size); 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_get_dir_and_filename_from_full(const char *full_path, char **filename, char **dir_path);