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

如何在Nix中用LLVM工具链静态链接libc++构建可执行文件

解决Nix下用LLVM/libc++构建静态可执行文件的链接错误

你遇到的问题是静态链接libc时缺少了它依赖的底层库,光加glibc.static不够——libc本身依赖libcxxabi(处理C++异常、静态初始化守卫等符号,比如__cxa_guard_acquire),还需要线程库(比如pthread)和数学库的静态版本。

解决方案:添加libc++和libcxxabi的静态依赖,并调整链接顺序

你可以直接从llvmPackages_10中引入对应的静态库包,同时在编译命令中显式指定依赖的库(静态链接对顺序要求很高,依赖库要放在被依赖的代码后面)。

修改后的Nix表达式如下:

let
  pkgs = import <nixpkgs> {};
  llvmPkgs = pkgs.llvmPackages_10;
  stdenv = llvmPkgs.libcxxStdenv;
in
stdenv.mkDerivation {
  name = "my-app";
  src = ./.;
  buildInputs = [
    glibc.static
    llvmPkgs.libcxx.static
    llvmPkgs.libcxxabi.static
  ];
  buildPhase = ''
    c++ -o main main.cpp -static -lc++ -lc++abi -lpthread -lm
  '';
  installPhase = ''
    mkdir -p $out/bin
    cp main $out/bin/
  '';
}

关键调整说明:

  • llvmPkgs.libcxx.static & llvmPkgs.libcxxabi.static:这两个包提供了libc++和其依赖的cxxabi静态库,解决你看到的__cxa_*系列未定义符号问题。
  • -lpthread:修复线程相关的未定义符号(比如pthread_mutex_unlock、pthread_cond_destroy),因为libc++的部分组件依赖POSIX线程库。
  • -lm:链接数学静态库,部分C++标准库函数(比如浮点运算相关)依赖它。
  • 链接顺序:要保证你的代码(main.cpp)在前,然后是libc++,接着是libcxxabi,最后是系统级的pthread和数学库——静态链接器会按顺序解析符号,顺序错了会导致依赖符号找不到。

更符合Nix习惯的写法(用NIX_LDFLAGS)

你也可以把链接参数放到NIX_LDFLAGS中,让Nix的构建环境自动处理:

let
  pkgs = import <nixpkgs> {};
  llvmPkgs = pkgs.llvmPackages_10;
  stdenv = llvmPkgs.libcxxStdenv;
in
stdenv.mkDerivation {
  name = "my-app";
  src = ./.;
  buildInputs = [
    glibc.static
    llvmPkgs.libcxx.static
    llvmPkgs.libcxxabi.static
  ];
  NIX_LDFLAGS = "-static -lc++ -lc++abi -lpthread -lm";
  buildPhase = "c++ -o main main.cpp $NIX_LDFLAGS";
  installPhase = ''
    mkdir -p $out/bin
    cp main $out/bin/
  '';
}

这样修改后,应该就能成功构建静态链接的可执行文件了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:37:39