From 19b620684f35dedc9765dffa434dca3939cbadf8 Mon Sep 17 00:00:00 2001 From: WeetHet Date: Sat, 15 Feb 2025 17:51:20 +0200 Subject: [PATCH] build(nix): fix nix builds and add CI --- .github/workflows/ci.yml | 22 ++++ flake.lock | 88 +++++++++----- flake.nix | 70 +++-------- nix/build.nix | 248 ------------------------------------- nix/overlays.nix | 16 +++ nix/package.nix | 18 +++ nix/shell.nix | 117 +++++++++--------- nix/treefmt.nix | 22 ++++ nix/zed-editor.nix | 256 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 467 insertions(+), 390 deletions(-) delete mode 100644 nix/build.nix create mode 100644 nix/overlays.nix create mode 100644 nix/package.nix create mode 100644 nix/treefmt.nix create mode 100644 nix/zed-editor.nix diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 419127b6aea9fe..22a280d0cf8869 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -287,6 +287,28 @@ jobs: if: always() run: Remove-Item -Path "${{ env.CARGO_HOME }}/config.toml" -Force + nix: + timeout-minutes: 120 + strategy: + matrix: + system: + - os: macOS + runner: self-hosted + sandbox: false + - os: Linux + runner: buildjet-16vcpu-ubuntu-2204 + sandbox: true + if: github.repository_owner == 'zed-industries' + runs-on: ${{ matrix.system.runner }} + name: (${{ matrix.system.os }}) Build Nix package + steps: + - name: Checkout repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - name: Setup nix + uses: samueldr/lix-gha-installer-action@54a4026004084aa2cf8d18335cc01b06a2e53b74 # v2025-01-21.prerelease + - name: Build Zed + run: nix build .#zed-editor.debug --option sandbox ${{ matrix.system.sandbox }} + bundle-mac: timeout-minutes: 120 name: Create a macOS bundle diff --git a/flake.lock b/flake.lock index 3acb60b7ed6930..2bd5bab533c2ee 100644 --- a/flake.lock +++ b/flake.lock @@ -1,42 +1,32 @@ { "nodes": { - "crane": { - "locked": { - "lastModified": 1736898272, - "narHash": "sha256-D10wlrU/HCpSRcb3a7yk+bU3ggpMD1kGbseKtO+7teo=", - "owner": "ipetkov", - "repo": "crane", - "rev": "6a589f034202a7c6e10bce6c5d1d392d7bc0f340", - "type": "github" + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "flake-compat": { "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "lastModified": 1738453229, + "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", "type": "github" }, "original": { - "owner": "edolstra", - "repo": "flake-compat", + "owner": "hercules-ci", + "repo": "flake-parts", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1737062831, - "narHash": "sha256-Tbk1MZbtV2s5aG+iM99U8FqwxU/YNArMcWAv6clcsBc=", + "lastModified": 1738680400, + "narHash": "sha256-ooLh+XW8jfa+91F1nhf9OF7qhuA/y1ChLx6lXDNeY5U=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5df43628fdf08d642be8ba5b3625a6c70731c19c", + "rev": "799ba5bffed04ced7067a91798353d360788b30d", "type": "github" }, "original": { @@ -48,10 +38,11 @@ }, "root": { "inputs": { - "crane": "crane", - "flake-compat": "flake-compat", + "flake-parts": "flake-parts", "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay" + "rust-overlay": "rust-overlay", + "systems": "systems", + "treefmt-nix": "treefmt-nix" } }, "rust-overlay": { @@ -61,11 +52,11 @@ ] }, "locked": { - "lastModified": 1737166965, - "narHash": "sha256-vlDROBAgq+7PEVM0vaS2zboY6DXs3oKK0qW/1dVuFs4=", + "lastModified": 1738895285, + "narHash": "sha256-4Ukr4reJfQ67c6QqIxbX47wnPIGxE8BXCAEPu1C3MFM=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "fc839c9d5d1ebc789b4657c43c4d54838c7c01de", + "rev": "85f3aed5f4b8eb312c6e8fe8c476bac248aed75f", "type": "github" }, "original": { @@ -73,6 +64,41 @@ "repo": "rust-overlay", "type": "github" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1738680491, + "narHash": "sha256-8X7tR3kFGkE7WEF5EXVkt4apgaN85oHZdoTGutCFs6I=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "64dbb922d51a42c0ced6a7668ca008dded61c483", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index f797227fba2be3..533973dfa0f966 100644 --- a/flake.nix +++ b/flake.nix @@ -3,65 +3,29 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + systems.url = "github:nix-systems/default"; rust-overlay = { url = "github:oxalica/rust-overlay"; inputs.nixpkgs.follows = "nixpkgs"; }; - crane.url = "github:ipetkov/crane"; - flake-compat.url = "github:edolstra/flake-compat"; + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = - { - nixpkgs, - rust-overlay, - crane, - ... - }: - let - systems = [ - "x86_64-linux" - "x86_64-darwin" - "aarch64-linux" - "aarch64-darwin" + { flake-parts, ... }@inputs: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = import inputs.systems; + imports = [ + ./nix/overlays.nix + ./nix/package.nix + ./nix/shell.nix + ./nix/treefmt.nix ]; - - overlays = { - rust-overlay = rust-overlay.overlays.default; - rust-toolchain = final: prev: { - rustToolchain = final.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; - }; - zed-editor = final: prev: { - zed-editor = final.callPackage ./nix/build.nix { - crane = crane.mkLib final; - rustToolchain = final.rustToolchain; - }; - }; - }; - - mkPkgs = - system: - import nixpkgs { - inherit system; - overlays = builtins.attrValues overlays; - }; - - forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f (mkPkgs system)); - in - { - packages = forAllSystems (pkgs: { - zed-editor = pkgs.zed-editor; - default = pkgs.zed-editor; - }); - - devShells = forAllSystems (pkgs: { - default = import ./nix/shell.nix { inherit pkgs; }; - }); - - formatter = forAllSystems (pkgs: pkgs.nixfmt-rfc-style); - - overlays = overlays // { - default = nixpkgs.lib.composeManyExtensions (builtins.attrValues overlays); - }; }; } diff --git a/nix/build.nix b/nix/build.nix deleted file mode 100644 index e78025dffdef2e..00000000000000 --- a/nix/build.nix +++ /dev/null @@ -1,248 +0,0 @@ -{ - lib, - crane, - rustToolchain, - fetchpatch, - clang, - cmake, - copyDesktopItems, - curl, - perl, - pkg-config, - protobuf, - fontconfig, - freetype, - libgit2, - openssl, - sqlite, - zlib, - zstd, - alsa-lib, - libxkbcommon, - wayland, - libglvnd, - xorg, - stdenv, - makeFontsConf, - vulkan-loader, - envsubst, - cargo-about, - cargo-bundle, - git, - apple-sdk_15, - darwinMinVersionHook, - makeWrapper, - nodejs_22, - nix-gitignore, - - withGLES ? false, -}: - -assert withGLES -> stdenv.hostPlatform.isLinux; - -let - includeFilter = - path: type: - let - baseName = baseNameOf (toString path); - parentDir = dirOf path; - inRootDir = type == "directory" && parentDir == ../.; - in - !( - inRootDir - && (baseName == "docs" || baseName == ".github" || baseName == ".git" || baseName == "target") - ); - craneLib = crane.overrideToolchain rustToolchain; - commonSrc = lib.cleanSourceWith { - src = nix-gitignore.gitignoreSource [ ] ../.; - filter = includeFilter; - name = "source"; - }; - commonArgs = rec { - pname = "zed-editor"; - version = "nightly"; - - src = commonSrc; - - nativeBuildInputs = - [ - clang - cmake - copyDesktopItems - curl - perl - pkg-config - protobuf - cargo-about - ] - ++ lib.optionals stdenv.hostPlatform.isLinux [ makeWrapper ] - ++ lib.optionals stdenv.hostPlatform.isDarwin [ cargo-bundle ]; - - 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") - ]; - - env = { - ZSTD_SYS_USE_PKG_CONFIG = true; - FONTCONFIG_FILE = makeFontsConf { - fontDirectories = [ - "${src}/assets/fonts/plex-mono" - "${src}/assets/fonts/plex-sans" - ]; - }; - ZED_UPDATE_EXPLANATION = "Zed has been installed using Nix. Auto-updates have thus been disabled."; - RELEASE_VERSION = version; - }; - }; - cargoArtifacts = craneLib.buildDepsOnly commonArgs; -in -craneLib.buildPackage ( - commonArgs - // rec { - inherit cargoArtifacts; - - 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="; - }) - ]; - - cargoExtraArgs = "--package=zed --package=cli --features=gpui/runtime_shaders"; - - dontUseCmakeConfigure = true; - preBuild = '' - bash script/generate-licenses - ''; - - postFixup = lib.optionalString stdenv.hostPlatform.isLinux '' - patchelf --add-rpath ${gpu-lib}/lib $out/libexec/* - patchelf --add-rpath ${wayland}/lib $out/libexec/* - wrapProgram $out/libexec/zed-editor --suffix PATH : ${lib.makeBinPath [ nodejs_22 ]} - ''; - - RUSTFLAGS = if withGLES then "--cfg gles" else ""; - gpu-lib = if withGLES then libglvnd else vulkan-loader; - - preCheck = '' - export HOME=$(mktemp -d); - ''; - - cargoTestExtraArgs = - "-- " - + lib.concatStringsSep " " ( - [ - # 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/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 "\n\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/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 - - mkdir -p $out/bin $out/libexec - cp target/release/zed $out/libexec/zed-editor - cp target/release/cli $out/bin/zed - - install -D ${commonSrc}/crates/zed/resources/app-icon@2x.png $out/share/icons/hicolor/1024x1024@2x/apps/zed.png - install -D ${commonSrc}/crates/zed/resources/app-icon.png $out/share/icons/hicolor/512x512/apps/zed.png - - # extracted from https://github.com/zed-industries/zed/blob/v0.141.2/script/bundle-linux (envsubst) - # and https://github.com/zed-industries/zed/blob/v0.141.2/script/install.sh (final desktop file name) - ( - export DO_STARTUP_NOTIFY="true" - export APP_CLI="zed" - export APP_ICON="zed" - 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 - ''; - - meta = { - description = "High-performance, multiplayer code editor from the creators of Atom and Tree-sitter"; - homepage = "https://zed.dev"; - changelog = "https://zed.dev/releases/preview"; - license = lib.licenses.gpl3Only; - mainProgram = "zed"; - platforms = lib.platforms.linux ++ lib.platforms.darwin; - }; - } -) diff --git a/nix/overlays.nix b/nix/overlays.nix new file mode 100644 index 00000000000000..83b7ebfeedd319 --- /dev/null +++ b/nix/overlays.nix @@ -0,0 +1,16 @@ +{ inputs, ... }: +{ + perSystem = + { system, ... }: + { + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ + inputs.rust-overlay.overlays.default + (final: prev: { + rust-toolchain = final.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml; + }) + ]; + }; + }; +} diff --git a/nix/package.nix b/nix/package.nix new file mode 100644 index 00000000000000..ab88a0849a28df --- /dev/null +++ b/nix/package.nix @@ -0,0 +1,18 @@ +{ self, ... }: +{ + perSystem = + { config, pkgs, ... }: + { + packages = { + zed-editor = pkgs.callPackage ./zed-editor.nix { + version = self.rev or self.dirtyRev or "unknown-nightly"; + rustPlatform = pkgs.makeRustPlatform { + cargo = pkgs.rust-toolchain; + rustc = pkgs.rust-toolchain; + }; + zed-editor = config.packages.zed-editor; + }; + default = config.packages.zed-editor; + }; + }; +} diff --git a/nix/shell.nix b/nix/shell.nix index edfa2f442c3bd2..b3d5e302b7a0ab 100644 --- a/nix/shell.nix +++ b/nix/shell.nix @@ -1,65 +1,66 @@ +{ ... }: { - pkgs ? import { }, -}: -let - inherit (pkgs) lib; -in -pkgs.mkShell rec { - packages = - [ - pkgs.clang - pkgs.curl - pkgs.cmake - pkgs.perl - pkgs.pkg-config - pkgs.protobuf - pkgs.rustPlatform.bindgenHook - pkgs.rust-analyzer - ] - ++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [ - pkgs.mold - ]; + perSystem = + { pkgs, lib, ... }: + { + devShells.default = pkgs.mkShell rec { + packages = + [ + pkgs.clang + pkgs.curl + pkgs.cmake + pkgs.perl + pkgs.pkg-config + pkgs.protobuf + pkgs.rustPlatform.bindgenHook + pkgs.rust-analyzer + pkgs.rust-toolchain + ] + ++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [ + pkgs.mold + ]; - buildInputs = - [ - pkgs.bzip2 - pkgs.curl - pkgs.fontconfig - pkgs.freetype - pkgs.libgit2 - pkgs.openssl - pkgs.sqlite - pkgs.stdenv.cc.cc - pkgs.zlib - pkgs.zstd - pkgs.rustToolchain - ] - ++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [ - pkgs.alsa-lib - pkgs.libxkbcommon - pkgs.wayland - pkgs.xorg.libxcb - pkgs.vulkan-loader - ] - ++ lib.optional pkgs.stdenv.hostPlatform.isDarwin pkgs.apple-sdk_15; + buildInputs = + [ + pkgs.bzip2 + pkgs.curl + pkgs.fontconfig + pkgs.freetype + pkgs.libgit2 + pkgs.openssl + pkgs.sqlite + pkgs.stdenv.cc.cc + pkgs.zlib + pkgs.zstd + ] + ++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [ + pkgs.alsa-lib + pkgs.libxkbcommon + pkgs.wayland + pkgs.xorg.libxcb + pkgs.vulkan-loader + ] + ++ lib.optional pkgs.stdenv.hostPlatform.isDarwin pkgs.apple-sdk_15; - LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs; + LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs; - PROTOC="${pkgs.protobuf}/bin/protoc"; + PROTOC = "${pkgs.protobuf}/bin/protoc"; - # 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 = 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"; - ''; + # 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 = 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" - ]; - }; - ZSTD_SYS_USE_PKG_CONFIG = true; + FONTCONFIG_FILE = pkgs.makeFontsConf { + fontDirectories = [ + "./assets/fonts/zed-mono" + "./assets/fonts/zed-sans" + ]; + }; + ZSTD_SYS_USE_PKG_CONFIG = true; + }; + }; } diff --git a/nix/treefmt.nix b/nix/treefmt.nix new file mode 100644 index 00000000000000..6e73cb438a7993 --- /dev/null +++ b/nix/treefmt.nix @@ -0,0 +1,22 @@ +{ inputs, ... }: +{ + imports = [ + inputs.treefmt-nix.flakeModule + ]; + perSystem = + { ... }: + { + treefmt = { + projectRootFile = "flake.nix"; + options = { + allow-missing-formatter = true; + }; + programs = { + rustfmt.enable = true; + nixfmt.enable = true; + shfmt.enable = true; + taplo.enable = true; + }; + }; + }; +} diff --git a/nix/zed-editor.nix b/nix/zed-editor.nix new file mode 100644 index 00000000000000..0dfdd37c99ecfc --- /dev/null +++ b/nix/zed-editor.nix @@ -0,0 +1,256 @@ +{ + lib, + fetchpatch, + nix-gitignore, + rustPlatform, + cmake, + copyDesktopItems, + curl, + perl, + pkg-config, + protobuf, + fontconfig, + freetype, + libgit2, + openssl, + sqlite, + zlib, + zstd, + alsa-lib, + libxkbcommon, + wayland, + libglvnd, + xorg, + stdenv, + makeFontsConf, + vulkan-loader, + envsubst, + cargo-about, + cargo-bundle, + git, + apple-sdk_15, + darwinMinVersionHook, + makeWrapper, + nodejs, + libGL, + libX11, + libXext, + livekit-libwebrtc, + writableTmpDirAsHomeHook, + zed-editor, + + version ? "unknown-nightly", + buildType ? "release", + withGLES ? false, + buildRemoteServer ? true, +}: + +assert withGLES -> stdenv.hostPlatform.isLinux; + +rustPlatform.buildRustPackage rec { + pname = "zed-editor"; + inherit version buildType; + + outputs = [ "out" ] ++ lib.optional buildRemoteServer "remote_server"; + + src = ../.; + + 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="; + }) + # See https://github.com/zed-industries/zed/pull/21661#issuecomment-2524161840 + "script/patches/use-cross-platform-livekit.patch" + ]; + + # Dynamically link WebRTC instead of static + postPatch = '' + substituteInPlace ../cargo-vendor-dir/webrtc-sys-*/build.rs \ + --replace-fail "cargo:rustc-link-lib=static=webrtc" "cargo:rustc-link-lib=dylib=webrtc" + ''; + + cargoLock = { + lockFile = ../Cargo.lock; + allowBuiltinFetchGit = true; + }; + + nativeBuildInputs = + [ + cmake + copyDesktopItems + curl + perl + pkg-config + protobuf + 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 + # required by livekit: + libGL + libX11 + libXext + ] + ++ lib.optionals stdenv.hostPlatform.isDarwin [ + apple-sdk_15 + # ScreenCaptureKit, required by livekit, is only available on 12.3 and up: + # https://developer.apple.com/documentation/screencapturekit + (darwinMinVersionHook "12.3") + ]; + + cargoBuildFlags = [ + "--package=zed" + "--package=cli" + ] ++ lib.optional buildRemoteServer "--package=remote_server"; + + # Required on darwin because we don't have access to the + # proprietary Metal shader compiler. + 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" + ]; + }; + # Setting this environment variable allows to disable auto-updates + # https://zed.dev/docs/development/linux#notes-for-packaging-zed + ZED_UPDATE_EXPLANATION = "Zed has been installed using Nix. Auto-updates have thus been disabled."; + # Used by `zed --version` + RELEASE_VERSION = version; + LK_CUSTOM_WEBRTC = livekit-libwebrtc; + }; + + RUSTFLAGS = if withGLES then "--cfg gles" else ""; + gpu-lib = if withGLES then libglvnd else vulkan-loader; + + preBuild = '' + bash script/generate-licenses + ''; + + postFixup = lib.optionalString stdenv.hostPlatform.isLinux '' + patchelf --add-rpath ${gpu-lib}/lib $out/libexec/* + patchelf --add-rpath ${wayland}/lib $out/libexec/* + wrapProgram $out/libexec/zed-editor --suffix PATH : ${lib.makeBinPath [ nodejs ]} + ''; + + nativeCheckInputs = [ + writableTmpDirAsHomeHook + ]; + + checkFlags = + [ + # 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 = + '' + runHook preInstall + + release_target="target/${stdenv.hostPlatform.rust.cargoShortTarget}/${buildType}" + '' + + lib.optionalString stdenv.hostPlatform.isDarwin '' + # cargo-bundle expects the binary in target/release + mv $release_target/zed target/${buildType}/zed + + pushd crates/zed + + # Note that this is GNU sed, 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 ${if buildType == "release" then "release" else ""} | xargs) + + # We're not using Zed's fork of cargo-bundle, so we must manually append their 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 "\n\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 ${lib.getExe git} $app_path/Contents/MacOS/git + mv $release_target/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 + '' + + lib.optionalString stdenv.hostPlatform.isLinux '' + install -Dm755 $release_target/zed $out/libexec/zed-editor + install -Dm755 $release_target/cli $out/bin/zed + + install -Dm644 ${src}/crates/zed/resources/app-icon@2x.png $out/share/icons/hicolor/1024x1024@2x/apps/zed.png + install -Dm644 ${src}/crates/zed/resources/app-icon.png $out/share/icons/hicolor/512x512/apps/zed.png + + # extracted from https://github.com/zed-industries/zed/blob/v0.141.2/script/bundle-linux (envsubst) + # and https://github.com/zed-industries/zed/blob/v0.141.2/script/install.sh (final desktop file name) + ( + export DO_STARTUP_NOTIFY="true" + export APP_CLI="zed" + export APP_ICON="zed" + 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" + ) + '' + + lib.optionalString buildRemoteServer '' + install -Dm755 $release_target/remote_server $remote_server/bin/zed-remote-server-stable-$version + '' + + '' + runHook postInstall + ''; + + doInstallCheck = false; + + passthru = { + debug = zed-editor.override { buildType = "debug"; }; + }; + + meta = { + description = "High-performance, multiplayer code editor from the creators of Atom and Tree-sitter"; + homepage = "https://zed.dev"; + changelog = "https://github.com/zed-industries/zed/releases/tag/v${version}"; + license = lib.licenses.gpl3Only; + mainProgram = "zed"; + platforms = lib.platforms.linux ++ lib.platforms.darwin; + }; +}