diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml index 87fef96..56e7ca7 100644 --- a/.github/workflows/ci-macos.yml +++ b/.github/workflows/ci-macos.yml @@ -5,9 +5,34 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 + - name: 构建依赖 blockmalloc / slotsboxmalloc / kvspace-c(macOS 无预编译 ABI,源码装 /usr/local) + run: | + set -euo pipefail + for repo in blockmalloc slotsboxmalloc kvspace-c; do + git clone --depth 1 "https://github.com/array2d/$repo.git" "/tmp/$repo" + cmake -S "/tmp/$repo" -B "/tmp/$repo/build" \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local + cmake --build "/tmp/$repo/build" -j + sudo cmake --install "/tmp/$repo/build" + done - name: 构建 run: | cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local cmake --build build - name: 安装(验证安装规则) run: sudo cmake --install build + - name: 后端装载冒烟(frontend 的 dlopen 真能加载后端) + run: | + cat > /tmp/conn.c <<'EOF' + #include + #include + int main(void) { + void *h = kvspaceConnect("shm:///tmp/ks_ci_macos"); + printf("connect shm:// → %p\n", h); + if (h) kvspaceClose(h); + return h ? 0 : 1; + } + EOF + cc /tmp/conn.c -o /tmp/conn -I/usr/local/include -L/usr/local/lib/kvspace -lkvspace + # libkvspace 在 /usr/local/lib/kvspace;后端依赖 libblockmalloc 在 /usr/local/lib + DYLD_FALLBACK_LIBRARY_PATH=/usr/local/lib:/usr/local/lib/kvspace /tmp/conn diff --git a/src/frontend.c b/src/frontend.c index a80c7c5..42d8f73 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -4,10 +4,10 @@ * (RTLD_NOW | RTLD_LOCAL)装载后端,把 handle 包一层 {vtable, dl, backend}。 * codec(TlvEncode、DecodeHead、New 等)无 handle,由前端静态实现,byte-identical。 * - * 后端装载名: - * shm://... → libkvspace-c.so.1 - * 其余(redis/fs/s3) → libkvspace_durable.so.1 - * 目录由 KVSPACE_BACKEND_PATH 覆盖(默认走动态链接器搜索路径)。 + * 后端装载名(后缀随平台): + * shm://... → libkvspace-c.so.1 / macOS: libkvspace-c.dylib + * 其余(redis/fs/s3) → libkvspace_durable.so.1 / macOS: libkvspace_durable.dylib + * 目录由 KVSPACE_BACKEND_PATH 覆盖,默认 Linux /usr/lib/kvspace、macOS /usr/local/lib/kvspace。 */ #include "kvspace/kvspace.h" @@ -60,15 +60,27 @@ static kvspace_handle *H(void *h) { return (kvspace_handle *)h; } /* ── 后端选择 ───────────────────────────────────────────────────────── */ +/* 后端库名:Linux 为 .so.1,macOS 为 .dylib。 */ static const char *backend_soname(const char *dsn) { - return (dsn && strncmp(dsn, "shm://", 6) == 0) - ? "libkvspace-c.so.1" - : "libkvspace_durable.so.1"; + int is_shm = dsn && strncmp(dsn, "shm://", 6) == 0; +#if defined(__APPLE__) + return is_shm ? "libkvspace-c.dylib" : "libkvspace_durable.dylib"; +#else + return is_shm ? "libkvspace-c.so.1" : "libkvspace_durable.so.1"; +#endif } +/* 后端目录默认值:Linux /usr/lib/kvspace;macOS /usr/local/lib/kvspace(/usr 受 SIP 保护)。 + * KVSPACE_BACKEND_PATH 可覆盖。 */ static char *backend_path(const char *soname, char *buf, size_t cap) { const char *dir = getenv("KVSPACE_BACKEND_PATH"); - if (!dir || !dir[0]) dir = "/usr/lib/kvspace"; + if (!dir || !dir[0]) { +#if defined(__APPLE__) + dir = "/usr/local/lib/kvspace"; +#else + dir = "/usr/lib/kvspace"; +#endif + } snprintf(buf, cap, "%s/%s", dir, soname); return buf; }