Nixpkgs: Julia Pkgs in NixOS

Created on 23 Nov 2016  Â·  70Comments  Â·  Source: NixOS/nixpkgs

Issue description

It would be nice to have julia pkgs easily installable the way we can install them in python on other languages

The packages resides in a git project (https://github.com/JuliaLang/METADATA.jl), every package has it's (git) url, every version hashes and dependencies

The variable JULIA_PKGDIR defines a folder in which packages get installed, I think we can symlink from the store to this folder (not sure if it needs to be ro/rw)

package (new)

Most helpful comment

what is the current status of packaging Julia with Nix?

All 70 comments

/cc maintainer @7c6f434c.

Is Julia package manager behaviour more stable than the language features now? I mean, Pkg is already quite fine, and for example opam2nix is harder to use for an outsider (me) than making opam work. So I am afraid that a simple approach to redoing Julia's Pkg will be hard to use and immediately out of date, if I do it myself… Maybe there is a sane plan, though — it's just my lack of clue.

As soon as they document their environment variables I'm up for having a further look at this.

I'd like an interface to the native package manager as well.

@FRidh: cf. pull request JuliaLang/julia#20162

The Julia package manager is due for a rewrite, any integration you do with it now would have to be redone.

Yesterday I had a short look at it.
https://github.com/FRidh/nixpkgs/tree/julia

Implemented thus far is

  • a function for building a Julia package. It will definitely need some more work, but the basic thing is there.
  • fix-point combinator based package set
  • buildEnv, withPackages. We might want to use JULIA_HOME for this.
  • some other helper functions.
  • a script to take the official packages index and create JSON.
  • uses JULIA_LOAD_PATH to build up a path with Julia modules.

To do:

  • have a function for building official packages
  • parse the data in the JSON further so we can extract platform-dependent dependencies and version constraints.
  • decide where packages should live. The current julia.site seems to me like the proper location
  • decide what to do with precompiled modules. The first time you import a module with Julia it precompiles it (like Python's .pyc). Ideally we would put this in the same derivation as the actual module code.

What's most important I think though is to decide on how we expect it to work with impure paths. Do we want to be able to also install packages using Pkg.add() or not? And if so, where should it put it?

Note the code is quite a mess at this point, and I just dumped everything in one commit. I won't have time to look at this for at least another week, and I might not even continue since I don't use Julia myself.

Hi, how is it going? Anybody has hints?

I know it may be a wrong place to ask, but for this day, is there a way to at least install Julia packages (IJulia.jl, Plots.jl, PyPlot.jl, DifferentialEquations.jl, Sundials.jl and so on)? It is the only thing which keeps me from trying NixOs one more time (last time all was good except I could not make Julia with packages work, it was a year ago)

maybe you can comment here
https://www.reddit.com/r/NixOS/comments/6btseq/nixos_and_julia/

Sorry for the wrong place again, but I cannot find people who would share their experience with Julia under NixOs

@AlexanderKoshkarov no, there is no "finished" implementation yet for installing Julia packages with Nix. The closest there is right now is, as far as I know, the branch I mentioned in https://github.com/NixOS/nixpkgs/issues/20649#issuecomment-296804784.

I'm using it, you just need to figure out the dependency of a package. I create a nix-shell env with Julia and the dependency the package needs, and set the Julia pkg dir to a subfolder of the project directory. I can upload an example tomorrow, not at my desk right now

Il 15 giugno 2017 18:19:26 CEST, AlexanderKoshkarov notifications@github.com ha scritto:

I know it may be a wrong place to ask, but for this day, is there a way
to at least install Julia packages (IJulia.jl, Plots.jl, PyPlot.jl,
DifferentialEquations.jl, Sundials.jl and so on)? It is the only thing
which keeps me from trying NixOs one more time (last time all was good
except I could not make Julia with packages work, it was a year ago)

maybe you can comment here
https://www.reddit.com/r/NixOS/comments/6btseq/nixos_and_julia/

Sorry for the wrong place again, but I cannot find people who would
share their experience with Julia under NixOs

--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
https://github.com/NixOS/nixpkgs/issues/20649#issuecomment-308792496

--
Inviato dal mio dispositivo Android con K-9 Mail. Perdonate la brevità.

@nico202, Thanks for the assurance that such people exist and it is possible! Yes, the example would be awesome, I already forgot a lot about nix, so it would be very helpful.

@AlexanderKoshkarov like @FRidh said, my solution is not that nix-y; nonetheless, if you are on NixOS and you want to use julia, this is the only way I found to install packages.

Here's a gist with an example
https://gist.github.com/nico202/9377b3b378eab950dc05566e733ea320
The hard part is figuring out what dependencies are needed by the packages you want to install, but I successfully installed GTK.jl, Plots.jl and others.
To figure out the dependencies I just enter the env, try to install the package, see any error message, if any just delete the .julia_pkgs dir (just to be sure to have a clean env), add the dependency and start over.
For example, Requests neets MBedTLS, which requires mbedtls and Libz, so in my LD_LIBRARY_PATH for projects needing Requests.jl I add ${pkgs.zlib}/lib:${pkgs.mbedtls}/lib

How does current Julia-NixOS-users deal with hard-coded references to /sbin/ldconfig when attempting to use Julia packages? E.g. try a Pkg.add("RCall") followed by using RCall to see what I mean.

Greping for ldconfig in a ~/.julia folder with some packages in it shows that this is a recurring pattern.

@lesscodeless see my gist in the previous comment. Just add to ld library path ${R}/lib/

Many Julia packages use BinDeps.jl in their deps/build.jl. BinDeps often calls yum, apt, pacman, or homebrew to install dependencies. How to manage this in Nix might be another concern.

BinDeps calls the package manager only if it's not able to find a suitable dependecy already installed. So we don't need to manage it

BinDeps calls the package manager only if it's not able to find a suitable dependecy already installed. So we don't need to manage it

It may be good to "disable" it anyway for non-sandboxed builds.

I see. How does BinDeps identify whether a library is available or not?

In my case on Darwin, I had to delete all dependency to Homebrew.jl to install a package using BinDeps. Here is an example: https://gist.github.com/mnacamura/ce3b8e6640d54158df1863cb54e94ff8

How does BinDeps identify whether a library is available or not?

Setting LD_LIBRARY_PATH works

Setting LD_LIBRARY_PATH works

Thanks for the answer. Even if I set LD_LIBRARY_PATH and delete a line @osx Homebrew in REQUIRE, Pkg.resolve() starts installing Homebrew.jl. Any suggestion?

Pkg.resolve() starts installing Homebrew.jl. Any suggestion?

Oh I misunderstood. deps/build.jl contains using Homebrew so that the build just failed.

Based on @FRidh's work (https://github.com/NixOS/nixpkgs/issues/20649#issuecomment-296804784, thanks @FRidh), I implemented this more: https://github.com/mnacamura/nixpkgs/tree/julia-modules. I'm still puzzled how to treat Homebrew on Darwin (https://github.com/mnacamura/nixpkgs/commit/e78f629837f2c3cc94d213abb72ac65db09587fc).

@mnacamura Wow, thanks! Some question:

  • Are you experiencing #34135?
  • Next julia will have Pkg3: in their juliacon 2017 talk they said part of the idea was taken from nixos, @tkelman do you know something more?

However on my config i'm using the following packages, with corresponding ld library path

# IJulia.jl
ijulialdpath = "${pkgs.mbedtls}/lib:${pkgs.zeromq3}/lib";

 # ImageMagick.jl
imagemagickldpath = "${pkgs.imagemagickBig}/lib";

# HDF5.jl
hdf5ldpath = "${pkgs.hdf5}/lib";

# Cairo.jl
cairojlldpath = "${pkgs.cairo}/lib:${pkgs.gettext}/lib:${pkgs.pango.out}/lib:${pkgs.glib.out}/lib";

# Gtk.jl
gtkjlldpath = "${pkgs.gtk3}/lib:${pkgs.gdk_pixbuf}/lib";
  # GZip.jl # Required by DataFrames.jl
  gzipldpath = "${pkgs.gzip}/lib:${pkgs.zlib}/lib";

# GR.jl # Runs even without Xrender and Xext, but cannot save files, so those are required
grldpath = "${pkgs.xorg.libXt}/lib:${pkgs.xorg.libX11}/lib:${pkgs.xorg.libXrender}/lib:${pkgs.xorg.libXext}/lib";
glfwldpath = "${pkgs.glfw}/lib";
freetypeldpath = "${pkgs.freetype}/lib";
glvisualizeldpath = "${glfwldpath}:${freetypeldpath}";

If you are adding the dependencies manually, this might help

edit: added GZip.jl

Are you experiencing #34135?

Hmm... I've never seen that segfault.

If you are adding the dependencies manually, this might help

Thank you, it is helpful. Currently ~120 packages seem to use BinDeps. Adding their native dependencies manually is tedious. I wish Pkg3 could provide information of native dependencies in a proper format...

So, what's the difference of Pkg3 from the current Pkg (Pkg2?)?

  1. Ok the fact that you have not seen the segfault is interesting, are you on linux 64bit? Are you using julia 0.6.2? does it work (non-segafualt) even in a pure nix-shell?
    The shortest way to reproduce is:
    nix-shell --pure -p julia --run 'julia -e "error()"'

could you try?

  1. dependencies should be defined in a toml file like here. Every package has it's own unique id (if it happens that multiple packages have the same name, it's not a problem, and renaming a package does not change much since the uuid stays the same). Also if I understood/remember well, the LOAD_PATH variable is changed, and it's replaced to a data structure containing multiple paths for system-level packages and official julia pkgs, user packages...
    Pinning a version should be easier (ie. add JSON @0.10), tarball are now preferred to git clone because of space/speed, and I even think better precompilation

edit: notes: I'm not involved in the dev of Pkg3, I just saw a youtube video weeks ago, so if anybody knows better if it will help the integration with nixpgks it would be useful to know :D

% nix-shell --pure -p julia --run 'julia -e "error()"'
Stacktrace:
 [1] error() at ./error.jl:30

I use Julia 0.6.2 on x86_64-darwin.

2.

Many important changes... I'm looking forward to seeing its release, and going to wait and see.

Adding their native dependencies manually is tedious.

Yep, it is, but it is manageable, at least as long as we have say one version per package.

dependencies should be defined in a toml file like here. Every package has it's own unique id (if it happens that multiple packages have the same name, it's not a problem, and renaming a package does not change much since the uuid stays the same)

That's interesting. So, that means we can translate every package and every version to a Nix expression of which the key is the uuid, and the value the derivation. Expressions can then refer to each other via the uuid. Furthermore, we could have a mapping of name to uuid corresponding to the latest or stable release. That basically allows including every package at every version in Nixpkgs, although it becomes unmanageable because of the earlier comment regarding native dependencies. Also, how will upstream deal with security issues? Using uuid to refer to dependencies is the same as using git submodules, or Python's pip freeze which should absolutely not be done for libraries.

they said part of the idea was taken from nixos

Nix uses a hash for the outputs. Pkg3 uses them for the inputs, for which Nix uses variables.

Also, how will upstream deal with security issues? Using uuid to refer to dependencies is the same as using git submodules, or Python's pip freeze which should absolutely not be done for libraries.

Sorry I can't follow you here. uuids are for package _names_, not package versions, so you can upgrade.

(The youtube video I was referring to is this, this is a slide with the feature highlight 2018-02-20-163827_794x407_scrot)

they said part of the idea was taken from nixos

Nix uses a hash for the outputs. Pkg3 uses them for the inputs, for which Nix uses variables.

They say this at 7:15. I think they say this just because once a package is installed is never touched again, not sure if there's anything more than this.

edit: maybe we can get in touch with @KristofferC

@nico202 thanks for the clarification. That changes things :)

In Pkg3 package versions are installed at ~/.julia/packages/$name/$slug where name is the name of the package slug is derived from (uuid, git-tree-sha1) where uuid identifies the package and git-tree-sha1 is the source tree that gets installed. Once this is installed and built (we'd like to get rid of the build step in the future so that it's just a pure source checkout), it is never touched again until it is no longer used anywhere and is removed by package garbage collection. Pkg3 is going to be merged into Julia's main repo as a stdlib package this week and there will be official documentation to follow which should help considerably.

I suspect that this approach should work well with Nix, but I'm not sure. My guess is that a bit less messing with symlinks may be required for Julia with Pkg3 than other systems, but maybe not.

Thanks @StefanKarpinski ! Does the garbage collector runs automatically/is it possible to prevent it trying to delete a read-only location (as the /nix/store)? Also, what about native dependencies? Will BinDeps.jl still be the way to go, or will they be declared in a .toml like julia ones?

@FRidh if we just replace ~/.julia/packages/ to /nix/store/derivation during the install phase. If BinDeps will still be used, maybe a script that advice the library_dependency function might do the dirty work for us

There's going to be a transition period where the old BinDeps/build-in-repo style is supported but we want to move fully to a separate binary dependency layer which, if BinDeps2 pans out the way we hope, will just involve downloading pre-built platform-specific shared libraries and putting them in the right location. In short: BinDeps for now but declared in .toml files in the future.

The package garbage collector is still a bit experimental – it works but Pkg3 hasn't really been widely used enough to know how everything should work. I suspect that the default should be that it is automatically invoked periodically when people are doing package operations. But that should be configurable and it is certainly reasonable that it wouldn't try to clean up read-only locations.

To have ImageMagick.jl working,the function preinit_libversion(lib, handle) must be replaced with something like

function preinit_libversion(lib, handle)
    return VersionNumber(6, 0, 5)
end

@mnacamura if you are interested in getting GR.jl working, with the latest update now it depends on an executable (gksqt). To get it working I had to patch it with patchelf and have qt in the ld library path (${pkgs.qt4.out}/lib). I tried building it (https://github.com/jheinen/gr) but I'm having problems

Just for future reference, it might be interesting to look at https://github.com/JuliaLang/PackageCompiler.jl and do something like what it does in nixos. I tried it and (for packages it is working with) is incredibly fast. If we precompile everything in the derivation, with slower nixos-rebuild / nix-env loading we have a super fast julia loading time. If anybody has experience with julia precompilation and can comment about it, it would be great to have an idea on the feasibility of the thing

@mnacamura Hi, if you are interested I compiled julia 0.7-alpha, here's the PR: https://github.com/NixOS/nixpkgs/pull/41499

Next step would be to port your code to Pkg3 :)

@mnacamura rebased your julia-module branch on top of my julia07 (here), will try to compile and try to support it

@nico202 Sorry for not responding. According to this, Pkg3 is gathering metadata of all packages in https://github.com/JuliaRegistries/Uncurated?

@mnacamura Yes! They provide julia dependencies there, there's still not yet a common way to define binary dependencies for what I know (they should be moving to BinaryBuilder.jl/BinDeps2.jl). I'll try to port your script to Uncurated registry this evening if I have time. I think trying to be compatible with both 0.6 and 0.7 simultaneously is not worth the effort, what do you think?

@nico202 I agree. Supporting only Pkg3 would be good enough.

@mnacamura my level of nix magic is too low, help welcomed :)

I'm curious about how this would ideally work. When one installs a package, do they do so via Pkg3 or via nix? It sounds like the approach discussed above is to manually install and compile all dependencies via nix. Is this the approach taken with python packages? Is there perhaps a solution that better leverages the existing language-specific package manager?

In general, can anyone give a description of how language-specific package managers can be handled with a declarative os package manager? Is Julia's Pkg3 better fitted to a declarative os PM than other language-specific PMs?

I'm just learning about both Nix and Pkg3, so any recommended reading would be appreciated.

Thanks!
Oliver

I think with unlimited tooling we would have an autoconverted package database usable as a set of Nix packages, which could be requested in nix-shell or used in juliaWithPackages

Now that julia 1.0 is in the repository and Pkg3 is working well, I think it's time to have this issue solved! @mnacamura do you have a wip or something to start on?

(triage) close.

@tomberek has the issue been solved?

Just found this issue and it's the best source of knowledge on nixos + Julia I've found so far. @nico202 do you by chance have a working solution for Julia 1.01? This approach for conda seems relevant

Edit: as a temporary solution, I enabled docker and use https://hub.docker.com/r/jupyter/datascience-notebook/

@tomberek why was this closed? Seems like things were just getting good :)

@thomasjm If there's progress, keep open.

As a quick prototype, I made a julia FHS and validated that the (manually downloaded) binaries at https://julialang.org/downloads/ work just fine, and succeed in installing packages with Pkg3. Still learning how to package with nix.

I think one interesting approach is to use nix to manage the ~/.julia/environments/v1.0/Manifest.toml file. This contains entries like:

[[JSON]]
deps = ["Dates", "Distributed", "Mmap", "Sockets", "Test", "Unicode"]
git-tree-sha1 = "fec8e4d433072731466d37ed0061b3ba7f70eeb9"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.19.0"

which is very nix-like in spirit. Since Julia does JIT compiling and using Pkg during an interactive session is convenient, I think we want to keep language packages in ~/.julia. Is there a way to make a nix package that is based on a FHS?

Do we need to install into ~/.julia just for the JIT cache? Maybe we could negotiate with upstream to have a JIT cache in ~/.julia for code from non-writeable locations…

If I'm not wrong, when first installing the package it get precompiled to the .julia/compiled/v*/[hash?].ji file that is immutable.

ls ~/.julia/compiled/v1.0/*                                                   ~/memories/inbox 
/home/IITaudio/.julia/compiled/v1.0/AccurateArithmetic:                                         
Z6zAA.ji                                                                                        

/home/IITaudio/.julia/compiled/v1.0/Arpack:                                                     
X5VZL.ji                                                                                        

/home/IITaudio/.julia/compiled/v1.0/Arrow:
QnF3w.ji

/home/IITaudio/.julia/compiled/v1.0/AssetRegistry:
2sUPq.ji

/home/IITaudio/.julia/compiled/v1.0/BenchmarkTools:
ZXPQo.ji

/home/IITaudio/.julia/compiled/v1.0/BinaryProvider:
ek6VZ.ji

/home/IITaudio/.julia/compiled/v1.0/BinDeps:
iBhbp.ji

We would just need to install them with nix, call julia to precompile them, (check the output is reproducible) and add the path to DEPOT_PATH

@nico202 I don’t believe that precompilation can always be done, and sometimes needs to be changed based on the code being generated. See this issue for example
https://github.com/JuliaLang/julia/issues/26094 that uses remote references that could change between sessions

Edit: moreover precompilation does not appear to be deterministic, further complicating the DEPOT-PATH approach
https://github.com/JuliaLang/julia/issues/25900

@tbenst: well in theory there's __init__() and __precompile__(false) for packages where precompilation cannot happen. See https://docs.julialang.org/en/v1/manual/modules/index.html#Module-initialization-and-precompilation-1

About the non-determinism: that seems to be a problem they need to solve, not one we need to workaround

@nico202 thx for the ref. In these cases it seems we have no other option than to use a mutable folder like ~/.julia?

Re: non-determinsim, I agree it's a julia problem, and while I'd love to see an idiomatic nix solution, it seems like for the time being we have to either compromise on 1) using git sha instead of binary sha for nix store or 2) use mutable directory

any progress on this?

I would love to build clean multi-language projects with R Python and Julia as a starter project to get into nix a bit more
it seems this is currently falling short because of julia's non-deterministic build

The closest I've gotten to getting the Julia ecosystem working on NixOS is the following. Unfortunately, while I can get CUDA working, CUDNN still does not, so not very useful for ML packages like CuArrays or Flux.

{ pkgs ? import <nixpkgs> {}}:

let
jupyterPort = pkgs.config.jupyterPort;
fhs = pkgs.buildFHSUserEnv {
  name = "julia-fhs";
  targetPkgs = pkgs: with pkgs;
    [
      git
      gitRepo
      gnupg
      autoconf
      curl
      procps
      gnumake
      utillinux
      m4
      gperf
      unzip
      libGLU_combined
      xorg.libXi xorg.libXmu freeglut
      xorg.libXext xorg.libX11 xorg.libXv xorg.libXrandr zlib
      ncurses5
      stdenv.cc
      binutils

      # Nvidia note: may need to change cudnn to match cudatoolkit version
      cudatoolkit_10_0
      cudnn_cudatoolkit_10_0
      linuxPackages.nvidia_x11



      julia_11
      vim
      atom

      # Arpack.jl
      arpack
      gfortran.cc
      (pkgs.runCommand "openblas64_" {} ''
        mkdir -p "$out"/lib/
        ln -s ${openblasCompat}/lib/libopenblas.so "$out"/lib/libopenblas64_.so.0
      '')

      # IJulia.jl
      mbedtls
      zeromq3
      python3Packages.jupyterlab
      # ImageMagick.jl
      imagemagickBig
      # HDF5.jl
      hdf5
      # Cairo.jl
      cairo
      gettext
      pango.out
      glib.out
      # Gtk.jl
      gtk3
      gdk_pixbuf
      # GZip.jl # Required by DataFrames.jl
      gzip
      zlib
      # GR.jl # Runs even without Xrender and Xext, but cannot save files, so those are required
      xorg.libXt
      xorg.libX11
      xorg.libXrender
      xorg.libXext
      glfw
      freetype
    ];
  multiPkgs = pkgs: with pkgs; [ zlib ];
  runScript = "bash";
  profile = with pkgs; ''
    export CUDA_PATH=${pkgs.cudatoolkit_10_0}
    export CUDNN_PATH=${cudnn_cudatoolkit_10_0}
    export LD_LIBRARY_PATH="${glfw}/lib:${mesa}/lib:${freetype}/lib:${imagemagick}/lib:${portaudio}/lib:${libsndfile.out}/lib:${libxml2.out}/lib:${expat.out}/lib:${cairo.out}/lib:${pango.out}/lib:${gettext.out}/lib:${glib.out}/lib:${gtk3.out}/lib:${gdk_pixbuf.out}/lib:${cairo.out}:${tk.out}/lib:${tcl.out}/lib:${pkgs.sqlite.out}/lib:${pkgs.zlib}/lib:${linuxPackages.nvidia_x11}/lib:${cudatoolkit_10_0}/lib:${cudnn_cudatoolkit_10_0}/lib"
    export EXTRA_LDFLAGS="-L/lib -L${pkgs.linuxPackages.nvidia_x11}/lib"
    export EXTRA_CCFLAGS="-I/usr/include"
    '';
  };
  shellHook = ''
    TEMPDIR=$(mktemp -d -p /tmp)
    mkdir -p $TEMPDIR
    cp -r ${pkgs.python3Packages.jupyterlab}/share/jupyter/lab/* $TEMPDIR
    chmod -R 755 $TEMPDIR
    echo "$TEMPDIR is the app directory"

    # start jupyterlab
    jupyter lab --app-dir=$TEMPDIR --port=${jupyterPort} --no-browser
  '';

in pkgs.stdenv.mkDerivation {
  name = "julia-shell";
  nativeBuildInputs = [fhs];
  shellHook = "exec julia-fhs";
}

edit: revised 2019/05/13

@tbenst how do you deal with ldconfig -p calls? E.g. when compiling the Cairo package:

  Building Cairo ───→ `~/.julia/packages/Cairo/p68X8/deps/build.log`
┌ Error: Error building `Cairo`: 
│ /sbin/ldconfig: Can't open cache file /nix/store/xqs95fqkjb1kd102yjv5h5q57gcsafb3-glibc-2.27/etc/ld.so.cache
│ : No such file or directory
│ ERROR: LoadError: failed process: Process(`/sbin/ldconfig -p`, ProcessExited(1)) [1]
│ Stacktrace:
│  [1] error(::String, ::Base.Process, ::String, ::Int64, ::String) at ./error.jl:42
│  [2] pipeline_error at ./process.jl:785 [inlined]
│  [3] (::getfield(Base, Symbol("##512#513")){Base.Process})() at ./process.jl:620
│  [4] iterate(::Base.EachLine{Base.PipeEndpoint}, ::Nothing) at ./io.jl:880 (repeats 2 times)
│  [5] read_sonames() at /home/daniel/.julia/packages/BinDeps/ZEval/src/dependencies.jl:398
│  [6] lookup_soname at /home/daniel/.julia/packages/BinDeps/ZEval/src/dependencies.jl:431 [inlined]
│  [7] #_find_library#42(::Type, ::Function, ::BinDeps.LibraryDependency) at /home/daniel/.julia/packages/BinDeps/ZEval/src/dependencies.jl:708
│  [8] _find_library at /home/daniel/.julia/packages/BinDeps/ZEval/src/dependencies.jl:643 [inlined]
│  [9] #45 at ./none:0 [inlined]
│  [10] iterate at ./generator.jl:47 [inlined]
│  [11] collect(::Base.Generator{Array{BinDeps.LibraryDependency,1},getfield(BinDeps, Symbol("##45#46"))}) at ./array.jl:606
│  [12] satisfy!(::BinDeps.LibraryGroup, ::Array{DataType,1}) at /home/daniel/.julia/packages/BinDeps/ZEval/src/dependencies.jl:806
│  [13] satisfy!(::BinDeps.LibraryGroup) at /home/daniel/.julia/packages/BinDeps/ZEval/src/dependencies.jl:874
│  [14] top-level scope at /home/daniel/.julia/packages/BinDeps/ZEval/src/dependencies.jl:977
│  [15] include at ./boot.jl:326 [inlined]
│  [16] include_relative(::Module, ::String) at ./loading.jl:1038
│  [17] include(::Module, ::String) at ./sysimg.jl:29
│  [18] include(::String) at ./client.jl:403
│  [19] top-level scope at none:0
│ in expression starting at /home/daniel/.julia/packages/Cairo/p68X8/deps/build.jl:176
â”” @

@danieldk needed to add appropriate paths to LD_LIBRARY_PATH (per @nico202 https://gist.github.com/nico202/9377b3b378eab950dc05566e733ea320). I revised the comment above and now works with Cario

@tbenst No dice. LD_LIBRARY_PATH already contains /lib in the chroot, which has symlinks for all libraries, so all libraries should be visible. The problem on my machine (NixOS unstable) is that Julia calls ldconfig -p, which fails due to ld.so.cache not being available. I now have the following big hack to create ld.so.cache in the chroot, and building Julia packages works:

~~~nix
self: super: {

julia-fhs =
let
ldconfigWrapper = with super; stdenv.mkDerivation {
name = "ldconfig-env";

nativeBuildInputs = [ makeWrapper ];

phases = [ "installPhase" "fixupPhase" ];

installPhase = ''
  makeWrapper ${glibc.bin}/bin/ldconfig $out/sbin/ldconfig \
    --add-flags "-C /usr/ld.so.cache"
'';

};
in
super.buildFHSUserEnv {
name = "julia-fhs";

targetPkgs = pkgs: with pkgs; [
  ldconfigWrapper

  julia_11

  autoconf
  binutils
  coreutils
  gnumake
  m4
  pkgconfig
  stdenv.cc
  utillinux

  curl
  git

  cairo
  fontconfig
  freetype
  gettext
  glib
  libintl
  libpng
  libffi
  librsvg
  pango
  pixman
  zlib
];

extraBuildCommands = with super; ''
  # Cannot write to /etc?
  echo "$out/lib" > $out/usr/ld.so.conf
  ldconfig -f $out/usr/ld.so.conf -C $out/usr/ld.so.cache
'';

runScript = "julia";

};
}
~~~

@danieldk yes that comes from https://github.com/JuliaPackaging/BinDeps.jl/blob/382082a30de7186d6e27880807f6be353fcbd593/src/dependencies.jl#L398 which if I recall correctly only gets called if a .so is not found. I could reproduce your error before adding the LD_LIBARARY_PATH line, and verified that it could build afterwards. I’m also on unstable so would be surprised indeed if the code in https://github.com/NixOS/nixpkgs/issues/20649#issuecomment-484930950 doesn’t work for building Cairo.

In an case great to have your solution for ldconfig -p!

@danieldk, I was trying to understand your nice piece of code but I am just a nix/nixos beginner, so I don't know how to manage overlays in a step by step guide (I am yet learning derivations...). Could you kindly indicate where I could find examples to implement your overlay at /etc/nixos/configuration.nix level? Thanks in advance!!

@RCHG For adding the overlay you need to add function from snippet to nixpkgs.overlays (https://nixos.org/nixpkgs/manual/#chap-overlays). Example content of the configuration.nix:

{ config, pkgs, lib, ... }:

let

juliaOverlay = self: super: {
  julia-fhs = ...
};

in {
...
nixpkgs.overlays = [
  juliaOverlay
];
...
}

The closest I've gotten to getting the Julia ecosystem working on NixOS is the following. Unfortunately, while I can get CUDA working, CUDNN still does not, so not very useful for ML packages like CuArrays or Flux.

For what it is worth test CuArrays passes almost all tests. Does that mean CUDNN is working?

what is the current status of packaging Julia with Nix?

@schlichtanders I'm not aware of any efforts. Seems like this is possible today however, using the approach in https://github.com/NixOS/nixpkgs/issues/20649#issuecomment-434236041. I don't think the lack of determinism in precompilation is a deal-breaker. From a practical standpoint, nix hashes the inputs not the outputs, so the ecosystem already works with non-deterministic builds: https://r13y.com/.

When upstream fixes reproducibility, great, we'll reap the benefits, but I don't think that should stop us from having a workable solution for now. I think we just need someone to spearhead the effort. I'd certainly be happy to help with specific packages I care about (e.g. Flux.jl).

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/system-with-nixos-how-to-add-another-extra-distribution/5767/11

With overlay by @danieldk and expression by @tbenst tried and got
builderror.log

Was this page helpful?
0 / 5 - 0 ratings

Related issues

domenkozar picture domenkozar  Â·  3Comments

copumpkin picture copumpkin  Â·  3Comments

chris-martin picture chris-martin  Â·  3Comments

langston-barrett picture langston-barrett  Â·  3Comments

rzetterberg picture rzetterberg  Â·  3Comments