Rust 跨平台构建贴士

使用 Nix Flake 搭建基础的 Rust 跨平台构建环境

  1. 新增 flake.nix 文件,并执行 git add flake.nix

    {
      inputs = {
        utils.url = "github:numtide/flake-utils";
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
      };
    
      outputs = {
        nixpkgs,
        utils,
        ...
      }:
        utils.lib.eachDefaultSystem
        (
          system: let
            pkgs = import nixpkgs {inherit system;};
            lib = pkgs.lib;
          in {
            devShells =
              {
                default = pkgs.mkShell {
                  nativeBuildInputs = with pkgs; [
                    pkg-config
                    gcc
                  ];
                };
              }
              // builtins.listToAttrs (map (target: {
                name = target;
                value = let
                  cross = import nixpkgs {
                    inherit system;
                    crossSystem = {config = target;};
                  };
                  cpkgs = cross.pkgsMusl;
                in (cross.mkShell {
                  nativeBuildInputs = with pkgs; [
                    pkg-config
                    gcc # proc macro 等编译过程,需要原架构 toolchians
                  ];
                  env = let
                    normalized = lib.strings.toUpper (builtins.replaceStrings ["-"] ["_"] target);
                  in
                    with cpkgs; {
                      # https://doc.rust-lang.org/cargo/reference/environment-variables.html#configuration-environment-variables
                      "CARGO_TARGET_${normalized}_LINKER" = "${stdenv.cc.targetPrefix}cc";
                    };
                });
              }) ["x86_64-unknown-linux-musl" "aarch64-unknown-linux-musl"]);
          }
        );
    }
    
  2. 执行构建

    # 本地构建
    nix develop .#default --command \
     cargo build
    
    # 跨平台构建
    #
    # 别忘了先安装对应的 rustup 组件
    # rustup target add aarch64-unknown-linux-musl
    # rustup target add x86_64-unknown-linux-musl
    
    TARGET=x86_64-unknown-linux-musl nix develop .#$TARGET --command \
     cargo build --target $TARGET
    

openssl, pq 等 C/C++ 依赖处理

使用静态编译,并使用有 vendor (打包 C/C++ 源码 )版本的 bindings 项目,把这些加入依赖管理,确保能稳定的可重复构建。

  1. 在 Cargo.toml 文件中增加对应 target 的依赖。

    [target.x86_64-unknown-linux-musl.dependencies]
    openssl-sys = { version = "0.9", features = ["vendored"] }
    pq-sys = { version = "0.7", features = ["bundled"] }
    
    [target.aarch64-unknown-linux-musl.dependencies]
    openssl-sys = { version = "0.9", features = ["vendored"] }
    pq-sys = { version = "0.7", features = ["bundled"] }
    
  2. 执行构建

    # 本地静态编译则需要指定 RUSTFLAGS。经实测,有些架构该配置无效
    RUSTFLAGS='-C target-feature=+crt-static' cargo build
    
    # 而 x86_64-unknown-linux-musl 则不需要指定,默认启用
    TARGET=x86_64-unknown-linux-musl nix develop .#$TARGET --command \
      cargo build --target $TARGET
    

CRT means standard C runtime. The default of crt-static will be different depending on the target. For example x86_64-unknown-linux-musl will have it on by default, whereas arm-unknown-linux-musleabi will have it turned off by default. 1

实现 DNS App

前言

Logo of WireGuard

家里的 NAS 通过 WireGuard 配合小水管云主机搭建了一个私有网络,方便我在外面访问家里的设备。 通过 Surge 可以定义简单的规则,把特定域名或 IP 段用 WireGuard 代理,这样就可以访问家里的设备了。 再通过 SSID 判断当前网络环境,在家就直连。

这样从理论上看是挺好的,但会遇到些问题。 IP 段可能会冲突,只能给每个地址配置域名,只用域名规则。 虽然很麻烦,但也没法子。配置域名可以在 Surge 上配置,也可以通过 /etc/hosts 。 但 Surge 更方便,可以配置 Unix Shell Style 通配符,减少些配置。

但这个方案有个问题,只能在 MacOS 和 iOS 上使用。而且 Surge 也很贵。 不太方便别人照搬方案(虽然我认识的基本都是 Surge 的用户)。 如果没有 Surge 呢,或者在不在 MacOS 上,又该如何处理。所以我诞生了自己实现 DNS 的想法。

不久前入了台 Mini-PC 装了 NixOS 后,就遇到这样的问题。 虽然用 sing-box (还免费)也能达到同样的效果, 但自己动手实现 DNS 也是种有益身心的消遣方式。

需要实现的功能十分简单,只要类似 /etc/hosts 文件,但又能像 Surge 这样配置统配符。 还能通过配置哪些行是在 WiFi SSID 为某个值时生效,就能实现我想要的功能了。

Read more  ↩︎

可乐是键盘杀手

周五晚上和女票在玩游戏 Go-Go Town ! 。游戏很上头,太专注了,不小心把可乐打翻了。 可乐撒了一丢丢在键盘上,当时是擦干净了,使用也没啥问题。

隔天早上起来用的时候,就发现它坏了。呜呜呜,陪伴5年的键盘。

Read more  ↩︎

在 NixOS 中配置 Neovim

前言

最近在需要在一个巨大的 Rust 项目中做开发工作,但我的笔记本已经不堪重负,无法做高效的开发。 So, 我决定购买一台新的迷你 PC 来专门处理这个问题。

mini PC is put on the left of my phone rack

由于还是习惯在 MacOS 上开发,且又不想折腾 Hackintosh, 我给这台新的迷你 PC 安装了 NixOS 。最早是打算继续使用 VSCode 远程开发, 后面发现 Neovim 也是一个不错的选择。

Read more  ↩︎