From dcd29f44a99f29f0a7808e3b1b278aeaad033d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=9A=93?= Date: Mon, 31 Mar 2025 13:26:54 -0400 Subject: [PATCH] Remove dependency on libzip in libretro builds --- binding-sandbox/wasi.cpp | 423 +----------------- binding-sandbox/wasi.h | 61 +-- meson.build | 25 -- src/core.cpp | 4 + subprojects/libzip.wrap | 5 - subprojects/packagefiles/libzip-deps.patch | 235 ---------- .../libzip-emscripten-endian.patch | 14 - 7 files changed, 9 insertions(+), 758 deletions(-) delete mode 100644 subprojects/libzip.wrap delete mode 100644 subprojects/packagefiles/libzip-deps.patch delete mode 100644 subprojects/packagefiles/libzip-emscripten-endian.patch diff --git a/binding-sandbox/wasi.cpp b/binding-sandbox/wasi.cpp index a9185c72..26987cfb 100644 --- a/binding-sandbox/wasi.cpp +++ b/binding-sandbox/wasi.cpp @@ -23,15 +23,11 @@ #include #include #include -#include #include #include "filesystem.h" #include "core.h" #include "wasi.h" -extern const uint8_t mkxp_retro_dist_zip[]; -extern const size_t mkxp_retro_dist_zip_len; - //#define WASI_DEBUG(...) mkxp_retro::log_printf(RETRO_LOG_INFO, __VA_ARGS__) #define WASI_DEBUG(...) @@ -50,81 +46,13 @@ struct FileSystem::File *wasi_file_entry::file_handle() { return (struct FileSystem::File *)handle; } -struct wasi_zip_handle *wasi_file_entry::zip_handle() { - return (wasi_zip_handle *)handle; -} - -struct wasi_zip_dir_handle *wasi_file_entry::zip_dir_handle() { - return (wasi_zip_dir_handle *)handle; -} - -struct wasi_zip_file_handle *wasi_file_entry::zip_file_handle() { - return (wasi_zip_file_handle *)handle; -} - -static std::vector compute_path_cache(zip_t *zip) { - if (zip == NULL) { - return std::vector(); - } - - std::vector path_cache; - - zip_int64_t num_entries = zip_get_num_entries(zip, 0); - - for (zip_int64_t i = 0; i < num_entries; ++i) { - std::string name(zip_get_name(zip, i, 0)); - if (!name.empty() && name.back() == '/') { - name.pop_back(); - } - u32 n_slashes = 0; - for (u32 i = 0; i < name.length(); ++i) { - if (name[i] == '/') { - ++n_slashes; - } - } - path_cache.push_back({n_slashes, name}); - } - - std::sort(path_cache.begin(), path_cache.end()); - - return path_cache; -} - -wasi_zip_container::wasi_zip_container() : source(NULL), zip(NULL), path_cache(compute_path_cache(zip)) {} - -wasi_zip_container::wasi_zip_container(const char *path, zip_flags_t flags) : source(NULL), zip(zip_open(path, flags, NULL)), path_cache(compute_path_cache(zip)) {} - -wasi_zip_container::wasi_zip_container(const void *buffer, zip_uint64_t length, zip_flags_t flags) : source(zip_source_buffer_create(buffer, length, 0, NULL)), zip(source == NULL ? NULL : zip_open_from_source(source, flags, NULL)), path_cache(compute_path_cache(zip)) {} - -wasi_zip_container::~wasi_zip_container() { - if (zip != NULL) { - zip_close(zip); - } else if (source != NULL) { - zip_source_close(source); - } -} - -wasi_zip_file_container::wasi_zip_file_container() : file(NULL) {} - -wasi_zip_file_container::wasi_zip_file_container(wasi_zip_container &zip, zip_uint64_t index, zip_flags_t flags) : file(zip_fopen_index(zip.zip, index, flags)) {} - -wasi_zip_file_container::~wasi_zip_file_container() { - if (file != NULL) { - zip_fclose(file); - } -} - -wasi_t::w2c_wasi__snapshot__preview1(std::shared_ptr ruby) : ruby(ruby), dist(new wasi_zip_container(mkxp_retro_dist_zip, mkxp_retro_dist_zip_len, ZIP_RDONLY)) { - if (dist->zip == NULL) { - throw SandboxTrapException(); - } - +wasi_t::w2c_wasi__snapshot__preview1(std::shared_ptr ruby) : ruby(ruby) { // Initialize WASI file descriptor table fdtable.push_back({.type = wasi_fd_type::STDIN}); fdtable.push_back({.type = wasi_fd_type::STDOUT}); fdtable.push_back({.type = wasi_fd_type::STDERR}); - fdtable.push_back({.type = wasi_fd_type::ZIP, .handle = new (struct wasi_zip_handle){.zip = dist, .path = "/mkxp-retro-dist"}}); fdtable.push_back({.type = wasi_fd_type::FS, .handle = new std::string("/mkxp-retro-game")}); + fdtable.push_back({.type = wasi_fd_type::FS, .handle = new std::string("/mkxp-retro-dist")}); } wasi_t::~w2c_wasi__snapshot__preview1() { @@ -134,81 +62,6 @@ wasi_t::~w2c_wasi__snapshot__preview1() { } } -// Gets information about a file or directory at a certain path within a zip file. -static struct wasi_zip_stat wasi_zip_stat(zip_t *zip, const char *path, u32 path_len) { - struct wasi_zip_stat info; - zip_stat_t stat; - - info.normalized_path = mkxp_retro::fs->normalize(path, false, false); - - if (info.normalized_path.length() == 0) { - info.exists = true; - info.filetype = WASI_IFDIR; - info.inode = -1; - info.size = 0; - info.mtime = 0; - return info; - } - - if (zip_stat(zip, info.normalized_path.c_str(), 0, &stat) == 0) { - info.exists = true; - info.filetype = WASI_IFREG; - info.inode = stat.index; - info.size = stat.size; - info.mtime = stat.mtime * 1000000000L; - return info; - } - - info.normalized_path.push_back('/'); - if (zip_stat(zip, info.normalized_path.c_str(), 0, &stat) == 0) { - info.exists = true; - info.filetype = WASI_IFDIR; - info.inode = stat.index; - info.size = stat.size; - info.mtime = stat.mtime * 1000000000L; - return info; - } - - info.exists = false; - return info; -} - -// Gets information about a file or directory at a certain index within a zip file. -static struct wasi_zip_stat wasi_zip_stat_entry(zip_t *zip, struct wasi_file_entry &entry) { - struct wasi_zip_stat info; - zip_stat_t stat; - - switch (entry.type) { - case wasi_fd_type::ZIPDIR: - if (zip_stat_index(zip, entry.zip_dir_handle()->index, 0, &stat) == 0) { - info.exists = true; - info.filetype = WASI_IFDIR; - info.inode = stat.index; - info.size = stat.size; - info.mtime = stat.mtime * 1000000000L; - } else { - info.exists = false; - } - return info; - - case wasi_fd_type::ZIPFILE: - if (zip_stat_index(zip, entry.zip_file_handle()->index, 0, &stat) == 0) { - info.exists = true; - info.filetype = WASI_IFREG; - info.inode = stat.index; - info.size = stat.size; - info.mtime = stat.mtime * 1000000000L; - } else { - info.exists = false; - } - return info; - - default: - info.exists = false; - return info; - } -} - struct fs_enumerate_data { wasi_t *wasi; u32 fd; @@ -242,15 +95,6 @@ void wasi_t::deallocate_file_descriptor(u32 fd) { case wasi_fd_type::FSFILE: delete fdtable[fd].file_handle(); break; - case wasi_fd_type::ZIP: - delete fdtable[fd].zip_handle(); - break; - case wasi_fd_type::ZIPDIR: - delete fdtable[fd].zip_dir_handle(); - break; - case wasi_fd_type::ZIPFILE: - delete fdtable[fd].zip_file_handle(); - break; default: break; } @@ -320,13 +164,9 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_close(wasi_t *wasi, u32 fd) { case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FS: - case wasi_fd_type::ZIP: - return WASI_EINVAL; case wasi_fd_type::FSDIR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPDIR: - case wasi_fd_type::ZIPFILE: wasi->deallocate_file_descriptor(fd); return WASI_ESUCCESS; } @@ -354,7 +194,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_fdstat_get(wasi_t *wasi, u32 fd, case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPFILE: WASM_SET(u8, result, WASI_IFCHR); // fs_filetype WASM_SET(u16, result + 2, 0); // fs_flags WASM_SET(u64, result + 8, WASI_FD_READ | WASI_FD_WRITE | WASI_FD_FILESTAT_GET); // fs_rights_base @@ -363,8 +202,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_fdstat_get(wasi_t *wasi, u32 fd, case wasi_fd_type::FS: case wasi_fd_type::FSDIR: - case wasi_fd_type::ZIP: - case wasi_fd_type::ZIPDIR: WASM_SET(u8, result, WASI_IFDIR); // fs_filetype WASM_SET(u16, result + 2, 0); // fs_flags WASM_SET(u64, result + 8, WASI_PATH_OPEN | WASI_FD_READDIR | WASI_PATH_FILESTAT_GET | WASI_FD_FILESTAT_GET); // fs_rights_base @@ -392,9 +229,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_fdstat_set_flags(wasi_t *wasi, u3 case wasi_fd_type::FS: case wasi_fd_type::FSDIR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIP: - case wasi_fd_type::ZIPDIR: - case wasi_fd_type::ZIPFILE: return WASI_ESUCCESS; } @@ -465,47 +299,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_filestat_get(wasi_t *wasi, u32 fd WASM_SET(u64, result + 56, stat.createtime * 1000000000L); // ctim return WASI_ESUCCESS; } - - case wasi_fd_type::ZIP: - { - struct wasi_zip_stat info = wasi_zip_stat(wasi->fdtable[fd].zip_handle()->zip->zip, "", 0); - if (!info.exists) { - return WASI_ENOENT; - } - WASM_SET(u64, result, fd); // dev - WASM_SET(u64, result + 8, info.inode); // ino - WASM_SET(u8, result + 16, info.filetype); // filetype - WASM_SET(u32, result + 24, 1); // nlink - WASM_SET(u64, result + 32, info.size); // size - WASM_SET(u64, result + 40, info.mtime); // atim - WASM_SET(u64, result + 48, info.mtime); // mtim - WASM_SET(u64, result + 56, info.mtime); // ctim - return WASI_ESUCCESS; - } - - case wasi_fd_type::ZIPDIR: - case wasi_fd_type::ZIPFILE: - { - u32 parent_fd = wasi->fdtable[fd].type == wasi_fd_type::ZIPDIR - ? wasi->fdtable[fd].zip_dir_handle()->parent_fd - : wasi->fdtable[fd].zip_file_handle()->parent_fd; - struct wasi_zip_stat info = wasi_zip_stat_entry( - wasi->fdtable[parent_fd].zip_handle()->zip->zip, - wasi->fdtable[fd] - ); - if (!info.exists) { - return WASI_ENOENT; - } - WASM_SET(u64, result, parent_fd); // dev - WASM_SET(u64, result + 8, info.inode); // ino - WASM_SET(u8, result + 16, info.filetype); // filetype - WASM_SET(u32, result + 24, 1); // nlink - WASM_SET(u64, result + 32, info.size); // size - WASM_SET(u64, result + 40, info.mtime); // atim - WASM_SET(u64, result + 48, info.mtime); // mtim - WASM_SET(u64, result + 56, info.mtime); // ctim - return WASI_ESUCCESS; - } } return WASI_EBADF; @@ -551,17 +344,11 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_prestat_dir_name(wasi_t *wasi, u3 std::strncpy((char *)WASM_MEM(path), wasi->fdtable[fd].dir_handle()->c_str(), path_len); return WASI_ESUCCESS; - case wasi_fd_type::ZIP: - std::strncpy((char *)WASM_MEM(path), wasi->fdtable[fd].zip_handle()->path.c_str(), path_len); - return WASI_ESUCCESS; - case wasi_fd_type::STDIN: case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FSDIR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPDIR: - case wasi_fd_type::ZIPFILE: return WASI_EINVAL; } @@ -584,18 +371,11 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_prestat_get(wasi_t *wasi, u32 fd, WASM_SET(u32, result + 4, wasi->fdtable[fd].dir_handle()->length()); return WASI_ESUCCESS; - case wasi_fd_type::ZIP: - WASM_SET(u32, result, 0); - WASM_SET(u32, result + 4, wasi->fdtable[fd].zip_handle()->path.length()); - return WASI_ESUCCESS; - case wasi_fd_type::STDIN: case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FSDIR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPDIR: - case wasi_fd_type::ZIPFILE: return WASI_EINVAL; } @@ -626,8 +406,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_read(wasi_t *wasi, u32 fd, usize case wasi_fd_type::FS: case wasi_fd_type::FSDIR: - case wasi_fd_type::ZIP: - case wasi_fd_type::ZIPDIR: return WASI_EINVAL; case wasi_fd_type::FSFILE: @@ -643,20 +421,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_read(wasi_t *wasi, u32 fd, usize WASM_SET(u32, result, size); return WASI_ESUCCESS; } - - case wasi_fd_type::ZIPFILE: - { - u32 size = 0; - while (iovs_len > 0) { - zip_int64_t n = zip_fread(wasi->fdtable[fd].zip_file_handle()->zip_file_handle.file, WASM_MEM(WASM_GET(u32, iovs)), WASM_GET(u32, iovs + 4)); - if (n < 0) return WASI_EIO; - size += n; - iovs += 8; - --iovs_len; - } - WASM_SET(u32, result, size); - return WASI_ESUCCESS; - } } return WASI_EBADF; @@ -677,7 +441,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_readdir(wasi_t *wasi, u32 fd, usi case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPFILE: return WASI_EINVAL; case wasi_fd_type::FS: @@ -748,88 +511,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_readdir(wasi_t *wasi, u32 fd, usi } return success ? WASI_ESUCCESS : WASI_ENOENT; } - - case wasi_fd_type::ZIP: - case wasi_fd_type::ZIPDIR: - { - usize original_buf = buf; - std::string *prefix = wasi->fdtable[fd].type == wasi_fd_type::ZIP ? NULL : &wasi->fdtable[fd].zip_dir_handle()->path; - - u32 n_slashes = 0; - if (prefix != NULL) { - for (u32 i = 0; i < prefix->length(); ++i) { - if ((*prefix)[i] == '/') { - ++n_slashes; - } - } - } - - std::shared_ptr zip = wasi->fdtable[fd].type == wasi_fd_type::ZIP - ? wasi->fdtable[fd].zip_handle()->zip - : wasi->fdtable[wasi->fdtable[fd].zip_dir_handle()->parent_fd].zip_handle()->zip; - - auto it = std::lower_bound( - zip->path_cache.begin(), - zip->path_cache.end(), - prefix == NULL ? std::make_pair(n_slashes, "") : std::make_pair(n_slashes, *prefix) - ); - - it += cookie; - while (it != zip->path_cache.end() && it->first == n_slashes && (prefix == NULL || std::strncmp(it->second.c_str(), prefix->c_str(), prefix->length()) == 0)) { - ++cookie; - - struct wasi_zip_stat info = wasi_zip_stat( - wasi->fdtable[fd].type == wasi_fd_type::ZIP - ? wasi->fdtable[fd].zip_handle()->zip->zip - : wasi->fdtable[wasi->fdtable[fd].zip_dir_handle()->parent_fd].zip_handle()->zip->zip, - it->second.c_str(), - it->second.length() - ); - if (!info.exists) { - ++it; - continue; - } - - u32 suffix_length = it->second.length() - (prefix == NULL ? 0 : prefix->length()); - - if (buf - original_buf + 8 > buf_len) { - WASM_SET(u32, result, buf - original_buf); - return WASI_ESUCCESS; - } - WASM_SET(u64, buf, cookie); - buf += 8; - - if (buf - original_buf + 8 > buf_len) { - WASM_SET(u32, result, buf - original_buf); - return WASI_ESUCCESS; - } - WASM_SET(u64, buf, info.inode); - buf += 8; - - if (buf - original_buf + 4 > buf_len) { - WASM_SET(u32, result, buf - original_buf); - return WASI_ESUCCESS; - } - WASM_SET(u32, buf, suffix_length); - buf += 4; - - if (buf - original_buf + 4 > buf_len) { - WASM_SET(u32, result, buf - original_buf); - return WASI_ESUCCESS; - } - WASM_SET(u8, buf, info.filetype); - buf += 4; - - u32 len = std::min(suffix_length, original_buf + buf_len - buf); - std::memcpy(WASM_MEM(buf), it->second.c_str() + (prefix == NULL ? 0 : prefix->length()), len); - buf += len; - - ++it; - } - - WASM_SET(u32, result, buf - original_buf); - return WASI_ESUCCESS; - } } return WASI_EBADF; @@ -850,13 +531,10 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_renumber(wasi_t *wasi, u32 fd, u3 case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FS: - case wasi_fd_type::ZIP: return WASI_EINVAL; case wasi_fd_type::FSDIR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPDIR: - case wasi_fd_type::ZIPFILE: break; } @@ -874,13 +552,10 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_renumber(wasi_t *wasi, u32 fd, u3 case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FS: - case wasi_fd_type::ZIP: return WASI_EINVAL; case wasi_fd_type::FSDIR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPDIR: - case wasi_fd_type::ZIPFILE: wasi->deallocate_file_descriptor(to); if (to == wasi->fdtable.size()) { wasi->fdtable.push_back(wasi->fdtable[fd]); @@ -925,17 +600,11 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_tell(wasi_t *wasi, u32 fd, usize case wasi_fd_type::STDERR: case wasi_fd_type::FS: case wasi_fd_type::FSDIR: - case wasi_fd_type::ZIP: - case wasi_fd_type::ZIPDIR: return WASI_EINVAL; case wasi_fd_type::FSFILE: WASM_SET(u64, result, PHYSFS_tell(wasi->fdtable[fd].file_handle()->get())); return WASI_ESUCCESS; - - case wasi_fd_type::ZIPFILE: - WASM_SET(u64, result, zip_ftell(wasi->fdtable[fd].zip_file_handle()->zip_file_handle.file)); - return WASI_ESUCCESS; } return WASI_EBADF; @@ -978,12 +647,9 @@ extern "C" u32 w2c_wasi__snapshot__preview1_fd_write(wasi_t *wasi, u32 fd, usize case wasi_fd_type::FS: case wasi_fd_type::FSDIR: - case wasi_fd_type::ZIP: - case wasi_fd_type::ZIPDIR: return WASI_EINVAL; case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPFILE: return WASI_EROFS; } @@ -1010,7 +676,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_path_filestat_get(wasi_t *wasi, u32 case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPFILE: return WASI_EINVAL; case wasi_fd_type::FS: @@ -1042,42 +707,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_path_filestat_get(wasi_t *wasi, u32 WASM_SET(u64, result + 56, stat.createtime * 1000000000L); // ctim return WASI_ESUCCESS; } - - case wasi_fd_type::ZIP: - { - struct wasi_zip_stat info = wasi_zip_stat(wasi->fdtable[fd].zip_handle()->zip->zip, (char *)WASM_MEM(path), path_len); - if (!info.exists) { - return WASI_ENOENT; - } - WASM_SET(u64, result, fd); // dev - WASM_SET(u64, result + 8, info.inode); // ino - WASM_SET(u8, result + 16, info.filetype); // filetype - WASM_SET(u32, result + 24, 1); // nlink - WASM_SET(u64, result + 32, info.size); // size - WASM_SET(u64, result + 40, info.mtime); // atim - WASM_SET(u64, result + 48, info.mtime); // mtim - WASM_SET(u64, result + 56, info.mtime); // ctim - return WASI_ESUCCESS; - } - - case wasi_fd_type::ZIPDIR: - { - std::string new_path(wasi->fdtable[fd].zip_dir_handle()->path); - new_path.append((const char *)WASM_MEM(path), strlen_safe((const char *)WASM_MEM(path), path_len)); - struct wasi_zip_stat info = wasi_zip_stat(wasi->fdtable[wasi->fdtable[fd].zip_dir_handle()->parent_fd].zip_handle()->zip->zip, new_path.c_str(), new_path.length()); - if (!info.exists) { - return WASI_ENOENT; - } - WASM_SET(u64, result, wasi->fdtable[fd].zip_dir_handle()->parent_fd); // dev - WASM_SET(u64, result + 8, info.inode); // ino - WASM_SET(u8, result + 16, info.filetype); // filetype - WASM_SET(u32, result + 24, 1); // nlink - WASM_SET(u64, result + 32, info.size); // size - WASM_SET(u64, result + 40, info.mtime); // atim - WASM_SET(u64, result + 48, info.mtime); // mtim - WASM_SET(u64, result + 56, info.mtime); // ctim - return WASI_ESUCCESS; - } } return WASI_EBADF; @@ -1108,7 +737,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_path_open(wasi_t *wasi, u32 fd, u32 case wasi_fd_type::STDOUT: case wasi_fd_type::STDERR: case wasi_fd_type::FSFILE: - case wasi_fd_type::ZIPFILE: return WASI_EINVAL; case wasi_fd_type::FS: @@ -1138,53 +766,6 @@ extern "C" u32 w2c_wasi__snapshot__preview1_path_open(wasi_t *wasi, u32 fd, u32 WASM_SET(u32, result, wasi->allocate_file_descriptor(wasi_fd_type::FSFILE, handle)); } - return WASI_ESUCCESS; - } - - case wasi_fd_type::ZIP: - case wasi_fd_type::ZIPDIR: - { - std::string new_path; - if (wasi->fdtable[fd].type == wasi_fd_type::ZIPDIR) { - new_path.append(wasi->fdtable[fd].zip_dir_handle()->path); - } - new_path.append((const char *)WASM_MEM(path), strlen_safe((const char *)WASM_MEM(path), path_len)); - - struct wasi_zip_stat info = wasi_zip_stat( - wasi->fdtable[fd].type == wasi_fd_type::ZIP - ? wasi->fdtable[fd].zip_handle()->zip->zip - : wasi->fdtable[wasi->fdtable[fd].zip_dir_handle()->parent_fd].zip_handle()->zip->zip, - new_path.c_str(), - new_path.length() - ); - if (!info.exists) { - return WASI_ENOENT; - } - - if (info.filetype == WASI_IFDIR) { - struct wasi_zip_dir_handle *handle = new (struct wasi_zip_dir_handle){ - .index = info.inode, - .path = info.normalized_path, - .parent_fd = wasi->fdtable[fd].type == wasi_fd_type::ZIPDIR ? wasi->fdtable[fd].zip_dir_handle()->parent_fd : fd, - }; - - WASM_SET(u32, result, wasi->allocate_file_descriptor(wasi_fd_type::ZIPDIR, handle)); - } else { - struct wasi_zip_file_handle *handle = new (struct wasi_zip_file_handle){ - .index = info.inode, - .zip_file_handle = wasi_zip_file_container( - wasi->fdtable[fd].type == wasi_fd_type::ZIP - ? *wasi->fdtable[fd].zip_handle()->zip - : *wasi->fdtable[wasi->fdtable[fd].zip_dir_handle()->parent_fd].zip_handle()->zip, - info.inode, - 0 - ), - .parent_fd = wasi->fdtable[fd].type == wasi_fd_type::ZIPDIR ? wasi->fdtable[fd].zip_dir_handle()->parent_fd : fd, - }; - - WASM_SET(u32, result, wasi->allocate_file_descriptor(wasi_fd_type::ZIPFILE, handle)); - } - return WASI_ESUCCESS; } } diff --git a/binding-sandbox/wasi.h b/binding-sandbox/wasi.h index cfed2d15..1b8b7516 100644 --- a/binding-sandbox/wasi.h +++ b/binding-sandbox/wasi.h @@ -25,7 +25,6 @@ #include #include #include -#include #include "filesystem.h" #include "types.h" @@ -191,55 +190,15 @@ typedef std::pair path_cache_entry_t; -struct wasi_zip_container { - private: - zip_source_t *const source; - - public: - zip_t *const zip; - std::vector path_cache; - wasi_zip_container(); - wasi_zip_container(const char *path, zip_flags_t flags); - wasi_zip_container(const void *buffer, zip_uint64_t length, zip_flags_t flags); - ~wasi_zip_container(); -}; - -struct wasi_zip_file_container { - zip_file_t *const file; - wasi_zip_file_container(); - wasi_zip_file_container(wasi_zip_container &zip, zip_uint64_t index, zip_flags_t flags); - ~wasi_zip_file_container(); -}; - -struct wasi_zip_handle { - std::shared_ptr zip; // Zip handle that can be used with libzip - std::string path; // Mount point of this archive relative to the root of the virtual filesystem, normalized to start with one leading slash and no trailing slashes (e.g. "/example/path") -}; - -struct wasi_zip_dir_handle { - zip_uint64_t index; // Index of this directory within the zip file - std::string path; // Path of this directory relative to the root of the zip file, normalized to start with no leading slashes or dots and one trailing slash (e.g. "example/path/") - u32 parent_fd; // WASI file descriptor of the zip file that contains this directory -}; - -struct wasi_zip_file_handle { - zip_uint64_t index; // Index of this file within the zip file - struct wasi_zip_file_container zip_file_handle; // Handle to this file that can be used with libzip - u32 parent_fd; // WASI file descriptor of the zip file that contains this file -}; - struct undefined {}; enum wasi_fd_type { STDIN, // This file descriptor is standard input. The `handle` field is null. STDOUT, // This file descriptor is standard output. The `handle` field is null. STDERR, // This file descriptor is standard error. The `handle` field is null. - FS, // This file descriptor is a preopened directory handled by the mkxp-z filesystem code. The `handle` field is a `std::string *` containing the path of the directory. - FSDIR, // This file descriptor is a directory handled by the mkxp-z filesystem code. The `handle` field is a `std::string *` containing the path of the directory. - FSFILE, // This file descriptor is a file handled by the mkxp-z filesystem code. The `handle` field is a `struct FileSystem::File *`. - ZIP, // This file descriptor is a read-only zip file. The `handle` field is a `struct wasi_zip_handle *`. - ZIPDIR, // This file descriptor is a directory inside of a zip file. The `handle` field is a `struct wasi_zip_dir_handle *`. - ZIPFILE, // This file descriptor is a file inside of a zip file. The `handle` field is a `struct wasi_zip_file_handle *`. + FS, // This file descriptor is a preopened directory handled by PhysFS. The `handle` field is a `std::string *` containing the path of the directory. + FSDIR, // This file descriptor is a directory handled by PhysFS. The `handle` field is a `std::string *` containing the path of the directory. + FSFILE, // This file descriptor is a file handled by PhysFS. The `handle` field is a `struct FileSystem::File *`. VACANT, // Indicates this is a vacant file descriptor that doesn't correspond to a file. The `handle` field is null. }; @@ -251,25 +210,11 @@ struct wasi_file_entry { std::string *dir_handle(); struct FileSystem::File *file_handle(); - struct wasi_zip_handle *zip_handle(); - struct wasi_zip_dir_handle *zip_dir_handle(); - struct wasi_zip_file_handle *zip_file_handle(); -}; - -struct wasi_zip_stat { - bool exists; - u8 filetype; - u64 inode; - u64 size; - u64 mtime; - std::string normalized_path; }; typedef struct w2c_wasi__snapshot__preview1 { std::shared_ptr ruby; - std::shared_ptr dist; - // WASI file descriptor table. Maps WASI file descriptors (unsigned 32-bit integers) to file handles. std::vector fdtable; diff --git a/meson.build b/meson.build index decfd073..05c58861 100644 --- a/meson.build +++ b/meson.build @@ -337,30 +337,6 @@ if is_libretro 'ZLIB_BUILD_EXAMPLES': false, }) - libzip_options = cmake.subproject_options() - libzip_options.add_cmake_defines({ - 'CMAKE_POLICY_VERSION_MINIMUM': '3.5', - 'CMAKE_C_FLAGS': ' '.join(libretro_defines + libretro_cflags), - 'CMAKE_CXX_FLAGS': ' '.join(libretro_defines + libretro_cppflags), - 'CMAKE_POSITION_INDEPENDENT_CODE': use_pic, - 'BUILD_SHARED_LIBS': false, - 'LIBZIP_DO_INSTALL': false, - 'BUILD_TOOLS': false, - 'BUILD_REGRESS': false, - 'BUILD_OSSFUZZ': false, - 'BUILD_EXAMPLES': false, - 'BUILD_DOC': false, - 'ENABLE_COMMONCRYPTO': false, - 'ENABLE_GNUTLS': false, - 'ENABLE_MBEDTLS': false, - 'ENABLE_OPENSSL': false, - 'ENABLE_WINDOWS_CRYPTO': false, - 'ENABLE_FDOPEN': false, - 'ENABLE_BZIP2': false, - 'ENABLE_LZMA': false, - 'ENABLE_ZSTD': false, - }) - physfs_options = cmake.subproject_options() physfs_options.add_cmake_defines({ 'CMAKE_POLICY_VERSION_MINIMUM': '3.5', @@ -548,7 +524,6 @@ if is_libretro cmake.subproject('boost_type_traits', options: boost_options).dependency('boost_type_traits'), cmake.subproject('boost_optional', options: boost_options).dependency('boost_optional'), cmake.subproject(host_system == 'darwin' ? 'zlib-darwin' : 'zlib', options: zlib_options).dependency('zlibstatic'), - cmake.subproject('libzip', options: libzip_options).dependency('zip'), cmake.subproject('physfs', options: physfs_options).dependency('physfs-static'), cmake.subproject('openal-soft', options: openal_options).dependency('OpenAL'), cmake.subproject('openal-soft', options: openal_options).dependency('alsoft.fmt'), diff --git a/src/core.cpp b/src/core.cpp index 034dd605..31310130 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -77,6 +77,8 @@ static inline void free_align(void *ptr) { extern const uint8_t mkxp_gmgsx_sf2[]; extern const size_t mkxp_gmgsx_sf2_len; +extern const uint8_t mkxp_retro_dist_zip[]; +extern const size_t mkxp_retro_dist_zip_len; static bool initialized = false; static ALCdevice *al_device = NULL; @@ -218,6 +220,8 @@ static bool init_sandbox() { } else if ((rgssad = PHYSFS_openRead("/mkxp-retro-game/Game.rgss3a")) != NULL) { PHYSFS_mountHandle(rgssad, "Game.rgss3a", "/mkxp-retro-game", 1); } + + PHYSFS_mountMemory(mkxp_retro_dist_zip, mkxp_retro_dist_zip_len, NULL, "mkxp-retro-dist.zip", "/mkxp-retro-dist", 1); } fs->createPathCache(); diff --git a/subprojects/libzip.wrap b/subprojects/libzip.wrap deleted file mode 100644 index cc8d711f..00000000 --- a/subprojects/libzip.wrap +++ /dev/null @@ -1,5 +0,0 @@ -[wrap-git] -url = https://github.com/nih-at/libzip -revision = v1.11.2 -depth = 1 -diff_files = libzip-deps.patch, libzip-emscripten-endian.patch diff --git a/subprojects/packagefiles/libzip-deps.patch b/subprojects/packagefiles/libzip-deps.patch deleted file mode 100644 index 4c17ea93..00000000 --- a/subprojects/packagefiles/libzip-deps.patch +++ /dev/null @@ -1,235 +0,0 @@ -# This patch prevents libzip's build system from trying to look for zlib, bzip2, lzma and zstd since Meson already handles that. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -200,64 +200,14 @@ int main(int argc, char *argv[]) { }" HAVE_NULLABLE) - --find_package(ZLIB 1.1.2 REQUIRED) --# so developers on systems where zlib is named differently (Windows, sometimes) --# can override the name used in the pkg-config file --if (NOT ZLIB_LINK_LIBRARY_NAME) -- set(ZLIB_LINK_LIBRARY_NAME "z") -- -- # Get the correct name in common cases -- list(LENGTH ZLIB_LIBRARIES N_ZLIB_LIBRARIES) -- if(N_ZLIB_LIBRARIES EQUAL 1) -- set(ZLIB_FILENAME ${ZLIB_LIBRARIES}) -- elseif(N_ZLIB_LIBRARIES EQUAL 4) -- # ZLIB_LIBRARIES might have the target_link_library() format like -- # "optimized;path/to/zlib.lib;debug;path/to/zlibd.lib". Use the 'optimized' -- # case unless we know we are in a Debug build. -- if(CMAKE_BUILD_TYPE STREQUAL "Debug") -- list(FIND ZLIB_LIBRARIES "debug" ZLIB_LIBRARIES_INDEX_OF_CONFIG) -- else() -- list(FIND ZLIB_LIBRARIES "optimized" ZLIB_LIBRARIES_INDEX_OF_CONFIG) -- endif() -- if(ZLIB_LIBRARIES_INDEX_OF_CONFIG GREATER_EQUAL 0) -- math(EXPR ZLIB_FILENAME_INDEX "${ZLIB_LIBRARIES_INDEX_OF_CONFIG}+1") -- list(GET ZLIB_LIBRARIES ${ZLIB_FILENAME_INDEX} ZLIB_FILENAME) -- endif() -- endif() -- if(ZLIB_FILENAME) -- get_filename_component(ZLIB_FILENAME ${ZLIB_FILENAME} NAME_WE) -- string(REGEX REPLACE "^lib" "" ZLIB_LINK_LIBRARY_NAME ${ZLIB_FILENAME}) -- endif() --endif(NOT ZLIB_LINK_LIBRARY_NAME) -- - if(ENABLE_BZIP2) -- find_package(BZip2) -- if(BZIP2_FOUND) - set(HAVE_LIBBZ2 1) -- else() -- message(WARNING "-- bzip2 library not found; bzip2 support disabled") -- endif(BZIP2_FOUND) - endif(ENABLE_BZIP2) - - if(ENABLE_LZMA) -- find_package(LibLZMA 5.2) -- if(LIBLZMA_FOUND) - set(HAVE_LIBLZMA 1) -- else() -- message(WARNING "-- lzma library not found; lzma/xz support disabled") -- endif(LIBLZMA_FOUND) - endif(ENABLE_LZMA) - - if(ENABLE_ZSTD) -- find_package(zstd 1.4.0) -- if(zstd_FOUND) - set(HAVE_LIBZSTD 1) -- if(TARGET zstd::libzstd_shared AND BUILD_SHARED_LIBS) -- set(zstd_TARGET zstd::libzstd_shared) -- else() -- set(zstd_TARGET zstd::libzstd_static) -- endif() -- else() -- message(WARNING "-- zstd library not found; zstandard support disabled") -- endif(zstd_FOUND) - endif(ENABLE_ZSTD) - - if (COMMONCRYPTO_FOUND) ---- a/lib/CMakeLists.txt -+++ b/lib/CMakeLists.txt -@@ -140,17 +140,14 @@ endif(WIN32) - - if(HAVE_LIBBZ2) - target_sources(zip PRIVATE zip_algorithm_bzip2.c) -- target_link_libraries(zip PRIVATE BZip2::BZip2) - endif() - - if(HAVE_LIBLZMA) - target_sources(zip PRIVATE zip_algorithm_xz.c) -- target_link_libraries(zip PRIVATE LibLZMA::LibLZMA) - endif() - - if(HAVE_LIBZSTD) - target_sources(zip PRIVATE zip_algorithm_zstd.c) -- target_link_libraries(zip PRIVATE ${zstd_TARGET}) - endif() - - if(HAVE_COMMONCRYPTO) -@@ -178,7 +175,6 @@ if(SHARED_LIB_VERSIONNING) - set_target_properties(zip PROPERTIES VERSION 5.5 SOVERSION 5 MACHO_CURRENT_VERSION 6.5 MACHO_COMPATIBILITY_VERSION 6) - endif() - --target_link_libraries(zip PRIVATE ZLIB::ZLIB) - target_include_directories(zip - PUBLIC - $ ---- a/lib/compat.h -+++ b/lib/compat.h -@@ -154,7 +154,8 @@ typedef off_t zip_off_t; - #define ZIP_OFF_MAX ZIP_INT16_MAX - #define ZIP_OFF_MIN ZIP_INT16_MIN - #else --#error unsupported size of off_t -+#define ZIP_OFF_MAX ZIP_INT64_MAX -+#define ZIP_OFF_MIN ZIP_INT64_MIN - #endif - - #define ZIP_FSEEK_MAX ZIP_OFF_MAX ---- a/lib/zip_algorithm_bzip2.c -+++ b/lib/zip_algorithm_bzip2.c -@@ -33,7 +33,7 @@ - - #include "zipint.h" - --#include -+#include "../../bzip2/bzlib.h" - #include - #include - ---- a/lib/zip_algorithm_deflate.c -+++ b/lib/zip_algorithm_deflate.c -@@ -35,7 +35,7 @@ - - #include - #include --#include -+#include "../../zlib/zlib.h" - - struct ctx { - zip_error_t *error; ---- a/lib/zip_algorithm_xz.c -+++ b/lib/zip_algorithm_xz.c -@@ -35,9 +35,9 @@ - #include "zipint.h" - - #include --#include -+#include "../../liblzma/src/liblzma/api/lzma.h" - #include --#include -+#include "../../zlib/zlib.h" - - enum header_state { INCOMPLETE, OUTPUT, DONE }; - ---- a/lib/zip_algorithm_zstd.c -+++ b/lib/zip_algorithm_zstd.c -@@ -34,8 +34,8 @@ - #include "zipint.h" - - #include --#include --#include -+#include "../../zstd/lib/zstd.h" -+#include "../../zstd/lib/zstd_errors.h" - - struct ctx { - zip_error_t *error; ---- a/lib/zip_dirent.c -+++ b/lib/zip_dirent.c -@@ -37,7 +37,7 @@ - #include - #include - #include --#include -+#include "../../zlib/zlib.h" - - #include "zipint.h" - ---- a/lib/zip_error_strerror.c -+++ b/lib/zip_error_strerror.c -@@ -35,7 +35,7 @@ - #include - #include - #include --#include -+#include "../../zlib/zlib.h" - - #include "zipint.h" - ---- a/lib/zip_io_util.c -+++ b/lib/zip_io_util.c -@@ -34,7 +34,7 @@ - #include - #include - #include --#include -+#include "../../zlib/zlib.h" - - #include "zipint.h" - ---- a/lib/zip_pkware.c -+++ b/lib/zip_pkware.c -@@ -33,7 +33,7 @@ - - - #include --#include -+#include "../../zlib/zlib.h" - - #include "zipint.h" - ---- a/lib/zip_source_crc.c -+++ b/lib/zip_source_crc.c -@@ -34,7 +34,7 @@ - - #include - #include --#include -+#include "../../zlib/zlib.h" - - #include "zipint.h" - ---- a/lib/zip_string.c -+++ b/lib/zip_string.c -@@ -34,7 +34,7 @@ - - #include - #include --#include -+#include "../../zlib/zlib.h" - - #include "zipint.h" - ---- a/src/zipcmp.c -+++ b/src/zipcmp.c -@@ -45,7 +45,7 @@ - #ifdef HAVE_FTS_H - #include - #endif --#include -+#include "../../zlib/zlib.h" - - #ifndef HAVE_GETOPT - #include "getopt.h" diff --git a/subprojects/packagefiles/libzip-emscripten-endian.patch b/subprojects/packagefiles/libzip-emscripten-endian.patch deleted file mode 100644 index 1abaf027..00000000 --- a/subprojects/packagefiles/libzip-emscripten-endian.patch +++ /dev/null @@ -1,14 +0,0 @@ -# Disables checking for endianness when targeting Emscripten because it causes configuration errors, and because we already know Emscripten targets are always little-endian. - ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -196,5 +196,8 @@ check_c_source_compiles(" - int foo(char * _Nullable bar); - int main(int argc, char *argv[]) { }" HAVE_NULLABLE) - --test_big_endian(WORDS_BIGENDIAN) -+string(TOLOWER ${CMAKE_SYSTEM_NAME} SYSTEM_LOWER) -+if(NOT SYSTEM_LOWER STREQUAL "emscripten") -+ test_big_endian(WORDS_BIGENDIAN) -+endif() -