tauri-apps / tauri

Build smaller, faster, and more secure desktop and mobile applications with a web frontend.
https://tauri.app
Apache License 2.0
85.99k stars 2.6k forks source link

[bug] Build is not working on NixOS #3323

Open flosse opened 2 years ago

flosse commented 2 years ago

Describe the bug

The build_appimage.sh script invoked by cargo tauri build fails to run on NixOS because the linuxdeploy-x86_64.AppImage always tells me No such file or directory. In contrast, the exact same project with the same version of tauri can be build successfully on Ubuntu.

Reproduction

  1. Place the following shell.nix file in the project root and run nix-shell
    let
    moz_overlay = import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz);
    pkgs = import <nixpkgs> { overlays = [ moz_overlay ]; };
    rustChannel = pkgs.rustChannelOf {
     channel = "stable";
    };
    rust = (rustChannel.rust.override {
    targets = [
      "wasm32-unknown-unknown"
    ];
    });
    in
    with pkgs;
    mkShell {
    buildInputs = [
      rust
      pkgconfig
      openssl
      sass
      glib
      cairo
      pango
      atk
      gdk-pixbuf
      libsoup
      gtk3
      gnome.webkitgtk
      librsvg
      patchelf
    ];
    }
  2. Run cargo tauri build

Expected behavior

No response

Platform and versions

Operating System - NixOS, version 21.11.0 X64
WARNING: no lock files found, defaulting to npm

Rust environment
  rustc - 1.58.1
  cargo - 1.58.0

Rust environment
  rustup - Not installed
  rustc - 1.58.1
  cargo - 1.58.0
  toolchain - Not installed

App directory structure
/frontend
/tests
/src-tauri
/target
/.git

App
  tauri.rs - 1.0.0-beta.8
  build-type - bundle
  CSP - default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'
  distDir - ../frontend/dist
  devPath - http://localhost:8080/
package.json not found

Stack trace

+ export ARCH=x86_64
+ ARCH=x86_64
+ mkdir -p spoty-sync.AppDir
+ cp -r ../appimage_deb/data/usr spoty-sync.AppDir
+ cd spoty-sync.AppDir
++ dirname '{}'
+ find '/usr/lib*' -name WebKitNetworkProcess -exec mkdir -p . ';' -exec cp --parents '{}' . ';'
find: ‘/usr/lib*’: No such file or directory
+ true
++ dirname '{}'
+ find '/usr/lib*' -name WebKitWebProcess -exec mkdir -p . ';' -exec cp --parents '{}' . ';'
find: ‘/usr/lib*’: No such file or directory
+ true
++ dirname '{}'
+ find '/usr/lib*' -name libwebkit2gtkinjectedbundle.so -exec mkdir -p . ';' -exec cp --parents '{}' . ';'
find: ‘/usr/lib*’: No such file or directory
+ true
+ wget -q -4 -O AppRun https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-x86_64
+ chmod +x AppRun
+ cp usr/share/icons/hicolor/512x512@2x/apps/spoty-sync.png .DirIcon
+ ln -s usr/share/icons/hicolor/512x512@2x/apps/spoty-sync.png spoty-sync.png
+ ln -s usr/share/applications/spoty-sync.desktop spoty-sync.desktop
+ cd ..
+ wget -q -4 -O linuxdeploy-plugin-gtk.sh https://raw.githubusercontent.com/tauri-apps/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh
+ wget -q -4 -O linuxdeploy-x86_64.AppImage https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
+ chmod +x linuxdeploy-plugin-gtk.sh
+ chmod +x linuxdeploy-x86_64.AppImage
+ args=()
+ lsmod
+ grep -q fuse
+ OUTPUT=spoty-sync_0.1.0_amd64.AppImage
+ ./linuxdeploy-x86_64.AppImage --appdir spoty-sync.AppDir --plugin gtk --output appimage
/home/mk/dev/spotysync/src-tauri/target/release/bundle/appimage/build_appimage.sh: Zeile 42: ./linuxdeploy-x86_64.AppImage: No such file or directory
Error: failed to bundle project

Caused by:
    Shell Scripting Error:`error running appimage.sh`

Additional context

No response

almahdi commented 2 years ago

You need to use patchelf or use the hook, or nix-ld to patch linuxdeploy-x86_64.AppImage

I'll try to fix your shell file when I get time this weekend.

miniBill commented 2 years ago

That script will also fail to get the libraries, which... why is it getting them from the host system in the first place? o.O

The script should also have set -e and explicitly choose where to allow errors

lucasfernog commented 2 years ago

Maybe #4457 fixes this? Please try it tomorrow when we release 1.0.1.

miniBill commented 2 years ago

Probably not. But feel free to ping me and I'll try again

Suyashtnt commented 2 years ago

some findings: image

miniBill commented 2 years ago

The No such file or directory is probably the binary trying to point to the standard FHS location for the dynamic linker.

I honestly think a bigger issue here is just wgetting and executing stuff off the internet. At the very least it should download a specific version and match it against a known good hash (taking a page out of Nix itself: derivations either know the hash of their output or are barred from accessing the internet).

miniBill commented 2 years ago

I wonder if something along the lines of https://blog.mediocregopher.com/posts/building-appimages-with-nix could packaged in a nice way for nix. Something like a "build tauri project" derivation.

I'm not knowledgeable enough in nix to write this but I think it should be doable.

IllustratedMan-code commented 2 years ago

Just a note, gnome.webkitgtk was removed in favor of pkgs.webkitgtk

IllustratedMan-code commented 2 years ago

@miniBill This is definitely possible. All you need is a derivation (or a function to create a derivation) to do what you want (build tauri project), then get that derivation into the nixpkgs repository through a pull request. It would then be available for everyone's use.

Since the transition to flakes, this isn't even necessary, just have a flake somewhere with the derivations that you want (git repo). These can be included in any other flake.

IllustratedMan-code commented 2 years ago

I'm pretty new to tauri, but cargo tauri build doesn't seem to be an availabe command. I was able to get the application to build with cargo build though, as well as through npm run tauri dev

IllustratedMan-code commented 2 years ago

Unless this is about building the main repo, haven't tried that yet.

IllustratedMan-code commented 2 years ago

Just built from the dev branch without any errors. Again, no cargo tauri build command was available, so I just did cargo build.

FabianLars commented 2 years ago

cargo tauri build is only a thing after installing the tauri cli via cargo install tauri-cli, similar to the nom package.

IllustratedMan-code commented 2 years ago

I see, well I can confirm that cargo tauri build fails on NixOS

IllustratedMan-code commented 2 years ago

Just took a look at build_appimage.sh. It seems entirely incompatible with the way nix does things in terms of packaging (nix will block all calls to wget, as well as any reference to absolute paths).

That being said, it is possible to get cargo tauri build to work within a nix shell, or a call to nix run with only a few modifications. One thing I am confused about is this line (one right before the last line in build_appimage.sh)

dd if=/dev/zero bs=1 count=3 seek=8 conv=notrunc of="/home/myuser/.cache/tauri/linuxdeploy-${ARCH}.AppImage"

Which seems to modify the ELF header magic bits so that the appImage can not be identified as an appImage. (why do this?) Removing this line seems to have no detrimental effect as far as I can tell.

adding appimage-run to the final line of build_appimage.sh almost works, except it can't find the gtk plugin.

FabianLars commented 2 years ago

@IllustratedMan-code See https://github.com/tauri-apps/tauri/pull/4457 for the elf header stuff.

IllustratedMan-code commented 2 years ago

Interesting, well I'm stumped then. I don't think there is a way to fix this issue without a major rewrite to build_appimage.sh or some fancy nix stuff that's beyond me for the moment.

appimage-run requires the correct elf header, so I would have to reverse the effects of #4457 to make it work at all.

It might be possible to sidestep this problem and do it through a nix derivation, maybe using something like https://github.com/matthewbauer/nix-bundle . This would start to get a bit nix-specific though and would probably need its own section of the documentation. This might end up looking like nix build .#appimage in practice.

It might be possible to replicate the effects of appimage-run for this specific use case as well. I'm not really sure how appimage-run works, but the sources are here if anyone wants to take a crack at it.

https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/package-management/appimage-run/default.nix

https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/appimage/appimage-exec.sh

IllustratedMan-code commented 2 years ago

Seems like you could also just run cargo tauri build in a docker container (which you could probably build with nix if you wanted), not the cleanest workaround but might be the easiest to implement.

miniBill commented 2 years ago

@IllustratedMan-code thank you for taking the time to look into that I agree that for now a nix-built docker container seems the simplest path

darichey commented 1 year ago

In my case, I don't need to build an appimage, so I can work around this issue by configuring the targets. i.e.,

// Can't build appimage: https://github.com/tauri-apps/tauri/issues/3323
"targets": ["deb", "msi", "app", "dmg", "updater"]

Obviously this is not helpful if you do want an appimage, but just wanted to share in case anyone else is in a similar situation.

Eveeifyeve commented 5 months ago

Here I have a package that may help when building tauri into a drv:

{
  lib,
  buildNpmPackage,
  openssl,
  stdenv,
  pkg-config,
  glibc,
  libsoup_3,
  gtk3,
  cairo,
  webkitgtk_4_1,
  nodejs-slim,
  cargo-tauri,
  cargo,
  rustPlatform,
  rustc,
  bun,
  darwin,
  llvmPackages,
  rustup,
  libiconv,
}:

let
  inherit (darwin.apple_sdk.frameworks)
    Security
    SystemConfiguration
    AppKit
    WebKit
    CoreFoundation
    ;
in
buildNpmPackage rec {
  pname = "Example Name";
  version = "0.0.1-dev";
  dontNpmBuild = true; # Don't want to npm build since it will produce the application from tauri

  src = ./..;

  npmDepsHash = "sha256-eNAOAjBZQ/L9MMHRFOZi6+wIsj0axF6y7bbdswOuPww=";

  cargoDeps = rustPlatform.importCargoLock {
    lockFile = "${src}/src-tauri/Cargo.lock";
    outputHashes = {
      "tauri-plugin-clipboard-manager-2.1.0-beta.1" = "sha256-2F+OkX92B2/aJva86orotHc7mYUZuaYAmKx50dDp2Sc=";
    };
  };

  configurePhase = ''
    export HOME=$(mktemp -d)
  '';

  preBuild = if stdenv.isLinux then "cargo tauri build -b deb" else "cargo tauri build -b app";
  cargoRoot = "src-tauri/";

  preInstall =
    if stdenv.isLinux then
      "mv src-tauri/target/release/bundle/deb/*/data/usr/ \"$out\""
    else
      "mv src-tauri/target/release/bundle/macos/* \"$out/\"";

  nativeBuildInputs =
    [
      pkg-config
      rustPlatform.cargoSetupHook
      cargo
      rustc
      cargo-tauri
      nodejs-slim
      openssl
      bun
    ]
    ++ lib.optionals stdenv.isDarwin [
      llvmPackages.libcxxStdenv
      llvmPackages.libcxxClang
      llvmPackages.libcxx
      darwin.libobjc
      darwin.libiconv
      libiconv
      Security
      SystemConfiguration
      AppKit
      WebKit
      CoreFoundation
    ];

  buildInputs =
    [ openssl ]
    ++ lib.optionals stdenv.isLinux [
      glibc
      libsoup_3
      cairo
      gtk3
      webkitgtk_4_1
    ]
    ++ lib.optionals stdenv.isDarwin [
      Security
      darwin.libiconv
      SystemConfiguration
      AppKit
      WebKit
      rustup
    ];

  meta = with lib; {
    description = "Example description";
    homepage = "https://example.com";
    license = with licenses; [ epl20 ];
    mainProgram = "program";
    maintainers = with maintainers; [ ];
  };
}