You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Nix从源码构建Zig时动态链接器不匹配问题排查

问题描述

我写了一个Nix派生用来从源码构建Zig工具链,作为Nix Shell的本地工具。这个派生在MacBook Pro(M1 Pro,macOS Ventura 13.1.1)上运行正常,但在Linux笔记本(Ubuntu 22.04,Lenovo T480)的stage3构建阶段出现大量Encountered error: FileNotFound, falling back to default ABI and dynamic linker警告。构建完成后,执行任何zig子命令(比如zig version)都会提示No such file or directory。

用ldd检查发现动态链接器不匹配:/lib/ld-musl-x86_64.so.1指向了glibc的ld-linux-x86-64.so.2。手动用patchelf修改解释器能临时解决问题,但我需要一个跨平台的干净解决方案。尝试在构建依赖中添加musl后出现大量编译错误,想知道如何正确指定链接器或解决这个问题。

原Nix派生代码:

with import (fetchTarball {
  url = "https://github.com/nixos/nixpkgs/tarball/b139b6056c8ad4ef7e0cffb81304d59cf077589b";
  sha256 = "0sn9l19ckvdh227n0rfxk1cjnslhb5hr3g8czf3a436zkyfdl3if";
}) {};

let
  zig = stdenv.mkDerivation rec {

    name = "zig";

    src = fetchFromGitHub {
      owner = "ziglang";
      repo = "zig";
      rev = "476bdc8b0b02cbd09f6a856aa7dc548dea565109";
      hash = "sha256-VdMNzvoWNGvVFiblE7vajOetmHa0hyUWw5tWWVZjKEs=";
    };

    nativeBuildInputs = [
      cmake
      llvmPackages_15.llvm.dev
    ];

    buildInputs = [
      libxml2
      zlib
    ] ++ (with llvmPackages_15; [
      libclang
      lld
      llvm
    ]);

    preBuild = ''
      export HOME=$TMPDIR;
    '';

    doCheck = false;
  };
in
mkShell {
  nativeBuildInputs = [
    zig
  ];
}
解决方案

1. 跨平台选择对应Stdenv

Linux平台默认Stdenv基于glibc,和Zig默认尝试链接的musl冲突,可通过条件判断为Linux指定muslStdenv,macOS保留默认stdenv:

let
  baseStdenv = if stdenv.isLinux then muslStdenv else stdenv;
  zig = baseStdenv.mkDerivation rec {
    # 其余代码不变
  };

2. 明确指定Zig构建参数

在preBuild中添加环境变量,强制Zig使用对应平台的链接器和目标三元组,消除构建警告:

preBuild = ''
  export HOME=$TMPDIR
  ${lib.optionalString stdenv.isLinux ''
    export ZIG_TARGET_TRIPLE=x86_64-linux-musl
    export ZIG_DYNAMIC_LINKER=${musl}/lib/ld-musl-x86_64.so.1
  ''}
'';

3. 正确引入musl依赖

不要直接将musl加入buildInputs,通过muslStdenv自动处理,或在Linux平台单独添加到nativeBuildInputs:

nativeBuildInputs = [
  cmake
  llvmPackages_15.llvm.dev
] ++ lib.optional stdenv.isLinux musl;

完整修正后的Nix代码

with import (fetchTarball {
  url = "https://github.com/nixos/nixpkgs/tarball/b139b6056c8ad4ef7e0cffb81304d59cf077589b";
  sha256 = "0sn9l19ckvdh227n0rfxk1cjnslhb5hr3g8czf3a436zkyfdl3if";
}) {};

let
  # 跨平台选择Stdenv:Linux用muslStdenv,macOS用默认stdenv
  baseStdenv = if stdenv.isLinux then muslStdenv else stdenv;

  zig = baseStdenv.mkDerivation rec {
    name = "zig";

    src = fetchFromGitHub {
      owner = "ziglang";
      repo = "zig";
      rev = "476bdc8b0b02cbd09f6a856aa7dc548dea565109";
      hash = "sha256-VdMNzvoWNGvVFiblE7vajOetmHa0hyUWw5tWWVZjKEs=";
    };

    nativeBuildInputs = [
      cmake
      llvmPackages_15.llvm.dev
    ] ++ lib.optional stdenv.isLinux musl;

    buildInputs = [
      libxml2
      zlib
    ] ++ (with llvmPackages_15; [
      libclang
      lld
      llvm
    ]);

    preBuild = ''
      export HOME=$TMPDIR
      ${lib.optionalString stdenv.isLinux ''
        # 明确指定musl目标和动态链接器路径
        export ZIG_TARGET_TRIPLE=x86_64-linux-musl
        export ZIG_DYNAMIC_LINKER=${musl}/lib/ld-musl-x86_64.so.1
      ''}
    '';

    doCheck = false;
  };
in
mkShell {
  nativeBuildInputs = [
    zig
  ];
}

关键说明

  • muslStdenv会自动配置musl作为C标准库,避免glibc与musl混合链接的问题。
  • 环境变量ZIG_TARGET_TRIPLE和ZIG_DYNAMIC_LINKER强制Zig使用正确的目标平台和链接器路径,消除构建阶段的警告。
  • 条件判断确保macOS平台不受影响,保持原有正常构建流程。

内容的提问来源于stack exchange,提问作者stefanobaghino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:39:21