From 305a36e5e0166484dd3562677cddd67aa672f4a7 Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Sat, 12 Sep 2026 18:53:51 +0800 Subject: [PATCH 1/2] =?UTF-8?q?ci:=20=E6=94=AF=E6=8C=81=20macOS=20?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E2=80=94=E2=80=94=E9=93=BE=E6=8E=A5=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E8=B7=A8=E5=B9=B3=E5=8F=B0=20+=20KVSPACE=5FLIB=5FDIR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runtime/layout/runtime-rs 原为 Linux-only,macOS 必挂: - runtime/CMakeLists:link kvspace m pthread + GNU ld 专属 --export-dynamic/--disable-new-dtags - layout/build.rs、runtime-rs/build.rs:--disable-new-dtags、$ORIGIN、 硬编码 /usr/lib/kvspace 改法: - 引入 KVSPACE_LIB_DIR(CMake cache 变量 / 构建环境变量),默认 /usr/lib/kvspace,macOS CI 传 /usr/local/lib/kvspace(/usr 受 SIP 保护) - 平台条件化:macOS 去掉 m/pthread、去掉 --disable-new-dtags、 $ORIGIN → @loader_path - Linux 默认行为不变 新增 ci-macos.yml:源码构建 kvspace → layout/runtime/runtime-rs 编译通过。 Closes #321 Co-Authored-By: Claude Code --- .github/workflows/ci-macos.yml | 28 ++++++++++++++++++++++++++++ layout/build.rs | 13 +++++++++---- runtime-rs/build.rs | 24 +++++++++++++++++------- runtime/CMakeLists.txt | 21 +++++++++++++++------ 4 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/ci-macos.yml diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml new file mode 100644 index 00000000..fa6aaa82 --- /dev/null +++ b/.github/workflows/ci-macos.yml @@ -0,0 +1,28 @@ +name: ci-macos +on: [push, pull_request] +jobs: + build: + runs-on: macos-latest + env: + # /usr 受 SIP 保护,kvspace 装到 /usr/local(本仓 runtime/layout/runtime-rs 均读该变量) + KVSPACE_LIB_DIR: /usr/local/lib/kvspace + steps: + - uses: actions/checkout@v4 + - name: 构建依赖 kvspace(macOS 无预编译 ABI,从源码装到 /usr/local) + run: | + git clone --depth 1 https://github.com/array2d/kvspace.git /tmp/kvspace + cmake -S /tmp/kvspace -B /tmp/kvspace/build \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local + cmake --build /tmp/kvspace/build -j + sudo cmake --install /tmp/kvspace/build + - name: 构建 layout(Rust;macOS 产物后缀为 .dylib) + run: | + cargo build --release --manifest-path layout/Cargo.toml + mkdir -p bin && cp layout/target/release/libkvlanglayout.dylib bin/ + - name: 构建 runtime(C) + run: | + cmake -S runtime -B build/runtime -DCMAKE_BUILD_TYPE=Release \ + -DKVSPACE_LIB_DIR="$KVSPACE_LIB_DIR" + cmake --build build/runtime --target kvlang_runtime -j + - name: 构建 runtime-rs(Rust) + run: cargo build --release --manifest-path runtime-rs/Cargo.toml diff --git a/layout/build.rs b/layout/build.rs index 1c92863c..230a503c 100644 --- a/layout/build.rs +++ b/layout/build.rs @@ -1,8 +1,13 @@ -// 链接 kvspace dispatch 前端(与后端同装 /usr/lib/kvspace)。布局侧只通过 extern "C" ABI 调用, +// 链接 kvspace dispatch 前端(与后端同装 /lib/kvspace)。布局侧只通过 extern "C" ABI 调用, // 运行期由前端按 DSN 选后端(shm://→kvspace-c,其余→kvspace-durable)。 +// KVSPACE_LIB_DIR 可覆盖安装目录:macOS 的 /usr 受 SIP 保护,应指向 /lib/kvspace。 fn main() { - println!("cargo:rustc-link-search=native=/usr/lib/kvspace"); + let dir = std::env::var("KVSPACE_LIB_DIR").unwrap_or_else(|_| "/usr/lib/kvspace".into()); + println!("cargo:rustc-link-search=native={dir}"); println!("cargo:rustc-link-lib=dylib=kvspace"); - println!("cargo:rustc-link-arg=-Wl,--disable-new-dtags"); // rpath 转 DT_RPATH,传递解析子依赖 - println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib/kvspace"); + println!("cargo:rustc-link-arg=-Wl,-rpath,{dir}"); + if !cfg!(target_os = "macos") { + // rpath 转 DT_RPATH,传递解析子依赖;ld64 无 --disable-new-dtags + println!("cargo:rustc-link-arg=-Wl,--disable-new-dtags"); + } } diff --git a/runtime-rs/build.rs b/runtime-rs/build.rs index d852c32c..61877adc 100644 --- a/runtime-rs/build.rs +++ b/runtime-rs/build.rs @@ -23,18 +23,28 @@ fn main() { let manifest = env!("CARGO_MANIFEST_DIR"); let bin = format!("{manifest}/../bin"); // kvlang/bin(新构建的 libkvlang_runtime.so) + // KVSPACE_LIB_DIR 可覆盖安装目录:macOS 的 /usr 受 SIP 保护,应指向 /lib/kvspace。 + let kvspace_dir = std::env::var("KVSPACE_LIB_DIR").unwrap_or_else(|_| "/usr/lib/kvspace".into()); + println!("cargo:rustc-link-search=native={bin}"); - println!("cargo:rustc-link-search=native=/usr/lib/kvspace"); - println!("cargo:rustc-link-search=native=/usr/lib"); + println!("cargo:rustc-link-search=native={kvspace_dir}"); println!("cargo:rustc-link-lib=dylib=kvlang_runtime"); println!("cargo:rustc-link-lib=dylib=kvspace"); println!("cargo:rustc-link-lib=dylib=kvlanglayout"); - println!("cargo:rustc-link-arg=-Wl,--disable-new-dtags"); // rpath 转 DT_RPATH,传递解析子依赖 - println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN"); - println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN/../lib"); - println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib/kvspace"); - println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib"); + if cfg!(target_os = "macos") { + // macOS:ld64 无 --disable-new-dtags;$ORIGIN 对应 @loader_path + println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path"); + println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path/../lib"); + println!("cargo:rustc-link-arg=-Wl,-rpath,{kvspace_dir}"); + } else { + println!("cargo:rustc-link-search=native=/usr/lib"); + println!("cargo:rustc-link-arg=-Wl,--disable-new-dtags"); // rpath 转 DT_RPATH,传递解析子依赖 + println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN"); + println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN/../lib"); + println!("cargo:rustc-link-arg=-Wl,-rpath,{kvspace_dir}"); + println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib"); + } // 内嵌顶层 stdlib/**/*.kv → EMBEDDED_KV。 let libdir = format!("{manifest}/../stdlib"); diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 40125248..67469545 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -15,10 +15,19 @@ add_library(kvlang_runtime SHARED ${KVLANG_RUNTIME_SRC}) target_include_directories(kvlang_runtime PUBLIC include src) target_compile_definitions(kvlang_runtime PRIVATE _GNU_SOURCE) -# 链接 kvspace dispatch 前端(已安装 /usr/lib),运行期按 DSN 选后端,编译期不再选后端。 -# 链接 kvspace dispatch 前端(与后端同装 /usr/lib/kvspace),运行期按 DSN 选后端,编译期不再选后端。 -target_link_directories(kvlang_runtime PRIVATE /usr/lib/kvspace) -target_link_libraries(kvlang_runtime PRIVATE kvspace m pthread) +# 链接 kvspace dispatch 前端(与后端同装 /lib/kvspace),运行期按 DSN 选后端,编译期不再选后端。 +# KVSPACE_LIB_DIR 可覆盖安装目录:macOS 的 /usr 受 SIP 保护,应指向 /lib/kvspace。 +set(KVSPACE_LIB_DIR "/usr/lib/kvspace" CACHE PATH "kvspace dispatch 前端安装目录") +target_link_directories(kvlang_runtime PRIVATE ${KVSPACE_LIB_DIR}) -# --export-dynamic 供 kvlang(term 扩展)找符号;--disable-new-dtags 使 rpath 转 DT_RPATH(传递)。 -set_target_properties(kvlang_runtime PROPERTIES LINK_FLAGS "-Wl,--export-dynamic -Wl,--disable-new-dtags -Wl,-rpath,/usr/lib/kvspace") +if(APPLE) + # macOS:数学/线程符号在 libSystem 内(无 -lm/-lpthread);ld64 无 --disable-new-dtags + target_link_libraries(kvlang_runtime PRIVATE kvspace) + set_target_properties(kvlang_runtime PROPERTIES + LINK_FLAGS "-Wl,-export_dynamic -Wl,-rpath,${KVSPACE_LIB_DIR}") +else() + target_link_libraries(kvlang_runtime PRIVATE kvspace m pthread) + # --export-dynamic 供 kvlang(term 扩展)找符号;--disable-new-dtags 使 rpath 转 DT_RPATH(传递)。 + set_target_properties(kvlang_runtime PROPERTIES + LINK_FLAGS "-Wl,--export-dynamic -Wl,--disable-new-dtags -Wl,-rpath,${KVSPACE_LIB_DIR}") +endif() From 0b2fb7243032d5fe106a9213b2d115daa497376a Mon Sep 17 00:00:00 2001 From: "peng.li24" <734991033@qq.com> Date: Sat, 12 Sep 2026 18:57:20 +0800 Subject: [PATCH 2/2] =?UTF-8?q?runtime:=20logx=20=E5=8F=AF=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E5=90=8D=E8=B7=A8=E5=B9=B3=E5=8F=B0=EF=BC=88macOS=20?= =?UTF-8?q?=E7=94=A8=20getprogname=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit program_invocation_short_name 是 glibc 专有,macOS/BSD 无。改用 getprogname();#if __APPLE__ 分支,Linux 路径不变。 Co-Authored-By: Claude Code --- runtime/src/logx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/src/logx.c b/runtime/src/logx.c index 3999c9ce..32280778 100644 --- a/runtime/src/logx.c +++ b/runtime/src/logx.c @@ -1,10 +1,16 @@ #define _GNU_SOURCE #include +#include /* getprogname(macOS/BSD) */ #include "runtime_internal.h" /* 可执行文件名(basename):runtime 诊断日志前缀,区别于 kvcode print(stdout、无前缀)。 */ static const char *kvlangExe(void) { +#if defined(__APPLE__) + /* macOS/BSD 无 glibc 的 program_invocation_short_name,用 getprogname()。 */ + const char *p = getprogname(); +#else const char *p = program_invocation_short_name; +#endif return (p && p[0]) ? p : "kvlang"; }