尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ScyllaDB Nix 开发环境搭建指南:用 `nix develop` 构建可复现的 Seastar/C++ 编译环境

ScyllaDB Nix 开发环境搭建指南:用 `nix develop` 构建可复现的 Seastar/C++ 编译环境 ScyllaDB Nix 开发环境搭建指南用nix develop构建可复现的 Seastar/C 编译环境【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladbScyllaDBScylla是基于 Seastar 框架的高性能 NoSQL 数据存储兼容 Apache Cassandra 与 Amazon DynamoDB其 C/Rust/Python 混合代码库对工具链版本要求苛刻。本指南以仓库内 dist/nix/README.md 为骨架完整讲解如何用 Nix 搭建一套与宿主机发行版状态无关、无需进入容器的可复现开发环境。读完本文你将掌握通过 flake 或经典nix-shell两种方式进入 Scylla 开发环境、理解default.nix中数百个依赖项与工具链封装的底层实现、用 direnv 自动化进入环境以及结合 ccache/distcc 提升大型 C 编译效率的实战方案。Nix 开发环境的设计目标与边界仓库根目录的*.nix文件与 dist/nix 目录共同实现了一套基于 Nix 的 Scylla 开发环境其核心设计目标在 default.nix 的注释中写得很清楚仅为开发环境不支持nix build产出可安装制品。default.nix中的installPhase直接echo not implemented并以exit 1结束default.nix也暂不适合并入 Nixpkgs 集合那需要实现完整的installPhase。这是刻意为之的取舍。环境可预测、独立于宿主发行版状态所有依赖从 Boost、LLVM 到 Python 包都由 Nix 固定版本不依赖系统里预装了什么。无需进入容器直接在宿主上通过 Nix store 提供依赖。内置调试工具链包含带绿色线程green thread调试支持的gdb以及其他杂项调试工具。编译器透明封装编译驱动会被自动包装以使用 ccache 和 distcc前提是你已配置它们。从源码结构看这套环境的实现由四个 Nix 文件协作完成文件职责flake.nixflake 入口声明 nixpkgs-unstable 与 flake-utils 输入导出 overlay、devShell 与默认包default.nix核心推导derivation完整依赖清单、configure/build/install 阶段、编译器封装切换shell.nix经典非 flake入口注入 shell 专用的 devInputsccache、distcc、gdb 等dist/nix/overlay.nixnixpkgs overlay提供gdbWithGreenThreadSupport、zstdStatic、scylla-driver等自定义包flake 与经典入口最终都汇聚到default.nixshell.nix只是import ./default.nix (args // { shell true; ... })的一层薄封装而 flake.nix 则分别导入default.nix作为 package与shell.nix作为 devShell。基本用法两种进入环境的方式进入开发环境只需一条命令取决于你是否启用了 Nix flake 支持# 推荐启用 flake 支持 nix develop . # 非 flake经典方式 nix-shell .进入后环境的configurePhase会自动为构建配置 Scylla它只是调用./configure.py --disable-dpdk随后按惯例操作即可ninja # 构建 test.py # 运行单元测试pytest 驱动见仓库根目录 test.pyconfigurePhase的底层含义文档所述的./configure.py --disable-dpdk可以在源码中逐一对上号。configure.py中通过add_tristate辅助函数生成成对的开关参数configure.pydef add_tristate(arg_parser, name, dest, help, defaultNone): arg_parser.add_argument(--enable- name, destdest, actionstore_true, defaultdefault, ...) arg_parser.add_argument(--disable- name, destdest, actionstore_false, defaultNone, ...)对 dpdk 的注册位于 configure.pyadd_tristate(arg_parser, namedpdk, destdpdk, defaultFalse, helpUse dpdk (from seastar dpdk sources))默认即关闭。因此在开发环境里显式--disable-dpdk是防御性写法确保即使默认值变化也不会意外启用 DPDK。后续代码在 configure.py 根据该开关决定是否调用./cooking.sh -i dpdk来引入 Seastar 的 DPDK 源码构建。值得注意的是default.nix中 shell 模式与非 shell 模式的configurePhase有差异default.nixshell 模式开发环境./configure.py --disable-dpdk可追加--verbose非 shell 模式nix build路径虽然 install 未实现./configure.py --mode${mode}mode参数默认release而--mode参数在 configure.py 处被注册为可从debug、release、dev、sanitize等模式中选择choices 取自modes字典。关于磁盘空间的警告非 flake 用户必读default.nix 顶部有一条醒目的注释非 flake 情况下为避免在/nix/store/下占用惊人ungodly的磁盘空间务必把实际构建目录移出本目录树并让./build成为指向它的符号链接或者直接使用 flake原文语气seriously, just use flakes。原因是非 flake 模式下源码通过gitignoreSource过滤后整体进入 store构建产物若落在其中会导致 store 膨胀与不可变性冲突。这是实践中最容易踩的坑务必留意。深度解析default.nix依赖、工具链与源码过滤固定版本的工具链default.nix对工具链版本做了明确钉死default.nix# 之后所有 Boost 版本都存在这样那样的问题 boost pkgs.boost175; llvm pkgs.llvmPackages_15; stdenvUnwrapped llvm.stdenv;注释直言“所有更晚的 Boost 版本都或多或少有问题”因此锁定boost175与 LLVM 15 工具链。这体现了 Nix 环境“可预测”的关键价值无论宿主系统装了什么Scylla 始终用这套被验证过的组合编译。数百个依赖的归类构建输入被分为nativeBuildInputs构建期工具与buildInputs链接期库两组default.nix。注释也坦承由于 Scylla 构建尚不具备交叉编译能力这种区分的准确性从“学究式”到“理想化”再到“仪式性”不等但“心意到了就行”。nativeBuildInputs覆盖完整工具链ant/antlr3CQL 语法生成、cargo/rustc/cxx-rsRust 组件、cmake/ninja/ragel、gcc与llvm.bintools、maven/openjdk11_headlessJMX/工具构建、以及带完整 Python 包集合的python3aiohttp、boto3Alternator/对象存储测试、psutil、pytest/pytest-asynciotest.py 驱动、scylla-driver、urwid等。buildInputs则对应 Scylla 运行与链接所需的核心库包括boost、abseil-cpp、c-ares、cryptopp、fmt、gnutls、hwlocNUMA 感知、liburing、libxfs、lua54Packages.luaLua UDF、lz4、numactl、openssl、protobuf、rapidjson、snappy、systemd、valgrind、xxHash、zlib、zstd等。同时设置JAVA8_HOME/JAVA_HOME环境变量指向 nixpkgs 提供的 headless JDKdefault.nix。源码过滤策略为避免把.git等无关内容灌入 storedefault.nix提供两种过滤default.nixnoNix path: type: type ! regular || (match .*\.nix path) null; src builtins.filterSource noNix (if flake then srcPath else gitignoreSource srcPath);flake 模式下用builtins.filterSource只剔除.nix文件避免 store 里的源码因 Nix 表达式变化而失效非 flake 模式则通过 hercules-ci 的gitignoreSource以固定 hash 的 tarball 引入遵循.gitignore规则。srcPath默认builtins.path { path ./.; name scylla; }flake 模式则直接传入${self}flake.nix。Direnv 自动化可选但强烈推荐文档推荐使用 direnv 简化日常开发。在项目根目录创建.envrcnix_direnv_watch_file default.nix nix_direnv_watch_file shell.nix for f in $(find dist/nix/ -type f); do nix_direnv_watch_file $f done use flake说明nix_direnv_watch_file来自 nix-direnv 插件让 direnv 在相应 Nix 文件变化时自动重新加载环境避免缓存失效。for f in $(find dist/nix/ -type f)把 dist/nix 下所有文件overlay、自定义包等都纳入监听因为 overlay.nix 与 ccache-distcc-wrap/default.nix 的变更同样会影响环境。非 flake 用户把最后一行换成use nix即可对应nix-shell .。use flake的语义等价于每次进入目录时执行nix develop配合nix_direnv_watch_file会在default.nix等文件改动时自动重建 shell 环境——这正是文档推荐的“更便捷”之处。ccache 与 distcc透明封装的编译驱动文档提到“编译器被透明地包装以使用 ccache 和 distcc”其实现位于 dist/nix/pkg/custom/ccache-distcc-wrap/default.nix。该封装为gcc、g、clang、clang、cc、c六个驱动各生成一个 shell 包装脚本行为由两个环境变量控制环境变量作用NODISTCC非空则禁用 distccCCACHE_DIR已设置则启用 ccacheNix 下通常通过 nix-direnv 或 shell 配置指向持久目录组合逻辑对应脚本内wrap变量的d/c/dc分支两者都未启用 → 直接exec原始驱动零开销仅 distcc →exec distcc driver仅 ccache →exec ccache driver两者都启用 → 设置CCACHE_PREFIX$distcc后exec ccache dist_driver即“ccache 缓存 miss 时回源到 distcc 分布式编译”。包装脚本还包含两个贴近 Scylla 工程实际的细节clang 特殊处理若驱动名匹配clang.*会追加-Wno-errorunused-command-line-argument避免 distcc 转发参数时触发误报错误ccache-distcc-wrap/default.nix。export DISTCC_IO_TIMEOUT1200注释调侃“你好repair/row_level.cc”ccache-distcc-wrap/default.nix——这是 Scylla 中著名的编译超慢文件普通超时阈值不够用因此拉长到 20 分钟。在 shell 模式中stdenv会通过pkgs.overrideCC stdenvUnwrapped cc-wrappers替换为带包装的编译器default.nix因此环境内所有gcc/clang调用都自动经过上述逻辑。ccache 与 distcc 本身则作为 devInputs 由 shell.nix 注入。Overlay绿色线程 gdb 与 Scylla 专属 Python 驱动dist/nix/overlay.nix 是一个标准的 nixpkgs overlay签名nixpkgs: final: prev: ...提供三个自定义包gdbWithGreenThreadSupport对prev.gdb应用来自 cmm/gnu-binutils 仓库的 commit1c52ca4补丁固定 sha256用于识别 Seastar 协程/绿色线程的栈帧这是调试 Scylla 这类 seastar 应用的核心工具overlay 中被patched辅助函数通过overrideAttrs追加 patch。zstdStatic以static true静态构建 zstd供需要静态链接的场景使用。scylla-driver由 pkg/upstreamable/python-driver/default.nix 构建从 scylladb/python-driver 固定版本3.25.10-scylla拉取供测试套件中的 Python 测试连接 Scylla 使用。flake 模式下overlay 通过overlays.default import ./dist/nix/overlay.nix nixpkgs;导出flake.nix并在lib._attrs中把 overlay 应用到nixpkgs输入上生成pkgsflake.nix从而让gdbWithGreenThreadSupport等名称在 devShell 中可用。常见问题与调试建议磁盘空间暴涨非 flake 模式下确认构建目录在仓库树之外、./build为符号链接或者干脆迁移到 flake。nix develop .报 flake 相关错误检查 Nix 版本2.4 才稳定支持 flake或在仓库根目录确认 flake.nix 与 flake.lock 存在。调试 Seastar 协程栈务必使用 overlay 提供的gdbWithGreenThreadSupport普通 gdb 无法正确展开绿色线程栈帧shell.nix的 devInputs 中还包含binutilsaddr2line 等、elfutils、llvm.llvm、lz4现代 Systemd 的 coredump 是 lz4 压缩的、diffutils/colordiffshell.nix可用于分析崩溃转储与反汇编。distcc 编译超时包装脚本已将DISTCC_IO_TIMEOUT设为 1200 秒若仍超时优先排查网络与 distcc 服务端负载。依赖缓存失效修改了 default.nix、shell.nix 或 dist/nix 下任何.nix文件后flake 用户需重新运行nix developdirenv 用户则由nix_direnv_watch_file自动触发。小结Scylla 的 Nix 开发环境是一套“刻意克制”的工程化方案不追求nix build产物只求为开发者提供确定性的编译环境。其核心资产在于 default.nix 对 Boost 175 LLVM 15 工具链与全部构建/运行依赖的版本钉死、dist/nix/overlay.nix 提供的绿色线程 gdb 与 scylla-driver、以及 ccache-distcc-wrap 对本地缓存与分布式编译的透明组合。无论你是初次尝试 Scylla 源码构建的新手还是需要稳定复现构建环境的老手nix develop .都是当前仓库官方推荐的入口——记得优先启用 flake并让 direnv 接管日常切换。【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表