Skip to content

Instantly share code, notes, and snippets.

@Excedrin
Created September 21, 2026 05:22
Show Gist options
  • Select an option

  • Save Excedrin/cf851832574372b3e9ade85c4ca679fa to your computer and use it in GitHub Desktop.

Select an option

Save Excedrin/cf851832574372b3e9ade85c4ca679fa to your computer and use it in GitHub Desktop.
UniClipboard flake
# Nix packaging for UniClipboard (daemon `uniclipd` + CLI `uniclip`).
#
# Usage:
# nix build .#uniclipd # daemon only
# nix build .#uniclip # CLI only
# nix build # both binaries (default package)
# nix develop # shell with everything `bun tauri dev/build`
# # needs (pkg-config, webkit2gtk, GTK3, ...)
#
# Notes:
# - The GUI (`uniclipboard` Tauri app) is intentionally not packaged here;
# it requires webkit2gtk and tauri-cli bundling. Use `nix develop` and the
# upstream `bun tauri build` flow if you need it.
# - Cargo.lock contains git dependencies (uc-engine, iroh-blobs fork). This
# requires a recent nixpkgs whose buildRustPackage uses fetchCargoVendor
# (nixpkgs >= 25.05).
{
description = "UniClipboard - encrypted peer-to-peer clipboard sync (daemon + CLI)";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
inherit (pkgs.rustPlatform) buildRustPackage;
version = "1.0.0-alpha.17";
# Native deps shared by the daemon and CLI builds.
# - pkg-config + dbus: `dbus` crate -> libdbus-sys probes libdbus-1
# via pkg-config (see crates/uc-platform/Cargo.toml comments).
# - cmake + clang + perl: aws-lc-sys (pulled transitively via iroh in
# uc-engine) builds its vendored AWS-LC with CMake and needs
# libclang for bindgen; perl is used by its build scripts.
# - wayland: wayland-client dlopens libwayland-client at runtime;
# adding it to buildInputs puts it on the RUNPATH.
nativeBuildInputs = [
pkgs.pkg-config
pkgs.cmake
pkgs.clang
pkgs.perl
];
buildInputs = [
pkgs.dbus
pkgs.wayland
];
commonArgs = {
inherit version;
src = self;
cargoLock.lockFile = ./Cargo.lock;
inherit nativeBuildInputs buildInputs;
# Skip the workspace-wide default-run resolution by naming packages
# explicitly; both binaries share one build for speed.
cargoBuildFlags = [
"-p"
"uc-daemon"
"--bin"
"uniclipd"
"-p"
"uc-cli"
"--bin"
"uniclip"
];
cargoTestFlags = [
"-p"
"uc-daemon"
"--bin"
"uniclipd"
"-p"
"uc-cli"
"--bin"
"uniclip"
];
# No testable bin-level units in the release build of these two
# binaries; workspace tests are exercised by CI instead.
doCheck = false;
# Hashes for the git dependencies pinned in Cargo.lock
# (UniClipboard/Engine and the UniClipboard/iroh-blobs fork).
cargoLock.outputHashes = {
"iroh-blobs-0.102.0" = "sha256-w+4me6aCA1GCnIiAcJXNlxv0u5YAInpAuB5BlHep8I4=";
"uc-application-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-content-hash-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-core-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-engine-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-infra-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-mobile-lan-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-mobile-proto-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-observability-contract-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
"uc-observability-runtime-1.1.0-rc.18" = "sha256-8xH9qQ16VpA1i/vMbuZysUevHhos6xbBGFsV3yeLt08=";
};
};
# nixpkgs' buildRustPackage passes `--target <triple>`, so cargo nests
# artifacts under target/<triple>/release/ instead of target/release/.
rustTargetDir = "target/${pkgs.stdenv.hostPlatform.rust.rustcTargetSpec}/release";
installBoth = ''
install -Dm755 ${rustTargetDir}/uniclipd $out/bin/uniclipd
install -Dm755 ${rustTargetDir}/uniclip $out/bin/uniclip
'';
in
{
packages = {
default = buildRustPackage (commonArgs // {
pname = "uniclipboard";
installPhase = installBoth;
});
uniclipd = buildRustPackage (commonArgs // {
pname = "uniclipd";
cargoBuildFlags = [
"-p"
"uc-daemon"
"--bin"
"uniclipd"
];
cargoTestFlags = [ "-p" "uc-daemon" ];
installPhase = ''
install -Dm755 ${rustTargetDir}/uniclipd $out/bin/uniclipd
'';
});
uniclip = buildRustPackage (commonArgs // {
pname = "uniclip";
cargoBuildFlags = [
"-p"
"uc-cli"
"--bin"
"uniclip"
];
cargoTestFlags = [ "-p" "uc-cli" ];
installPhase = ''
install -Dm755 ${rustTargetDir}/uniclip $out/bin/uniclip
'';
});
};
devShells.default = pkgs.mkShell {
# Everything `bun tauri dev` / `bun tauri build` needs on Linux:
# pkg-config (the missing piece you hit), the GTK3/webkit2gtk-4.1
# stack, tray-icon (libayatana-appindicator), gtk-layer-shell,
# OpenSSL/ring, aws-lc-sys toolchain, and the JS/Rust toolchains.
packages =
[
pkgs.pkg-config
pkgs.cmake
pkgs.clang
pkgs.perl
# Tauri Linux stack
pkgs.glib
pkgs.gtk3
pkgs.webkitgtk_4_1
pkgs.libsoup_3
pkgs.cairo
pkgs.gdk-pixbuf
pkgs.librsvg
pkgs.libayatana-appindicator
pkgs.gtk-layer-shell
pkgs.glib-networking # TLS for webkit at runtime
# daemon/CLI native deps (same as above)
pkgs.dbus
pkgs.wayland
pkgs.openssl
# toolchains
pkgs.rustup
pkgs.bun
pkgs.nodejs
];
env = {
# rustup reads rust-toolchain.toml (pins 1.95.0) and installs it
# into its own home on first use.
RUSTUP_TOOLCHAIN = "1.95.0";
};
shellHook = ''
export RUSTUP_HOME="$PWD/.rustup"
export CARGO_HOME="$PWD/.cargo"
export PATH="$PWD/.cargo/bin:$PATH"
'';
};
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment