diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml new file mode 100644 index 0000000..a551409 --- /dev/null +++ b/.github/workflows/ci-macos.yml @@ -0,0 +1,32 @@ +name: ci-macos +on: [push, pull_request] +jobs: + build: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - name: 构建依赖 blockmalloc(macOS 无预编译 ABI,从源码装) + run: | + git clone --depth 1 --branch v0.1.4 https://github.com/array2d/blockmalloc.git /tmp/blockmalloc + cmake -S /tmp/blockmalloc -B /tmp/blockmalloc/build \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local + cmake --build /tmp/blockmalloc/build -j + sudo cmake --install /tmp/blockmalloc/build + - name: 构建依赖 slotsboxmalloc(同上,从源码装) + run: | + # 跟 main:v0.1.5 尚不含 macOS 的 _POSIX_C_SOURCE 修复(待其发新 tag 后改回固定版本) + git clone --depth 1 https://github.com/array2d/slotsboxmalloc.git /tmp/slotsboxmalloc + cmake -S /tmp/slotsboxmalloc -B /tmp/slotsboxmalloc/build \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local + cmake --build /tmp/slotsboxmalloc/build -j + sudo cmake --install /tmp/slotsboxmalloc/build + - name: 构建 + run: | + cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DKVSPACE_BUILD_TESTS=ON + cmake --build build -j + - name: 测试 + env: + # macOS 无 ldconfig,dyld 不会自动搜 /usr/local/lib + DYLD_FALLBACK_LIBRARY_PATH: /usr/local/lib + run: cd build && ctest --output-on-failure diff --git a/src/durable_abi.c b/src/durable_abi.c index ed25863..84f2611 100644 --- a/src/durable_abi.c +++ b/src/durable_abi.c @@ -2,7 +2,12 @@ * 让 kvlang 的 Rust layout 零改动对接 kvspace-c 的 SHM。内部复用 kvspaceShm* 与 * kvspaceXvalue*。 */ -#define _POSIX_C_SOURCE 199309L +/* macOS 需 _DARWIN_C_SOURCE 才暴露 usleep 等完整 Darwin API;_POSIX_C_SOURCE ≥200112 + * 才在 macOS 暴露 C99 的 snprintf(Linux 走 glibc 的 _DEFAULT_SOURCE)。 */ +#if defined(__APPLE__) +#define _DARWIN_C_SOURCE +#endif +#define _POSIX_C_SOURCE 200809L #define _DEFAULT_SOURCE #include "kvspace_shm.h" diff --git a/src/kvspace.c b/src/kvspace.c index 151ae71..942e107 100644 --- a/src/kvspace.c +++ b/src/kvspace.c @@ -306,6 +306,8 @@ static uint64_t kv_sbo_alloc(kvspace_t *kv, size_t n) { /* Punch before free: once freed, another process may reuse the range. */ static void kv_sbo_free(kvspace_t *kv, uint64_t off) { +#if defined(__linux__) + /* Linux 用 fallocate PUNCH_HOLE 归还磁盘块;macOS 无该 API(仅空间回收优化),跳过。 */ uint64_t sz = sbo_allocated_size(kv->sbo_meta, off); if (sz >= SBO_PUNCH_MIN) { uint64_t pg = (uint64_t)sysconf(_SC_PAGESIZE); @@ -315,6 +317,7 @@ static void kv_sbo_free(kvspace_t *kv, uint64_t off) { FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, (off_t)a, (off_t)(b - a)); } +#endif sbo_free(kv->sbo_meta, off); } diff --git a/tests/test_shm_resize.c b/tests/test_shm_resize.c index 57f14b9..b566ec2 100644 --- a/tests/test_shm_resize.c +++ b/tests/test_shm_resize.c @@ -250,6 +250,10 @@ static void t_cross_process(const char *dir) { } static int punch_supported(const char *dir) { +#if !defined(__linux__) + (void)dir; + return 0; /* macOS 无 fallocate PUNCH_HOLE */ +#else char p[600]; snprintf(p, sizeof p, "%s/punch-probe", dir); int fd = open(p, O_RDWR | O_CREAT | O_TRUNC, 0644); @@ -261,6 +265,7 @@ static int punch_supported(const char *dir) { close(fd); unlink(p); return ok; +#endif } static void t_punch(const char *dir) {