Improve Nix package and shell (#21075)

With an addition of useFetchCargoVendor, crane becomes less necessary
for our use. This reuses the package from nixpkgs as well as creating a
better devshell that both work on macOS.

I use Xcode's SDKROOT and DEVELOPER_DIR to point the swift in the
livekit client crate to a correct sdk when using a devshell. Devshell
should work without that once apple releases sources for the 15.1 SDK
but for now this is an easy fix

This also replaces fenix with rust-overlay because of issues with the
out-of-sandbox access I've noticed fenix installed toolchains have

Release Notes:

- N/A
This commit is contained in:
Stanislav Alekseev 2024-11-27 20:22:17 +02:00 committed by GitHub
parent c021ee60d6
commit 4564da2875
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 326 additions and 238 deletions

2
.envrc Normal file
View file

@ -0,0 +1,2 @@
watch_file nix/shell.nix
use flake

View file

@ -1,41 +1,5 @@
{ {
"nodes": { "nodes": {
"crane": {
"locked": {
"lastModified": 1727060013,
"narHash": "sha256-/fC5YlJy4IoAW9GhkJiwyzk0K/gQd9Qi4rRcoweyG9E=",
"owner": "ipetkov",
"repo": "crane",
"rev": "6b40cc876c929bfe1e3a24bf538ce3b5622646ba",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1727073227,
"narHash": "sha256-1kmkEQmFfGVuPBasqSZrNThqyMDV1SzTalQdRZxtDRs=",
"owner": "nix-community",
"repo": "fenix",
"rev": "88cc292eb3c689073c784d6aecc0edbd47e12881",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-compat": { "flake-compat": {
"locked": { "locked": {
"lastModified": 1696426674, "lastModified": 1696426674,
@ -53,11 +17,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1726937504, "lastModified": 1732014248,
"narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=", "narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "9357f4f23713673f310988025d9dc261c20e70c6", "rev": "23e89b7da85c3640bbc2173fe04f4bd114342367",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -69,26 +33,28 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"crane": "crane",
"fenix": "fenix",
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
} }
}, },
"rust-analyzer-src": { "rust-overlay": {
"flake": false, "inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1726443025, "lastModified": 1732242723,
"narHash": "sha256-nCmG4NJpwI0IoIlYlwtDwVA49yuspA2E6OhfCOmiArQ=", "narHash": "sha256-NWI8csIK0ujFlFuEXKnoc+7hWoCiEtINK9r48LUUMeU=",
"owner": "rust-lang", "owner": "oxalica",
"repo": "rust-analyzer", "repo": "rust-overlay",
"rev": "94b526fc86eaa0e90fb4d54a5ba6313aa1e9b269", "rev": "a229311fcb45b88a95fdfa5cecd8349c809a272a",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "rust-lang", "owner": "oxalica",
"ref": "nightly", "repo": "rust-overlay",
"repo": "rust-analyzer",
"type": "github" "type": "github"
} }
} }

View file

@ -3,60 +3,61 @@
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable";
fenix = { rust-overlay = {
url = "github:nix-community/fenix"; url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
crane.url = "github:ipetkov/crane";
flake-compat.url = "github:edolstra/flake-compat"; flake-compat.url = "github:edolstra/flake-compat";
}; };
outputs = { outputs =
nixpkgs, { nixpkgs, rust-overlay, ... }:
crane, let
fenix, systems = [
... "x86_64-linux"
}: let "x86_64-darwin"
systems = ["x86_64-linux" "aarch64-linux"]; "aarch64-linux"
"aarch64-darwin"
];
overlays = { overlays = {
fenix = fenix.overlays.default; rust-overlay = rust-overlay.overlays.default;
rust-toolchain = final: prev: { rust-toolchain = final: prev: {
rustToolchain = final.fenix.stable.toolchain; rustToolchain = final.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
}; };
zed-editor = final: prev: { zed-editor = final: prev: {
zed-editor = final.callPackage ./nix/build.nix { zed-editor = final.callPackage ./nix/build.nix {
craneLib = (crane.mkLib final).overrideToolchain final.rustToolchain; rustPlatform = final.makeRustPlatform {
rustPlatform = final.makeRustPlatform { cargo = final.rustToolchain;
inherit (final.rustToolchain) cargo rustc; rustc = final.rustToolchain;
};
}; };
}; };
}; };
};
mkPkgs = system: mkPkgs =
import nixpkgs { system:
inherit system; import nixpkgs {
overlays = builtins.attrValues overlays; inherit system;
}; overlays = builtins.attrValues overlays;
};
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f (mkPkgs system)); forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f (mkPkgs system));
in { in
packages = forAllSystems (pkgs: { {
zed-editor = pkgs.zed-editor; packages = forAllSystems (pkgs: {
default = pkgs.zed-editor; zed-editor = pkgs.zed-editor;
}); default = pkgs.zed-editor;
});
devShells = forAllSystems (pkgs: { devShells = forAllSystems (pkgs: {
default = import ./nix/shell.nix {inherit pkgs;}; default = import ./nix/shell.nix { inherit pkgs; };
}); });
formatter = forAllSystems (pkgs: pkgs.alejandra); formatter = forAllSystems (pkgs: pkgs.nixfmt-rfc-style);
overlays = overlays = overlays // {
overlays
// {
default = nixpkgs.lib.composeManyExtensions (builtins.attrValues overlays); default = nixpkgs.lib.composeManyExtensions (builtins.attrValues overlays);
}; };
}; };
} }

View file

@ -1,10 +1,9 @@
{ {
lib, lib,
craneLib,
rustPlatform, rustPlatform,
fetchpatch,
clang, clang,
llvmPackages_18, cmake,
mold-wrapped,
copyDesktopItems, copyDesktopItems,
curl, curl,
perl, perl,
@ -22,122 +21,236 @@
wayland, wayland,
libglvnd, libglvnd,
xorg, xorg,
stdenv,
makeFontsConf, makeFontsConf,
vulkan-loader, vulkan-loader,
envsubst, envsubst,
stdenvAdapters, cargo-about,
versionCheckHook,
cargo-bundle,
git,
apple-sdk_15,
darwinMinVersionHook,
makeWrapper,
nodejs_22,
nix-gitignore, nix-gitignore,
withGLES ? false, withGLES ? false,
cmake, }:
}: let
includeFilter = path: type: let assert withGLES -> stdenv.hostPlatform.isLinux;
baseName = baseNameOf (toString path);
parentDir = dirOf path; let
inRootDir = type == "directory" && parentDir == ../.; includeFilter =
in path: type:
!(inRootDir && (baseName == "docs" || baseName == ".github" || baseName == "script" || baseName == ".git" || baseName == "target")); let
baseName = baseNameOf (toString path);
parentDir = dirOf path;
inRootDir = type == "directory" && parentDir == ../.;
in
!(
inRootDir
&& (
baseName == "docs"
|| baseName == ".github"
|| baseName == "script"
|| baseName == ".git"
|| baseName == "target"
)
);
in
rustPlatform.buildRustPackage rec {
pname = "zed-editor";
version = "nightly";
src = lib.cleanSourceWith { src = lib.cleanSourceWith {
src = nix-gitignore.gitignoreSource [] ../.; src = nix-gitignore.gitignoreSource [ ] ../.;
filter = includeFilter; filter = includeFilter;
name = "source"; name = "source";
}; };
stdenv = stdenvAdapters.useMoldLinker llvmPackages_18.stdenv; patches =
[
# Zed uses cargo-install to install cargo-about during the script execution.
# We provide cargo-about ourselves and can skip this step.
# Until https://github.com/zed-industries/zed/issues/19971 is fixed,
# we also skip any crate for which the license cannot be determined.
(fetchpatch {
url = "https://raw.githubusercontent.com/NixOS/nixpkgs/1fd02d90c6c097f91349df35da62d36c19359ba7/pkgs/by-name/ze/zed-editor/0001-generate-licenses.patch";
hash = "sha256-cLgqLDXW1JtQ2OQFLd5UolAjfy7bMoTw40lEx2jA2pk=";
})
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
# Livekit requires Swift 6
# We need this until livekit-rust sdk is used
(fetchpatch {
url = "https://raw.githubusercontent.com/NixOS/nixpkgs/1fd02d90c6c097f91349df35da62d36c19359ba7/pkgs/by-name/ze/zed-editor/0002-disable-livekit-darwin.patch";
hash = "sha256-whZ7RaXv8hrVzWAveU3qiBnZSrvGNEHTuyNhxgMIo5w=";
})
];
commonArgs = useFetchCargoVendor = true;
craneLib.crateNameFromCargoToml {cargoToml = ../crates/zed/Cargo.toml;} cargoHash = "sha256-xL/EBe3+rlaPwU2zZyQtsZNHGBjzAD8ZCWrQXCQVxm8=";
// {
inherit src stdenv;
nativeBuildInputs = [ nativeBuildInputs =
clang [
copyDesktopItems clang
curl cmake
mold-wrapped copyDesktopItems
perl curl
pkg-config perl
protobuf pkg-config
rustPlatform.bindgenHook protobuf
cmake rustPlatform.bindgenHook
cargo-about
]
++ lib.optionals stdenv.hostPlatform.isLinux [ makeWrapper ]
++ lib.optionals stdenv.hostPlatform.isDarwin [ cargo-bundle ];
dontUseCmakeConfigure = true;
buildInputs =
[
curl
fontconfig
freetype
libgit2
openssl
sqlite
zlib
zstd
]
++ lib.optionals stdenv.hostPlatform.isLinux [
alsa-lib
libxkbcommon
wayland
xorg.libxcb
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
apple-sdk_15
(darwinMinVersionHook "10.15")
];
cargoBuildFlags = [
"--package=zed"
"--package=cli"
];
buildFeatures = lib.optionals stdenv.hostPlatform.isDarwin [ "gpui/runtime_shaders" ];
env = {
ZSTD_SYS_USE_PKG_CONFIG = true;
FONTCONFIG_FILE = makeFontsConf {
fontDirectories = [
"${src}/assets/fonts/plex-mono"
"${src}/assets/fonts/plex-sans"
]; ];
buildInputs = [
curl
fontconfig
freetype
libgit2
openssl
sqlite
zlib
zstd
alsa-lib
libxkbcommon
wayland
xorg.libxcb
];
ZSTD_SYS_USE_PKG_CONFIG = true;
FONTCONFIG_FILE = makeFontsConf {
fontDirectories = [
"../assets/fonts/zed-mono"
"../assets/fonts/zed-sans"
];
};
ZED_UPDATE_EXPLANATION = "zed has been installed using nix. Auto-updates have thus been disabled.";
}; };
ZED_UPDATE_EXPLANATION = "Zed has been installed using Nix. Auto-updates have thus been disabled.";
RELEASE_VERSION = version;
};
cargoArtifacts = craneLib.buildDepsOnly commonArgs; RUSTFLAGS = if withGLES then "--cfg gles" else "";
gpu-lib = if withGLES then libglvnd else vulkan-loader;
gpu-lib = preBuild = ''
if withGLES bash script/generate-licenses
then libglvnd '';
else vulkan-loader;
zed = craneLib.buildPackage (commonArgs postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
// { patchelf --add-rpath ${gpu-lib}/lib $out/libexec/*
inherit cargoArtifacts; patchelf --add-rpath ${wayland}/lib $out/libexec/*
cargoExtraArgs = "--package=zed --package=cli"; wrapProgram $out/libexec/zed-editor --suffix PATH : ${lib.makeBinPath [ nodejs_22 ]}
buildFeatures = ["gpui/runtime_shaders"]; '';
doCheck = false;
RUSTFLAGS = preCheck = ''
if withGLES export HOME=$(mktemp -d);
then "--cfg gles" '';
else "";
postFixup = '' checkFlags =
patchelf --add-rpath ${gpu-lib}/lib $out/libexec/* [
patchelf --add-rpath ${wayland}/lib $out/libexec/* # Flaky: unreliably fails on certain hosts (including Hydra)
''; "--skip=zed::tests::test_window_edit_state_restoring_enabled"
]
++ lib.optionals stdenv.hostPlatform.isLinux [
# Fails on certain hosts (including Hydra) for unclear reason
"--skip=test_open_paths_action"
];
installPhase =
if stdenv.hostPlatform.isDarwin then
''
runHook preInstall
# cargo-bundle expects the binary in target/release
mv target/${stdenv.hostPlatform.rust.cargoShortTarget}/release/zed target/release/zed
pushd crates/zed
# Note that this is GNU sed, while Zed's bundle-mac uses BSD sed
sed -i "s/package.metadata.bundle-stable/package.metadata.bundle/" Cargo.toml
export CARGO_BUNDLE_SKIP_BUILD=true
app_path=$(cargo bundle --release | xargs)
# We're not using the fork of cargo-bundle, so we must manually append plist extensions
# Remove closing tags from Info.plist (last two lines)
head -n -2 $app_path/Contents/Info.plist > Info.plist
# Append extensions
cat resources/info/*.plist >> Info.plist
# Add closing tags
printf "</dict>\n</plist>\n" >> Info.plist
mv Info.plist $app_path/Contents/Info.plist
popd
mkdir -p $out/Applications $out/bin
# Zed expects git next to its own binary
ln -s ${git}/bin/git $app_path/Contents/MacOS/git
mv target/${stdenv.hostPlatform.rust.cargoShortTarget}/release/cli $app_path/Contents/MacOS/cli
mv $app_path $out/Applications/
# Physical location of the CLI must be inside the app bundle as this is used
# to determine which app to start
ln -s $out/Applications/Zed.app/Contents/MacOS/cli $out/bin/zed
runHook postInstall
''
else
''
runHook preInstall
postInstall = ''
mkdir -p $out/bin $out/libexec mkdir -p $out/bin $out/libexec
mv $out/bin/zed $out/libexec/zed-editor cp target/${stdenv.hostPlatform.rust.cargoShortTarget}/release/zed $out/libexec/zed-editor
mv $out/bin/cli $out/bin/zed cp target/${stdenv.hostPlatform.rust.cargoShortTarget}/release/cli $out/bin/zed
install -D crates/zed/resources/app-icon@2x.png $out/share/icons/hicolor/1024x1024@2x/apps/zed.png install -D ${src}/crates/zed/resources/app-icon@2x.png $out/share/icons/hicolor/1024x1024@2x/apps/zed.png
install -D crates/zed/resources/app-icon.png $out/share/icons/hicolor/512x512/apps/zed.png install -D ${src}/crates/zed/resources/app-icon.png $out/share/icons/hicolor/512x512/apps/zed.png
export DO_STARTUP_NOTIFY="true" # extracted from https://github.com/zed-industries/zed/blob/v0.141.2/script/bundle-linux (envsubst)
export APP_CLI="zed" # and https://github.com/zed-industries/zed/blob/v0.141.2/script/install.sh (final desktop file name)
export APP_ICON="zed" (
export APP_NAME="Zed" export DO_STARTUP_NOTIFY="true"
export APP_ARGS="%U" export APP_CLI="zed"
mkdir -p "$out/share/applications" export APP_ICON="zed"
${lib.getExe envsubst} < "crates/zed/resources/zed.desktop.in" > "$out/share/applications/dev.zed.Zed.desktop" export APP_NAME="Zed"
export APP_ARGS="%U"
mkdir -p "$out/share/applications"
${lib.getExe envsubst} < "crates/zed/resources/zed.desktop.in" > "$out/share/applications/dev.zed.Zed.desktop"
)
runHook postInstall
''; '';
});
in nativeInstallCheckInputs = [
zed versionCheckHook
// { ];
meta = with lib; {
description = "High-performance, multiplayer code editor from the creators of Atom and Tree-sitter"; meta = {
homepage = "https://zed.dev"; description = "High-performance, multiplayer code editor from the creators of Atom and Tree-sitter";
changelog = "https://zed.dev/releases/preview"; homepage = "https://zed.dev";
license = licenses.gpl3Only; changelog = "https://zed.dev/releases/preview";
mainProgram = "zed"; license = lib.licenses.gpl3Only;
platforms = platforms.linux; mainProgram = "zed";
}; platforms = lib.platforms.linux ++ lib.platforms.darwin;
} };
}

View file

@ -1,51 +1,57 @@
{pkgs ? import <nixpkgs> {}}: let {
stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.llvmPackages_18.stdenv; pkgs ? import <nixpkgs> { },
}:
let
inherit (pkgs) lib;
in in
if pkgs.stdenv.isDarwin pkgs.mkShell rec {
then packages = [
# See https://github.com/NixOS/nixpkgs/issues/320084 pkgs.clang
throw "zed: nix dev-shell isn't supported on darwin yet." pkgs.curl
else let pkgs.cmake
buildInputs = with pkgs; [ pkgs.perl
curl pkgs.pkg-config
fontconfig pkgs.protobuf
freetype pkgs.rustPlatform.bindgenHook
libgit2 pkgs.rust-analyzer
openssl ];
sqlite
zlib buildInputs =
zstd [
alsa-lib pkgs.curl
libxkbcommon pkgs.fontconfig
wayland pkgs.freetype
xorg.libxcb pkgs.libgit2
vulkan-loader pkgs.openssl
rustToolchain pkgs.sqlite
pkgs.zlib
pkgs.zstd
pkgs.rustToolchain
]
++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [
pkgs.alsa-lib
pkgs.libxkbcommon
]
++ lib.optional pkgs.stdenv.hostPlatform.isDarwin pkgs.apple-sdk_15;
# We set SDKROOT and DEVELOPER_DIR to the Xcode ones instead of the nixpkgs ones,
# because we need Swift 6.0 and nixpkgs doesn't have it.
# Xcode is required for development anyways
shellHook =
''
export LD_LIBRARY_PATH="${lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH"
export PROTOC="${pkgs.protobuf}/bin/protoc"
''
+ lib.optionalString pkgs.stdenv.hostPlatform.isDarwin ''
export SDKROOT="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk";
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer";
'';
FONTCONFIG_FILE = pkgs.makeFontsConf {
fontDirectories = [
"./assets/fonts/zed-mono"
"./assets/fonts/zed-sans"
]; ];
in };
pkgs.mkShell.override {inherit stdenv;} { ZSTD_SYS_USE_PKG_CONFIG = true;
nativeBuildInputs = with pkgs; [ }
clang
curl
cmake
perl
pkg-config
protobuf
rustPlatform.bindgenHook
];
inherit buildInputs;
shellHook = ''
export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH"
export PROTOC="${pkgs.protobuf}/bin/protoc"
'';
FONTCONFIG_FILE = pkgs.makeFontsConf {
fontDirectories = [
"./assets/fonts/zed-mono"
"./assets/fonts/zed-sans"
];
};
ZSTD_SYS_USE_PKG_CONFIG = true;
}