Python: Difference between revisions

Klinger (talk | contribs)
Ad2tba (talk | contribs)
Running compiled libraries: provide simple alternative using symlinkJoin and wrapProgram
Line 106: Line 106:
* Create a FHS user env with <code>buildFHSUserEnv</code>.
* Create a FHS user env with <code>buildFHSUserEnv</code>.
* Setup <code>nix-ld</code><ref name=":0">https://github.com/Mic92/nix-ld</ref> in your NixOS configuration.
* Setup <code>nix-ld</code><ref name=":0">https://github.com/Mic92/nix-ld</ref> in your NixOS configuration.
* Prefix library paths using wrapProgram utility.


==== Setup nix-ld ====
==== Setup nix-ld ====
nix-ld<ref name=":0" /> allow you to <code>Run unpatched dynamic binaries on NixOS.</code>
nix-ld<ref name=":0" /> allow you to run unpatched dynamic binaries on NixOS.


The following configuration automatically fix the dependencies :<syntaxhighlight lang="nixos" line="1">
The following configuration automatically fix the dependencies:<syntaxhighlight lang="nixos" line="1">
let
let
   python = pkgs.python311;
   python = pkgs.python311;
  # We currently take all libraries from systemd and nix as the default
   # https://github.com/NixOS/nixpkgs/blob/c339c066b893e5683830ba870b1ccd3bbea88ece/nixos/modules/programs/nix-ld.nix#L44
   # https://github.com/NixOS/nixpkgs/blob/c339c066b893e5683830ba870b1ccd3bbea88ece/nixos/modules/programs/nix-ld.nix#L44
  # > We currently take all libraries from systemd and nix as the default.
   pythonldlibpath = lib.makeLibraryPath (with pkgs; [
   pythonldlibpath = lib.makeLibraryPath (with pkgs; [
     zlib
     zlib
Line 178: Line 179:
After this step, you should be able to install compiled libraries using venv, poetry, conda or other packages managers...
After this step, you should be able to install compiled libraries using venv, poetry, conda or other packages managers...


==== Prefix library paths using wrapProgram ====
wrapProgram is a part of the makeWrapper build input<ref>https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/make-wrapper.sh</ref>. By combining it with the symlinkJoin, we can create a wrapper around the Python executable that will always set the required library paths. It’s worth noting that, for this solution to be compatible with Darwin, we need to use a different wrap prefix, as shown in the example below.<syntaxhighlight lang="nixos" line="1">
let
  # We currently take all libraries from systemd and nix as the default
  # https://github.com/NixOS/nixpkgs/blob/c339c066b893e5683830ba870b1ccd3bbea88ece/nixos/modules/programs/nix-ld.nix#L44
  pythonldlibpath = lib.makeLibraryPath (with pkgs; [
    zlib
    zstd
    stdenv.cc.cc
    curl
    openssl
    attr
    libssh
    bzip2
    libxml2
    acl
    libsodium
    util-linux
    xz
    systemd
  ]);
  # Darwin requires a different library path prefix
  wrapPrefix = if (!pkgs.stdenv.isDarwin) then "LD_LIBRARY_PATH" else "DYLD_LIBRARY_PATH";
  patchedpython = (pkgs.symlinkJoin {
    name = "python";
    paths = [ pkgs.python312 ];
    buildInputs = [ pkgs.makeWrapper ];
    postBuild = ''
      wrapProgram "$out/bin/python3.12" --prefix ${wrapPrefix} : "${pythonldlibpath}"
    '';
  });
in
{
  environment.systemPackages = with pkgs; [
    patchedpython
  ];
}
</syntaxhighlight>
=== Using <code>venv</code> ===
=== Using <code>venv</code> ===