Fixup phase can't find `libcuda.so.1`: build abort. How to provide dummy `libcuda.so.1`?

Hello,
I’m trying to write a derivation for a binary software that can (optionally I think) use CUDA. As far as I understand, the library libcuda.so comes at runtime only, depending on your driver, in /run/opengl-drivers/, and people (see blender project for example) seem to use addOpenGLRunpath like that to automatically add at runtime a dependency to libraries in /run/opengl-drivers:

  postFixup = ''
    for program in $out/bin/*; do
      isELF "$program" || continue
      addOpenGLRunpath "$program"
    done
  '';

Unfortunately, in my case the build fails even before, during the fixup phase, where it tries to search dependencies:

  automatically fixing dependencies for ELF files
  searching for dependencies of /nix/store/9xv1xixw4h7x3w0z4rq1xv83vl7fgdcp-DaVinci_Resolve_16.2.7/BlackmagicRAWSpeedTest/BlackmagicRawAPI/libDecoderCUDA.so
    libc++.so.1 -> found: /nix/store/9xv1xixw4h7x3w0z4rq1xv83vl7fgdcp-DaVinci_Resolve_16.2.7/BlackmagicRAWSpeedTest/lib/libc++.so.1
    libc++abi.so.1 -> found: /nix/store/9xv1xixw4h7x3w0z4rq1xv83vl7fgdcp-DaVinci_Resolve_16.2.7/BlackmagicRAWSpeedTest/lib/libc++abi.so.1
    libGL.so.1 -> found: /nix/store/avz5z36i6xmzvzzasqzq5j5xhbyzb1qd-libGL-1.2.0/lib/libGL.so.1
    libcuda.so.1 -> not found!
    libuuid.so.1 -> found: /nix/store/6fl90xarrf13vq63kyl47vqjz67n34ar-util-linux-2.33.2/lib/libuuid.so.1

The problem is that libcuda.so.1 does not exist at build time. I was thinking that adding cudatoolkit to the buildInputs would be enough to provide a dummy libcuda.so.1 to pass the fixup phase, but apparently it’s not enough :frowning:

What is the solution to my problem? Is there a way to provide a dummy libcuda.so.1 at compilation time to pass the fixup phase? I don’t know if it matters, but on the build machine I may not have access to CUDA (and since CUDA should be optional, it may not even be present on the running machine I guess).

Thanks!

For reference, here is the file I’m using, trying to build DaVinci Resolve (free “normal” version). You can test it by simply downloading the .zip file and putting it in the same folder as the following files:

derivation.nix:

{ stdenv, mkDerivation, unzip, autoPatchelfHook, wrapQtAppsHook, libarchive, gtk2, qtbase, gstreamer, libpng12, ocl-icd, openssl, opencl-headers, alsaLib, libXtst, libXdamage, libGLU, cudatoolkit, addOpenGLRunpath }:
mkDerivation rec {
  version = "16.2.7";
  name = "DaVinci_Resolve_${version}";

  src = ./DaVinci_Resolve_16.2.7_Linux.zip;

  unpackPhase = ''
    unzip $src
    # Folder to extract the .run ISO image to
    mkdir extracted
    # bsdtar comes from libarchive
    bsdtar x -f DaVinci_Resolve_${version}_Linux.run -C extracted
    export sourceRoot=extracted
  '';

  
  nativeBuildInputs = [
    unzip
    libarchive
    autoPatchelfHook
    wrapQtAppsHook
    addOpenGLRunpath
  ];

  buildInputs = [
    alsaLib
    gtk2
    gstreamer
    libpng12
    ocl-icd
    openssl
    qtbase
    alsaLib
    libXtst
    libXdamage
    libGLU
    cudatoolkit
  ];
  
 
  installPhase= ''
    mkdir -p $out
    cp -r * $out
  '';

  postFixup = ''
    for program in $out/bin/*; do
      isELF "$program" || continue
      addOpenGLRunpath "$program"
    done
  '';

  meta = {
    description = "DaVinci Resolve";
    homepage = https://;
    license = stdenv.lib.licenses.unfree;
    maintainers = [ stdenv.lib.maintainers.tobiasBora ];
    platforms = stdenv.lib.platforms.linux;
  };
}

default.nix:

{ pkgs ? import <nixpkgs> {} }:
pkgs.libsForQt5.callPackage ./derivation.nix {}

– EDIT –
Maybe I can use the option autoPatchelfIgnoreMissingDeps = false; but not sure it’s the best solution since it may miss other missing libraries.

1 Like

I’m planning to use Resolve on NixOS as well. Have you resolved (hehe) these issues? Is it running for you?

Not really, but I didn’t tried recently. I can just say that:

  • steam-run “hides” (at least for me) the opencl interface, so when I use steam-run I can go only until a message saying something like “you don’t have opencl, impossible to run resolve”
  • buildFhsEnv does not have this issue, but I had another error at runtime I think about QT… I’m also curious to see if adding appImage-run as a dependency could help, but not sure at all I’m quite new to this. If you feel advanturous, I think I stopped here:
{ stdenv, buildFHSUserEnv, writeShellScriptBin, unzip, libarchive, ocl-icd, gnome3, writeScriptBin, xkeyboard_config }:
let
  davinci_binaries = stdenv.mkDerivation rec {
    version = "16.2.7";
    name = "DaVinci_Resolve_${version}";
  
    ## To speed-up debug, I'll use a manually unpack folder. It will copy only once in /nix that way
    # src = ./DaVinci_Resolve_16.2.7_Linux/DaVinci_Resolve_16.2.7_Linux;
    # unpackPhase = ''
    # '';
    ##
    src = ./DaVinci_Resolve_16.2.7_Linux.zip;
  
    unpackPhase = ''
      unzip $src
      # Folder to extract the .run ISO image to
      mkdir extracted
      # bsdtar comes from libarchive
      bsdtar x -f DaVinci_Resolve_${version}_Linux.run -C extracted
      export sourceRoot=extracted
    '';
  
    passAsFile = [ "steamWrapper" ];
  
    nativeBuildInputs = [
      unzip
      libarchive # to get bsdtar
    ];
  
    # Otherwise it tries automatically to path the binaries, but we don't care, we use steam-run:
    dontFixup = true;
    
    installPhase= ''
      mkdir -p $out/{bin,opt}
      cp -r * $out/opt/
    '';
  
    meta = {
      description = "DaVinci Resolve";
      homepage = https://;
      license = stdenv.lib.licenses.unfree;
      maintainers = [ stdenv.lib.maintainers.tobiasBora ];
      platforms = stdenv.lib.platforms.linux;
    };
  };
  # xkbcommon: ERROR: failed to add default include path /usr/share/X11/xkb
  # Qt: Failed to create XKB context!
  # Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, add ':' as separator to provide several search paths and/or make sure that XKB configuration data directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ .
  # Inspired by https://github.com/NixOS/nixpkgs/blob/7ebcaec02f2f250220db63ffc87d69663ffdaa86/pkgs/applications/editors/android-studio/common.nix
  davinci_fhsWrapper = writeShellScriptBin "davinci_resolve" ''
    export QT_XKB_CONFIG_ROOT "${xkeyboard_config}/share/X11/xkb"
    strace ${davinci_binaries}/opt/bin/resolve
  '';  
  buildFHS_with_lib = buildFHSUserEnv {
    name="fhs";
    targetPkgs=pkgs:[
      davinci_fhsWrapper
    ];
    multiPkgs=pkgs: [
      pkgs.ocl-icd
      pkgs.gnome3.librsvg
      pkgs.bash
      pkgs.clinfo
      pkgs.libGLU
      pkgs.libGL
      pkgs.xorg.libXxf86vm
      pkgs.xorg.libXext
      pkgs.xorg.libSM
      pkgs.xorg.libICE
      pkgs.xorg.libX11
      pkgs.xorg.libxcb
      pkgs.xorg.libXcomposite
      pkgs.xorg.libXext
      pkgs.xorg.libXi
      pkgs.xorg.libXrender
      pkgs.xorg.libXtst
      pkgs.xorg.libXdamage
      pkgs.glib
      pkgs.libxml2
      pkgs.libtool
      pkgs.alsaLib
      pkgs.expat
      pkgs.freetype
      pkgs.xkeyboard_config
    ];
    runScript="davinci_resolve";
  };
in
buildFHS_with_lib

I think libcuda.so.1 is provided by linuxPackages.nvidia_x11, have you tried using that?

Packages shouldn’t really directly link against linuxPackages.nvidia_x11 (or any other linuxPackages.*) since this would hard-code a specific Kernel version and break the package for other kernels.
Usually when building packages using cudatoolkit the build time linker will link to the empty libcuda stub shipped with cudatoolkit. We would then add the addOpenGLRunpath hook that the OP described and the libcuda should remain unresolved in the build result. It would only find the correct library when the /run/opengl-driver/lib is populated with the nvidia_x11 (which needs to match your kernel)

I think the problem usually doesn’t occur when building but surfaces here because we also use autoPatchelfHook which errors on missing libcuda.

I guess the autoPatchelfIgnoreMissingDeps is a good idea. I don’t know if there is a way to only ignore specific packages.

1 Like

Hi @tobiasBora I did some modifications in your derivation and I was able to make Davinci Resolve works. See:

{ stdenv, buildFHSUserEnv, writeShellScriptBin, unzip, libarchive, ocl-icd, gnome3, writeScriptBin, xkeyboard_config,  qtbase, appimageTools}:

let
  davinci_binaries = stdenv.mkDerivation rec {
    version = "16.2.8";
    pname = "davinci_resolve";

    ## To speed-up debug, I'll use a manually unpack folder. It will copy only once in /nix that way
    # src = ./DaVinci_Resolve_16.2.7_Linux/DaVinci_Resolve_16.2.7_Linux;
    # unpackPhase = ''
    # '';
    ##
    src = ./DaVinci_Resolve_16.2.8_Linux.zip;

    unpackPhase = ''
      unzip $src
      # Folder to extract the .run ISO image to
      mkdir extracted
      # bsdtar comes from libarchive
      bsdtar x -f DaVinci_Resolve_${version}_Linux.run -C extracted
      export sourceRoot=extracted
    '';

    passAsFile = [ "steamWrapper" ];

    nativeBuildInputs = [
      unzip
      libarchive # to get bsdtar
    ];

    # Otherwise it tries automatically to path the binaries, but we don't care, we use steam-run:
    dontFixup = true;

    installPhase = ''
      mkdir -p $out/{bin,opt}
      cp -r * $out/opt/
    '';

    meta = {
      description = "DaVinci Resolve";
      homepage = https://;
      license = stdenv.lib.licenses.unfree;
      maintainers = [ stdenv.lib.maintainers.tobiasBora ];
      platforms = stdenv.lib.platforms.linux;
    };
  };
  # xkbcommon: ERROR: failed to add default include path /usr/share/X11/xkb
  # Qt: Failed to create XKB context!
  # Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, add ':' as separator to provide several search paths and/or make sure that XKB configuration data directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ .
  # Inspired by https://github.com/NixOS/nixpkgs/blob/7ebcaec02f2f250220db63ffc87d69663ffdaa86/pkgs/applications/editors/android-studio/common.nix
  davinci_fhsWrapper = writeShellScriptBin "davinci_resolve" ''
    export QT_XKB_CONFIG_ROOT "${xkeyboard_config}/share/X11/xkb"
    ${davinci_binaries}/opt/bin/resolve
  '';

  buildFHS_with_lib = buildFHSUserEnv {
    name = "fhs";

    targetPkgs = pkgs: [
      davinci_fhsWrapper
    ];

    multiPkgs = p: (appimageTools.defaultFhsEnvArgs.multiPkgs p) ++ [
      p.ocl-icd
      p.clinfo
      qtbase
      p.ffmpeg
      p.libxml2
      p.libuuid
    ];
    runScript = "davinci_resolve";
  };
in
buildFHS_with_lib

The main problem is it importing my medias as sound only :frowning:

Updated, now it’s downloading the installer:

# Based on https://github.com/egasimus/nur-packages/blob/b892a8769ba7f1391c725fd76ccd47c7e1a7a794/davinci-resolve/default.nix
# downloader based on https://github.com/NixOS/nixpkgs/issues/94032#issuecomment-733637809
# which is itself based on https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=davinci-resolve
# also based on https://discourse.nixos.org/t/fixup-phase-cant-find-libcuda-so-1-build-abort-how-to-provide-dummy-libcuda-so-1/9541/3?u=brogos

{ appimageTools
, autoPatchelfHook
, bash
, buildFHSUserEnv
, callPackage
, dpkg
, e2fsprogs
, fakeroot
, fetchurl
, fuse
, glib
, glibc
, gnome3
, kmod
, lib
, libarchive
, ocl-icd
, pkgs
, qtbase
, runCommand
, stdenv
, strace
, targetPlatform
, unzip
, utillinux
, vmTools
, writeScriptBin
, writeShellScriptBin
, xkeyboard_config
, zlib
}:
let
  rpath = stdenv.lib.makeLibraryPath [ fuse glib glibc zlib ];

  pname = "davinci-resolve";
  version = "16.2.8";

  installer =
    let
      name = "${pname}-${version}-src";
      context = rec {
        outputHashMode = "recursive";
        outputHashAlgo = "sha256";
        outputHash = "jNBFgg52xkOBYO5XF2p8Fr0BGW02jkqj12OireVCZYE=";
        impureEnvVars = lib.fetchers.proxyImpureEnvVars;
        nativeBuildInputs = with pkgs; [ curl gnused unzip ];

        SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
        DOWNLOADID = "3dc96708d3e841c4a19f9ca17aca2e6b";
        REFERID = "0221c32a73844413bc0b1ec35686a4d3";
        SITEURL = "https://www.blackmagicdesign.com/api/register/us/download/${DOWNLOADID}";
        USERAGENT = builtins.concatStringsSep " " [
          "User-Agent: Mozilla/5.0 (X11; Linux ${targetPlatform.system})"
          "AppleWebKit/537.36 (KHTML, like Gecko)"
          "Chrome/77.0.3865.75"
          "Safari/537.36"
        ];
        REQJSON = ''{
         "firstname": "Arch",
         "lastname": "Linux",
         "email": "someone@archlinux.org",
         "phone": "202-555-0194",
         "country": "us",
         "state": "New York",
         "city": "AUR",
         "product": "DaVinci Resolve"
      }'';
      };
    in
    runCommand name context ''
      REQJSON="$(  printf '%s' "$REQJSON"   | sed 's/[[:space:]]\+/ /g')"
      USERAGENT="$(printf '%s' "$USERAGENT" | sed 's/[[:space:]]\+/ /g')"
      RESOLVEURL=$(curl \
           -s \
           -H 'Host: www.blackmagicdesign.com' \
           -H 'Accept: application/json, text/plain, */*' \
           -H 'Origin: https://www.blackmagicdesign.com' \
           -H "$USERAGENT" \
           -H 'Content-Type: application/json;charset=UTF-8' \
           -H "Referer: https://www.blackmagicdesign.com/support/download/$REFERID/Linux" \
           -H 'Accept-Encoding: gzip, deflate, br' \
           -H 'Accept-Language: en-US,en;q=0.9' \
           -H 'Authority: www.blackmagicdesign.com' \
           -H 'Cookie: _ga=GA1.2.1849503966.1518103294; _gid=GA1.2.953840595.1518103294' \
           --data-ascii "$REQJSON" \
           --compressed \
           "$SITEURL")
      curl --retry 3 --retry-delay 3 \
           -H "Host: sw.blackmagicdesign.com" \
           -H "Upgrade-Insecure-Requests: 1" \
           -H "$USERAGENT" \
           -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" \
           -H "Accept-Language: en-US,en;q=0.9" \
           --compressed \
           "$RESOLVEURL" \
           > resolve.zip
      mkdir -p $out
      unzip resolve.zip -d $out
      rm resolve.zip
    '';

  unpacked =
    let
      name = "${pname}-${version}-unpacked";
      context = {
        nativeBuildInputs = [ bash fakeroot dpkg strace libarchive ];
      };
      script = ''
        mkdir -p $out
        ls -l
        bsdtar x -f ${installer}/DaVinci_Resolve_${version}_Linux.run -C $out
        echo $out
        echo $PWD
      '';
    in
    runCommand name context script;

  davinci_binaries = stdenv.mkDerivation rec {
    version = "16.2.8";
    pname = "davinci_resolve";

    src = unpacked;

    passAsFile = [ "steamWrapper" ];

    nativeBuildInputs = [
      unzip
      libarchive # to get bsdtar
    ];

    # Otherwise it tries automatically to path the binaries, but we don't care, we use steam-run:
    dontFixup = true;

    installPhase = ''
      mkdir -p $out/{bin,opt}
      cp -r $src/* $out/opt/
    '';

    meta = {
      description = "DaVinci Resolve";
      homepage = https://;
      license = stdenv.lib.licenses.unfree;
      maintainers = [ stdenv.lib.maintainers.tobiasBora ];
      platforms = stdenv.lib.platforms.linux;
    };
  };
  # xkbcommon: ERROR: failed to add default include path /usr/share/X11/xkb
  # Qt: Failed to create XKB context!
  # Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, add ':' as separator to provide several search paths and/or make sure that XKB configuration data directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ .
  # Inspired by https://github.com/NixOS/nixpkgs/blob/7ebcaec02f2f250220db63ffc87d69663ffdaa86/pkgs/applications/editors/android-studio/common.nix
  davinci_fhsWrapper = writeShellScriptBin "davinci_resolve" ''
    export QT_XKB_CONFIG_ROOT "${xkeyboard_config}/share/X11/xkb"
    ${davinci_binaries}/opt/bin/resolve
  '';

  buildFHS_with_lib = buildFHSUserEnv {
    name = "fhs";

    targetPkgs = pkgs: [
      davinci_fhsWrapper
    ];

    multiPkgs = p: (appimageTools.defaultFhsEnvArgs.multiPkgs p) ++ [
      p.ocl-icd
      p.clinfo
      qtbase
      p.ffmpeg
      p.libxml2
      p.libuuid
    ];
    runScript = "davinci_resolve";
  };
in
buildFHS_with_lib

Cool, thanks! This relies on buildfhsenv so the initial error is still there, but it’s a good news buildfhsenv works! I’ll try it later, but my computer do not have any NVIDIA GPU (only intel opencl), so I guess I won’t be able to use it. Also, it’s funny, I saw that opencl in nixos is detected as “CPU”, while if I run ubuntu in a podman container, it detects the opencl as a “GPU” hardware… But it’s another problem I guess.

Have you solved your issues with medias as sound only? Does it mean that you can’t import any video? (which is a bit pointless…)

I haven’t fixed this problem. Other problem is Davinci uses Alsa and it tries to manage my sound card, but my sound card is already managed by Pipewire… Maybe that’s the cause of my problem with importing everything as sound.

With the update of Pipewire (0.3.23) Davinci Resolve is importing my medias as video correctly.

1 Like